elements) {
this.elements = elements;
}
public Layer add(MapObject element) {
element.setLayer(this);
elements = add(elements, element);
return this;
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/JMapController.java 0000644 0000000 0000000 00000002117 12475707776 025274 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
/**
* Abstract base class for all mouse controller implementations. For
* implementing your own controller create a class that derives from this one
* and implements one or more of the following interfaces:
*
* - {@link MouseListener}
* - {@link MouseMotionListener}
* - {@link MouseWheelListener}
*
*
* @author Jan Peter Stotz
*/
public abstract class JMapController {
protected JMapViewer map;
public JMapController(JMapViewer map) {
this.map = map;
if (this instanceof MouseListener)
map.addMouseListener((MouseListener) this);
if (this instanceof MouseWheelListener)
map.addMouseWheelListener((MouseWheelListener) this);
if (this instanceof MouseMotionListener)
map.addMouseMotionListener((MouseMotionListener) this);
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/events/ 0000755 0000000 0000000 00000000000 12604423574 023022 5 ustar root root jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/events/JMVCommandEvent.java 0000644 0000000 0000000 00000001755 12604423574 026632 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.events;
import java.util.EventObject;
/**
* Used for passing events between UI components and other
* objects that register as a JMapViewerEventListener
*
* @author Jason Huntley
*
*/
public class JMVCommandEvent extends EventObject {
public enum COMMAND {
MOVE,
ZOOM
}
private COMMAND command;
/**
*
*/
private static final long serialVersionUID = 8701544867914969620L;
public JMVCommandEvent(COMMAND cmd, Object source) {
super(source);
setCommand(cmd);
}
public JMVCommandEvent(Object source) {
super(source);
}
/**
* @return the command
*/
public COMMAND getCommand() {
return command;
}
/**
* @param command the command to set
*/
public void setCommand(COMMAND command) {
this.command = command;
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/MapMarkerDot.java 0000644 0000000 0000000 00000003301 12566160376 024711 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer;
import java.awt.Color;
import org.openstreetmap.gui.jmapviewer.interfaces.MapMarker;
/**
* A simple implementation of the {@link MapMarker} interface. Each map marker
* is painted as a circle with a black border line and filled with a specified
* color.
*
* @author Jan Peter Stotz
*
*/
public class MapMarkerDot extends MapMarkerCircle {
public static final int DOT_RADIUS = 5;
public MapMarkerDot(Coordinate coord) {
this(null, null, coord);
}
public MapMarkerDot(String name, Coordinate coord) {
this(null, name, coord);
}
public MapMarkerDot(Layer layer, Coordinate coord) {
this(layer, null, coord);
}
public MapMarkerDot(Layer layer, String name, Coordinate coord) {
this(layer, name, coord, getDefaultStyle());
}
public MapMarkerDot(Color color, double lat, double lon) {
this(null, null, lat, lon);
setColor(color);
}
public MapMarkerDot(double lat, double lon) {
this(null, null, lat, lon);
}
public MapMarkerDot(Layer layer, double lat, double lon) {
this(layer, null, lat, lon);
}
public MapMarkerDot(Layer layer, String name, double lat, double lon) {
this(layer, name, new Coordinate(lat, lon), getDefaultStyle());
}
public MapMarkerDot(Layer layer, String name, Coordinate coord, Style style) {
super(layer, name, coord, DOT_RADIUS, STYLE.FIXED, style);
}
public static Style getDefaultStyle() {
return new Style(Color.BLACK, Color.YELLOW, null, getDefaultFont());
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/OsmMercator.java 0000644 0000000 0000000 00000015775 12566160376 024640 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer;
/**
* This class implements the Mercator Projection as it is used by OpenStreetMap
* (and google). It provides methods to translate coordinates from 'map space'
* into latitude and longitude (on the WGS84 ellipsoid) and vice versa. Map
* space is measured in pixels. The origin of the map space is the top left
* corner. The map space origin (0,0) has latitude ~85 and longitude -180.
* @author Jan Peter Stotz
* @author Jason Huntley
*/
public class OsmMercator {
/**
* default tile size
*/
public static final int DEFAUL_TILE_SIZE = 256;
/** maximum latitude (north) for mercator display */
public static final double MAX_LAT = 85.05112877980659;
/** minimum latitude (south) for mercator display */
public static final double MIN_LAT = -85.05112877980659;
/** equatorial earth radius for EPSG:3857 (Mercator) */
private static double EARTH_RADIUS = 6378137;
/**
* instance with tile size of 256 for easy conversions
*/
public static final OsmMercator MERCATOR_256 = new OsmMercator();
/** tile size of the displayed tiles */
private int tileSize = DEFAUL_TILE_SIZE;
/**
* Creates instance with default tile size of 256
*/
public OsmMercator() {
}
/**
* Creates instance with provided tile size.
* @param tileSize tile size in pixels
*/
public OsmMercator(int tileSize) {
this.tileSize = tileSize;
}
public double radius(int aZoomlevel) {
return (tileSize * (1 << aZoomlevel)) / (2.0 * Math.PI);
}
/**
* Returns the absolut number of pixels in y or x, defined as: 2^Zoomlevel *
* tileSize where tileSize is the width of a tile in pixels
*
* @param aZoomlevel zoom level to request pixel data
* @return number of pixels
*/
public int getMaxPixels(int aZoomlevel) {
return tileSize * (1 << aZoomlevel);
}
public int falseEasting(int aZoomlevel) {
return getMaxPixels(aZoomlevel) / 2;
}
public int falseNorthing(int aZoomlevel) {
return -1 * getMaxPixels(aZoomlevel) / 2;
}
/**
* Transform pixelspace to coordinates and get the distance.
*
* @param x1 the first x coordinate
* @param y1 the first y coordinate
* @param x2 the second x coordinate
* @param y2 the second y coordinate
*
* @param zoomLevel the zoom level
* @return the distance
*/
public double getDistance(int x1, int y1, int x2, int y2, int zoomLevel) {
double la1 = yToLat(y1, zoomLevel);
double lo1 = xToLon(x1, zoomLevel);
double la2 = yToLat(y2, zoomLevel);
double lo2 = xToLon(x2, zoomLevel);
return getDistance(la1, lo1, la2, lo2);
}
/**
* Gets the distance using Spherical law of cosines.
*
* @param la1 the Latitude in degrees
* @param lo1 the Longitude in degrees
* @param la2 the Latitude from 2nd coordinate in degrees
* @param lo2 the Longitude from 2nd coordinate in degrees
* @return the distance
*/
public double getDistance(double la1, double lo1, double la2, double lo2) {
double aStartLat = Math.toRadians(la1);
double aStartLong = Math.toRadians(lo1);
double aEndLat = Math.toRadians(la2);
double aEndLong = Math.toRadians(lo2);
double distance = Math.acos(Math.sin(aStartLat) * Math.sin(aEndLat)
+ Math.cos(aStartLat) * Math.cos(aEndLat)
* Math.cos(aEndLong - aStartLong));
return EARTH_RADIUS * distance;
}
/**
* Transform longitude to pixelspace
*
*
* Mathematical optimization
*
* x = radius(aZoomlevel) * toRadians(aLongitude) + falseEasting(aZoomLevel)
* x = getMaxPixels(aZoomlevel) / (2 * PI) * (aLongitude * PI) / 180 + getMaxPixels(aZoomlevel) / 2
* x = getMaxPixels(aZoomlevel) * aLongitude / 360 + 180 * getMaxPixels(aZoomlevel) / 360
* x = getMaxPixels(aZoomlevel) * (aLongitude + 180) / 360
*
*
*
* @param aLongitude
* [-180..180]
* @param aZoomlevel zoom level
* @return [0..2^Zoomlevel*TILE_SIZE[
*/
public double lonToX(double aLongitude, int aZoomlevel) {
int mp = getMaxPixels(aZoomlevel);
double x = (mp * (aLongitude + 180L)) / 360L;
return Math.min(x, mp);
}
/**
* Transforms latitude to pixelspace
*
* Mathematical optimization
*
* log(u) := log((1.0 + sin(toRadians(aLat))) / (1.0 - sin(toRadians(aLat))
*
* y = -1 * (radius(aZoomlevel) / 2 * log(u)))) - falseNorthing(aZoomlevel))
* y = -1 * (getMaxPixel(aZoomlevel) / 2 * PI / 2 * log(u)) - -1 * getMaxPixel(aZoomLevel) / 2
* y = getMaxPixel(aZoomlevel) / (-4 * PI) * log(u)) + getMaxPixel(aZoomLevel) / 2
* y = getMaxPixel(aZoomlevel) * ((log(u) / (-4 * PI)) + 1/2)
*
*
* @param aLat
* [-90...90]
* @param aZoomlevel zoom level
* @return [0..2^Zoomlevel*TILE_SIZE[
*/
public double latToY(double aLat, int aZoomlevel) {
if (aLat < MIN_LAT)
aLat = MIN_LAT;
else if (aLat > MAX_LAT)
aLat = MAX_LAT;
double sinLat = Math.sin(Math.toRadians(aLat));
double log = Math.log((1.0 + sinLat) / (1.0 - sinLat));
int mp = getMaxPixels(aZoomlevel);
double y = mp * (0.5 - (log / (4.0 * Math.PI)));
return Math.min(y, mp - 1);
}
/**
* Transforms pixel coordinate X to longitude
*
*
* Mathematical optimization
*
* lon = toDegree((aX - falseEasting(aZoomlevel)) / radius(aZoomlevel))
* lon = 180 / PI * ((aX - getMaxPixels(aZoomlevel) / 2) / getMaxPixels(aZoomlevel) / (2 * PI)
* lon = 180 * ((aX - getMaxPixels(aZoomlevel) / 2) / getMaxPixels(aZoomlevel))
* lon = 360 / getMaxPixels(aZoomlevel) * (aX - getMaxPixels(aZoomlevel) / 2)
* lon = 360 * aX / getMaxPixels(aZoomlevel) - 180
*
*
* @param aX
* [0..2^Zoomlevel*TILE_WIDTH[
* @param aZoomlevel zoom level
* @return ]-180..180[
*/
public double xToLon(int aX, int aZoomlevel) {
return ((360d * aX) / getMaxPixels(aZoomlevel)) - 180.0;
}
/**
* Transforms pixel coordinate Y to latitude
*
* @param aY
* [0..2^Zoomlevel*TILE_WIDTH[
* @param aZoomlevel zoom level
* @return [MIN_LAT..MAX_LAT] is about [-85..85]
*/
public double yToLat(int aY, int aZoomlevel) {
aY += falseNorthing(aZoomlevel);
double latitude = (Math.PI / 2) - (2 * Math.atan(Math.exp(-1.0 * aY / radius(aZoomlevel))));
return -1 * Math.toDegrees(latitude);
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/AbstractLayer.java 0000644 0000000 0000000 00000005177 12566160406 025132 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer;
import java.util.ArrayList;
import java.util.List;
public class AbstractLayer {
private LayerGroup parent;
private String name;
private String description;
private Style style;
private Boolean visible;
private Boolean visibleTexts = Boolean.TRUE;
public AbstractLayer(String name) {
this(name, (String) null);
}
public AbstractLayer(String name, String description) {
this(name, description, MapMarkerCircle.getDefaultStyle());
}
public AbstractLayer(String name, Style style) {
this(name, null, style);
}
public AbstractLayer(String name, String description, Style style) {
this(null, name, description, style);
}
public AbstractLayer(LayerGroup parent, String name) {
this(parent, name, MapMarkerCircle.getDefaultStyle());
}
public AbstractLayer(LayerGroup parent, String name, Style style) {
this(parent, name, null, style);
}
public AbstractLayer(LayerGroup parent, String name, String description, Style style) {
setParent(parent);
setName(name);
setDescription(description);
setStyle(style);
setVisible(Boolean.TRUE);
if (parent != null) parent.add(this);
}
public LayerGroup getParent() {
return parent;
}
public void setParent(LayerGroup parent) {
this.parent = parent;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Style getStyle() {
return style;
}
public void setStyle(Style style) {
this.style = style;
}
public Boolean isVisible() {
return visible;
}
public void setVisible(Boolean visible) {
this.visible = visible;
}
public static List add(List list, E element) {
if (element != null) {
if (list == null) list = new ArrayList<>();
if (!list.contains(element)) list.add(element);
}
return list;
}
public Boolean isVisibleTexts() {
return visibleTexts;
}
public void setVisibleTexts(Boolean visibleTexts) {
this.visibleTexts = visibleTexts;
}
@Override
public String toString() {
return name;
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/JMapViewerTree.java 0000644 0000000 0000000 00000014512 12641052742 025211 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSplitPane;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import org.openstreetmap.gui.jmapviewer.checkBoxTree.CheckBoxNodePanel;
import org.openstreetmap.gui.jmapviewer.checkBoxTree.CheckBoxTree;
import org.openstreetmap.gui.jmapviewer.interfaces.MapObject;
/**
* Tree of layers for JMapViewer component
* @author galo
*/
public class JMapViewerTree extends JPanel {
/** Serial Version UID */
private static final long serialVersionUID = 3050203054402323972L;
private JMapViewer map;
private CheckBoxTree tree;
private JPanel treePanel;
private JSplitPane splitPane;
public JMapViewerTree(String name) {
this(name, false);
}
public JMapViewerTree(String name, boolean treeVisible) {
super();
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
tree = new CheckBoxTree(name);
treePanel = new JPanel();
treePanel.setLayout(new BorderLayout());
treePanel.add(tree, BorderLayout.CENTER);
treePanel.add(new JLabel("Use right mouse button to
show/hide texts"), BorderLayout.SOUTH);
map = new JMapViewer();
splitPane.setOneTouchExpandable(true);
splitPane.setDividerLocation(150);
//Provide minimum sizes for the two components in the split pane
Dimension minimumSize = new Dimension(100, 50);
//tree.setMinimumSize(minimumSize);
map.setMinimumSize(minimumSize);
createRefresh();
setLayout(new BorderLayout());
setTreeVisible(treeVisible);
tree.addNodeListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
@Override
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
AbstractLayer layer = ((CheckBoxNodePanel) e.getComponent()).getData().getAbstractLayer();
if (layer != null)
JMapViewerTree.this.createPopupMenu(layer).show(e.getComponent(), e.getX(), e.getY());
}
}
});
}
private JPopupMenu createPopupMenu(final AbstractLayer layer) {
JMenuItem menuItemShow = new JMenuItem("show texts");
JMenuItem menuItemHide = new JMenuItem("hide texts");
//Create the popup menu.
JPopupMenu popup = new JPopupMenu();
// Create items
if (layer.isVisibleTexts() == null) {
popup.add(menuItemShow);
popup.add(menuItemHide);
} else if (layer.isVisibleTexts()) popup.add(menuItemHide);
else popup.add(menuItemShow);
menuItemShow.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
setVisibleTexts(layer, true);
if (layer.getParent() != null) layer.getParent().calculateVisibleTexts();
map.repaint();
}
});
menuItemHide.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
setVisibleTexts(layer, false);
if (layer.getParent() != null) layer.getParent().calculateVisibleTexts();
map.repaint();
}
});
return popup;
}
private static void setVisibleTexts(AbstractLayer layer, boolean visible) {
layer.setVisibleTexts(visible);
if (layer instanceof LayerGroup) {
LayerGroup group = (LayerGroup) layer;
if (group.getLayers() != null)
for (AbstractLayer al: group.getLayers()) {
setVisibleTexts(al, visible);
}
}
}
public Layer addLayer(String name) {
Layer layer = new Layer(name);
this.addLayer(layer);
return layer;
}
public JMapViewerTree addLayer(Layer layer) {
tree.addLayer(layer);
return this;
}
public JMapViewerTree addLayer(MapObject element) {
//element.getLayer().add(element);
return addLayer(element.getLayer());
}
public Layer removeFromLayer(MapObject element) {
element.getLayer().getElements().remove(element);
return element.getLayer();
}
public static int size(List> list) {
return list == null ? 0 : list.size();
}
public JMapViewer getViewer() {
return map;
}
public CheckBoxTree getTree() {
return tree;
}
public void addMapObject(MapObject o){
}
public void setTreeVisible(boolean visible) {
removeAll();
revalidate();
if (visible) {
splitPane.setLeftComponent(treePanel);
splitPane.setRightComponent(map);
add(splitPane, BorderLayout.CENTER);
} else add(map, BorderLayout.CENTER);
repaint();
}
private void createRefresh() {
tree.getModel().addTreeModelListener(new TreeModelListener() {
@Override
public void treeNodesChanged(final TreeModelEvent e) {
repaint();
}
@Override
public void treeNodesInserted(TreeModelEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void treeNodesRemoved(TreeModelEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void treeStructureChanged(TreeModelEvent arg0) {
// TODO Auto-generated method stub
}
});
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/MemoryTileCache.java 0000644 0000000 0000000 00000014526 12641052742 025377 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import org.openstreetmap.gui.jmapviewer.interfaces.TileCache;
import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
/**
* {@link TileCache} implementation that stores all {@link Tile} objects in
* memory up to a certain limit ({@link #getCacheSize()}). If the limit is
* exceeded the least recently used {@link Tile} objects will be deleted.
*
* @author Jan Peter Stotz
*/
public class MemoryTileCache implements TileCache {
protected static final Logger log = Logger.getLogger(MemoryTileCache.class.getName());
/**
* Default cache size
*/
protected int cacheSize;
protected final Map hash;
/**
* List of all tiles in their last recently used order
*/
protected final CacheLinkedListElement lruTiles;
/**
* Constructs a new {@code MemoryTileCache}.
*/
public MemoryTileCache() {
this(200);
}
/**
* Constructs a new {@code MemoryTileCache}.
* @param cacheSize size of the cache
*/
public MemoryTileCache(int cacheSize) {
this.cacheSize = cacheSize;
hash = new HashMap<>(cacheSize);
lruTiles = new CacheLinkedListElement();
}
@Override
public synchronized void addTile(Tile tile) {
CacheEntry entry = createCacheEntry(tile);
if (hash.put(tile.getKey(), entry) == null) {
// only if hash hadn't had the element, add it to LRU
lruTiles.addFirst(entry);
if (hash.size() > cacheSize || lruTiles.getElementCount() > cacheSize) {
removeOldEntries();
}
}
}
@Override
public synchronized Tile getTile(TileSource source, int x, int y, int z) {
CacheEntry entry = hash.get(Tile.getTileKey(source, x, y, z));
if (entry == null)
return null;
lruTiles.moveElementToFirstPos(entry);
return entry.tile;
}
/**
* Removes the least recently used tiles
*/
protected synchronized void removeOldEntries() {
try {
while (lruTiles.getElementCount() > cacheSize) {
removeEntry(lruTiles.getLastElement());
}
} catch (Exception e) {
log.warning(e.getMessage());
}
}
protected synchronized void removeEntry(CacheEntry entry) {
hash.remove(entry.tile.getKey());
lruTiles.removeEntry(entry);
}
protected CacheEntry createCacheEntry(Tile tile) {
return new CacheEntry(tile);
}
@Override
public synchronized void clear() {
hash.clear();
lruTiles.clear();
}
@Override
public synchronized int getTileCount() {
return hash.size();
}
@Override
public synchronized int getCacheSize() {
return cacheSize;
}
/**
* Changes the maximum number of {@link Tile} objects that this cache holds.
*
* @param cacheSize
* new maximum number of tiles
*/
public synchronized void setCacheSize(int cacheSize) {
this.cacheSize = cacheSize;
if (hash.size() > cacheSize)
removeOldEntries();
}
/**
* Linked list element holding the {@link Tile} and links to the
* {@link #next} and {@link #prev} item in the list.
*/
protected static class CacheEntry {
private Tile tile;
private CacheEntry next;
private CacheEntry prev;
protected CacheEntry(Tile tile) {
this.tile = tile;
}
}
/**
* Special implementation of a double linked list for {@link CacheEntry}
* elements. It supports element removal in constant time - in difference to
* the Java implementation which needs O(n).
*
* @author Jan Peter Stotz
*/
protected static class CacheLinkedListElement {
protected CacheEntry firstElement;
protected CacheEntry lastElement;
protected int elementCount;
/**
* Constructs a new {@code CacheLinkedListElement}.
*/
public CacheLinkedListElement() {
clear();
}
public void clear() {
elementCount = 0;
firstElement = null;
lastElement = null;
}
/**
* Add the element to the head of the list.
*
* @param element new element to be added
*/
public void addFirst(CacheEntry element) {
if (element == null) return;
if (elementCount == 0) {
firstElement = element;
lastElement = element;
element.prev = null;
element.next = null;
} else {
element.next = firstElement;
firstElement.prev = element;
element.prev = null;
firstElement = element;
}
elementCount++;
}
/**
* Removes the specified element from the list.
*
* @param element element to be removed
*/
public void removeEntry(CacheEntry element) {
if (element == null) return;
if (element.next != null) {
element.next.prev = element.prev;
}
if (element.prev != null) {
element.prev.next = element.next;
}
if (element == firstElement)
firstElement = element.next;
if (element == lastElement)
lastElement = element.prev;
element.next = null;
element.prev = null;
elementCount--;
}
public void moveElementToFirstPos(CacheEntry entry) {
if (firstElement == entry)
return;
removeEntry(entry);
addFirst(entry);
}
public int getElementCount() {
return elementCount;
}
public CacheEntry getLastElement() {
return lastElement;
}
public CacheEntry getFirstElement() {
return firstElement;
}
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/ 0000755 0000000 0000000 00000000000 12641052742 024053 5 ustar root root jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/TileSourceInfo.java 0000644 0000000 0000000 00000010757 12641052742 027622 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
import java.util.Map;
import org.openstreetmap.gui.jmapviewer.OsmMercator;
/**
* Data class that keeps basic information about a tile source.
*
* @since 31122
*/
public class TileSourceInfo {
/** id for this imagery entry, optional at the moment */
protected String id;
/** URL of the imagery service */
protected String url;
/** name of the imagery layer */
protected String name;
/** headers meaning, that there is no tile at this zoom level */
protected Map noTileHeaders;
/** minimum zoom level supported by the tile source */
protected int minZoom;
/** maximum zoom level supported by the tile source */
protected int maxZoom;
/** cookies that needs to be sent to tile source */
protected String cookies = "";
/** tile size of the displayed tiles */
private int tileSize = OsmMercator.DEFAUL_TILE_SIZE; // FIXME: set to -1 for next release
/** mapping <header key, metadata key> */
protected Map metadataHeaders;
/**
* Create a TileSourceInfo class
*
* @param name name
* @param baseUrl base URL
* @param id unique id
*/
public TileSourceInfo(String name, String baseUrl, String id) {
this.name = name;
this.url = baseUrl;
this.id = id;
}
/**
* Create a TileSourceInfo class
*
* @param name name
*/
public TileSourceInfo(String name) {
this(name, null, null);
}
/**
* Creates empty TileSourceInfo class
*/
public TileSourceInfo() {
this(null, null, null);
}
/**
* Request name of the tile source
* @return name of the tile source
*/
public final String getName() {
return name;
}
/**
* Request URL of the tile source
* @return url of the tile source
*/
public final String getUrl() {
return url;
}
/**
* Request ID of the tile source. Id can be null. This gets the configured id as is.
* Due to a user error, this may not be unique.
* @return id of the tile source
*/
public final String getId() {
return id;
}
/**
* Request header information for empty tiles for servers delivering such tile types
* @return map of headers, that when set, means that this is "no tile at this zoom level" situation
*/
public Map getNoTileHeaders() {
return noTileHeaders;
}
/**
* Request supported minimum zoom level
* @return minimum zoom level supported by tile source
*/
public int getMinZoom() {
return minZoom;
}
/**
* Request supported maximum zoom level
* @return maximum zoom level supported by tile source
*/
public int getMaxZoom() {
return maxZoom;
}
/**
* Request cookies to be sent together with request
* @return cookies to be sent along with request to tile source
*/
public String getCookies() {
return cookies;
}
/**
* Request tile size of this tile source
* @return tile size provided by this tile source, or -1 when default value should be used
*/
public int getTileSize() {
return tileSize;
}
/**
* Request metadata headers
* @return mapping <HTTP header name, Metadata key name> for copying HTTP headers to Tile metadata
* @since 31125
*/
public Map getMetadataHeaders() {
return metadataHeaders;
}
/**
* Sets the tile size provided by this tile source
* @param tileSize tile size in pixels
*/
public final void setTileSize(int tileSize) {
if (tileSize == 0 || tileSize < -1) {
throw new AssertionError("Invalid tile size: " + tileSize);
}
this.tileSize = tileSize;
}
/**
* Sets the tile URL.
* @param url tile URL
*/
public final void setUrl(String url) {
this.url = url;
}
/**
* Sets the tile name.
* @param name tile name
*/
public final void setName(String name) {
this.name = name;
}
/**
* Sets the tile id.
* @param id tile id
*/
public final void setId(String id) {
this.id = id;
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractMapQuestTileSource.java 0000644 0000000 0000000 00000005025 12641052742 032142 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
public class AbstractMapQuestTileSource extends AbstractOsmTileSource {
// MapQuest logo in base64: http://developer.mapquest.com/content/osm/mq_logo.png
private static final String LOGO_BASE64 =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJl"+
"YWR5ccllPAAAAZtJREFUeNpi/P//P0PPcYf/DGSAEssDjIzdx+zJ0gwDLMQqVBWyZVAStGRgBMK33x8wnH62"+
"kngD+DmkGBwUshn42SXA/P8M/xg+/3rDcOPNPuIMMJeKAmv+8OMpw7ffHxikeLUZXBTzgez3DEzEGMDGzAmm"+
"jz5ewLDqWiHE6UwcDHxsYhAXsLPwMFhKxzIIccozPP18ieHhx3MMGsKOYP7td4fBzgUBN+ViBkeFLDD7zbf7"+
"DK++3WFgAMXC448X/uMDV17t+H/r7UEM8VNPl/8Hu0CGTx9s6tXXOxhEuJQYxLnVgK44w/Dzz1cGNWF7BlGg"+
"2KJLqQzCQBcxMbEw/P77g0FTxBkYJs8gXgCFKiMwOLbf6WDQF/djcFUqAvv33fdHYAM4WPjAFrz9/hAeLsef"+
"LALT4EBkhIYlMxMrAxerIJjNCdTExy4OZv/59xNnAKPEAh+bBNAQSMwKcsgAQ5odzBbilGNghcYE1pS4+14f"+
"MKq4GP79/w1OHCC/v/x6Exzv+x9MhbiOEeh3LAZQnBeYGCgEjJRmZ4AAAwCE6rplT3Ba/gAAAABJRU5ErkJg"+
"gg==";
protected static final String MAPQUEST_ATTRIBUTION = "Tiles Courtesy of MapQuest ";
protected static final String MAPQUEST_WEBSITE = "http://www.mapquest.com";
private static final int NUMBER_OF_SERVERS = 4;
private int SERVER_NUM = 1;
public AbstractMapQuestTileSource(String name, String baseUrl, String id) {
super(name, baseUrl, id);
}
@Override
public String getBaseUrl() {
String url = String.format(this.baseUrl, SERVER_NUM);
SERVER_NUM = (SERVER_NUM % NUMBER_OF_SERVERS) + 1;
return url;
}
@Override
public Image getAttributionImage() {
try {
return ImageIO.read(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(LOGO_BASE64)));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@Override
public String getAttributionImageURL() {
return MAPQUEST_WEBSITE;
}
/* (non-Javadoc)
* @see org.openstreetmap.gui.jmapviewer.tilesources.AbstractOsmTileSource#getTermsOfUseURL()
*/
@Override
public String getTermsOfUseURL() {
return "http://developer.mapquest.com/web/products/open/map#terms";
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/ScanexTileSource.java 0000644 0000000 0000000 00000010523 12641052742 030137 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
import java.util.Random;
import org.openstreetmap.gui.jmapviewer.OsmMercator;
/**
* This tilesource uses different to OsmMercator projection.
*
* Earth is assumed an ellipsoid in this projection, unlike
* sphere in OsmMercator, so latitude calculation differs a lot.
*
* The longitude calculation is the same as in OsmMercator,
* we inherit it from AbstractTMSTileSource.
*
* TODO: correct getDistance() method.
*/
public class ScanexTileSource extends TMSTileSource {
private static final String DEFAULT_URL = "http://maps.kosmosnimki.ru";
private static final int DEFAULT_MAXZOOM = 14;
private static final String API_KEY = "4018C5A9AECAD8868ED5DEB2E41D09F7";
// Latitude to Y and back calculations.
/** radius of Earth at equator, m */
private static double RADIUS_E = 6378137;
/** equator length, m */
private static double EQUATOR = 40075016.68557849;
/** eccentricity of Earth's ellipsoid */
private static double E = 0.0818191908426;
private enum ScanexLayer {
IRS("irs", "/TileSender.ashx?ModeKey=tile&MapName=F7B8CF651682420FA1749D894C8AD0F6&LayerName=BAC78D764F0443BD9AF93E7A998C9F5B"),
SPOT("spot", "/TileSender.ashx?ModeKey=tile&MapName=F7B8CF651682420FA1749D894C8AD0F6&LayerName=F51CE95441284AF6B2FC319B609C7DEC");
private String name;
private String uri;
ScanexLayer(String name, String uri) {
this.name = name;
this.uri = uri;
}
public String getName() {
return name;
}
public String getUri() {
return uri;
}
}
/** IRS by default */
private ScanexLayer layer = ScanexLayer.IRS;
/** cached latitude used in {@link #tileYToLat(double, int)} */
private double cachedLat;
/**
* Constructs a new {@code ScanexTileSource}.
* @param info tile source info
*/
public ScanexTileSource(TileSourceInfo info) {
super(info);
String url = info.getUrl();
for (ScanexLayer slayer : ScanexLayer.values()) {
if (url.equalsIgnoreCase(slayer.getName())) {
this.layer = slayer;
// Override baseUrl and maxZoom in base class.
this.baseUrl = DEFAULT_URL;
if (maxZoom == 0)
this.maxZoom = DEFAULT_MAXZOOM;
break;
}
}
}
@Override
public String getExtension() {
return "jpeg";
}
@Override
public String getTilePath(int zoom, int tilex, int tiley) {
int tmp = (int) Math.pow(2.0, zoom - 1);
tilex = tilex - tmp;
tiley = tmp - tiley - 1;
return this.layer.getUri() + "&apikey=" + API_KEY + "&x=" + tilex + "&y=" + tiley + "&z=" + zoom;
}
/*
* To solve inverse formula latitude = f(y) we use
* Newton's method. We cache previous calculated latitude,
* because new one is usually close to the old one. In case
* if solution gets out of bounds, we reset to a new random value.
*/
private double tileYToLat(double y, int zoom) {
double lat0;
double lat = cachedLat;
do {
lat0 = lat;
lat = lat - Math.toDegrees(nextTerm(Math.toRadians(lat), y, zoom));
if (lat > OsmMercator.MAX_LAT || lat < OsmMercator.MIN_LAT) {
Random r = new Random();
lat = OsmMercator.MIN_LAT +
r.nextInt((int) (OsmMercator.MAX_LAT - OsmMercator.MIN_LAT));
}
} while (Math.abs(lat0 - lat) > 0.000001);
cachedLat = lat;
return lat;
}
/* Next term in Newton's polynomial */
private static double nextTerm(double lat, double y, int zoom) {
double sinl = Math.sin(lat);
double cosl = Math.cos(lat);
zoom = (int) Math.pow(2.0, zoom - 1);
double ec = Math.exp((1 - y/zoom)*Math.PI);
double f = Math.tan(Math.PI/4+lat/2) -
ec * Math.pow(Math.tan(Math.PI/4 + Math.asin(E * sinl)/2), E);
double df = 1/(1 - sinl) - ec * E * cosl/((1 - E * sinl) *
(Math.sqrt(1 - E * E * sinl * sinl)));
return f/df;
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/MapQuestOsmTileSource.java 0000644 0000000 0000000 00000001241 12566160376 031142 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
public class MapQuestOsmTileSource extends AbstractMapQuestTileSource {
private static final String PATTERN = "http://otile%d.mqcdn.com/tiles/1.0.0/osm";
public MapQuestOsmTileSource() {
super("MapQuest-OSM", PATTERN, "mapquest-osm");
}
@Override
public String getAttributionText(int zoom, ICoordinate topLeft,
ICoordinate botRight) {
return super.getAttributionText(zoom, topLeft, botRight)+" - "+MAPQUEST_ATTRIBUTION;
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractTMSTileSource.java 0000644 0000000 0000000 00000016165 12604423574 031061 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
import java.awt.Point;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.openstreetmap.gui.jmapviewer.OsmMercator;
import org.openstreetmap.gui.jmapviewer.Tile;
import org.openstreetmap.gui.jmapviewer.TileXY;
import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
/**
* Class generalizing all tile based tile sources
*
* @author Wiktor Niesiobędzki
*
*/
public abstract class AbstractTMSTileSource extends AbstractTileSource {
protected String name;
protected String baseUrl;
protected String id;
private final Map noTileHeaders;
private final Map metadataHeaders;
protected int tileSize;
protected OsmMercator osmMercator;
/**
* Creates an instance based on TileSource information
*
* @param info description of the Tile Source
*/
public AbstractTMSTileSource(TileSourceInfo info) {
this.name = info.getName();
this.baseUrl = info.getUrl();
if (baseUrl != null && baseUrl.endsWith("/")) {
baseUrl = baseUrl.substring(0, baseUrl.length()-1);
}
this.id = info.getUrl();
this.noTileHeaders = info.getNoTileHeaders();
this.metadataHeaders = info.getMetadataHeaders();
this.tileSize = info.getTileSize();
this.osmMercator = new OsmMercator(this.tileSize);
}
/**
* @return default tile size to use, when not set in Imagery Preferences
*/
@Override
public int getDefaultTileSize() {
return OsmMercator.DEFAUL_TILE_SIZE;
}
@Override
public String getName() {
return name;
}
@Override
public String getId() {
return id;
}
@Override
public int getMaxZoom() {
return 21;
}
@Override
public int getMinZoom() {
return 0;
}
/**
* @return image extension, used for URL creation
*/
public String getExtension() {
return "png";
}
/**
* @param zoom level of the tile
* @param tilex tile number in x axis
* @param tiley tile number in y axis
* @return String containg path part of URL of the tile
* @throws IOException when subclass cannot return the tile URL
*/
public String getTilePath(int zoom, int tilex, int tiley) throws IOException {
return "/" + zoom + "/" + tilex + "/" + tiley + "." + getExtension();
}
/**
* @return Base part of the URL of the tile source
*/
public String getBaseUrl() {
return this.baseUrl;
}
@Override
public String getTileUrl(int zoom, int tilex, int tiley) throws IOException {
return this.getBaseUrl() + getTilePath(zoom, tilex, tiley);
}
@Override
public String toString() {
return getName();
}
/*
* Most tilesources use OsmMercator projection.
*/
@Override
public int getTileSize() {
if (tileSize <= 0) {
return getDefaultTileSize();
}
return tileSize;
}
@Override
public double getDistance(double lat1, double lon1, double lat2, double lon2) {
return osmMercator.getDistance(lat1, lon1, lat2, lon2);
}
@Override
public Point latLonToXY(double lat, double lon, int zoom) {
return new Point(
(int) osmMercator.lonToX(lon, zoom),
(int) osmMercator.latToY(lat, zoom)
);
}
@Override
public Point latLonToXY(ICoordinate point, int zoom) {
return latLonToXY(point.getLat(), point.getLon(), zoom);
}
@Override
public ICoordinate xyToLatLon(Point point, int zoom) {
return xyToLatLon(point.x, point.y, zoom);
}
@Override
public ICoordinate xyToLatLon(int x, int y, int zoom) {
return new Coordinate(
osmMercator.yToLat(y, zoom),
osmMercator.xToLon(x, zoom)
);
}
@Override
public TileXY latLonToTileXY(double lat, double lon, int zoom) {
return new TileXY(
osmMercator.lonToX(lon, zoom) / tileSize,
osmMercator.latToY(lat, zoom) / tileSize
);
}
@Override
public TileXY latLonToTileXY(ICoordinate point, int zoom) {
return latLonToTileXY(point.getLat(), point.getLon(), zoom);
}
@Override
public ICoordinate tileXYToLatLon(TileXY xy, int zoom) {
return tileXYToLatLon(xy.getXIndex(), xy.getYIndex(), zoom);
}
@Override
public ICoordinate tileXYToLatLon(Tile tile) {
return tileXYToLatLon(tile.getXtile(), tile.getYtile(), tile.getZoom());
}
@Override
public ICoordinate tileXYToLatLon(int x, int y, int zoom) {
return new Coordinate(
osmMercator.yToLat(y * tileSize, zoom),
osmMercator.xToLon(x * tileSize, zoom)
);
}
@Override
public int getTileXMax(int zoom) {
return getTileMax(zoom);
}
@Override
public int getTileXMin(int zoom) {
return 0;
}
@Override
public int getTileYMax(int zoom) {
return getTileMax(zoom);
}
@Override
public int getTileYMin(int zoom) {
return 0;
}
@Override
public boolean isNoTileAtZoom(Map> headers, int statusCode, byte[] content) {
if (noTileHeaders != null && headers != null) {
for (Entry searchEntry: noTileHeaders.entrySet()) {
List headerVals = headers.get(searchEntry.getKey());
if (headerVals != null) {
for (String headerValue: headerVals) {
if (headerValue.matches(searchEntry.getValue())) {
return true;
}
}
}
}
}
return super.isNoTileAtZoom(headers, statusCode, content);
}
@Override
public Map getMetadata(Map> headers) {
Map ret = new HashMap<>();
if (metadataHeaders != null && headers != null) {
for (Entry searchEntry: metadataHeaders.entrySet()) {
List headerVals = headers.get(searchEntry.getKey());
if (headerVals != null) {
for (String headerValue: headerVals) {
ret.put(searchEntry.getValue(), headerValue);
}
}
}
}
return ret;
}
@Override
public String getTileId(int zoom, int tilex, int tiley) {
return this.baseUrl + "/" + zoom + "/" + tilex + "/" + tiley;
}
private static int getTileMax(int zoom) {
return (int) Math.pow(2.0, zoom) - 1;
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/TMSTileSource.java 0000644 0000000 0000000 00000001156 12641052742 027363 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
public class TMSTileSource extends AbstractTMSTileSource {
protected int maxZoom;
protected int minZoom;
public TMSTileSource(TileSourceInfo info) {
super(info);
minZoom = info.getMinZoom();
maxZoom = info.getMaxZoom();
}
@Override
public int getMinZoom() {
return (minZoom == 0) ? super.getMinZoom() : minZoom;
}
@Override
public int getMaxZoom() {
return (maxZoom == 0) ? super.getMaxZoom() : maxZoom;
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSource.java 0000644 0000000 0000000 00000012360 12641052742 031222 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.openstreetmap.gui.jmapviewer.interfaces.TemplatedTileSource;
/**
* Handles templated TMS Tile Source. Templated means, that some patterns within
* URL gets substituted.
*
* Supported parameters
* {zoom} - substituted with zoom level
* {z} - as above
* {NUMBER-zoom} - substituted with result of equation "NUMBER - zoom",
* eg. {20-zoom} for zoom level 15 will result in 5 in this place
* {zoom+number} - substituted with result of equation "zoom + number",
* eg. {zoom+5} for zoom level 15 will result in 20.
* {x} - substituted with X tile number
* {y} - substituted with Y tile number
* {!y} - substituted with Yahoo Y tile number
* {-y} - substituted with reversed Y tile number
* {switch:VAL_A,VAL_B,VAL_C,...} - substituted with one of VAL_A, VAL_B, VAL_C. Usually
* used to specify many tile servers
* {header:(HEADER_NAME,HEADER_VALUE)} - sets the headers to be sent to tile server
*/
public class TemplatedTMSTileSource extends TMSTileSource implements TemplatedTileSource {
private Random rand;
private String[] randomParts;
private final Map headers = new HashMap<>();
private static final String COOKIE_HEADER = "Cookie";
private static final String PATTERN_ZOOM = "\\{(?:(\\d+)-)?z(?:oom)?([+-]\\d+)?\\}";
private static final String PATTERN_X = "\\{x\\}";
private static final String PATTERN_Y = "\\{y\\}";
private static final String PATTERN_Y_YAHOO = "\\{!y\\}";
private static final String PATTERN_NEG_Y = "\\{-y\\}";
private static final String PATTERN_SWITCH = "\\{switch:([^}]+)\\}";
private static final String PATTERN_HEADER = "\\{header\\(([^,]+),([^}]+)\\)\\}";
private static final String[] ALL_PATTERNS = {
PATTERN_HEADER, PATTERN_ZOOM, PATTERN_X, PATTERN_Y, PATTERN_Y_YAHOO, PATTERN_NEG_Y,
PATTERN_SWITCH
};
/**
* Creates Templated TMS Tile Source based on ImageryInfo
* @param info imagery info
*/
public TemplatedTMSTileSource(TileSourceInfo info) {
super(info);
if (info.getCookies() != null) {
headers.put(COOKIE_HEADER, info.getCookies());
}
handleTemplate();
}
private void handleTemplate() {
// Capturing group pattern on switch values
Matcher m = Pattern.compile(".*"+PATTERN_SWITCH+".*").matcher(baseUrl);
if (m.matches()) {
rand = new Random();
randomParts = m.group(1).split(",");
}
Pattern pattern = Pattern.compile(PATTERN_HEADER);
StringBuffer output = new StringBuffer();
Matcher matcher = pattern.matcher(baseUrl);
while (matcher.find()) {
headers.put(matcher.group(1), matcher.group(2));
matcher.appendReplacement(output, "");
}
matcher.appendTail(output);
baseUrl = output.toString();
}
@Override
public Map getHeaders() {
return headers;
}
@Override
public String getTileUrl(int zoom, int tilex, int tiley) {
int finalZoom = zoom;
Matcher m = Pattern.compile(".*"+PATTERN_ZOOM+".*").matcher(this.baseUrl);
if (m.matches()) {
if (m.group(1) != null) {
finalZoom = Integer.parseInt(m.group(1))-zoom;
}
if (m.group(2) != null) {
String ofs = m.group(2);
if (ofs.startsWith("+"))
ofs = ofs.substring(1);
finalZoom += Integer.parseInt(ofs);
}
}
String r = this.baseUrl
.replaceAll(PATTERN_ZOOM, Integer.toString(finalZoom))
.replaceAll(PATTERN_X, Integer.toString(tilex))
.replaceAll(PATTERN_Y, Integer.toString(tiley))
.replaceAll(PATTERN_Y_YAHOO, Integer.toString((int) Math.pow(2, zoom-1)-1-tiley))
.replaceAll(PATTERN_NEG_Y, Integer.toString((int) Math.pow(2, zoom)-1-tiley));
if (rand != null) {
r = r.replaceAll(PATTERN_SWITCH, randomParts[rand.nextInt(randomParts.length)]);
}
return r;
}
/**
* Checks if url is acceptable by this Tile Source
* @param url URL to check
*/
public static void checkUrl(String url) {
assert url != null && !"".equals(url) : "URL cannot be null or empty";
Matcher m = Pattern.compile("\\{[^}]*\\}").matcher(url);
while (m.find()) {
boolean isSupportedPattern = false;
for (String pattern : ALL_PATTERNS) {
if (m.group().matches(pattern)) {
isSupportedPattern = true;
break;
}
}
if (!isSupportedPattern) {
throw new IllegalArgumentException(
m.group() + " is not a valid TMS argument. Please check this server URL:\n" + url);
}
}
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java 0000644 0000000 0000000 00000031666 12641052742 030726 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
import java.awt.Image;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.openstreetmap.gui.jmapviewer.JMapViewer;
import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class BingAerialTileSource extends AbstractTMSTileSource {
private static final String API_KEY = "Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU";
private static volatile Future> attributions; // volatile is required for getAttribution(), see below.
private static String imageUrlTemplate;
private static Integer imageryZoomMax;
private static String[] subdomains;
private static final Pattern subdomainPattern = Pattern.compile("\\{subdomain\\}");
private static final Pattern quadkeyPattern = Pattern.compile("\\{quadkey\\}");
private static final Pattern culturePattern = Pattern.compile("\\{culture\\}");
private String brandLogoUri;
/**
* Constructs a new {@code BingAerialTileSource}.
*/
public BingAerialTileSource() {
super(new TileSourceInfo("Bing", null, null));
}
/**
* Constructs a new {@code BingAerialTileSource}.
* @param info imagery info
*/
public BingAerialTileSource(TileSourceInfo info) {
super(info);
}
protected static class Attribution {
private String attribution;
private int minZoom;
private int maxZoom;
private Coordinate min;
private Coordinate max;
}
@Override
public String getTileUrl(int zoom, int tilex, int tiley) throws IOException {
// make sure that attribution is loaded. otherwise subdomains is null.
if (getAttribution() == null)
throw new IOException("Attribution is not loaded yet");
int t = (zoom + tilex + tiley) % subdomains.length;
String subdomain = subdomains[t];
String url = imageUrlTemplate;
url = subdomainPattern.matcher(url).replaceAll(subdomain);
url = quadkeyPattern.matcher(url).replaceAll(computeQuadTree(zoom, tilex, tiley));
return url;
}
protected URL getAttributionUrl() throws MalformedURLException {
return new URL("https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&output=xml&key="
+ API_KEY);
}
protected List parseAttributionText(InputSource xml) throws IOException {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xml);
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
imageUrlTemplate = xpath.compile("//ImageryMetadata/ImageUrl/text()").evaluate(document);
imageUrlTemplate = imageUrlTemplate.replace(
"http://ecn.{subdomain}.tiles.virtualearth.net/",
"https://ecn.{subdomain}.tiles.virtualearth.net/");
imageUrlTemplate = culturePattern.matcher(imageUrlTemplate).replaceAll(Locale.getDefault().toString());
imageryZoomMax = Integer.valueOf(xpath.compile("//ImageryMetadata/ZoomMax/text()").evaluate(document));
NodeList subdomainTxt = (NodeList) xpath.compile("//ImageryMetadata/ImageUrlSubdomains/string/text()")
.evaluate(document, XPathConstants.NODESET);
subdomains = new String[subdomainTxt.getLength()];
for (int i = 0; i < subdomainTxt.getLength(); i++) {
subdomains[i] = subdomainTxt.item(i).getNodeValue();
}
brandLogoUri = xpath.compile("/Response/BrandLogoUri/text()").evaluate(document);
XPathExpression attributionXpath = xpath.compile("Attribution/text()");
XPathExpression coverageAreaXpath = xpath.compile("CoverageArea");
XPathExpression zoomMinXpath = xpath.compile("ZoomMin/text()");
XPathExpression zoomMaxXpath = xpath.compile("ZoomMax/text()");
XPathExpression southLatXpath = xpath.compile("BoundingBox/SouthLatitude/text()");
XPathExpression westLonXpath = xpath.compile("BoundingBox/WestLongitude/text()");
XPathExpression northLatXpath = xpath.compile("BoundingBox/NorthLatitude/text()");
XPathExpression eastLonXpath = xpath.compile("BoundingBox/EastLongitude/text()");
NodeList imageryProviderNodes = (NodeList) xpath.compile("//ImageryMetadata/ImageryProvider")
.evaluate(document, XPathConstants.NODESET);
List attributions = new ArrayList<>(imageryProviderNodes.getLength());
for (int i = 0; i < imageryProviderNodes.getLength(); i++) {
Node providerNode = imageryProviderNodes.item(i);
String attribution = attributionXpath.evaluate(providerNode);
NodeList coverageAreaNodes = (NodeList) coverageAreaXpath.evaluate(providerNode, XPathConstants.NODESET);
for (int j = 0; j < coverageAreaNodes.getLength(); j++) {
Node areaNode = coverageAreaNodes.item(j);
Attribution attr = new Attribution();
attr.attribution = attribution;
attr.maxZoom = Integer.parseInt(zoomMaxXpath.evaluate(areaNode));
attr.minZoom = Integer.parseInt(zoomMinXpath.evaluate(areaNode));
Double southLat = Double.valueOf(southLatXpath.evaluate(areaNode));
Double northLat = Double.valueOf(northLatXpath.evaluate(areaNode));
Double westLon = Double.valueOf(westLonXpath.evaluate(areaNode));
Double eastLon = Double.valueOf(eastLonXpath.evaluate(areaNode));
attr.min = new Coordinate(southLat, westLon);
attr.max = new Coordinate(northLat, eastLon);
attributions.add(attr);
}
}
return attributions;
} catch (SAXException e) {
System.err.println("Could not parse Bing aerials attribution metadata.");
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return null;
}
@Override
public int getMaxZoom() {
if (imageryZoomMax != null)
return imageryZoomMax;
else
return 22;
}
@Override
public boolean requiresAttribution() {
return true;
}
@Override
public String getAttributionLinkURL() {
//return "http://bing.com/maps"
// FIXME: I've set attributionLinkURL temporarily to ToU URL to comply with bing ToU
// (the requirement is that we have such a link at the bottom of the window)
return "http://go.microsoft.com/?linkid=9710837";
}
@Override
public Image getAttributionImage() {
try {
final InputStream imageResource = JMapViewer.class.getResourceAsStream("images/bing_maps.png");
if (imageResource != null) {
return ImageIO.read(imageResource);
} else {
// Some Linux distributions (like Debian) will remove Bing logo from sources, so get it at runtime
for (int i = 0; i < 5 && getAttribution() == null; i++) {
// Makes sure attribution is loaded
if (JMapViewer.debug) {
System.out.println("Bing attribution attempt " + (i+1));
}
}
if (brandLogoUri != null && !brandLogoUri.isEmpty()) {
System.out.println("Reading Bing logo from "+brandLogoUri);
return ImageIO.read(new URL(brandLogoUri));
}
}
} catch (IOException e) {
System.err.println("Error while retrieving Bing logo: "+e.getMessage());
}
return null;
}
@Override
public String getAttributionImageURL() {
return "http://opengeodata.org/microsoft-imagery-details";
}
@Override
public String getTermsOfUseText() {
return null;
}
@Override
public String getTermsOfUseURL() {
return "http://opengeodata.org/microsoft-imagery-details";
}
protected Callable> getAttributionLoaderCallable() {
return new Callable>() {
@Override
public List call() throws Exception {
int waitTimeSec = 1;
while (true) {
try {
InputSource xml = new InputSource(getAttributionUrl().openStream());
List r = parseAttributionText(xml);
System.out.println("Successfully loaded Bing attribution data.");
return r;
} catch (IOException ex) {
System.err.println("Could not connect to Bing API. Will retry in " + waitTimeSec + " seconds.");
Thread.sleep(waitTimeSec * 1000L);
waitTimeSec *= 2;
}
}
}
};
}
protected List getAttribution() {
if (attributions == null) {
// see http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
synchronized (BingAerialTileSource.class) {
if (attributions == null) {
final FutureTask> loader = new FutureTask<>(getAttributionLoaderCallable());
new Thread(loader, "bing-attribution-loader").start();
attributions = loader;
}
}
}
try {
return attributions.get(0, TimeUnit.MILLISECONDS);
} catch (TimeoutException ex) {
System.err.println("Bing: attribution data is not yet loaded.");
} catch (ExecutionException ex) {
throw new RuntimeException(ex.getCause());
} catch (InterruptedException ign) {
System.err.println("InterruptedException: " + ign.getMessage());
}
return null;
}
@Override
public String getAttributionText(int zoom, ICoordinate topLeft, ICoordinate botRight) {
try {
final List data = getAttribution();
if (data == null)
return "Error loading Bing attribution data";
StringBuilder a = new StringBuilder();
for (Attribution attr : data) {
if (zoom <= attr.maxZoom && zoom >= attr.minZoom) {
if (topLeft.getLon() < attr.max.getLon() && botRight.getLon() > attr.min.getLon()
&& topLeft.getLat() > attr.min.getLat() && botRight.getLat() < attr.max.getLat()) {
a.append(attr.attribution);
a.append(' ');
}
}
}
return a.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "Error loading Bing attribution data";
}
private static String computeQuadTree(int zoom, int tilex, int tiley) {
StringBuilder k = new StringBuilder();
for (int i = zoom; i > 0; i--) {
char digit = 48;
int mask = 1 << (i - 1);
if ((tilex & mask) != 0) {
digit += 1;
}
if ((tiley & mask) != 0) {
digit += 2;
}
k.append(digit);
}
return k.toString();
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/MapQuestOpenAerialTileSource.java 0000644 0000000 0000000 00000001462 12566160406 032422 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
public class MapQuestOpenAerialTileSource extends AbstractMapQuestTileSource {
private static final String PATTERN = "http://oatile%d.mqcdn.com/tiles/1.0.0/sat";
public MapQuestOpenAerialTileSource() {
super("MapQuest Open Aerial", PATTERN, "mapquest-oa");
}
@Override
public String getAttributionText(int zoom, ICoordinate topLeft, ICoordinate botRight) {
return "Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency - "+MAPQUEST_ATTRIBUTION;
}
@Override
public String getAttributionLinkURL() {
return MAPQUEST_WEBSITE;
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/OsmTileSource.java 0000644 0000000 0000000 00000003333 12641052742 027455 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
/**
* OSM Tile source.
*/
public class OsmTileSource {
/**
* The default "Mapnik" OSM tile source.
*/
public static class Mapnik extends AbstractOsmTileSource {
private static final String PATTERN = "https://%s.tile.openstreetmap.org";
private static final String[] SERVER = {"a", "b", "c"};
private int serverNum;
/**
* Constructs a new {@code "Mapnik"} tile source.
*/
public Mapnik() {
super("Mapnik", PATTERN, "MAPNIK");
}
@Override
public String getBaseUrl() {
String url = String.format(this.baseUrl, new Object[] {SERVER[serverNum]});
serverNum = (serverNum + 1) % SERVER.length;
return url;
}
}
/**
* The "Cycle Map" OSM tile source.
*/
public static class CycleMap extends AbstractOsmTileSource {
private static final String PATTERN = "http://%s.tile.opencyclemap.org/cycle";
private static final String[] SERVER = {"a", "b", "c"};
private int serverNum;
/**
* Constructs a new {@code CycleMap} tile source.
*/
public CycleMap() {
super("Cyclemap", PATTERN, "opencyclemap");
}
@Override
public String getBaseUrl() {
String url = String.format(this.baseUrl, new Object[] {SERVER[serverNum]});
serverNum = (serverNum + 1) % SERVER.length;
return url;
}
@Override
public int getMaxZoom() {
return 18;
}
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractTileSource.java 0000644 0000000 0000000 00000004657 12566160376 030505 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
import java.awt.Image;
import java.util.List;
import java.util.Map;
import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
public abstract class AbstractTileSource implements TileSource {
protected String attributionText;
protected String attributionLinkURL;
protected Image attributionImage;
protected String attributionImageURL;
protected String termsOfUseText;
protected String termsOfUseURL;
@Override
public boolean requiresAttribution() {
return attributionText != null || attributionImage != null || termsOfUseText != null || termsOfUseURL != null;
}
@Override
public String getAttributionText(int zoom, ICoordinate topLeft, ICoordinate botRight) {
return attributionText;
}
@Override
public String getAttributionLinkURL() {
return attributionLinkURL;
}
@Override
public Image getAttributionImage() {
return attributionImage;
}
@Override
public String getAttributionImageURL() {
return attributionImageURL;
}
@Override
public String getTermsOfUseText() {
return termsOfUseText;
}
@Override
public String getTermsOfUseURL() {
return termsOfUseURL;
}
public void setAttributionText(String attributionText) {
this.attributionText = attributionText;
}
public void setAttributionLinkURL(String attributionLinkURL) {
this.attributionLinkURL = attributionLinkURL;
}
public void setAttributionImage(Image attributionImage) {
this.attributionImage = attributionImage;
}
public void setAttributionImageURL(String attributionImageURL) {
this.attributionImageURL = attributionImageURL;
}
public void setTermsOfUseText(String termsOfUseText) {
this.termsOfUseText = termsOfUseText;
}
public void setTermsOfUseURL(String termsOfUseURL) {
this.termsOfUseURL = termsOfUseURL;
}
@Override
public boolean isNoTileAtZoom(Map> headers, int statusCode, byte[] content) {
// default handler - when HTTP 404 is returned, then treat this situation as no tile at this zoom level
return statusCode == 404;
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractOsmTileSource.java 0000644 0000000 0000000 00000003502 12641052742 031137 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
import java.awt.Image;
import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
/**
* Abstract class for OSM Tile sources
*/
public abstract class AbstractOsmTileSource extends AbstractTMSTileSource {
/**
* The OSM attribution. Must be always in line with
* https://www.openstreetmap.org/copyright/en
*/
public static final String DEFAULT_OSM_ATTRIBUTION = "\u00a9 OpenStreetMap contributors";
/**
* Constructs a new OSM tile source
* @param name Source name as displayed in GUI
* @param baseUrl Source URL
* @param id unique id for the tile source; contains only characters that
* are safe for file names; can be null
*/
public AbstractOsmTileSource(String name, String baseUrl, String id) {
super(new TileSourceInfo(name, baseUrl, id));
}
@Override
public int getMaxZoom() {
return 19;
}
@Override
public boolean requiresAttribution() {
return true;
}
@Override
public String getAttributionText(int zoom, ICoordinate topLeft, ICoordinate botRight) {
return DEFAULT_OSM_ATTRIBUTION;
}
@Override
public String getAttributionLinkURL() {
return "https://openstreetmap.org/";
}
@Override
public Image getAttributionImage() {
return null;
}
@Override
public String getAttributionImageURL() {
return null;
}
@Override
public String getTermsOfUseText() {
return null;
}
@Override
public String getTermsOfUseURL() {
return "https://www.openstreetmap.org/copyright";
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/FeatureAdapter.java 0000644 0000000 0000000 00000005534 12566160376 025271 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.logging.Logger;
public final class FeatureAdapter {
private static BrowserAdapter browserAdapter = new DefaultBrowserAdapter();
private static TranslationAdapter translationAdapter = new DefaultTranslationAdapter();
private static LoggingAdapter loggingAdapter = new DefaultLoggingAdapter();
private FeatureAdapter() {
// private constructor for utility classes
}
public interface BrowserAdapter {
void openLink(String url);
}
public interface TranslationAdapter {
String tr(String text, Object... objects);
// TODO: more i18n functions
}
public interface LoggingAdapter {
Logger getLogger(String name);
}
public static void registerBrowserAdapter(BrowserAdapter browserAdapter) {
FeatureAdapter.browserAdapter = browserAdapter;
}
public static void registerTranslationAdapter(TranslationAdapter translationAdapter) {
FeatureAdapter.translationAdapter = translationAdapter;
}
public static void registerLoggingAdapter(LoggingAdapter loggingAdapter) {
FeatureAdapter.loggingAdapter = loggingAdapter;
}
public static void openLink(String url) {
browserAdapter.openLink(url);
}
public static String tr(String text, Object... objects) {
return translationAdapter.tr(text, objects);
}
public static Logger getLogger(String name) {
return loggingAdapter.getLogger(name);
}
public static class DefaultBrowserAdapter implements BrowserAdapter {
@Override
public void openLink(String url) {
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
try {
Desktop.getDesktop().browse(new URI(url));
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
} else {
System.err.println(tr("Opening link not supported on current platform (''{0}'')", url));
}
}
}
public static class DefaultTranslationAdapter implements TranslationAdapter {
@Override
public String tr(String text, Object... objects) {
return MessageFormat.format(text, objects);
}
}
public static class DefaultLoggingAdapter implements LoggingAdapter {
@Override
public Logger getLogger(String name) {
return Logger.getLogger(name);
}
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/MapRectangleImpl.java 0000644 0000000 0000000 00000005222 12566160376 025553 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import org.openstreetmap.gui.jmapviewer.interfaces.MapRectangle;
public class MapRectangleImpl extends MapObjectImpl implements MapRectangle {
private Coordinate topLeft;
private Coordinate bottomRight;
public MapRectangleImpl(Coordinate topLeft, Coordinate bottomRight) {
this(null, null, topLeft, bottomRight);
}
public MapRectangleImpl(String name, Coordinate topLeft, Coordinate bottomRight) {
this(null, name, topLeft, bottomRight);
}
public MapRectangleImpl(Layer layer, Coordinate topLeft, Coordinate bottomRight) {
this(layer, null, topLeft, bottomRight);
}
public MapRectangleImpl(Layer layer, String name, Coordinate topLeft, Coordinate bottomRight) {
this(layer, name, topLeft, bottomRight, getDefaultStyle());
}
public MapRectangleImpl(Layer layer, String name, Coordinate topLeft, Coordinate bottomRight, Style style) {
super(layer, name, style);
this.topLeft = topLeft;
this.bottomRight = bottomRight;
}
@Override
public Coordinate getTopLeft() {
return topLeft;
}
@Override
public Coordinate getBottomRight() {
return bottomRight;
}
@Override
public void paint(Graphics g, Point topLeft, Point bottomRight) {
// Prepare graphics
Color oldColor = g.getColor();
g.setColor(getColor());
Stroke oldStroke = null;
if (g instanceof Graphics2D) {
Graphics2D g2 = (Graphics2D) g;
oldStroke = g2.getStroke();
g2.setStroke(getStroke());
}
// Draw
g.drawRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
// Restore graphics
g.setColor(oldColor);
if (g instanceof Graphics2D) {
((Graphics2D) g).setStroke(oldStroke);
}
int width = bottomRight.x-topLeft.x;
int height = bottomRight.y-topLeft.y;
Point p = new Point(topLeft.x+(width/2), topLeft.y+(height/2));
if (getLayer() == null || getLayer().isVisibleTexts()) paintText(g, p);
}
public static Style getDefaultStyle() {
return new Style(Color.BLUE, null, new BasicStroke(2), getDefaultFont());
}
@Override
public String toString() {
return "MapRectangle from " + getTopLeft() + " to " + getBottomRight();
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/ 0000755 0000000 0000000 00000000000 12641052742 023635 5 ustar root root jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/CachedTileLoader.java 0000644 0000000 0000000 00000000440 12566160406 027615 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
/**
* Interface that allow cleaning the tile cache without specifying exact type of loader
*/
public interface CachedTileLoader {
void clearCache(TileSource source);
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/ICoordinate.java 0000644 0000000 0000000 00000000377 12566160406 026712 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
public interface ICoordinate {
double getLat();
void setLat(double lat);
double getLon();
void setLon(double lon);
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/MapObject.java 0000644 0000000 0000000 00000001114 12566160406 026344 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import java.awt.Color;
import java.awt.Font;
import java.awt.Stroke;
import org.openstreetmap.gui.jmapviewer.Layer;
import org.openstreetmap.gui.jmapviewer.Style;
public interface MapObject {
Layer getLayer();
void setLayer(Layer layer);
Style getStyle();
Style getStyleAssigned();
Color getColor();
Color getBackColor();
Stroke getStroke();
Font getFont();
String getName();
boolean isVisible();
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/MapMarker.java 0000644 0000000 0000000 00000002637 12641052742 026367 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import java.awt.Graphics;
import java.awt.Point;
import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.openstreetmap.gui.jmapviewer.JMapViewer;
/**
* Interface to be implemented by all one dimensional elements that can be displayed on the map.
*
* @author Jan Peter Stotz
* @see JMapViewer#addMapMarker(MapMarker)
* @see JMapViewer#getMapMarkerList()
*/
public interface MapMarker extends MapObject, ICoordinate {
enum STYLE {
FIXED,
VARIABLE
}
/**
* @return Latitude and Longitude of the map marker position
*/
Coordinate getCoordinate();
/**
* @return Latitude of the map marker position
*/
@Override
double getLat();
/**
* @return Longitude of the map marker position
*/
@Override
double getLon();
/**
* @return Radius of the map marker position
*/
double getRadius();
/**
* @return Style of the map marker
*/
STYLE getMarkerStyle();
/**
* Paints the map marker on the map. The position
specifies the
* coordinates within g
*
* @param g graphics
* @param position coordinates
* @param radius radius
*/
void paint(Graphics g, Point position, int radius);
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/JMapViewerEventListener.java 0000644 0000000 0000000 00000000720 12566160406 031223 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import java.util.EventListener;
import org.openstreetmap.gui.jmapviewer.events.JMVCommandEvent;
/**
* Must be implemented for processing commands while user
* interacts with map viewer.
*
* @author Jason Huntley
*
*/
public interface JMapViewerEventListener extends EventListener {
void processCommand(JMVCommandEvent command);
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/TileLoaderListener.java 0000644 0000000 0000000 00000001052 12566160406 030233 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import org.openstreetmap.gui.jmapviewer.Tile;
public interface TileLoaderListener {
/**
* Will be called if a new {@link Tile} has been loaded successfully.
* Loaded can mean downloaded or loaded from file cache.
*
* @param tile The tile
* @param success {@code true} if the tile has been loaded successfully, {@code false} otherwise
*/
void tileLoadingFinished(Tile tile, boolean success);
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/TileClearController.java 0000644 0000000 0000000 00000000533 12566160406 030414 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import java.io.File;
public interface TileClearController {
void initClearDir(File dir);
void initClearFiles(File[] files);
boolean cancel();
void fileDeleted(File file);
void clearFinished();
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/Attributed.java 0000644 0000000 0000000 00000003132 12566160406 026611 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import java.awt.Image;
public interface Attributed {
/**
* @return True if the tile source requires attribution in text or image form.
*/
boolean requiresAttribution();
/**
* @param zoom The optional zoom level for the view.
* @param botRight The bottom right of the bounding box for attribution.
* @param topLeft The top left of the bounding box for attribution.
* @return Attribution text for the image source.
*/
String getAttributionText(int zoom, ICoordinate topLeft, ICoordinate botRight);
/**
* @return The URL to open when the user clicks the attribution text.
*/
String getAttributionLinkURL();
/**
* @return The URL for the attribution image. Null if no image should be displayed.
*/
Image getAttributionImage();
/**
* @return The URL to open when the user clicks the attribution image.
* When return value is null, the image is still displayed (provided getAttributionImage()
* returns a value other than null), but the image does not link to a website.
*/
String getAttributionImageURL();
/**
* @return The attribution "Terms of Use" text.
* In case it returns null, but getTermsOfUseURL() is not null, a default
* terms of use text is used.
*/
String getTermsOfUseText();
/**
* @return The URL to open when the user clicks the attribution "Terms of Use" text.
*/
String getTermsOfUseURL();
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/TileCache.java 0000644 0000000 0000000 00000003104 12641052742 026317 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import org.openstreetmap.gui.jmapviewer.JMapViewer;
import org.openstreetmap.gui.jmapviewer.Tile;
/**
* Implement this interface for creating your custom tile cache for
* {@link JMapViewer}.
*
* @author Jan Peter Stotz
*/
public interface TileCache {
/**
* Retrieves a tile from the cache if present, otherwise null
* will be returned.
*
* @param source
* the tile source
* @param x
* tile number on the x axis of the tile to be retrieved
* @param y
* tile number on the y axis of the tile to be retrieved
* @param z
* zoom level of the tile to be retrieved
* @return the requested tile or null
if the tile is not
* present in the cache
*/
Tile getTile(TileSource source, int x, int y, int z);
/**
* Adds a tile to the cache. How long after adding a tile can be retrieved
* via {@link #getTile(TileSource, int, int, int)} is unspecified and depends on the
* implementation.
*
* @param tile the tile to be added
*/
void addTile(Tile tile);
/**
* @return the number of tiles hold by the cache
*/
int getTileCount();
/**
* Clears the cache deleting all tiles from memory.
*/
void clear();
/**
* Size of the cache.
* @return maximum number of tiles in cache
*/
int getCacheSize();
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/TileLoader.java 0000644 0000000 0000000 00000001611 12604423574 026527 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import org.openstreetmap.gui.jmapviewer.Tile;
/**
* Interface for implementing a tile loader. Tiles are usually loaded via HTTP
* or from a file.
*
* @author Jan Peter Stotz
*/
public interface TileLoader {
/**
* A typical implementation of this function should create and return a
* new {@link TileJob} instance that performs the load action.
*
* @param tile the tile to be loaded
* @return {@link TileJob} implementation that performs the desired load
* action.
*/
TileJob createTileLoaderJob(Tile tile);
/**
* cancels all outstanding tasks in the queue. This should rollback the state of the tiles in the queue
* to loading = false / loaded = false
*/
void cancelOutstandingTasks();
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/TileSource.java 0000644 0000000 0000000 00000014064 12604423574 026567 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import java.awt.Point;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.openstreetmap.gui.jmapviewer.JMapViewer;
import org.openstreetmap.gui.jmapviewer.Tile;
import org.openstreetmap.gui.jmapviewer.TileXY;
/**
*
* @author Jan Peter Stotz
*/
public interface TileSource extends Attributed {
/**
* Specifies the maximum zoom value. The number of zoom levels is [0..
* {@link #getMaxZoom()}].
*
* @return maximum zoom value that has to be smaller or equal to
* {@link JMapViewer#MAX_ZOOM}
*/
int getMaxZoom();
/**
* Specifies the minimum zoom value. This value is usually 0.
* Only for maps that cover a certain region up to a limited zoom level
* this method should return a value different than 0.
*
* @return minimum zoom value - usually 0
*/
int getMinZoom();
/**
* A tile layer name as displayed to the user.
*
* @return Name of the tile layer
*/
String getName();
/**
* A unique id for this tile source.
*
* Unlike the name it has to be unique and has to consist only of characters
* valid for filenames.
*
* @return the id
*/
String getId();
/**
* Constructs the tile url.
*
* @param zoom zoom level
* @param tilex X coordinate
* @param tiley Y coordinate
* @return fully qualified url for downloading the specified tile image
* @throws IOException if any I/O error occurs
*/
String getTileUrl(int zoom, int tilex, int tiley) throws IOException;
/**
* Creates tile identifier that is unique among all tile sources, but the same tile will always
* get the same identifier. Used for creation of cache key.
*
* @param zoom zoom level
* @param tilex X coordinate
* @param tiley Y coordinate
* @return tile identifier
*/
String getTileId(int zoom, int tilex, int tiley);
/**
* Specifies how large each tile is.
* @return The size of a single tile in pixels. -1 if default size should be used
*/
int getTileSize();
/**
* @return default tile size, for this tile source
* TODO: @since
*/
int getDefaultTileSize();
/**
* Gets the distance using Spherical law of cosines.
* @param la1 latitude of first point
* @param lo1 longitude of first point
* @param la2 latitude of second point
* @param lo2 longitude of second point
* @return the distance betwen first and second point, in m.
*/
double getDistance(double la1, double lo1, double la2, double lo2);
/**
* @param lon longitude
* @param lat latitude
* @param zoom zoom level
* @return transforms longitude and latitude to pixel space (as if all tiles at specified zoom level where joined)
*/
Point latLonToXY(double lat, double lon, int zoom);
/**
* @param point point
* @param zoom zoom level
* @return transforms longitude and latitude to pixel space (as if all tiles at specified zoom level where joined)
*/
Point latLonToXY(ICoordinate point, int zoom);
/**
* @param point point
* @param zoom zoom level
* @return WGS84 Coordinates of given point
*/
ICoordinate xyToLatLon(Point point, int zoom);
/**
*
* @param x X coordinate
* @param y Y coordinate
* @param zoom zoom level
* @return WGS84 Coordinates of given point
*/
ICoordinate xyToLatLon(int x, int y, int zoom);
/**
* @param lon longitude
* @param lat latitude
* @param zoom zoom level
* @return x and y tile indices
*/
TileXY latLonToTileXY(double lat, double lon, int zoom);
/**
*
* @param point point
* @param zoom zoom level
* @return x and y tile indices
*/
TileXY latLonToTileXY(ICoordinate point, int zoom);
/**
* @param xy X/Y coordinates
* @param zoom zoom level
* @return WGS84 coordinates of given tile
*/
ICoordinate tileXYToLatLon(TileXY xy, int zoom);
/**
*
* @param tile Tile
* @return WGS84 coordinates of given tile
*/
ICoordinate tileXYToLatLon(Tile tile);
/**
*
* @param x X coordinate
* @param y Y coordinate
* @param zoom zoom level
* @return WGS84 coordinates of given tile
*/
ICoordinate tileXYToLatLon(int x, int y, int zoom);
/**
* @param zoom zoom level
* @return maximum X index of tile for specified zoom level
*/
int getTileXMax(int zoom);
/**
*
* @param zoom zoom level
* @return minimum X index of tile for specified zoom level
*/
int getTileXMin(int zoom);
/**
*
* @param zoom zoom level
* @return maximum Y index of tile for specified zoom level
*/
int getTileYMax(int zoom);
/**
* @param zoom zoom level
* @return minimum Y index of tile for specified zoom level
*/
int getTileYMin(int zoom);
/**
* Determines, if the returned data from TileSource represent "no tile at this zoom level" situation. Detection
* algorithms differ per TileSource, so each TileSource should implement each own specific way.
*
* @param headers HTTP headers from response from TileSource server
* @param statusCode HTTP status code
* @param content byte array representing the data returned from the server
* @return true, if "no tile at this zoom level" situation detected
*/
boolean isNoTileAtZoom(Map> headers, int statusCode, byte[] content);
/**
* Extracts metadata about the tile based on HTTP headers
*
* @param headers HTTP headers from Tile Source server
* @return tile metadata
*/
Map getMetadata(Map> headers);
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/TileJob.java 0000644 0000000 0000000 00000001373 12566160406 026037 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import org.openstreetmap.gui.jmapviewer.Tile;
/**
* Interface for implementing a tile loading job. Tiles are usually loaded via HTTP
* or from a file.
*
* @author Dirk Stöcker
*/
public interface TileJob extends Runnable {
/**
* Function to return the tile associated with the job
*
* @return {@link Tile} to be handled
*/
Tile getTile();
/**
* submits download job to backend.
*/
void submit();
/**
* submits download job to backend.
* @param force true if the load should skip all the caches (local & remote)
*/
void submit(boolean force);
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/TemplatedTileSource.java 0000644 0000000 0000000 00000000654 12566160406 030426 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import java.util.Map;
/**
* Interface for template tile sources, @see TemplatedTMSTileSource
*
* @author Wiktor Niesiobędzki
* @since 1.10
*/
public interface TemplatedTileSource extends TileSource {
/**
*
* @return headers to be sent with http requests
*/
Map getHeaders();
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/MapRectangle.java 0000644 0000000 0000000 00000002237 12641052742 027046 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import java.awt.Graphics;
import java.awt.Point;
import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.openstreetmap.gui.jmapviewer.JMapViewer;
/**
* Interface to be implemented by rectangles that can be displayed on the map.
*
* @author Stefan Zeller
* @see JMapViewer#addMapRectangle(MapRectangle)
* @see JMapViewer#getMapRectangleList()
*/
public interface MapRectangle extends MapObject {
/**
* @return Latitude/Longitude of top left of rectangle
*/
Coordinate getTopLeft();
/**
* @return Latitude/Longitude of bottom right of rectangle
*/
Coordinate getBottomRight();
/**
* Paints the map rectangle on the map. The topLeft
and
* bottomRight
are specifying the coordinates within g
*
* @param g graphics structure for painting
* @param topLeft lop left edge of painting region
* @param bottomRight bottom right edge of painting region
*/
void paint(Graphics g, Point topLeft, Point bottomRight);
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/interfaces/MapPolygon.java 0000644 0000000 0000000 00000002060 12641052742 026563 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.interfaces;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.util.List;
/**
* Interface to be implemented by polygons that can be displayed on the map.
*
* @author Vincent Privat
*/
public interface MapPolygon extends MapObject {
/**
* @return Latitude/Longitude of each point of polygon
*/
List extends ICoordinate> getPoints();
/**
* Paints the map polygon on the map. The points
* are specifying the coordinates within g
*
* @param g graphics
* @param points list of points defining the polygon to draw
*/
void paint(Graphics g, List points);
/**
* Paints the map polygon on the map. The polygon
* is specifying the coordinates within g
*
* @param g graphics
* @param polygon polygon to draw
*/
void paint(Graphics g, Polygon polygon);
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/MapPolygonImpl.java 0000644 0000000 0000000 00000007011 12641052742 025263 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.util.Arrays;
import java.util.List;
import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
import org.openstreetmap.gui.jmapviewer.interfaces.MapPolygon;
public class MapPolygonImpl extends MapObjectImpl implements MapPolygon {
private List extends ICoordinate> points;
public MapPolygonImpl(ICoordinate ... points) {
this(null, null, points);
}
public MapPolygonImpl(List extends ICoordinate> points) {
this(null, null, points);
}
public MapPolygonImpl(String name, List extends ICoordinate> points) {
this(null, name, points);
}
public MapPolygonImpl(String name, ICoordinate ... points) {
this(null, name, points);
}
public MapPolygonImpl(Layer layer, List extends ICoordinate> points) {
this(layer, null, points);
}
public MapPolygonImpl(Layer layer, String name, List extends ICoordinate> points) {
this(layer, name, points, getDefaultStyle());
}
public MapPolygonImpl(Layer layer, String name, ICoordinate ... points) {
this(layer, name, Arrays.asList(points), getDefaultStyle());
}
public MapPolygonImpl(Layer layer, String name, List extends ICoordinate> points, Style style) {
super(layer, name, style);
this.points = points;
}
@Override
public List extends ICoordinate> getPoints() {
return this.points;
}
@Override
public void paint(Graphics g, List points) {
Polygon polygon = new Polygon();
for (Point p : points) {
polygon.addPoint(p.x, p.y);
}
paint(g, polygon);
}
@Override
public void paint(Graphics g, Polygon polygon) {
// Prepare graphics
Color oldColor = g.getColor();
g.setColor(getColor());
Stroke oldStroke = null;
if (g instanceof Graphics2D) {
Graphics2D g2 = (Graphics2D) g;
oldStroke = g2.getStroke();
g2.setStroke(getStroke());
}
// Draw
g.drawPolygon(polygon);
if (g instanceof Graphics2D && getBackColor() != null) {
Graphics2D g2 = (Graphics2D) g;
Composite oldComposite = g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
g2.setPaint(getBackColor());
g2.fillPolygon(polygon);
g2.setComposite(oldComposite);
}
// Restore graphics
g.setColor(oldColor);
if (g instanceof Graphics2D) {
((Graphics2D) g).setStroke(oldStroke);
}
Rectangle rec = polygon.getBounds();
Point corner = rec.getLocation();
Point p = new Point(corner.x+(rec.width/2), corner.y+(rec.height/2));
if (getLayer() == null || getLayer().isVisibleTexts()) paintText(g, p);
}
public static Style getDefaultStyle() {
return new Style(Color.BLUE, new Color(100, 100, 100, 50), new BasicStroke(2), getDefaultFont());
}
@Override
public String toString() {
return "MapPolygon [points=" + points + ']';
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/ 0000755 0000000 0000000 00000000000 12641052742 024060 5 ustar root root jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeRenderer.java 0000644 0000000 0000000 00000011116 12641052742 030706 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.checkBoxTree;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellRenderer;
/**
* Renderer for checkBox Tree
*
* @author galo
*/
public class CheckBoxNodeRenderer implements TreeCellRenderer {
private final CheckBoxNodePanel panel = new CheckBoxNodePanel();
private final DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
private final Color selectionForeground;
private final Color selectionBackground;
private final Color textForeground;
private final Color textBackground;
/**
* Constructs a new {@code CheckBoxNodeRenderer}.
*/
public CheckBoxNodeRenderer() {
final Font fontValue = UIManager.getFont("Tree.font");
if (fontValue != null) panel.getLabel().setFont(fontValue);
final Boolean focusPainted =
(Boolean) UIManager.get("Tree.drawsFocusBorderAroundIcon");
panel.check.setFocusPainted(focusPainted != null && focusPainted);
selectionForeground = UIManager.getColor("Tree.selectionForeground");
selectionBackground = UIManager.getColor("Tree.selectionBackground");
textForeground = UIManager.getColor("Tree.textForeground");
textBackground = UIManager.getColor("Tree.textBackground");
}
protected CheckBoxNodePanel getPanel() {
return panel;
}
public void addNodeListener(MouseAdapter listener) {
panel.addMouseListener(listener);
}
// -- TreeCellRenderer methods --
@Override
public Component getTreeCellRendererComponent(final JTree tree,
final Object value, final boolean selected, final boolean expanded,
final boolean leaf, final int row, final boolean hasFocus) {
CheckBoxNodeData data = null;
if (value instanceof DefaultMutableTreeNode) {
final DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
final Object userObject = node.getUserObject();
if (userObject instanceof CheckBoxNodeData) {
data = (CheckBoxNodeData) userObject;
}
}
//final String stringValue =
// tree.convertValueToText(value, selected, expanded, leaf, row, false);
//panel.label.setText(stringValue);
panel.setSelected(Boolean.FALSE);
panel.setEnabled(tree.isEnabled());
if (selected) {
panel.setForeground(selectionForeground);
panel.setBackground(selectionBackground);
panel.getLabel().setForeground(selectionForeground);
panel.getLabel().setBackground(selectionBackground);
} else {
panel.setForeground(textForeground);
panel.setBackground(textBackground);
panel.getLabel().setForeground(textForeground);
panel.getLabel().setBackground(textBackground);
}
if (data == null) {
// not a check box node; return default cell renderer
return defaultRenderer.getTreeCellRendererComponent(tree, value,
selected, expanded, leaf, row, hasFocus);
}
//panel.label.setText(data.getText());
panel.setData(data);
panel.setSelected(data.isSelected());
return panel;
}
/*
private JPopupMenu createPopupMenu(final AbstractLayer layer) {
JMenuItem menuItem;
//Create the popup menu.
if (layer.isVisibleTexts()) menuItem = new JMenuItem("hide texts");
else menuItem = new JMenuItem("show texts");
JPopupMenu popup = new JPopupMenu();
popup.add(menuItem);
menuItem.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
setVisibleTexts(layer, !layer.isVisibleTexts());
}
});
return popup;
}
private void setVisibleTexts(AbstractLayer layer, boolean visible) {
layer.setVisibleTexts(visible);
if (layer instanceof LayerGroup) {
LayerGroup group = (LayerGroup) layer;
if (group.getLayers() != null)
for (AbstractLayer al : group.getLayers()) {
setVisibleTexts(al, visible);
}
}
}
*/
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeData.java 0000644 0000000 0000000 00000002376 12641052742 030021 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.checkBoxTree;
import org.openstreetmap.gui.jmapviewer.AbstractLayer;
import org.openstreetmap.gui.jmapviewer.LayerGroup;
/**
* Node Data for checkBox Tree
*
* @author galo
*/
public class CheckBoxNodeData {
private AbstractLayer layer;
public CheckBoxNodeData(final AbstractLayer layer) {
this.layer = layer;
}
public CheckBoxNodeData(final String txt) {
this(new LayerGroup(txt));
}
public CheckBoxNodeData(final String txt, final Boolean selected) {
this(new LayerGroup(txt));
layer.setVisible(selected);
}
public Boolean isSelected() {
return layer.isVisible();
}
public void setSelected(final Boolean newValue) {
layer.setVisible(newValue);
}
public String getText() {
return layer.getName();
}
public AbstractLayer getAbstractLayer() {
return layer;
}
public void setAbstractLayer(final AbstractLayer layer) {
this.layer = layer;
}
@Override
public String toString() {
return getClass().getSimpleName() + '[' + getText() + '/' + isSelected() + ']';
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxTree.java 0000644 0000000 0000000 00000023211 12641052742 027230 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.checkBoxTree;
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import org.openstreetmap.gui.jmapviewer.AbstractLayer;
import org.openstreetmap.gui.jmapviewer.Layer;
import org.openstreetmap.gui.jmapviewer.LayerGroup;
/**
* JTree for checkBox Tree Layers
*
* @author galo
*/
public class CheckBoxTree extends JTree {
/** Serial Version UID */
private static final long serialVersionUID = 6943401106938034256L;
private final CheckBoxNodeEditor editor;
public CheckBoxTree(AbstractLayer layer) {
this(new CheckBoxNodeData(layer));
}
public CheckBoxTree(String rootName) {
this(new CheckBoxNodeData(rootName));
}
public CheckBoxTree(CheckBoxNodeData root) {
this(new DefaultMutableTreeNode(root));
}
public CheckBoxTree(DefaultMutableTreeNode node) {
super(new DefaultTreeModel(node));
final CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
setCellRenderer(renderer);
editor = new CheckBoxNodeEditor(this);
setCellEditor(editor);
setEditable(true);
// listen for changes in the model (including check box toggles)
getModel().addTreeModelListener(new TreeModelListener() {
@Override
public void treeNodesChanged(final TreeModelEvent e) {
DefaultTreeModel model = (DefaultTreeModel) e.getSource();
Object[] nodes = e.getChildren();
DefaultMutableTreeNode node;
if (nodes == null || nodes.length == 0) {
node = node(model.getRoot());
} else {
node = node(nodes[0]);
}
nodeChanged(node);
repaint();
}
@Override
public void treeNodesInserted(final TreeModelEvent e) {
//System.out.println("nodes inserted");
}
@Override
public void treeNodesRemoved(final TreeModelEvent e) {
//System.out.println("nodes removed");
}
@Override
public void treeStructureChanged(final TreeModelEvent e) {
//System.out.println("structure changed");
}
});
}
public void addNodeListener(MouseAdapter listener) {
editor.addNodeListener(listener);
}
public static void main(final String[] args) {
final DefaultMutableTreeNode root = new DefaultMutableTreeNode(new CheckBoxNodeData("Root", Boolean.TRUE));
final DefaultMutableTreeNode accessibility =
add(root, "Accessibility", true);
add(accessibility, "Move system caret with focus/selection changes", false);
add(accessibility, "Always expand alt text for images", true);
root.add(accessibility);
final DefaultMutableTreeNode browsing =
new DefaultMutableTreeNode(new CheckBoxNodeData("Browsing", null));
add(browsing, "Notify when downloads complete", true);
add(browsing, "Disable script debugging", true);
add(browsing, "Use AutoComplete", true);
add(browsing, "Browse in a new process", false);
root.add(browsing);
final CheckBoxTree tree = new CheckBoxTree(root);
((DefaultMutableTreeNode) tree.getModel().getRoot()).add(new DefaultMutableTreeNode(new CheckBoxNodeData("gggg", null)));
((DefaultTreeModel) tree.getModel()).reload();
// listen for changes in the selection
tree.addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(final TreeSelectionEvent e) {
//System.out.println("selection changed");
}
});
// show the tree on screen
final JFrame frame = new JFrame("CheckBox Tree");
final JScrollPane scrollPane = new JScrollPane(tree);
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 150);
frame.setVisible(true);
}
private static Boolean childStatus(DefaultMutableTreeNode node) {
Boolean status = data(node.getChildAt(0)).isSelected();
for (int i = 1; i < node.getChildCount() && status != null; i++) {
if (!status.equals(
data(node.getChildAt(i)).isSelected()
))
return null;
}
return status;
}
private static void changeParents(DefaultMutableTreeNode node) {
if (node != null) {
DefaultMutableTreeNode parent = node(node.getParent());
if (parent != null) {
CheckBoxNodeData dataParent = data(parent);
Boolean childStatus = childStatus(parent);
if (childStatus != null && !childStatus.equals(dataParent.isSelected())) {
dataParent.setSelected(childStatus);
changeParents(parent);
}
}
}
}
private static void nodeChanged(DefaultMutableTreeNode node) {
if (node != null) {
changeParents(node);
setChildrens(node, data(node).isSelected());
}
}
private static void setChildrens(DefaultMutableTreeNode node, Boolean value) {
for (int i = 0; i < node.getChildCount(); i++) {
DefaultMutableTreeNode childNode = node(node.getChildAt(i));
if (!data(childNode).isSelected().equals(data(node).isSelected())) {
data(childNode).setSelected(data(node).isSelected());
setChildrens(childNode, value);
}
}
}
public DefaultMutableTreeNode rootNode() {
return node(getModel().getRoot());
}
public LayerGroup rootLayer() {
return (LayerGroup) rootData().getAbstractLayer();
}
public CheckBoxNodeData rootData() {
return data(rootNode());
}
private static DefaultMutableTreeNode node(Object node) {
return (DefaultMutableTreeNode) node;
}
public static CheckBoxNodeData data(DefaultMutableTreeNode node) {
return node == null ? null : (CheckBoxNodeData) node.getUserObject();
}
private static CheckBoxNodeData data(Object node) {
return data(node(node));
}
private static DefaultMutableTreeNode add(final DefaultMutableTreeNode parent, final String text, final boolean checked) {
final CheckBoxNodeData data = new CheckBoxNodeData(text, checked);
final DefaultMutableTreeNode node = new DefaultMutableTreeNode(data);
parent.add(node);
return node;
}
public static CheckBoxNodeData createNodeData(AbstractLayer layer) {
return new CheckBoxNodeData(layer);
}
public static DefaultMutableTreeNode createNode(AbstractLayer layer) {
return new DefaultMutableTreeNode(createNodeData(layer));
}
/*public DefaultMutableTreeNode addLayerGroup(LayerGroup group) {
if (group != null){
if (group.getParent() == null){
return add(rootNode(), group);
} else {
DefaultMutableTreeNode parentGroup = searchNode(group.getParent());
if(parentGroup==null) parentGroup = addLayerGroup(group.getParent());
DefaultMutableTreeNode node = add(parentGroup, group);
return node;
}
}else return null;
}*/
public Layer addLayer(String name) {
Layer layer = new Layer(name);
addLayer(layer);
return layer;
}
public DefaultMutableTreeNode addLayer(AbstractLayer layer) {
if (layer != null) {
DefaultMutableTreeNode parent;
if (layer.getParent() == null) {
rootLayer().add(layer);
parent = rootNode();
} else {
parent = searchNode(layer.getParent());
if (parent == null)
parent = addLayer(layer.getParent());
}
return add(parent, layer);
} else return null;
}
public DefaultMutableTreeNode add(DefaultMutableTreeNode parent, final AbstractLayer layer) {
layer.setVisible(data(parent).isSelected());
DefaultMutableTreeNode node = createNode(layer);
parent.add(node);
((DefaultTreeModel) getModel()).reload();
//System.out.println("Created node "+layer+" upper of "+data(parent));
return node;
}
public DefaultMutableTreeNode searchNode(AbstractLayer layer) {
return searchNode(rootNode(), layer);
}
public DefaultMutableTreeNode searchNode(DefaultMutableTreeNode node, AbstractLayer layer) {
CheckBoxNodeData data = CheckBoxTree.data(node);
if (data.getAbstractLayer() == layer) return node;
else {
DefaultMutableTreeNode found = null;
for (int i = 0; i < node.getChildCount() && found == null; i++) {
found = searchNode((DefaultMutableTreeNode) node.getChildAt(i), layer);
}
return found;
}
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodePanel.java 0000644 0000000 0000000 00000002652 12566160376 030215 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.checkBoxTree;
import java.awt.BorderLayout;
import java.awt.Insets;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* Node Panel for checkBox Tree
*
* @author galo
*/
public class CheckBoxNodePanel extends JPanel {
/** Serial Version UID */
private static final long serialVersionUID = -7236481597785619029L;
private final JLabel label = new JLabel();
private CheckBoxNodeData data;
public final JCheckBox check = new JCheckBox();
public CheckBoxNodePanel() {
this.check.setMargin(new Insets(0, 0, 0, 0));
setLayout(new BorderLayout());
add(check, BorderLayout.WEST);
add(label, BorderLayout.CENTER);
}
public void setSelected(Boolean bool) {
if (bool == null) {
check.getModel().setPressed(true);
check.getModel().setArmed(true);
} else {
check.setSelected(bool.booleanValue());
check.getModel().setArmed(false);
}
}
public CheckBoxNodeData getData() {
data.setSelected(check.isSelected());
return data;
}
public void setData(CheckBoxNodeData data) {
this.data = data;
label.setText(data.getText());
}
public JLabel getLabel() {
return label;
}
}
jmapviewer-1.14/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeEditor.java 0000644 0000000 0000000 00000007027 12641052742 030374 0 ustar root root // License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.checkBoxTree;
import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreePath;
/**
* Editor for checkBox Tree
*
* @author galo
*/
public class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
/** SerialVersionUID */
private static final long serialVersionUID = -8921320784224636657L;
private final CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
private final CheckBoxTree theTree;
public CheckBoxNodeEditor(final CheckBoxTree tree) {
theTree = tree;
}
@Override
public Object getCellEditorValue() {
final CheckBoxNodePanel panel = renderer.getPanel();
/*final CheckBoxNodeData checkBoxNode =
new CheckBoxNodeData(panel.label.getText(), panel.check.isSelected());
return checkBoxNode;
CheckBoxNodeData data = search(theTree.rootNode(), panel.label.getText());
data.setSelected(panel.check.isSelected());*/
return panel.getData();
}
/*public CheckBoxNodeData search(DefaultMutableTreeNode node, String name){
CheckBoxNodeData data = CheckBoxTree.data(node);
if(data.getText().equals(name)) return data;
else{
data = null;
for(int i=0; i