Changeset 14053 in osm for applications/viewer/jmapviewer/src/org
- Timestamp:
- 2009-03-10T13:45:35+01:00 (16 years ago)
- Location:
- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/DefaultMapController.java
r9713 r14053 17 17 * 18 18 */ 19 public class DefaultMapController extends JMapController implements MouseListener, 20 MouseMotionListener,MouseWheelListener {19 public class DefaultMapController extends JMapController implements MouseListener, MouseMotionListener, 20 MouseWheelListener { 21 21 22 private static final int MOUSE_BUTTONS_MASK = 23 MouseEvent.BUTTON3_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK 24 | MouseEvent.BUTTON2_DOWN_MASK; 22 private static final int MOUSE_BUTTONS_MASK = MouseEvent.BUTTON3_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK 23 | MouseEvent.BUTTON2_DOWN_MASK; 25 24 26 27 28 25 public DefaultMapController(JMapViewer map) { 26 super(map); 27 } 29 28 30 29 private Point lastDragPoint; 31 30 32 31 private boolean isMoving = false; 33 32 34 33 private boolean movementEnabled = true; 35 34 36 37 35 private int movementMouseButton = MouseEvent.BUTTON3; 36 private int movementMouseButtonMask = MouseEvent.BUTTON3_DOWN_MASK; 38 37 39 40 38 private boolean wheelZoomEnabled = true; 39 private boolean doubleClickZoomEnabled = true; 41 40 42 43 44 45 46 47 48 49 50 51 52 53 54 55 41 public void mouseDragged(MouseEvent e) { 42 if (!movementEnabled || !isMoving) 43 return; 44 // Is only the selected mouse button pressed? 45 if ((e.getModifiersEx() & MOUSE_BUTTONS_MASK) == movementMouseButtonMask) { 46 Point p = e.getPoint(); 47 if (lastDragPoint != null) { 48 int diffx = lastDragPoint.x - p.x; 49 int diffy = lastDragPoint.y - p.y; 50 map.moveMap(diffx, diffy); 51 } 52 lastDragPoint = p; 53 } 54 } 56 55 57 58 59 60 56 public void mouseClicked(MouseEvent e) { 57 if (doubleClickZoomEnabled && e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) 58 map.zoomIn(e.getPoint()); 59 } 61 60 62 63 64 65 66 67 61 public void mousePressed(MouseEvent e) { 62 if (e.getButton() == movementMouseButton) { 63 lastDragPoint = null; 64 isMoving = true; 65 } 66 } 68 67 69 70 71 72 73 74 68 public void mouseReleased(MouseEvent e) { 69 if (e.getButton() == movementMouseButton) { 70 lastDragPoint = null; 71 isMoving = false; 72 } 73 } 75 74 76 77 78 79 75 public void mouseWheelMoved(MouseWheelEvent e) { 76 if (wheelZoomEnabled) 77 map.setZoom(map.getZoom() - e.getWheelRotation(), e.getPoint()); 78 } 80 79 81 82 83 80 public boolean isMovementEnabled() { 81 return movementEnabled; 82 } 84 83 85 86 87 88 89 90 91 92 84 /** 85 * Enables or disables that the map pane can be moved using the mouse. 86 * 87 * @param movementEnabled 88 */ 89 public void setMovementEnabled(boolean movementEnabled) { 90 this.movementEnabled = movementEnabled; 91 } 93 92 94 95 96 93 public int getMovementMouseButton() { 94 return movementMouseButton; 95 } 97 96 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 97 /** 98 * Sets the mouse button that is used for moving the map. Possible values 99 * are: 100 * <ul> 101 * <li>{@link MouseEvent#BUTTON1} (left mouse button)</li> 102 * <li>{@link MouseEvent#BUTTON2} (middle mouse button)</li> 103 * <li>{@link MouseEvent#BUTTON3} (right mouse button)</li> 104 * </ul> 105 * 106 * @param movementMouseButton 107 */ 108 public void setMovementMouseButton(int movementMouseButton) { 109 this.movementMouseButton = movementMouseButton; 110 switch (movementMouseButton) { 111 case MouseEvent.BUTTON1: 112 movementMouseButtonMask = MouseEvent.BUTTON1_DOWN_MASK; 113 break; 114 case MouseEvent.BUTTON2: 115 movementMouseButtonMask = MouseEvent.BUTTON2_DOWN_MASK; 116 break; 117 case MouseEvent.BUTTON3: 118 movementMouseButtonMask = MouseEvent.BUTTON3_DOWN_MASK; 119 break; 120 default: 121 throw new RuntimeException("Unsupported button"); 122 } 123 } 125 124 126 127 128 125 public boolean isWheelZoomEnabled() { 126 return wheelZoomEnabled; 127 } 129 128 130 131 132 129 public void setWheelZoomEnabled(boolean wheelZoomEnabled) { 130 this.wheelZoomEnabled = wheelZoomEnabled; 131 } 133 132 134 135 136 133 public boolean isDoubleClickZoomEnabled() { 134 return doubleClickZoomEnabled; 135 } 137 136 138 139 140 137 public void setDoubleClickZoomEnabled(boolean doubleClickZoomEnabled) { 138 this.doubleClickZoomEnabled = doubleClickZoomEnabled; 139 } 141 140 142 143 141 public void mouseEntered(MouseEvent e) { 142 } 144 143 145 146 144 public void mouseExited(MouseEvent e) { 145 } 147 146 148 149 147 public void mouseMoved(MouseEvent e) { 148 } 150 149 151 150 } -
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Demo.java
r11103 r14053 28 28 public class Demo extends JFrame { 29 29 30 30 private static final long serialVersionUID = 1L; 31 31 32 public Demo() { 33 super("JMapViewer Demo"); 34 setSize(400, 400); 35 final JMapViewer map = new JMapViewer(); 36 // final JMapViewer map = new JMapViewer(new MemoryTileCache(),4); 37 // map.setTileLoader(new OsmFileCacheTileLoader(map)); 38 // new DefaultMapController(map); 39 setLayout(new BorderLayout()); 40 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 41 setExtendedState(JFrame.MAXIMIZED_BOTH); 42 JPanel panel = new JPanel(); 43 JPanel helpPanel = new JPanel(); 44 add(panel, BorderLayout.NORTH); 45 add(helpPanel, BorderLayout.SOUTH); 46 JLabel helpLabel = 47 new JLabel("Use right mouse button to move,\n " 48 + "left double click or mouse wheel to zoom."); 49 helpPanel.add(helpLabel); 50 JButton button = new JButton("setDisplayToFitMapMarkers"); 51 button.addActionListener(new ActionListener() { 32 public Demo() { 33 super("JMapViewer Demo"); 34 setSize(400, 400); 35 final JMapViewer map = new JMapViewer(); 36 // final JMapViewer map = new JMapViewer(new MemoryTileCache(),4); 37 // map.setTileLoader(new OsmFileCacheTileLoader(map)); 38 // new DefaultMapController(map); 39 setLayout(new BorderLayout()); 40 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 41 setExtendedState(JFrame.MAXIMIZED_BOTH); 42 JPanel panel = new JPanel(); 43 JPanel helpPanel = new JPanel(); 44 add(panel, BorderLayout.NORTH); 45 add(helpPanel, BorderLayout.SOUTH); 46 JLabel helpLabel = new JLabel("Use right mouse button to move,\n " 47 + "left double click or mouse wheel to zoom."); 48 helpPanel.add(helpLabel); 49 JButton button = new JButton("setDisplayToFitMapMarkers"); 50 button.addActionListener(new ActionListener() { 52 51 53 public void actionPerformed(ActionEvent e) { 54 map.setDisplayToFitMapMarkers(); 55 } 56 }); 57 JComboBox tileSourceSelector = 58 new JComboBox(new TileSource[] { new OsmTileSource.Mapnik(), 59 new OsmTileSource.TilesAtHome(), new OsmTileSource.CycleMap() }); 60 tileSourceSelector.addItemListener(new ItemListener() { 61 public void itemStateChanged(ItemEvent e) { 62 map.setTileSource((TileSource) e.getItem()); 63 } 64 }); 65 JComboBox tileLoaderSelector = 66 new JComboBox(new TileLoader[] { new OsmFileCacheTileLoader(map), 67 new OsmTileLoader(map) }); 68 tileLoaderSelector.addItemListener(new ItemListener() { 69 public void itemStateChanged(ItemEvent e) { 70 map.setTileLoader((TileLoader) e.getItem()); 71 } 72 }); 73 map.setTileLoader((TileLoader) tileLoaderSelector.getSelectedItem()); 74 panel.add(tileSourceSelector); 75 panel.add(tileLoaderSelector); 76 final JCheckBox showMapMarker = new JCheckBox("Map markers visible"); 77 showMapMarker.setSelected(map.getMapMarkersVisible()); 78 showMapMarker.addActionListener(new ActionListener() { 52 public void actionPerformed(ActionEvent e) { 53 map.setDisplayToFitMapMarkers(); 54 } 55 }); 56 JComboBox tileSourceSelector = new JComboBox(new TileSource[] { new OsmTileSource.Mapnik(), 57 new OsmTileSource.TilesAtHome(), new OsmTileSource.CycleMap() }); 58 tileSourceSelector.addItemListener(new ItemListener() { 59 public void itemStateChanged(ItemEvent e) { 60 map.setTileSource((TileSource) e.getItem()); 61 } 62 }); 63 JComboBox tileLoaderSelector = new JComboBox(new TileLoader[] { new OsmFileCacheTileLoader(map), 64 new OsmTileLoader(map) }); 65 tileLoaderSelector.addItemListener(new ItemListener() { 66 public void itemStateChanged(ItemEvent e) { 67 map.setTileLoader((TileLoader) e.getItem()); 68 } 69 }); 70 map.setTileLoader((TileLoader) tileLoaderSelector.getSelectedItem()); 71 panel.add(tileSourceSelector); 72 panel.add(tileLoaderSelector); 73 final JCheckBox showMapMarker = new JCheckBox("Map markers visible"); 74 showMapMarker.setSelected(map.getMapMarkersVisible()); 75 showMapMarker.addActionListener(new ActionListener() { 79 76 80 81 82 83 84 85 86 87 77 public void actionPerformed(ActionEvent e) { 78 map.setMapMarkerVisible(showMapMarker.isSelected()); 79 } 80 }); 81 panel.add(showMapMarker); 82 final JCheckBox showTileGrid = new JCheckBox("Tile grid visible"); 83 showTileGrid.setSelected(map.isTileGridVisible()); 84 showTileGrid.addActionListener(new ActionListener() { 88 85 89 90 91 92 93 94 95 96 86 public void actionPerformed(ActionEvent e) { 87 map.setTileGridVisible(showTileGrid.isSelected()); 88 } 89 }); 90 panel.add(showTileGrid); 91 final JCheckBox showZoomControls = new JCheckBox("Show zoom controls"); 92 showZoomControls.setSelected(map.getZoomContolsVisible()); 93 showZoomControls.addActionListener(new ActionListener() { 97 94 98 99 100 101 102 103 104 95 public void actionPerformed(ActionEvent e) { 96 map.setZoomContolsVisible(showZoomControls.isSelected()); 97 } 98 }); 99 panel.add(showZoomControls); 100 panel.add(button); 101 add(map, BorderLayout.CENTER); 105 102 106 107 108 109 110 111 103 // 104 map.addMapMarker(new MapMarkerDot(49.814284999, 8.642065999)); 105 map.addMapMarker(new MapMarkerDot(49.91, 8.24)); 106 map.addMapMarker(new MapMarkerDot(49.71, 8.64)); 107 map.addMapMarker(new MapMarkerDot(48.71, -1)); 108 map.addMapMarker(new MapMarkerDot(49.8588, 8.643)); 112 109 113 114 115 110 // map.setDisplayPositionByLatLon(49.807, 8.6, 11); 111 // map.setTileGridVisible(true); 112 } 116 113 117 118 119 120 121 122 123 124 125 114 /** 115 * @param args 116 */ 117 public static void main(String[] args) { 118 // java.util.Properties systemProperties = System.getProperties(); 119 // systemProperties.setProperty("http.proxyHost", "localhost"); 120 // systemProperties.setProperty("http.proxyPort", "8008"); 121 new Demo().setVisible(true); 122 } 126 123 127 124 } -
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapController.java
r9780 r14053 21 21 public abstract class JMapController { 22 22 23 23 protected JMapViewer map; 24 24 25 26 27 28 29 30 31 32 33 25 public JMapController(JMapViewer map) { 26 this.map = map; 27 if (this instanceof MouseListener) 28 map.addMouseListener((MouseListener) this); 29 if (this instanceof MouseWheelListener) 30 map.addMouseWheelListener((MouseWheelListener) this); 31 if (this instanceof MouseMotionListener) 32 map.addMouseMotionListener((MouseMotionListener) this); 33 } 34 34 35 35 } -
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JobDispatcher.java
r10722 r14053 18 18 public class JobDispatcher { 19 19 20 20 private static JobDispatcher instance; 21 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 22 /** 23 * @return the singelton instance of the {@link JobDispatcher} 24 */ 25 public static JobDispatcher getInstance() { 26 // for speed reasons we check if the instance has been created 27 // one time before we enter the synchronized section... 28 if (instance != null) 29 return instance; 30 synchronized (JobDispatcher.class) { 31 // ... and for thread safety reasons one time inside the 32 // synchronized section. 33 if (instance != null) 34 return instance; 35 new JobDispatcher(); 36 return instance; 37 } 38 } 39 39 40 41 42 43 40 private JobDispatcher() { 41 instance = this; 42 addWorkerThread().firstThread = true; 43 } 44 44 45 45 protected BlockingQueue<Runnable> jobQueue = new LinkedBlockingQueue<Runnable>(); 46 46 47 47 public static int WORKER_THREAD_MAX_COUNT = 8; 48 48 49 50 51 52 53 54 55 49 /** 50 * Specifies the time span in seconds that a worker thread waits for new 51 * jobs to perform. If the time span has elapsed the worker thread 52 * terminates itself. Only the first worker thread works differently, it 53 * ignores the timeout and will never terminate itself. 54 */ 55 public static int WORKER_THREAD_TIMEOUT = 30; 56 56 57 58 59 60 57 /** 58 * Total number of worker threads currently idle or active 59 */ 60 protected int workerThreadCount = 0; 61 61 62 63 64 65 62 /** 63 * Number of worker threads currently idle 64 */ 65 protected int workerThreadIdleCount = 0; 66 66 67 68 69 70 67 /** 68 * Just an id for identifying an worker thread instance 69 */ 70 protected int workerThreadId = 0; 71 71 72 73 74 75 76 77 72 /** 73 * Removes all jobs from the queue that are currently not being processed. 74 */ 75 public void cancelOutstandingJobs() { 76 jobQueue.clear(); 77 } 78 78 79 80 81 82 83 84 85 86 79 public void addJob(Runnable job) { 80 try { 81 jobQueue.put(job); 82 if (workerThreadIdleCount == 0 && workerThreadCount < WORKER_THREAD_MAX_COUNT) 83 addWorkerThread(); 84 } catch (InterruptedException e) { 85 } 86 } 87 87 88 89 90 91 92 93 94 88 protected JobThread addWorkerThread() { 89 JobThread jobThread = new JobThread(++workerThreadId); 90 synchronized (this) { 91 workerThreadCount++; 92 } 93 return jobThread; 94 } 95 95 96 96 protected class JobThread extends Thread { 97 97 98 99 98 Runnable job; 99 boolean firstThread = false; 100 100 101 102 103 104 105 106 101 public JobThread(int threadId) { 102 super("OSMJobThread " + threadId); 103 setDaemon(true); 104 job = null; 105 start(); 106 } 107 107 108 109 110 111 112 113 114 108 @Override 109 public void run() { 110 executeJobs(); 111 synchronized (instance) { 112 workerThreadCount--; 113 } 114 } 115 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 116 protected void executeJobs() { 117 while (!isInterrupted()) { 118 try { 119 synchronized (instance) { 120 workerThreadIdleCount++; 121 } 122 if (firstThread) 123 job = jobQueue.take(); 124 else 125 job = jobQueue.poll(WORKER_THREAD_TIMEOUT, TimeUnit.SECONDS); 126 } catch (InterruptedException e1) { 127 return; 128 } finally { 129 synchronized (instance) { 130 workerThreadIdleCount--; 131 } 132 } 133 if (job == null) 134 return; 135 try { 136 job.run(); 137 job = null; 138 } catch (Exception e) { 139 e.printStackTrace(); 140 } 141 } 142 } 143 } 144 144 145 145 } -
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapMarkerDot.java
r9494 r14053 19 19 public class MapMarkerDot implements MapMarker { 20 20 21 22 23 21 double lat; 22 double lon; 23 Color color; 24 24 25 26 27 25 public MapMarkerDot(double lat, double lon) { 26 this(Color.YELLOW, lat, lon); 27 } 28 28 29 30 31 32 33 34 29 public MapMarkerDot(Color color, double lat, double lon) { 30 super(); 31 this.color = color; 32 this.lat = lat; 33 this.lon = lon; 34 } 35 35 36 37 38 36 public double getLat() { 37 return lat; 38 } 39 39 40 41 42 40 public double getLon() { 41 return lon; 42 } 43 43 44 45 46 47 48 49 50 51 44 public void paint(Graphics g, Point position) { 45 int size_h = 5; 46 int size = size_h * 2; 47 g.setColor(color); 48 g.fillOval(position.x - size_h, position.y - size_h, size, size); 49 g.setColor(Color.BLACK); 50 g.drawOval(position.x - size_h, position.y - size_h, size, size); 51 } 52 52 53 54 55 56 53 @Override 54 public String toString() { 55 return "MapMarker at " + lat + " " + lon; 56 } 57 57 58 58 } -
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MemoryTileCache.java
r9780 r14053 18 18 public class MemoryTileCache implements TileCache { 19 19 20 protected static final Logger log = Logger.getLogger(MemoryTileCache.class.getName()); 21 22 /** 23 * Default cache size 24 */ 25 protected int cacheSize = 200; 26 27 protected Hashtable<String, CacheEntry> hashtable; 28 29 /** 30 * List of all tiles in their last recently used order 31 */ 32 protected CacheLinkedListElement lruTiles; 33 34 public MemoryTileCache() { 35 hashtable = new Hashtable<String, CacheEntry>(cacheSize); 36 lruTiles = new CacheLinkedListElement(); 37 } 38 39 public void addTile(Tile tile) { 40 CacheEntry entry = createCacheEntry(tile); 41 hashtable.put(tile.getKey(), entry); 42 lruTiles.addFirst(entry); 43 if (hashtable.size() > cacheSize) 44 removeOldEntries(); 45 } 46 47 public Tile getTile(TileSource source, int x, int y, int z) { 48 CacheEntry entry = hashtable.get(Tile.getTileKey(source, x, y, z)); 49 if (entry == null) 50 return null; 51 // We don't care about placeholder tiles and hourglass image tiles, the 52 // important tiles are the loaded ones 53 if (entry.tile.isLoaded()) 54 lruTiles.moveElementToFirstPos(entry); 55 return entry.tile; 56 } 57 58 /** 59 * Removes the least recently used tiles 60 */ 61 protected void removeOldEntries() { 62 synchronized (lruTiles) { 63 try { 64 while (lruTiles.getElementCount() > cacheSize) { 65 removeEntry(lruTiles.getLastElement()); 66 } 67 } catch (Exception e) { 68 log.warning(e.getMessage()); 69 } 70 } 71 } 72 73 protected void removeEntry(CacheEntry entry) { 74 hashtable.remove(entry.tile.getKey()); 75 lruTiles.removeEntry(entry); 76 } 77 78 protected CacheEntry createCacheEntry(Tile tile) { 79 return new CacheEntry(tile); 80 } 81 82 public int getTileCount() { 83 return hashtable.size(); 84 } 85 86 public int getCacheSize() { 87 return cacheSize; 88 } 89 90 /** 91 * Changes the maximum number of {@link Tile} objects that this cache holds. 92 * 93 * @param cacheSize 94 * new maximum number of tiles 95 */ 96 public void setCacheSize(int cacheSize) { 97 this.cacheSize = cacheSize; 98 if (hashtable.size() > cacheSize) 99 removeOldEntries(); 100 } 101 102 /** 103 * Linked list element holding the {@link Tile} and links to the 104 * {@link #next} and {@link #prev} item in the list. 105 */ 106 protected static class CacheEntry { 107 Tile tile; 108 109 CacheEntry next; 110 CacheEntry prev; 111 112 protected CacheEntry(Tile tile) { 113 this.tile = tile; 114 } 115 116 } 117 118 /** 119 * Special implementation of a double linked list for {@link CacheEntry} 120 * elements. It supports element removal in constant time - in difference to 121 * the Java implementation which needs O(n). 122 * 123 * @author Jan Peter Stotz 124 */ 125 protected static class CacheLinkedListElement { 126 protected CacheEntry firstElement = null; 127 protected CacheEntry lastElement; 128 protected int elementCount; 129 130 public CacheLinkedListElement() { 131 elementCount = 0; 132 firstElement = null; 133 lastElement = null; 134 } 135 136 /** 137 * Add the element to the head of the list. 138 * 139 * @param new element to be added 140 */ 141 public synchronized void addFirst(CacheEntry element) { 142 if (elementCount == 0) { 143 firstElement = element; 144 lastElement = element; 145 element.prev = null; 146 element.next = null; 147 } else { 148 element.next = firstElement; 149 firstElement.prev = element; 150 element.prev = null; 151 firstElement = element; 152 } 153 elementCount++; 154 } 155 156 /** 157 * Removes the specified elemntent form the list. 158 * 159 * @param element 160 * to be removed 161 */ 162 public synchronized void removeEntry(CacheEntry element) { 163 if (element.next != null) { 164 element.next.prev = element.prev; 165 } 166 if (element.prev != null) { 167 element.prev.next = element.next; 168 } 169 if (element == firstElement) 170 firstElement = element.next; 171 if (element == lastElement) 172 lastElement = element.prev; 173 element.next = null; 174 element.prev = null; 175 elementCount--; 176 } 177 178 public synchronized void moveElementToFirstPos(CacheEntry entry) { 179 if (firstElement == entry) 180 return; 181 removeEntry(entry); 182 addFirst(entry); 183 } 184 185 public int getElementCount() { 186 return elementCount; 187 } 188 189 public CacheEntry getLastElement() { 190 return lastElement; 191 } 192 } 20 protected static final Logger log = Logger.getLogger(MemoryTileCache.class.getName()); 21 22 /** 23 * Default cache size 24 */ 25 protected int cacheSize = 200; 26 27 protected Hashtable<String, CacheEntry> hashtable; 28 29 /** 30 * List of all tiles in their last recently used order 31 */ 32 protected CacheLinkedListElement lruTiles; 33 34 public MemoryTileCache() { 35 hashtable = new Hashtable<String, CacheEntry>(cacheSize); 36 lruTiles = new CacheLinkedListElement(); 37 } 38 39 public void addTile(Tile tile) { 40 CacheEntry entry = createCacheEntry(tile); 41 hashtable.put(tile.getKey(), entry); 42 lruTiles.addFirst(entry); 43 if (hashtable.size() > cacheSize) 44 removeOldEntries(); 45 } 46 47 public Tile getTile(TileSource source, int x, int y, int z) { 48 CacheEntry entry = hashtable.get(Tile.getTileKey(source, x, y, z)); 49 if (entry == null) 50 return null; 51 // We don't care about placeholder tiles and hourglass image tiles, the 52 // important tiles are the loaded ones 53 if (entry.tile.isLoaded()) 54 lruTiles.moveElementToFirstPos(entry); 55 return entry.tile; 56 } 57 58 /** 59 * Removes the least recently used tiles 60 */ 61 protected void removeOldEntries() { 62 synchronized (lruTiles) { 63 try { 64 while (lruTiles.getElementCount() > cacheSize) { 65 removeEntry(lruTiles.getLastElement()); 66 } 67 } catch (Exception e) { 68 log.warning(e.getMessage()); 69 } 70 } 71 } 72 73 protected void removeEntry(CacheEntry entry) { 74 hashtable.remove(entry.tile.getKey()); 75 lruTiles.removeEntry(entry); 76 } 77 78 protected CacheEntry createCacheEntry(Tile tile) { 79 return new CacheEntry(tile); 80 } 81 82 /** 83 * Clears the cache deleting all tiles from memory 84 */ 85 public void clear() { 86 synchronized (lruTiles) { 87 hashtable.clear(); 88 lruTiles.clear(); 89 } 90 } 91 92 public int getTileCount() { 93 return hashtable.size(); 94 } 95 96 public int getCacheSize() { 97 return cacheSize; 98 } 99 100 /** 101 * Changes the maximum number of {@link Tile} objects that this cache holds. 102 * 103 * @param cacheSize 104 * new maximum number of tiles 105 */ 106 public void setCacheSize(int cacheSize) { 107 this.cacheSize = cacheSize; 108 if (hashtable.size() > cacheSize) 109 removeOldEntries(); 110 } 111 112 /** 113 * Linked list element holding the {@link Tile} and links to the 114 * {@link #next} and {@link #prev} item in the list. 115 */ 116 protected static class CacheEntry { 117 Tile tile; 118 119 CacheEntry next; 120 CacheEntry prev; 121 122 protected CacheEntry(Tile tile) { 123 this.tile = tile; 124 } 125 126 public Tile getTile() { 127 return tile; 128 } 129 130 public CacheEntry getNext() { 131 return next; 132 } 133 134 public CacheEntry getPrev() { 135 return prev; 136 } 137 138 } 139 140 /** 141 * Special implementation of a double linked list for {@link CacheEntry} 142 * elements. It supports element removal in constant time - in difference to 143 * the Java implementation which needs O(n). 144 * 145 * @author Jan Peter Stotz 146 */ 147 protected static class CacheLinkedListElement { 148 protected CacheEntry firstElement = null; 149 protected CacheEntry lastElement; 150 protected int elementCount; 151 152 public CacheLinkedListElement() { 153 clear(); 154 } 155 156 public synchronized void clear() { 157 elementCount = 0; 158 firstElement = null; 159 lastElement = null; 160 } 161 162 /** 163 * Add the element to the head of the list. 164 * 165 * @param new element to be added 166 */ 167 public synchronized void addFirst(CacheEntry element) { 168 if (elementCount == 0) { 169 firstElement = element; 170 lastElement = element; 171 element.prev = null; 172 element.next = null; 173 } else { 174 element.next = firstElement; 175 firstElement.prev = element; 176 element.prev = null; 177 firstElement = element; 178 } 179 elementCount++; 180 } 181 182 /** 183 * Removes the specified elemntent form the list. 184 * 185 * @param element 186 * to be removed 187 */ 188 public synchronized void removeEntry(CacheEntry element) { 189 if (element.next != null) { 190 element.next.prev = element.prev; 191 } 192 if (element.prev != null) { 193 element.prev.next = element.next; 194 } 195 if (element == firstElement) 196 firstElement = element.next; 197 if (element == lastElement) 198 lastElement = element.prev; 199 element.next = null; 200 element.prev = null; 201 elementCount--; 202 } 203 204 public synchronized void moveElementToFirstPos(CacheEntry entry) { 205 if (firstElement == entry) 206 return; 207 removeEntry(entry); 208 addFirst(entry); 209 } 210 211 public int getElementCount() { 212 return elementCount; 213 } 214 215 public CacheEntry getLastElement() { 216 return lastElement; 217 } 218 219 public CacheEntry getFirstElement() { 220 return firstElement; 221 } 222 223 } 193 224 } -
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmMercator.java
r11376 r14053 16 16 public class OsmMercator { 17 17 18 19 20 18 private static int TILE_SIZE = 256; 19 public static final double MAX_LAT = 85.05112877980659; 20 public static final double MIN_LAT = -85.05112877980659; 21 21 22 23 24 22 public static double radius(int aZoomlevel) { 23 return (TILE_SIZE * (1 << aZoomlevel)) / (2.0 * Math.PI); 24 } 25 25 26 27 28 29 30 31 32 33 34 35 26 /** 27 * Returns the absolut number of pixels in y or x, defined as: 2^Zoomlevel * 28 * TILE_WIDTH where TILE_WIDTH is the width of a tile in pixels 29 * 30 * @param aZoomlevel 31 * @return 32 */ 33 public static int getMaxPixels(int aZoomlevel) { 34 return TILE_SIZE * (1 << aZoomlevel); 35 } 36 36 37 38 39 37 public static int falseEasting(int aZoomlevel) { 38 return getMaxPixels(aZoomlevel) / 2; 39 } 40 40 41 42 43 41 public static int falseNorthing(int aZoomlevel) { 42 return (-1 * getMaxPixels(aZoomlevel) / 2); 43 } 44 44 45 46 47 48 49 50 51 52 53 54 55 56 57 45 /** 46 * Transform longitude to pixelspace 47 * 48 * @param aLongitude 49 * [-180..180] 50 * @return [0..2^Zoomlevel*TILE_SIZE[ 51 */ 52 public static int LonToX(double aLongitude, int aZoomlevel) { 53 double longitude = Math.toRadians(aLongitude); 54 int x = (int) ((radius(aZoomlevel) * longitude) + falseEasting(aZoomlevel)); 55 x = Math.min(x, getMaxPixels(aZoomlevel) - 1); 56 return x; 57 } 58 58 59 /** 60 * Transforms latitude to pixelspace 61 * 62 * @param aLat 63 * [-90...90] 64 * @return [0..2^Zoomlevel*TILE_SIZE[ 65 */ 66 public static int LatToY(double aLat, int aZoomlevel) { 67 if (aLat < MIN_LAT) 68 aLat = MIN_LAT; 69 else if (aLat > MAX_LAT) 70 aLat = MAX_LAT; 71 double latitude = Math.toRadians(aLat); 72 int y = 73 (int) (-1 74 * (radius(aZoomlevel) / 2.0 * Math.log((1.0 + Math.sin(latitude)) 75 / (1.0 - Math.sin(latitude)))) - falseNorthing(aZoomlevel)); 76 y = Math.min(y, getMaxPixels(aZoomlevel) - 1); 77 return y; 78 } 59 /** 60 * Transforms latitude to pixelspace 61 * 62 * @param aLat 63 * [-90...90] 64 * @return [0..2^Zoomlevel*TILE_SIZE[ 65 */ 66 public static int LatToY(double aLat, int aZoomlevel) { 67 if (aLat < MIN_LAT) 68 aLat = MIN_LAT; 69 else if (aLat > MAX_LAT) 70 aLat = MAX_LAT; 71 double latitude = Math.toRadians(aLat); 72 int y = (int) (-1 73 * (radius(aZoomlevel) / 2.0 * Math.log((1.0 + Math.sin(latitude)) / (1.0 - Math.sin(latitude)))) - falseNorthing(aZoomlevel)); 74 y = Math.min(y, getMaxPixels(aZoomlevel) - 1); 75 return y; 76 } 79 77 80 81 82 83 84 85 86 87 88 89 90 91 92 78 /** 79 * Transforms pixel coordinate X to longitude 80 * 81 * @param aX 82 * [0..2^Zoomlevel*TILE_WIDTH[ 83 * @return ]-180..180[ 84 */ 85 public static double XToLon(int aX, int aZoomlevel) { 86 aX -= falseEasting(aZoomlevel); 87 double longRadians = aX / radius(aZoomlevel); 88 double longDegrees = Math.toDegrees(longRadians); 89 return longDegrees; 90 } 93 91 94 95 96 97 98 99 100 101 102 103 104 105 92 /** 93 * Transforms pixel coordinate Y to latitude 94 * 95 * @param aY 96 * [0..2^Zoomlevel*TILE_WIDTH[ 97 * @return [MIN_LAT..MAX_LAT] is about [-85..85] 98 */ 99 public static double YToLat(int aY, int aZoomlevel) { 100 aY += falseNorthing(aZoomlevel); 101 double latitude = (Math.PI / 2) - (2 * Math.atan(Math.exp(-1.0 * aY / radius(aZoomlevel)))); 102 return -1 * Math.toDegrees(latitude); 103 } 106 104 107 105 } -
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileSource.java
r13035 r14053 5 5 public class OsmTileSource { 6 6 7 8 7 public static final String MAP_MAPNIK = "http://tile.openstreetmap.org"; 8 public static final String MAP_OSMA = "http://tah.openstreetmap.org/Tiles/tile"; 9 9 10 10 protected static abstract class AbstractOsmTileSource implements TileSource { 11 11 12 13 14 12 public int getMaxZoom() { 13 return 18; 14 } 15 15 16 16 public int getMinZoom() { 17 17 return 0; 18 18 } 19 19 20 21 22 20 public String getTileUrl(int zoom, int tilex, int tiley) { 21 return "/" + zoom + "/" + tilex + "/" + tiley + ".png"; 22 } 23 23 24 25 26 27 24 @Override 25 public String toString() { 26 return getName(); 27 } 28 28 29 public String getTileType() { 30 return "png"; 31 } 32 33 } 29 public String getTileType() { 30 return "png"; 31 } 34 32 35 public static class Mapnik extends AbstractOsmTileSource { 33 } 36 34 37 public static String NAME = "Mapnik"; 38 39 public String getName() { 40 return NAME; 41 } 35 public static class Mapnik extends AbstractOsmTileSource { 42 36 43 @Override 44 public String getTileUrl(int zoom, int tilex, int tiley) { 45 return MAP_MAPNIK + super.getTileUrl(zoom, tilex, tiley); 46 } 37 public static String NAME = "Mapnik"; 47 38 48 public TileUpdate getTileUpdate() {49 return TileUpdate.IfNoneMatch;50 39 public String getName() { 40 return NAME; 41 } 51 42 52 } 43 @Override 44 public String getTileUrl(int zoom, int tilex, int tiley) { 45 return MAP_MAPNIK + super.getTileUrl(zoom, tilex, tiley); 46 } 53 47 54 public static class CycleMap extends AbstractOsmTileSource { 55 56 private static final String PATTERN = "http://%s.andy.sandbox.cloudmade.com/tiles/cycle/%d/%d/%d.png"; 48 public TileUpdate getTileUpdate() { 49 return TileUpdate.IfNoneMatch; 50 } 51 52 } 53 54 public static class CycleMap extends AbstractOsmTileSource { 55 56 private static final String PATTERN = "http://%s.andy.sandbox.cloudmade.com/tiles/cycle/%d/%d/%d.png"; 57 57 public static String NAME = "OSM Cycle Map"; 58 58 … … 68 68 } 69 69 70 71 72 70 public String getName() { 71 return NAME; 72 } 73 73 74 75 76 74 public TileUpdate getTileUpdate() { 75 return TileUpdate.LastModified; 76 } 77 77 78 78 } 79 79 80 80 public static class TilesAtHome extends AbstractOsmTileSource { 81 81 82 82 public static String NAME = "TilesAtHome"; 83 83 84 85 86 84 public int getMaxZoom() { 85 return 17; 86 } 87 87 88 89 90 88 public String getName() { 89 return NAME; 90 } 91 91 92 93 94 95 92 @Override 93 public String getTileUrl(int zoom, int tilex, int tiley) { 94 return MAP_OSMA + super.getTileUrl(zoom, tilex, tiley); 95 } 96 96 97 98 99 100 97 public TileUpdate getTileUpdate() { 98 return TileUpdate.IfModifiedSince; 99 } 100 } 101 101 } -
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapMarker.java
r9494 r14053 17 17 public interface MapMarker { 18 18 19 20 21 22 19 /** 20 * @return Latitude of the map marker position 21 */ 22 public double getLat(); 23 23 24 25 26 27 24 /** 25 * @return Longitude of the map marker position 26 */ 27 public double getLon(); 28 28 29 30 31 32 33 34 35 36 29 /** 30 * Paints the map marker on the map. The <code>position</code> specifies the 31 * coordinates within <code>g</code> 32 * 33 * @param g 34 * @param position 35 */ 36 public void paint(Graphics g, Point position); 37 37 } -
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/TileCache.java
r9780 r14053 14 14 public interface TileCache { 15 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 16 /** 17 * Retrieves a tile from the cache if present, otherwise <code>null</code> 18 * will be returned. 19 * 20 * @param source 21 * @param x 22 * tile number on the x axis of the tile to be retrieved 23 * @param y 24 * tile number on the y axis of the tile to be retrieved 25 * @param z 26 * zoom level of the tile to be retrieved 27 * @return the requested tile or <code>null</code> if the tile is not 28 * present in the cache 29 */ 30 public Tile getTile(TileSource source, int x, int y, int z); 31 31 32 33 34 35 36 37 38 39 32 /** 33 * Adds a tile to the cache. How long after adding a tile can be retrieved 34 * via {@link #getTile(int, int, int)} is unspecified and depends on the 35 * implementation. 36 * 37 * @param tile 38 */ 39 public void addTile(Tile tile); 40 40 41 42 43 44 41 /** 42 * @return the number of tiles hold by the cache 43 */ 44 public int getTileCount(); 45 45 } -
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/TileLoader.java
r9846 r14053 11 11 public interface TileLoader { 12 12 13 14 15 16 17 18 19 20 21 22 23 24 25 13 /** 14 * A typical {@link #createTileLoaderJob(int, int, int)} implementation 15 * should create and return a new {@link Job} instance that performs the 16 * load action. 17 * 18 * @param tileLayerSource 19 * @param tilex 20 * @param tiley 21 * @param zoom 22 * @returns {@link Runnable} implementation that performs the desired load 23 * action. 24 */ 25 public Runnable createTileLoaderJob(TileSource tileLayerSource, int tilex, int tiley, int zoom); 26 26 } -
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/TileLoaderListener.java
r11783 r14053 7 7 public interface TileLoaderListener { 8 8 9 10 11 12 13 14 15 9 /** 10 * Will be called if a new {@link Tile} has been loaded successfully. 11 * Loaded can mean downloaded or loaded from file cache. 12 * 13 * @param tile 14 */ 15 public void tileLoadingFinished(Tile tile, boolean success); 16 16 17 17 public TileCache getTileCache(); 18 18 }
Note:
See TracChangeset
for help on using the changeset viewer.