Changeset 23190 in osm for applications/editors/josm/plugins/walkingpapers/src
- Timestamp:
- 2010-09-15T18:54:18+02:00 (14 years ago)
- Location:
- applications/editors/josm/plugins/walkingpapers/src/org/openstreetmap/josm/plugins/walkingpapers
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/walkingpapers/src/org/openstreetmap/josm/plugins/walkingpapers/WalkingPapersAddLayerAction.java
r18542 r23190 21 21 22 22 public WalkingPapersAddLayerAction() { 23 super(tr("Scanned Map..."), "walkingpapers", 24 23 super(tr("Scanned Map..."), "walkingpapers", 24 tr("Display a map that was previously scanned and uploaded to walking-papers.org"), null, false); 25 25 } 26 26 27 27 public void actionPerformed(ActionEvent e) { 28 String wpid = JOptionPane.showInputDialog(Main.parent, 29 30 28 String wpid = JOptionPane.showInputDialog(Main.parent, 29 tr("Enter a walking-papers.org URL or ID (the bit after the ?id= in the URL)"), 30 Main.pref.get("walkingpapers.last-used-id")); 31 31 32 32 if (wpid == null || wpid.equals("")) return; … … 42 42 Pattern spanPattern = Pattern.compile("<span class=\"(\\S+)\">(\\S+)</span>"); 43 43 Matcher m; 44 44 45 45 double north = 0; 46 46 double south = 0; … … 52 52 53 53 try { 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 54 BufferedReader r = new BufferedReader(new InputStreamReader(new URL(wpUrl).openStream(), "utf-8")); 55 for (String line = r.readLine(); line != null; line = r.readLine()) { 56 m = spanPattern.matcher(line); 57 if (m.find()) { 58 if ("tile".equals(m.group(1))) tile = m.group(2); 59 else if ("north".equals(m.group(1))) north = Double.parseDouble(m.group(2)); 60 else if ("south".equals(m.group(1))) south = Double.parseDouble(m.group(2)); 61 else if ("east".equals(m.group(1))) east = Double.parseDouble(m.group(2)); 62 else if ("west".equals(m.group(1))) west = Double.parseDouble(m.group(2)); 63 else if ("minzoom".equals(m.group(1))) minz = Integer.parseInt(m.group(2)); 64 else if ("maxzoom".equals(m.group(1))) maxz = Integer.parseInt(m.group(2)); 65 } 66 } 67 r.close(); 68 if ((tile == null) || (north == 0 && south == 0) || (east == 0 && west == 0)) throw new Exception(); 69 69 } catch (Exception ex) { 70 71 70 JOptionPane.showMessageDialog(Main.parent,tr("Could not read information from walking-papers.org the id \"{0}\"", mungedWpId)); 71 return; 72 72 } 73 73 … … 82 82 83 83 Bounds b = new Bounds(new LatLon(south, west), new LatLon(north, east)); 84 84 85 85 WalkingPapersLayer wpl = new WalkingPapersLayer(mungedWpId, tile, b, minz, maxz); 86 86 Main.main.addLayer(wpl); -
applications/editors/josm/plugins/walkingpapers/src/org/openstreetmap/josm/plugins/walkingpapers/WalkingPapersKey.java
r16522 r23190 1 1 /** 2 * 2 * 3 3 */ 4 4 package org.openstreetmap.josm.plugins.walkingpapers; … … 9 9 * {@link #equals(Object)} and also {@link #toString()}. 10 10 * </p> 11 * 11 * 12 12 * @author LuVar <lubomir.varga@freemap.sk> 13 13 * @author Dave Hansen <dave@sr71.net> … … 15 15 */ 16 16 public class WalkingPapersKey { 17 18 19 20 21 22 23 24 25 26 * 27 * @param xx position in tiles table28 * @param yy position in tiles table29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 * 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 * @returnreturn new Integer(this.x + this.y * 10000).hashCode();63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 17 private final int x; 18 private final int y; 19 private final int level; 20 21 /** 22 * <p> 23 * Constructs key for hashmaps for some tile describedy by X and Y position. X and Y are tiles 24 * positions on discrete map. 25 * </p> 26 * 27 * @param x x position in tiles table 28 * @param y y position in tiles table 29 */ 30 public final boolean valid; 31 public WalkingPapersKey(int level, int x, int y) { 32 this.x = x; 33 this.y = y; 34 this.level = level; 35 if (level <= 0 || x < 0 || y < 0) { 36 this.valid = false; 37 System.err.println("invalid WalkingPapersKey("+level+", "+x+", "+y+")"); 38 } else { 39 this.valid = true; 40 } 41 } 42 43 /** 44 * <p> 45 * Returns true ONLY if x and y are equals. 46 * </p> 47 * 48 * @see java.lang.Object#equals(java.lang.Object) 49 */ 50 @Override 51 public boolean equals(Object obj) { 52 if (obj instanceof WalkingPapersKey) { 53 WalkingPapersKey smk = (WalkingPapersKey) obj; 54 if((smk.x == this.x) && (smk.y == this.y) && (smk.level == this.level)) { 55 return true; 56 } 57 } 58 return false; 59 } 60 61 /** 62 * @return return new Integer(this.x + this.y * 10000).hashCode(); 63 * @see java.lang.Object#hashCode() 64 */ 65 @Override 66 public int hashCode() { 67 return new Integer(this.x + this.y * 10000 + this.level * 100000).hashCode(); 68 } 69 70 /** 71 * @see java.lang.Object#toString() 72 */ 73 @Override 74 public String toString() { 75 return "WalkingPapersKey(x=" + this.x + ",y=" + this.y + ",level=" + level + ")"; 76 } 77 78 78 } -
applications/editors/josm/plugins/walkingpapers/src/org/openstreetmap/josm/plugins/walkingpapers/WalkingPapersLayer.java
r22549 r23190 36 36 */ 37 37 public class WalkingPapersLayer extends Layer implements ImageObserver { 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 */ 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 38 /** 39 * Actual zoom lvl. Initial zoom lvl is set to 40 * {@link WalkingPapersPreferences#getMinZoomLvl()}. 41 */ 42 private int currentZoomLevel; 43 private HashMap<WalkingPapersKey, WalkingPapersTile> tileStorage = null; 44 45 private Point[][] pixelpos = new Point[21][21]; 46 private LatLon lastTopLeft; 47 private LatLon lastBotRight; 48 private int viewportMinX, viewportMaxX, viewportMinY, viewportMaxY; 49 private Image bufferImage; 50 private boolean needRedraw; 51 52 private int minzoom, maxzoom; 53 private Bounds printBounds; 54 private String tileUrlTemplate; 55 private String walkingPapersId; 56 57 @SuppressWarnings("serial") 58 public WalkingPapersLayer(String id, String tile, Bounds b, int minz, int maxz) { 59 super(tr("Walking Papers: {0}", id)); 60 setBackgroundLayer(true); 61 walkingPapersId = id; 62 63 tileUrlTemplate = tile; 64 this.printBounds = b; 65 this.minzoom = minz; this.maxzoom = maxz; 66 currentZoomLevel = minz; 67 68 clearTileStorage(); 69 70 MapView.addLayerChangeListener(new LayerChangeListener() { 71 public void activeLayerChange(Layer oldLayer, Layer newLayer) { 72 // if user changes to a walking papers layer, zoom there just as if 73 // it was newly added 74 layerAdded(newLayer); 75 } 76 77 public void layerAdded(Layer newLayer) { 78 // only do something if we are affected 79 if (newLayer != WalkingPapersLayer.this) return; 80 BoundingXYVisitor bbox = new BoundingXYVisitor(); 81 bbox.visit(printBounds); 82 Main.map.mapView.recalculateCenterScale(bbox); 83 needRedraw = true; 84 } 85 86 public void layerRemoved(Layer oldLayer) { 87 if (oldLayer == WalkingPapersLayer.this) { 88 MapView.removeLayerChangeListener(this); 89 } 90 } 91 }); 92 } 93 94 /** 95 * Zoom in, go closer to map. 96 */ 97 public void increaseZoomLevel() { 98 if (currentZoomLevel < maxzoom) { 99 currentZoomLevel++; 100 needRedraw = true; 101 } 102 } 103 104 /** 105 * Zoom out from map. 106 */ 107 public void decreaseZoomLevel() { 108 if (currentZoomLevel > minzoom) { 109 currentZoomLevel--; 110 needRedraw = true; 111 } 112 } 113 114 public void clearTileStorage() { 115 tileStorage = new HashMap<WalkingPapersKey, WalkingPapersTile>(); 116 checkTileStorage(); 117 } 118 119 static class TileTimeComp implements Comparator<WalkingPapersTile> { 120 public int compare(WalkingPapersTile s1, WalkingPapersTile s2) { 121 long t1 = s1.access_time(); 122 long t2 = s2.access_time(); 123 if (s1 == s2) return 0; 124 if (t1 == t2) { 125 t1 = s1.hashCode(); 126 t2 = s2.hashCode(); 127 } 128 if (t1 < t2) return -1; 129 return 1; 130 } 131 } 132 133 long lastCheck = 0; 134 /** 135 * <p> 136 * Check if tiles.size() is not more than max_nr_tiles. If yes, oldest tiles by timestamp 137 * are fired out from cache. 138 * </p> 139 */ 140 public void checkTileStorage() { 141 long now = System.currentTimeMillis(); 142 if (now - lastCheck < 1000) return; 143 lastCheck = now; 144 TreeSet<WalkingPapersTile> tiles = new TreeSet<WalkingPapersTile>(new TileTimeComp()); 145 tiles.addAll(tileStorage.values()); 146 int max_nr_tiles = 100; 147 if (tiles.size() < max_nr_tiles) { 148 return; 149 } 150 int dropCount = tiles.size() - max_nr_tiles;; 151 for (WalkingPapersTile t : tiles) { 152 if (dropCount <= 0) 153 break; 154 t.dropImage(); 155 dropCount--; 156 } 157 } 158 159 void loadSingleTile(WalkingPapersTile tile) { 160 tile.loadImage(); 161 this.checkTileStorage(); 162 } 163 164 /* 165 * Attempt to approximate how much the image is 166 * being scaled. For instance, a 100x100 image 167 * being scaled to 50x50 would return 0.25. 168 */ 169 Double getImageScaling(Image img, Point p0, Point p1) { 170 int realWidth = img.getWidth(this); 171 int realHeight = img.getHeight(this); 172 if (realWidth == -1 || realHeight == -1) 173 return null; 174 int drawWidth = p1.x - p0.x; 175 int drawHeight = p1.x - p0.x; 176 177 double drawArea = drawWidth * drawHeight; 178 double realArea = realWidth * realHeight; 179 180 return drawArea / realArea; 181 } 182 183 /** 184 */ 185 @Override 186 public void paint(Graphics2D g, MapView mv, Bounds bounds) { 187 LatLon topLeft = mv.getLatLon(0, 0); 188 LatLon botRight = mv.getLatLon(mv.getWidth(), mv.getHeight()); 189 Graphics2D oldg = g; 190 191 if (botRight.lon() == 0.0 || botRight.lat() == 0) { 192 // probably still initializing 193 return; 194 } 195 if (lastTopLeft != null && lastBotRight != null 196 && topLeft.equalsEpsilon(lastTopLeft) 197 && botRight.equalsEpsilon(lastBotRight) && bufferImage != null 198 && mv.getWidth() == bufferImage.getWidth(null) 199 && mv.getHeight() == bufferImage.getHeight(null) && !needRedraw) { 200 201 g.drawImage(bufferImage, 0, 0, null); 202 return; 203 } 204 205 needRedraw = false; 206 lastTopLeft = topLeft; 207 lastBotRight = botRight; 208 bufferImage = mv.createImage(mv.getWidth(), mv.getHeight()); 209 g = (Graphics2D) bufferImage.getGraphics(); 210 210 211 211 if (!LatLon.isValidLat(topLeft.lat()) || … … 215 215 return; 216 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 217 viewportMinX = lonToTileX(topLeft.lon()); 218 viewportMaxX = lonToTileX(botRight.lon()); 219 viewportMinY = latToTileY(topLeft.lat()); 220 viewportMaxY = latToTileY(botRight.lat()); 221 222 if (viewportMinX > viewportMaxX) { 223 int tmp = viewportMinX; 224 viewportMinX = viewportMaxX; 225 viewportMaxX = tmp; 226 } 227 if (viewportMinY > viewportMaxY) { 228 int tmp = viewportMinY; 229 viewportMinY = viewportMaxY; 230 viewportMaxY = tmp; 231 } 232 233 if (viewportMaxX-viewportMinX > 18) return; 234 if (viewportMaxY-viewportMinY > 18) return; 235 236 for (int x = viewportMinX - 1; x <= viewportMaxX + 1; x++) { 237 double lon = tileXToLon(x); 238 for (int y = viewportMinY - 1; y <= viewportMaxY + 1; y++) { 239 LatLon tmpLL = new LatLon(tileYToLat(y), lon); 240 pixelpos[x - viewportMinX + 1][y - viewportMinY + 1] = mv.getPoint(Main.proj 241 .latlon2eastNorth(tmpLL)); 242 } 243 } 244 245 g.setColor(Color.DARK_GRAY); 246 247 Double imageScale = null; 248 int count = 0; 249 250 for (int x = viewportMinX-1; x <= viewportMaxX; x++) { 251 252 for (int y = viewportMinY-1; y <= viewportMaxY; y++) { 253 WalkingPapersKey key = new WalkingPapersKey(currentZoomLevel, x, y); 254 WalkingPapersTile tile; 255 tile = tileStorage.get(key); 256 if (!key.valid) continue; 257 if (tile == null) { 258 // check if tile is in range 259 Bounds tileBounds = new Bounds(new LatLon(tileYToLat(y+1), tileXToLon(x)), 260 new LatLon(tileYToLat(y), tileXToLon(x+1))); 261 if (!tileBounds.asRect().intersects(printBounds.asRect())) continue; 262 tile = new WalkingPapersTile(x, y, currentZoomLevel, this); 263 tileStorage.put(key, tile); 264 loadSingleTile(tile); 265 checkTileStorage(); 266 } 267 Image img = tile.getImage(); 268 269 if (img != null) { 270 Point p = pixelpos[x - viewportMinX + 1][y - viewportMinY + 1]; 271 Point p2 = pixelpos[x - viewportMinX + 2][y - viewportMinY + 2]; 272 g.drawImage(img, p.x, p.y, p2.x - p.x, p2.y - p.y, this); 273 if (imageScale == null) 274 imageScale = getImageScaling(img, p, p2); 275 count++; 276 } 277 } 278 } 279 280 if (count == 0) 281 { 282 //System.out.println("no images on " + walkingPapersId + ", return"); 283 return; 284 } 285 286 oldg.drawImage(bufferImage, 0, 0, null); 287 288 if (imageScale != null) { 289 // If each source image pixel is being stretched into > 3 290 // drawn pixels, zoom in... getting too pixelated 291 if (imageScale > 3) { 292 increaseZoomLevel(); 293 this.paint(oldg, mv, bounds); 294 } 295 296 // If each source image pixel is being squished into > 0.32 297 // of a drawn pixels, zoom out. 298 else if (imageScale < 0.32) { 299 decreaseZoomLevel(); 300 this.paint(oldg, mv, bounds); 301 } 302 } 303 }// end of paint metod 304 305 WalkingPapersTile getTileForPixelpos(int px, int py) { 306 int tilex = viewportMaxX; 307 int tiley = viewportMaxY; 308 for (int x = viewportMinX; x <= viewportMaxX; x++) { 309 if (pixelpos[x - viewportMinX + 1][0].x > px) { 310 tilex = x - 1; 311 break; 312 } 313 } 314 315 if (tilex == -1) return null; 316 317 for (int y = viewportMinY; y <= viewportMaxY; y++) { 318 if (pixelpos[0][y - viewportMinY + 1].y > py) { 319 tiley = y - 1; 320 break; 321 } 322 } 323 324 if (tiley == -1) return null; 325 326 WalkingPapersKey key = new WalkingPapersKey(currentZoomLevel, tilex, tiley); 327 if (!key.valid) { 328 System.err.println("getTileForPixelpos("+px+","+py+") made invalid key"); 329 return null; 330 } 331 WalkingPapersTile tile = tileStorage.get(key); 332 if (tile == null) 333 tileStorage.put(key, tile = new WalkingPapersTile(tilex, tiley, currentZoomLevel, this)); 334 checkTileStorage(); 335 return tile; 336 } 337 338 @Override 339 public Icon getIcon() { 340 return ImageProvider.get("walkingpapers"); 341 } 342 343 @Override 344 public Object getInfoComponent() { 345 return getToolTipText(); 346 } 347 348 @Override 349 public Action[] getMenuEntries() { 350 return new Action[] { 351 LayerListDialog.getInstance().createShowHideLayerAction(), 352 LayerListDialog.getInstance().createDeleteLayerAction(), 353 SeparatorLayerAction.INSTANCE, 354 // color, 355 // new JMenuItem(new RenameLayerAction(associatedFile, this)), 356 SeparatorLayerAction.INSTANCE, 357 new LayerListPopup.InfoAction(this) }; 358 } 359 360 @Override 361 public String getToolTipText() { 362 return tr("Walking Papers layer ({0}) in zoom {1}", this.getWalkingPapersId(), currentZoomLevel); 363 } 364 365 @Override 366 public boolean isMergable(Layer other) { 367 return false; 368 } 369 370 @Override 371 public void mergeFrom(Layer from) { 372 } 373 374 @Override 375 public void visitBoundingBox(BoundingXYVisitor v) { 376 376 if (printBounds != null) 377 377 v.visit(printBounds); 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 378 } 379 380 private int latToTileY(double lat) { 381 double l = lat / 180 * Math.PI; 382 double pf = Math.log(Math.tan(l) + (1 / Math.cos(l))); 383 return (int) (Math.pow(2.0, currentZoomLevel - 1) * (Math.PI - pf) / Math.PI); 384 } 385 386 private int lonToTileX(double lon) { 387 return (int) (Math.pow(2.0, currentZoomLevel - 3) * (lon + 180.0) / 45.0); 388 } 389 390 private double tileYToLat(int y) { 391 return Math.atan(Math.sinh(Math.PI 392 - (Math.PI * y / Math.pow(2.0, currentZoomLevel - 1)))) 393 * 180 / Math.PI; 394 } 395 396 private double tileXToLon(int x) { 397 return x * 45.0 / Math.pow(2.0, currentZoomLevel - 3) - 180.0; 398 } 399 400 public boolean imageUpdate(Image img, int infoflags, int x, int y, 401 int width, int height) { 402 boolean done = ((infoflags & (ERROR | FRAMEBITS | ALLBITS)) != 0); 403 if ((infoflags & ERROR) != 0) return false; 404 // Repaint immediately if we are done, otherwise batch up 405 // repaint requests every 100 milliseconds 406 needRedraw = true; 407 Main.map.repaint(done ? 0 : 100); 408 return !done; 409 } 410 411 public String getWalkingPapersId() { 412 return walkingPapersId; 413 } 414 415 public URL formatImageUrl(int x, int y, int z) { 416 String urlstr = tileUrlTemplate. 417 replace("{x}", String.valueOf(x)). 418 replace("{y}", String.valueOf(y)). 419 replace("{z}", String.valueOf(z)); 420 try { 421 return new URL(urlstr); 422 } catch (Exception ex) { 423 return null; 424 } 425 } 426 426 427 427 } -
applications/editors/josm/plugins/walkingpapers/src/org/openstreetmap/josm/plugins/walkingpapers/WalkingPapersPlugin.java
r19487 r23190 26 26 public WalkingPapersPlugin(PluginInformation info) 27 27 { 28 28 super(info); 29 29 MainMenu menu = Main.main.menu; 30 30 walkingPapersMenu = menu.addMenu(marktr("Walking Papers"), KeyEvent.VK_K, menu.defaultMenuPos, ht("/Plugin/WalkingPapers")); -
applications/editors/josm/plugins/walkingpapers/src/org/openstreetmap/josm/plugins/walkingpapers/WalkingPapersTile.java
r16549 r23190 7 7 /** 8 8 * Class that contains information about one single slippy map tile. 9 * 9 * 10 10 * @author Frederik Ramm <frederik@remote.org> 11 11 * @author LuVar <lubomir.varga@freemap.sk> 12 12 * @author Dave Hansen <dave@sr71.net> 13 * 13 * 14 14 */ 15 15 public class WalkingPapersTile { 16 16 private Image tileImage; 17 17 long timestamp; 18 18 19 19 int x; 20 20 int y; 21 21 int z; 22 22 23 23 WalkingPapersLayer parentLayer; 24 24 … … 29 29 this.z = z; 30 30 parentLayer = parent; 31 31 timestamp = System.currentTimeMillis(); 32 32 } 33 33 34 34 public URL getImageUrl() { 35 35 return parentLayer.formatImageUrl(x, y, z); 36 36 } 37 37 … … 39 39 URL imageUrl = this.getImageUrl(); 40 40 tileImage = Toolkit.getDefaultToolkit().createImage(imageUrl); 41 42 41 Toolkit.getDefaultToolkit().sync(); 42 timestamp = System.currentTimeMillis(); 43 43 } 44 44 … … 49 49 50 50 public void dropImage() { 51 52 53 54 51 tileImage = null; 52 // This should work in theory but doesn't seem to actually 53 // reduce the X server memory usage 54 //tileImage.flush(); 55 55 } 56 56
Note:
See TracChangeset
for help on using the changeset viewer.