Changeset 9118 in josm for trunk/src/org
- Timestamp:
- 2015-12-14T14:14:23+01:00 (9 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/projection/AbstractProjection.java
r9105 r9118 2 2 package org.openstreetmap.josm.data.projection; 3 3 4 import org.openstreetmap.josm.data.Bounds; 5 import org.openstreetmap.josm.data.ProjectionBounds; 4 6 import org.openstreetmap.josm.data.coor.EastNorth; 5 7 import org.openstreetmap.josm.data.coor.LatLon; … … 31 33 protected double pm; /* prime meridian */ 32 34 protected double k0 = 1.0; /* general scale factor */ 35 36 private volatile ProjectionBounds projectionBoundsBox; 33 37 34 38 public final Ellipsoid getEllipsoid() { … … 105 109 return degree + (minute/60.0) + (second/3600.0); 106 110 } 111 112 @Override 113 public final ProjectionBounds getWorldBoundsBoxEastNorth() { 114 ProjectionBounds result = projectionBoundsBox; 115 if (result == null) { 116 synchronized (this) { 117 result = projectionBoundsBox; 118 if (result == null) { 119 Bounds b = getWorldBoundsLatLon(); 120 // add 4 corners 121 result = new ProjectionBounds(latlon2eastNorth(b.getMin())); 122 result.extend(latlon2eastNorth(b.getMax())); 123 result.extend(latlon2eastNorth(new LatLon(b.getMinLat(), b.getMaxLon()))); 124 result.extend(latlon2eastNorth(new LatLon(b.getMaxLat(), b.getMinLon()))); 125 // and trace along the outline 126 double dLon = (b.getMaxLon() - b.getMinLon()) / 1000; 127 double dLat = (b.getMaxLat() - b.getMinLat()) / 1000; 128 for (double lon=b.getMinLon(); lon<b.getMaxLon(); lon += dLon) { 129 result.extend(latlon2eastNorth(new LatLon(b.getMinLat(), lon))); 130 result.extend(latlon2eastNorth(new LatLon(b.getMaxLat(), lon))); 131 } 132 for (double lat=b.getMinLat(); lat<b.getMaxLat(); lat += dLat) { 133 result.extend(latlon2eastNorth(new LatLon(lat, b.getMinLon()))); 134 result.extend(latlon2eastNorth(new LatLon(lat, b.getMaxLat()))); 135 } 136 projectionBoundsBox = result; 137 } 138 } 139 } 140 return projectionBoundsBox; 141 } 107 142 } -
trunk/src/org/openstreetmap/josm/data/projection/Projection.java
r8584 r9118 3 3 4 4 import org.openstreetmap.josm.data.Bounds; 5 import org.openstreetmap.josm.data.ProjectionBounds; 5 6 import org.openstreetmap.josm.data.coor.EastNorth; 6 7 import org.openstreetmap.josm.data.coor.LatLon; … … 70 71 71 72 /** 73 * Get an approximate EastNorth box around the lat/lon world bounds. 74 * 75 * Note: The projection is only valid within the bounds returned by 76 * {@link #getWorldBoundsLatLon()}. The lat/lon bounds need not be a 77 * rectangular shape in east/north space. This method returns a box that 78 * contains this shape. 79 * 80 * @return EastNorth box around the lat/lon world bounds 81 */ 82 ProjectionBounds getWorldBoundsBoxEastNorth(); 83 84 /** 72 85 * Get the number of meters per unit of this projection. This more 73 86 * defines the scale of the map, than real conversion of unit to meters -
trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java
r9078 r9118 391 391 public void zoomTo(EastNorth newCenter, double newScale, boolean initial) { 392 392 Bounds b = getProjection().getWorldBoundsLatLon(); 393 LatLon cl = Projections.inverseProject(newCenter); 394 boolean changed = false; 395 double lat = cl.lat(); 396 double lon = cl.lon(); 397 if (lat < b.getMinLat()) { 398 changed = true; 399 lat = b.getMinLat(); 400 } else if (lat > b.getMaxLat()) { 401 changed = true; 402 lat = b.getMaxLat(); 403 } 404 if (lon < b.getMinLon()) { 405 changed = true; 406 lon = b.getMinLon(); 407 } else if (lon > b.getMaxLon()) { 408 changed = true; 409 lon = b.getMaxLon(); 410 } 411 if (changed) { 412 newCenter = Projections.project(new LatLon(lat, lon)); 413 } 414 int width = getWidth()/2; 415 int height = getHeight()/2; 416 LatLon l1 = new LatLon(b.getMinLat(), lon); 417 LatLon l2 = new LatLon(b.getMaxLat(), lon); 418 EastNorth e1 = getProjection().latlon2eastNorth(l1); 419 EastNorth e2 = getProjection().latlon2eastNorth(l2); 420 double d = e2.north() - e1.north(); 421 if (height > 0 && d < height*newScale) { 422 double newScaleH = d/height; 423 e1 = getProjection().latlon2eastNorth(new LatLon(lat, b.getMinLon())); 424 e2 = getProjection().latlon2eastNorth(new LatLon(lat, b.getMaxLon())); 425 d = e2.east() - e1.east(); 426 if (width > 0 && d < width*newScale) { 427 newScale = Math.max(newScaleH, d/width); 428 } 429 } else if (height > 0) { 430 d = d/(l1.greatCircleDistance(l2)*height*10); 431 if (newScale < d) { 432 newScale = d; 393 ProjectionBounds pb = getProjection().getWorldBoundsBoxEastNorth(); 394 int width = getWidth(); 395 int height = getHeight(); 396 397 // make sure, the center of the screen is within projection bounds 398 double east = newCenter.east(); 399 double north = newCenter.north(); 400 east = Math.max(east, pb.minEast); 401 east = Math.min(east, pb.maxEast); 402 north = Math.max(north, pb.minNorth); 403 north = Math.min(north, pb.maxNorth); 404 newCenter = new EastNorth(east, north); 405 406 // don't zoom out too much, the world bounds should be at least 407 // half the size of the screen 408 double pbHeight = pb.maxNorth - pb.minNorth; 409 if (height > 0 && 2 * pbHeight < height * newScale) { 410 double newScaleH = 2 * pbHeight / height; 411 double pbWidth = pb.maxEast - pb.minEast; 412 if (width > 0 && 2 * pbWidth < width * newScale) { 413 double newScaleW = 2 * pbWidth / width; 414 newScale = Math.max(newScaleH, newScaleW); 415 } 416 } 417 418 // don't zoom in too much, minimum: 100 px = 1 cm 419 LatLon ll1 = getLatLon(width / 2 - 50, height / 2); 420 LatLon ll2 = getLatLon(width / 2 + 50, height / 2); 421 if (ll1.isValid() && ll1.isValid() && b.contains(ll1) && b.contains(ll2)) { 422 double d_m = ll1.greatCircleDistance(ll2); 423 double d_en = 100 * scale; 424 double scaleMin = 0.01 * d_en / d_m / 100; 425 if (newScale < scaleMin) { 426 newScale = scaleMin; 433 427 } 434 428 }
Note:
See TracChangeset
for help on using the changeset viewer.