Changeset 14732 in osm for applications
- Timestamp:
- 2009-04-24T19:34:33+02:00 (16 years ago)
- Location:
- applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapKey.java
r13665 r14732 11 11 * 12 12 * @author LuVar <lubomir.varga@freemap.sk> 13 * @author Dave Hansen <dave@sr71.net> 13 14 * 14 15 */ … … 16 17 private final int x; 17 18 private final int y; 19 private final int level; 18 20 19 21 /** … … 26 28 * @param y y position in tiles table 27 29 */ 28 public SlippyMapKey(int x, int y) { 30 public final boolean valid; 31 public SlippyMapKey(int level, int x, int y) { 29 32 this.x = x; 30 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 SlippyMapKey("+level+", "+x+", "+y+")"); 38 } else { 39 this.valid = true; 40 } 31 41 } 32 42 … … 42 52 if (obj instanceof SlippyMapKey) { 43 53 SlippyMapKey smk = (SlippyMapKey) obj; 44 if((smk.x == this.x) && (smk.y == this.y) ) {54 if((smk.x == this.x) && (smk.y == this.y) && (smk.level == this.level)) { 45 55 return true; 46 56 } … … 55 65 @Override 56 66 public int hashCode() { 57 return new Integer(this.x + this.y * 10000 ).hashCode();67 return new Integer(this.x + this.y * 10000 + this.level * 100000).hashCode(); 58 68 } 59 69 … … 63 73 @Override 64 74 public String toString() { 65 return "SlippyMapKey(x=" + this.x + ",y=" + this.y + " )";75 return "SlippyMapKey(x=" + this.x + ",y=" + this.y + ",level=" + level + ")"; 66 76 } 67 77 -
applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapLayer.java
r13961 r14732 12 12 import java.awt.event.MouseEvent; 13 13 import java.awt.image.ImageObserver; 14 import java.util.Comparator; 14 15 import java.util.HashMap; 16 import java.util.TreeSet; 15 17 16 18 import javax.swing.AbstractAction; … … 37 39 * @author Frederik Ramm <frederik@remote.org> 38 40 * @author LuVar <lubomir.varga@freemap.sk> 41 * @author Dave Hansen <dave@sr71.net> 39 42 * 40 43 */ … … 46 49 */ 47 50 public int currentZoomLevel = SlippyMapPreferences.getMinZoomLvl(); 48 private HashMap<SlippyMapKey, SlippyMapTile> []tileStorage = null;51 private HashMap<SlippyMapKey, SlippyMapTile> tileStorage = null; 49 52 50 53 Point[][] pixelpos = new Point[21][21]; … … 68 71 public void actionPerformed(ActionEvent ae) { 69 72 if (clickedTile != null) { 70 clickedTile.loadImage();73 loadSingleTile(clickedTile); 71 74 needRedraw = true; 72 75 Main.map.repaint(); … … 120 123 public void actionPerformed(ActionEvent ae) { 121 124 decreaseZoomLevel(); 122 needRedraw = true;123 125 Main.map.repaint(); 124 126 } … … 162 164 if (currentZoomLevel < SlippyMapPreferences.getMaxZoomLvl()) { 163 165 currentZoomLevel++; 166 Main.debug("increasing zoom level to: " + currentZoomLevel); 167 needRedraw = true; 164 168 } else { 165 System.err 166 .println("current zoom lvl couldnt be increased. MaxZoomLvlreached.");169 System.err.println("current zoom lvl ("+currentZoomLevel+") couldnt be increased. "+ 170 "MaxZoomLvl ("+SlippyMapPreferences.getMaxZoomLvl()+") reached."); 167 171 } 168 172 } … … 173 177 public void decreaseZoomLevel() { 174 178 if (currentZoomLevel > SlippyMapPreferences.getMinZoomLvl()) { 179 Main.debug("decreasing zoom level to: " + currentZoomLevel); 175 180 currentZoomLevel--; 181 needRedraw = true; 176 182 } else { 177 System.err 178 .println("current zoom lvl couldnt be decreased. MinZoomLvl reached."); 183 System.err.println("current zoom lvl couldnt be decreased. MinZoomLvl reached."); 179 184 } 180 185 } … … 184 189 // the setting isnt saved yet. 185 190 int maxZoom = 30; // SlippyMapPreferences.getMaxZoomLvl(); 186 // +1 because of array indexed from 0. 187 tileStorage = new HashMap[maxZoom + 1]; 188 189 for (int i = 0; i < maxZoom + 1; i++) 190 tileStorage[i] = new HashMap<SlippyMapKey, SlippyMapTile>(); 191 tileStorage = new HashMap<SlippyMapKey, SlippyMapTile>(); 192 193 checkTileStorage(); 194 } 195 196 class TileTimeComp implements Comparator<SlippyMapTile> { 197 public int compare(SlippyMapTile s1, SlippyMapTile s2) { 198 long t1 = s1.access_time(); 199 long t2 = s2.access_time(); 200 if (s1 == s2) 201 return 0; 202 if (t1 == t2) { 203 t1 = s1.hashCode(); 204 t2 = s2.hashCode(); 205 } 206 if (t1 < t2) 207 return -1; 208 return 1; 209 } 210 } 211 212 long lastCheck = 0; 213 /** 214 * <p> 215 * Check if tiles.size() is not more than max_nr_tiles. If yes, oldest tiles by timestamp 216 * are fired out from cache. 217 * </p> 218 */ 219 public void checkTileStorage() { 220 int maxZoom = 30; // SlippyMapPreferences.getMaxZoomLvl(); 221 long now = System.currentTimeMillis(); 222 if (now - lastCheck < 1000) 223 return; 224 lastCheck = now; 225 TreeSet<SlippyMapTile> tiles = new TreeSet<SlippyMapTile>(new TileTimeComp()); 226 tiles.addAll(tileStorage.values()); 227 int max_nr_tiles = 100; 228 if (tiles.size() < max_nr_tiles) { 229 Main.debug("total of " + tiles.size() + " loaded tiles, size OK " + now); 230 return; 231 } 232 int nr_to_drop = tiles.size() - max_nr_tiles;; 233 Main.debug("total of " + tiles.size() + " tiles, need to flush " + nr_to_drop + " tiles"); 234 for (SlippyMapTile t : tiles) { 235 if (nr_to_drop <= 0) 236 break; 237 t.dropImage(); 238 nr_to_drop--; 239 } 240 } 241 242 void loadSingleTile(SlippyMapTile tile) 243 { 244 tile.loadImage(); 245 this.checkTileStorage(); 191 246 } 192 247 … … 224 279 for (int x = z12x0 - 1; x <= z12x1; x++) { 225 280 for (int y = z12y0 - 1; y <= z12y1; y++) { 226 SlippyMapKey key = new SlippyMapKey(x, y); 227 228 SlippyMapTile tile = tileStorage[currentZoomLevel].get(key); 229 281 SlippyMapKey key = new SlippyMapKey(currentZoomLevel, x, y); 282 SlippyMapTile tile = tileStorage.get(key); 283 if (!key.valid) { 284 System.out.println("paint-1() made invalid key"); 285 continue; 286 } 230 287 if (tile == null) 231 tileStorage [currentZoomLevel].put(key,288 tileStorage.put(key, 232 289 tile = new SlippyMapTile(x, y, currentZoomLevel)); 233 234 if (tile.getImage() == null) 235 tile.loadImage(); 236 } 237 } 290 if (tile.getImage() == null) { 291 this.loadSingleTile(tile); 292 } 293 } 294 } 295 } 296 297 /* 298 * Attempt to approximate how much the image is 299 * being scaled. For instance, a 100x100 image 300 * being scaled to 50x50 would return 0.25. 301 */ 302 double getImageScaling(Image img, Point p0, Point p1) 303 { 304 int realWidth = img.getWidth(this); 305 int realHeight = img.getHeight(this); 306 if (realWidth == -1 || realHeight == -1) 307 return 1.0; 308 int drawWidth = p1.x - p0.x; 309 int drawHeight = p1.x - p0.x; 310 311 double drawArea = drawWidth * drawHeight; 312 double realArea = realWidth * realHeight; 313 314 return drawArea / realArea; 238 315 } 239 316 … … 242 319 @Override 243 320 public void paint(Graphics g, MapView mv) { 321 long start = System.currentTimeMillis(); 244 322 LatLon topLeft = mv.getLatLon(0, 0); 245 323 LatLon botRight = mv.getLatLon(mv.getWidth(), mv.getHeight()); 246 324 Graphics oldg = g; 247 325 326 if (botRight.lon() == 0.0 || botRight.lat() == 0) { 327 // probably still initializing 328 return; 329 } 248 330 if (lastTopLeft != null && lastBotRight != null 249 331 && topLeft.equalsEpsilon(lastTopLeft) … … 298 380 float fadeBackground = SlippyMapPreferences.getFadeBackground(); 299 381 382 Double imageScale = null; 383 int count = 0; 300 384 for (int x = z12x0 - 1; x <= z12x1; x++) { 301 385 for (int y = z12y0 - 1; y <= z12y1; y++) { 302 SlippyMapKey key = new SlippyMapKey( x, y);386 SlippyMapKey key = new SlippyMapKey(currentZoomLevel, x, y); 303 387 SlippyMapTile tile; 304 try { 305 tile = tileStorage[currentZoomLevel].get(key); 306 } catch (IndexOutOfBoundsException ex) { 307 throw new RuntimeException("currentZoomLevel=" 308 + currentZoomLevel 309 + " and tile storage array have just size=" 310 + tileStorage.length 311 + " and maxZoomLvl in preferences is " 312 + SlippyMapPreferences.getMaxZoomLvl() + ".", ex); 313 } 314 388 tile = tileStorage.get(key); 389 if (!key.valid) { 390 System.out.println("loadAllTiles() made invalid key"); 391 continue; 392 } 315 393 if (tile == null) { 316 394 tile = new SlippyMapTile(x, y, currentZoomLevel); 317 tileStorage [currentZoomLevel].put(key, tile);395 tileStorage.put(key, tile); 318 396 if (SlippyMapPreferences.getAutoloadTiles()) { 319 397 // TODO probably do on background 320 tile.loadImage(); 321 } 398 loadSingleTile(tile); 399 } 400 checkTileStorage(); 322 401 } 323 402 Image img = tile.getImage(); … … 327 406 Point p2 = pixelpos[x - z12x0 + 2][y - z12y0 + 2]; 328 407 g.drawImage(img, p.x, p.y, p2.x - p.x, p2.y - p.y, this); 329 408 if (imageScale == null) 409 imageScale = new Double(getImageScaling(img, p, p2)); 410 count++; 330 411 if (fadeBackground != 0f) { 331 412 // dimm by painting opaque rect... … … 336 417 }// end of for 337 418 }// end of for 338 339 419 g.setColor(Color.red); 340 420 for (int x = z12x0 - 1; x <= z12x1; x++) { … … 351 431 352 432 for (int y = z12y0 - 1; y <= z12y1; y++) { 353 SlippyMapKey key = new SlippyMapKey( x, y);433 SlippyMapKey key = new SlippyMapKey(currentZoomLevel, x, y); 354 434 int texty = p.y + 2 + fontHeight; 355 SlippyMapTile tile = tileStorage [currentZoomLevel].get(key);435 SlippyMapTile tile = tileStorage.get(key); 356 436 if (tile == null) { 357 437 continue; 438 } 439 if (!key.valid) { 440 System.out.println("paint-0() made invalid key"); 441 continue; 442 } 443 if (tile.getImage() == null) { 444 loadSingleTile(tile); 358 445 } 359 446 p = pixelpos[x - z12x0 + 1][y - z12y0 + 2]; … … 395 482 oldg.drawImage(bufferImage, 0, 0, null); 396 483 397 // TODO do autozoom nicer 398 if ((z12x1 - z12x0 < 2) || (z12y1 - z12y0 < 2)) { 399 if (SlippyMapPreferences.getAutozoom()) { 400 increaseZoomLevel(); 401 } 402 this.paint(oldg, mv); 403 } 404 405 if ((z12x1 - z12x0 > 6) || (z12y1 - z12y0 > 6)) { 406 if (SlippyMapPreferences.getAutozoom()) { 407 decreaseZoomLevel(); 408 } 409 this.paint(oldg, mv); 410 } 411 484 if (imageScale != null) { 485 // If each source image pixel is being stretched into > 3 486 // drawn pixels, zoom in... getting too pixelated 487 if (imageScale > 3) { 488 if (SlippyMapPreferences.getAutozoom()) { 489 Main.debug("autozoom increase: "+z12x1+" " + z12x0 + " " + z12y1 + " " + z12y0 490 + topLeft + " " + botRight + " scale: " + imageScale); 491 increaseZoomLevel(); 492 } 493 this.paint(oldg, mv); 494 } 495 496 // If each source image pixel is being squished into > 0.32 497 // of a drawn pixels, zoom out. 498 if (imageScale < 0.32) { 499 if (SlippyMapPreferences.getAutozoom()) { 500 Main.debug("autozoom decrease: "+z12x1+" " + z12x0 + " " + z12y1 + " " + z12y0 501 + topLeft + " " + botRight + " scale: " + imageScale); 502 decreaseZoomLevel(); 503 } 504 this.paint(oldg, mv); 505 } 506 } 412 507 g.setColor(Color.black); 413 508 g.drawString("currentZoomLevel=" + currentZoomLevel, 120, 120); … … 433 528 } 434 529 } 435 if (tiley == -1) 530 if (tiley == -1) { 436 531 return null; 437 438 SlippyMapKey key = new SlippyMapKey(tilex, tiley); 439 SlippyMapTile tile = tileStorage[currentZoomLevel].get(key); 532 } 533 534 SlippyMapKey key = new SlippyMapKey(currentZoomLevel, tilex, tiley); 535 if (!key.valid) { 536 System.err.println("getTileForPixelpos("+px+","+py+") made invalid key"); 537 return null; 538 } 539 SlippyMapTile tile = tileStorage.get(key); 440 540 if (tile == null) 441 tileStorage [currentZoomLevel].put(key, tile = new SlippyMapTile(442 tilex, tiley, currentZoomLevel));541 tileStorage.put(key, tile = new SlippyMapTile(tilex, tiley, currentZoomLevel)); 542 checkTileStorage(); 443 543 return tile; 444 544 } … … 506 606 public boolean imageUpdate(Image img, int infoflags, int x, int y, 507 607 int width, int height) { 508 509 608 boolean done = ((infoflags & (ERROR | FRAMEBITS | ALLBITS)) != 0); 609 if ((infoflags & ERROR) != 0) { 610 String url = "unknown"; 611 for (SlippyMapTile tile : tileStorage.values()) { 612 if (tile.getImage() != img) 613 continue; 614 url = tile.getImageURL().toString(); 615 } 616 System.err.println("imageUpdate(" + img + ") error " + url +")"); 617 } 618 if ((infoflags & SOMEBITS) != 0) { 619 //if (y%100 == 0) 620 // System.out.println("imageUpdate("+img+") SOMEBITS ("+x+","+y+")"); 621 } 510 622 // Repaint immediately if we are done, otherwise batch up 511 623 // repaint requests every 100 milliseconds -
applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapTile.java
r13625 r14732 16 16 * @author Frederik Ramm <frederik@remote.org> 17 17 * @author LuVar <lubomir.varga@freemap.sk> 18 * @author Dave Hansen <dave@sr71.net> 18 19 * 19 20 */ … … 21 22 { 22 23 private Image tileImage; 24 long timestamp; 23 25 24 26 int x; … … 33 35 this.y = y; 34 36 this.z = z; 37 timestamp = System.currentTimeMillis(); 35 38 } 36 39 … … 40 43 } 41 44 42 public void loadImage() 45 46 public URL getImageURL() 43 47 { 44 48 try 45 49 { 46 URL imageURL = new URL(SlippyMapPreferences.getMapUrl() + "/" + z 47 + "/" + x + "/" + y + ".png"); 48 49 tileImage = Toolkit.getDefaultToolkit().createImage(imageURL); 50 return new URL(SlippyMapPreferences.getMapUrl() + "/" + z + "/" + x + "/" + y + ".png"); 50 51 } 51 52 catch (MalformedURLException mfu) … … 53 54 mfu.printStackTrace(); 54 55 } 56 return null; 57 } 58 59 public void loadImage() 60 { 61 URL imageURL = this.getImageURL(); 62 tileImage = Toolkit.getDefaultToolkit().createImage(imageURL); 63 Toolkit.getDefaultToolkit().sync(); 64 timestamp = System.currentTimeMillis(); 55 65 } 56 66 57 67 public Image getImage() 58 68 { 69 timestamp = System.currentTimeMillis(); 59 70 return tileImage; 71 } 72 73 public void dropImage() 74 { 75 tileImage = null; 76 // This should work in theory but doesn't seem to actually 77 // reduce the X server memory usage 78 //tileImage.flush(); 60 79 } 61 80 … … 74 93 catch (Exception ex) 75 94 { 76 metadata = tr("error loading metadata" );95 metadata = tr("error loading metadata" + ex.toString()); 77 96 } 78 97 … … 88 107 BufferedReader in = new BufferedReader(new InputStreamReader(devc 89 108 .getInputStream())); 109 timestamp = System.currentTimeMillis(); 90 110 metadata = tr("requested: {0}", tr(in.readLine())); 91 111 } … … 94 114 metadata = tr("error requesting update"); 95 115 } 116 } 117 118 public long access_time() 119 { 120 return timestamp; 96 121 } 97 122
Note:
See TracChangeset
for help on using the changeset viewer.