Changeset 18367 in osm for applications/editors/josm/plugins/slippymap
- Timestamp:
- 2009-10-29T22:32:51+01:00 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapLayer.java
r18360 r18367 173 173 })); 174 174 175 /* FIXME 175 176 tileOptionMenu.add(new JMenuItem(new AbstractAction( 176 177 tr("Request Update")) { 177 178 public void actionPerformed(ActionEvent ae) { 178 179 if (clickedTile != null) { 179 //FIXME//clickedTile.requestUpdate();180 clickedTile.requestUpdate(); 180 181 redraw(); 181 182 } 182 183 } 183 })); 184 }));*/ 184 185 185 186 tileOptionMenu.add(new JMenuItem(new AbstractAction( … … 204 205 public void actionPerformed(ActionEvent ae) { 205 206 decreaseZoomLevel(); 206 Main.map.repaint();207 redraw(); 207 208 } 208 209 })); … … 337 338 } 338 339 340 /* 341 * We use these for quick, hackish calculations. They 342 * are temporary only and intentionally not inserted 343 * into the tileCache. 344 */ 345 synchronized Tile tempCornerTile(Tile t) { 346 int x = t.getXtile() + 1; 347 int y = t.getYtile() + 1; 348 int zoom = t.getZoom(); 349 Tile tile = getTile(x, y, zoom); 350 if (tile != null) 351 return tile; 352 return new Tile(tileSource, x, y, zoom); 353 } 339 354 synchronized Tile getOrCreateTile(int x, int y, int zoom) { 340 355 Tile tile = getTile(x, y, zoom); … … 386 401 // if there is more than 18 tiles on screen in any direction, do not 387 402 // load all tiles! 388 if (ts.t ilesSpanned() > (18*18)) {403 if (ts.tooLarge()) { 389 404 System.out.println("Not downloading all tiles because there is more than 18 tiles on an axis!"); 390 405 return; … … 401 416 boolean done = ((infoflags & (ERROR | FRAMEBITS | ALLBITS)) != 0); 402 417 needRedraw = true; 418 if (debug) 419 out("imageUpdate() done: " + done + " calling repaint"); 403 420 Main.map.repaint(done ? 0 : 100); 404 421 return !done; … … 422 439 } 423 440 424 double getImageScaling(Image img, Point p0, Point p1) {441 double getImageScaling(Image img, Rectangle r) { 425 442 int realWidth = -1; 426 443 int realHeight = -1; 427 444 if (img != null) { 428 445 realWidth = img.getHeight(this); 429 446 realWidth = img.getWidth(this); 430 447 } 431 448 if (realWidth == -1 || realHeight == -1) { … … 437 454 */ 438 455 if (lastScaledImage != null) { 439 return getImageScaling(lastScaledImage, p0, p1);456 return getImageScaling(lastScaledImage, r); 440 457 } 441 458 realWidth = 256; … … 449 466 * overflows. 450 467 */ 451 double drawWidth = p1.x - p0.x;452 double drawHeight = p1.x - p0.x;468 double drawWidth = r.width; 469 double drawHeight = r.height; 453 470 // stem.out.println("drawWidth: " + drawWidth + " drawHeight: " + 454 471 // drawHeight); … … 472 489 LatLon botRight = tileLatLon(botRightTile); 473 490 474 if (!autoZoomEnabled())475 return 0;476 if (!SlippyMapPreferences.getAutoloadTiles())477 return 0;478 491 479 492 /* … … 489 502 int otherZooms[] = { -1, 1, -2, 2, -3, -4, -5}; 490 503 int painted = 0;; 504 debug = true; 491 505 for (int zoomOff : otherZooms) { 492 506 int zoom = currentZoomLevel + zoomOff; … … 496 510 } 497 511 TileSet ts = new TileSet(topLeft, botRight, zoom); 498 int zoom_painted = this.paintTileImages(g, ts, zoom); 512 int zoom_painted = 0; 513 this.paintTileImages(g, ts, zoom, null); 499 514 if (debug && zoom_painted > 0) 500 515 out("painted " + zoom_painted + "/"+ ts.size() + … … 507 522 } 508 523 } 524 debug = false; 509 525 return painted; 510 526 } 527 Rectangle tileToRect(Tile t1) 528 { 529 /* 530 * We need to get a box in which to draw, so advance by one tile in 531 * each direction to find the other corner of the box. 532 * Note: this somewhat pollutes the tile cache 533 */ 534 Tile t2 = tempCornerTile(t1); 535 Rectangle rect = new Rectangle(pixelPos(t1)); 536 rect.add(pixelPos(t2)); 537 return rect; 538 } 539 540 // 'source' is the pixel coordinates for the area that 541 // the img is capable of filling in. However, we probably 542 // only want a portion of it. 543 // 544 // 'border' is the screen cordinates that need to be drawn. 545 // We must not draw outside of it. 546 void drawImageInside(Graphics g, Image sourceImg, Rectangle source, Rectangle border) 547 { 548 Rectangle target = source; 549 550 // If a border is specified, only draw the intersection 551 // if what we have combined with what we are supposed 552 // to draw. 553 if (border != null) { 554 target = source.intersection(border); 555 if (debug) 556 out("source: " + source + "\nborder: " + border + "\nintersection: " + target); 557 } 558 559 // All of the rectangles are in screen coordinates. We need 560 // to how these correlate to the sourceImg pixels. We could 561 // avoid doing this by scaling the image up to the 'source' size, 562 // but this should be cheaper. 563 // 564 // In some projections, x any y are scaled differently enough to 565 // cause a pixel or two of fudge. Calculate them separately. 566 double imageYScaling = sourceImg.getHeight(this) / source.getHeight(); 567 double imageXScaling = sourceImg.getWidth(this) / source.getWidth(); 568 569 // How many pixels into the 'source' rectangle are we drawing? 570 int screen_x_offset = target.x - source.x; 571 int screen_y_offset = target.y - source.y; 572 // And how many pixels into the image itself does that 573 // correlate to? 574 int img_x_offset = (int)(screen_x_offset * imageXScaling); 575 int img_y_offset = (int)(screen_y_offset * imageYScaling); 576 // Now calculate the other corner of the image that we need 577 // by scaling the 'target' rectangle's dimensions. 578 int img_x_end = img_x_offset + (int)(target.getWidth() * imageXScaling); 579 int img_y_end = img_y_offset + (int)(target.getHeight() * imageYScaling); 580 581 if (debug) { 582 out("drawing image into target rect: " + target); 583 } 584 g.drawImage(sourceImg, 585 target.x, target.y, 586 target.x + target.width, target.y + target.height, 587 img_x_offset, img_y_offset, 588 img_x_end, img_y_end, 589 this); 590 float fadeBackground = SlippyMapPreferences.getFadeBackground(); 591 if (fadeBackground != 0f) { 592 // dimm by painting opaque rect... 593 g.setColor(new Color(1f, 1f, 1f, fadeBackground)); 594 g.fillRect(target.x, target.y, 595 target.width, target.height); 596 } 597 } 598 Double lastImageScale = null; 511 599 // This function is called for several zoom levels, not just 512 600 // the current one. It should not trigger any tiles to be 513 601 // downloaded. It should also avoid polluting the tile cache 514 602 // with any tiles since these tiles are not mandatory. 515 Double lastImageScale = null; 516 int paintTileImages(Graphics g, TileSet ts, int zoom) { 517 int paintedTiles = 0; 603 // 604 // The "border" tile tells us the boundaries of where we may 605 // draw. It will not be from the zoom level that is being 606 // drawn currently. If drawing the currentZoomLevel, 607 // border is null and we draw the entire tile set. 608 List<Tile> paintTileImages(Graphics g, TileSet ts, int zoom, Tile border) { 609 Rectangle borderRect = null; 610 if (border != null) 611 borderRect = tileToRect(border); 612 List<Tile> missedTiles = new LinkedList<Tile>(); 518 613 boolean imageScaleRecorded = false; 519 614 for (Tile tile : ts.allTiles()) { 520 /*521 * We need to get a box in which to draw, so advance by one tile in522 * each direction to find the other corner of the box.523 * Note: this somewhat pollutes the tile cache524 */525 Tile t2 = getOrCreateTile(tile.getXtile() + 1, tile.getYtile() + 1, zoom);526 615 Image img = getLoadedTileImage(tile); 527 Point p = pixelPos(tile); 528 Point p2 = pixelPos(t2); 529 if (currentZoomLevel == zoom && img == null) { 530 int painted = paintFromOtherZooms(g, tile, t2); 531 if (painted > 0 && debug) 532 out("painted a total of " + painted); 616 if (img == null) { 617 if (debug) 618 out("missed tile: " + tile); 619 missedTiles.add(tile); 533 620 continue; 534 621 } 535 g.drawImage(img, p.x, p.y, p2.x - p.x, p2.y - p.y, this); 536 paintedTiles++; 537 if (!imageScaleRecorded && zoom == currentZoomLevel) { 538 lastImageScale = new Double(getImageScaling(img, p, p2)); 622 Rectangle sourceRect = tileToRect(tile); 623 if (borderRect != null && !sourceRect.intersects(borderRect)) 624 continue; 625 drawImageInside(g, img, sourceRect, borderRect); 626 if (autoZoomEnabled() && 627 !imageScaleRecorded && zoom == currentZoomLevel) { 628 lastImageScale = new Double(getImageScaling(img, sourceRect)); 539 629 imageScaleRecorded = true; 540 630 } 541 float fadeBackground = SlippyMapPreferences.getFadeBackground();542 if (fadeBackground != 0f) {543 // dimm by painting opaque rect...544 g.setColor(new Color(1f, 1f, 1f, fadeBackground));545 g.fillRect(p.x, p.y, p2.x - p.x, p2.y - p.y);546 }547 631 }// end of for 548 return paintedTiles;632 return missedTiles; 549 633 } 550 634 … … 578 662 texty += 1 + fontHeight; 579 663 } 580 /* 581 We already do repaint when the images load 582 we don't need to poll like this 583 */ 584 if (!tile.isLoaded()) 585 redraw(); 586 664 665 int xCursor = -1; 666 int yCursor = -1; 587 667 if (SlippyMapPreferences.getDrawDebug()) { 588 if ( ts.leftTile(t)) {668 if (yCursor < t.getYtile()) { 589 669 if (t.getYtile() % 32 == 31) { 590 670 g.fillRect(0, p.y - 1, mv.getWidth(), 3); … … 592 672 g.drawLine(0, p.y, mv.getWidth(), p.y); 593 673 } 594 } 595 }// /end of if draw debug 596 } 597 674 yCursor = t.getYtile(); 675 } 676 // This draws the vertical lines for the entire 677 // column. Only draw them for the top tile in 678 // the column. 679 if (xCursor < t.getXtile()) { 680 if (SlippyMapPreferences.getDrawDebug()) { 681 if (t.getXtile() % 32 == 0) { 682 // level 7 tile boundary 683 g.fillRect(p.x - 1, 0, 3, mv.getHeight()); 684 } else { 685 g.drawLine(p.x, 0, p.x, mv.getHeight()); 686 } 687 } 688 xCursor = t.getXtile(); 689 } 690 } 691 } 692 693 public Point pixelPos(LatLon ll) { 694 return Main.map.mapView.getPoint(ll); 695 } 598 696 public Point pixelPos(Tile t) { 599 double lon = tileXToLon(t.getXtile(), t.getZoom()); 600 LatLon tmpLL = new LatLon(tileYToLat(t.getYtile(), t.getZoom()), lon); 601 MapView mv = Main.map.mapView; 602 return mv.getPoint(tmpLL); 603 } 697 double lon = tileXToLon(t.getXtile(), t.getZoom()); 698 LatLon tmpLL = new LatLon(tileYToLat(t.getYtile(), t.getZoom()), lon); 699 return pixelPos(tmpLL); 700 } 604 701 private class TileSet { 605 702 int z12x0, z12x1, z12y0, z12y1; … … 609 706 TileSet(LatLon topLeft, LatLon botRight, int zoom) { 610 707 this.zoom = zoom; 611 z12x0 = lonToTileX(topLeft.lon(), zoom) - 1;612 z12y0 = latToTileY(topLeft.lat(), zoom) - 1;613 z12x1 = lonToTileX(botRight.lon(), zoom) + 1;614 z12y1 = latToTileY(botRight.lat(), zoom) + 1;708 z12x0 = lonToTileX(topLeft.lon(), zoom); 709 z12y0 = latToTileY(topLeft.lat(), zoom); 710 z12x1 = lonToTileX(botRight.lon(), zoom); 711 z12y1 = latToTileY(botRight.lat(), zoom); 615 712 if (z12x0 > z12x1) { 616 713 int tmp = z12x0; … … 628 725 if (z12x1 > tileMax) z12x1 = tileMax; 629 726 if (z12y1 > tileMax) z12y1 = tileMax; 727 } 728 boolean tooSmall() { 729 return this.tilesSpanned() < 2.1; 730 } 731 boolean tooLarge() { 732 return this.tilesSpanned() > 10; 630 733 } 631 734 double tilesSpanned() { … … 730 833 731 834 if (autoZoomEnabled()) { 732 if (zoomDecreaseAllowed() && (ts.tilesSpanned() > 18)) {835 if (zoomDecreaseAllowed() && ts.tooLarge()) { 733 836 if (debug) 734 837 out("too many tiles, decreasing zoom from " + currentZoomLevel); … … 737 840 return; 738 841 } 739 if (zoomIncreaseAllowed() && (ts.tilesSpanned() < 1.0)) {842 if (zoomIncreaseAllowed() && ts.tooSmall()) { 740 843 if (debug) 741 out(" doesn't even cover one tile(" + ts.tilesSpanned()844 out("too zoomed in, (" + ts.tilesSpanned() 742 845 + "), increasing zoom from " + currentZoomLevel); 743 846 if (increaseZoomLevel()) … … 748 851 749 852 // Too many tiles... refuse to draw 750 if (ts.tilesSpanned() > 18) 751 return; 752 753 ts.loadAllTiles(false); 853 if (!ts.tooLarge()) { 854 ts.loadAllTiles(false); 855 } 754 856 755 857 int fontHeight = g.getFontMetrics().getHeight(); … … 757 859 g.setColor(Color.DARK_GRAY); 758 860 759 this.paintTileImages(g, ts, currentZoomLevel); 861 List<Tile> missedTiles = this.paintTileImages(g, ts, currentZoomLevel, null); 862 int otherZooms[] = { -1, 1, -2, 2, -3, -4, -5}; 863 for (int zoomOffset : otherZooms) { 864 if (!autoZoomEnabled()) 865 break; 866 if (!SlippyMapPreferences.getAutoloadTiles()) 867 break; 868 int newzoom = currentZoomLevel + zoomOffset; 869 if (missedTiles.size() <= 0) 870 break; 871 List<Tile> newlyMissedTiles = new LinkedList<Tile>(); 872 for (Tile missed : missedTiles) { 873 Tile t2 = tempCornerTile(missed); 874 LatLon topLeft2 = tileLatLon(missed); 875 LatLon botRight2 = tileLatLon(t2); 876 TileSet ts2 = new TileSet(topLeft2, botRight2, newzoom); 877 newlyMissedTiles.addAll(this.paintTileImages(g, ts2, newzoom, missed)); 878 } 879 missedTiles = newlyMissedTiles; 880 } 881 if (debug && missedTiles.size() > 0) { 882 out("still missed "+missedTiles.size()+" in the end"); 883 } 760 884 g.setColor(Color.red); 761 885 … … 763 887 // its tiles 764 888 for (Tile t : ts.allTiles()) { 765 // This draws the vertical lines for the entire766 // column. Only draw them for the top tile in767 // the column.768 if (ts.topTile(t)) {769 Point p = pixelPos(t);770 if (SlippyMapPreferences.getDrawDebug()) {771 if (t.getXtile() % 32 == 0) {772 // level 7 tile boundary773 g.fillRect(p.x - 1, 0, 3, mv.getHeight());774 } else {775 g.drawLine(p.x, 0, p.x, mv.getHeight());776 }777 }778 }779 889 this.paintTileText(ts, t, g, mv, currentZoomLevel, t); 780 890 } … … 782 892 oldg.drawImage(bufferImage, 0, 0, null); 783 893 784 if ( lastImageScale != null) {894 if (autoZoomEnabled() && lastImageScale != null) { 785 895 // If each source image pixel is being stretched into > 3 786 896 // drawn pixels, zoom in... getting too pixelated 787 897 if (lastImageScale > 3 && zoomIncreaseAllowed()) { 788 if (autoZoomEnabled()) { 789 if (debug) 790 out("autozoom increase: scale: " + lastImageScale); 791 increaseZoomLevel(); 792 this.paint(oldg, mv); 793 } 898 if (debug) 899 out("autozoom increase: scale: " + lastImageScale); 900 increaseZoomLevel(); 901 this.paint(oldg, mv); 794 902 // If each source image pixel is being squished into > 0.32 795 903 // of a drawn pixels, zoom out. 796 904 } else if ((lastImageScale < 0.45) && (lastImageScale > 0) && zoomDecreaseAllowed()) { 797 if (autoZoomEnabled()) { 798 if (debug) 799 out("autozoom decrease: scale: " + lastImageScale); 800 decreaseZoomLevel(); 801 this.paint(oldg, mv); 802 } 803 } 804 } 805 g.setColor(Color.black); 806 g.drawString("currentZoomLevel=" + currentZoomLevel, 120, 120); 905 if (debug) 906 out("autozoom decrease: scale: " + lastImageScale); 907 decreaseZoomLevel(); 908 this.paint(oldg, mv); 909 } 910 } 911 //g.drawString("currentZoomLevel=" + currentZoomLevel, 120, 120); 912 oldg.setColor(Color.black); 913 if (ts.tooLarge()) { 914 oldg.drawString("zoom in to load more tiles", 120, 120); 915 } else if (ts.tooSmall()) { 916 oldg.drawString("increase zoom level to see more detail", 120, 120); 917 } 807 918 }// end of paint method 808 919 … … 821 932 TileSet ts = new TileSet(topLeft, botRight, z); 822 933 823 ts.loadAllTiles(false); // make sure there are tile objects for all tiles 934 if (!ts.tooLarge()) 935 ts.loadAllTiles(false); // make sure there are tile objects for all tiles 824 936 Tile clickedTile = null; 825 937 Point p1 = null, p2 = null; 826 938 for (Tile t1 : ts.allTiles()) { 827 Tile t2 = getOrCreateTile(t1.getXtile()+1, t1.getYtile()+1, z);939 Tile t2 = tempCornerTile(t1); 828 940 Rectangle r = new Rectangle(pixelPos(t1)); 829 941 r.add(pixelPos(t2));
Note:
See TracChangeset
for help on using the changeset viewer.