Ignore:
Timestamp:
2015-07-26T17:03:37+02:00 (9 years ago)
Author:
wiktorn
Message:

Fix calculation of World Bounds for WMS when no projection has no bounds defined, and bogus results are returned on boundaries.

Closes: #11697, #11701

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java

    r8598 r8618  
    1616
    1717import org.openstreetmap.gui.jmapviewer.Coordinate;
     18import org.openstreetmap.gui.jmapviewer.OsmMercator;
    1819import org.openstreetmap.gui.jmapviewer.Tile;
    1920import org.openstreetmap.gui.jmapviewer.TileXY;
     
    3940    private final List<String> serverProjections;
    4041    private EastNorth topLeftCorner;
     42    private Bounds worldBounds;
    4143
    4244    private static final String PATTERN_HEADER  = "\\{header\\(([^,]+),([^}]+)\\)\\}";
     
    7981     */
    8082    public void initProjection(Projection proj) {
    81         Bounds bounds = proj.getWorldBoundsLatLon();
    82         EastNorth min = proj.latlon2eastNorth(bounds.getMin());
    83         EastNorth max = proj.latlon2eastNorth(bounds.getMax());
     83        this.worldBounds = getWorldBounds();
     84        EastNorth min = proj.latlon2eastNorth(worldBounds.getMin());
     85        EastNorth max = proj.latlon2eastNorth(worldBounds.getMax());
    8486        this.topLeftCorner = new EastNorth(min.east(), max.north());
    8587    }
     
    230232    @Override
    231233    public int getTileXMax(int zoom) {
    232         Projection proj = Main.getProjection();
    233         double scale = getDegreesPerTile(zoom);
    234         Bounds bounds = Main.getProjection().getWorldBoundsLatLon();
    235         EastNorth min = proj.latlon2eastNorth(bounds.getMin());
    236         EastNorth max = proj.latlon2eastNorth(bounds.getMax());
    237         return (int) Math.ceil(Math.abs(max.getX() - min.getX()) / scale);
     234        LatLon bottomRight = new LatLon(worldBounds.getMinLat(), worldBounds.getMaxLon());
     235        return latLonToTileXY(bottomRight.toCoordinate(), zoom).getXIndex();
    238236    }
    239237
     
    245243    @Override
    246244    public int getTileYMax(int zoom) {
    247         Projection proj = Main.getProjection();
    248         double scale = getDegreesPerTile(zoom);
    249         Bounds bounds = Main.getProjection().getWorldBoundsLatLon();
    250         EastNorth min = proj.latlon2eastNorth(bounds.getMin());
    251         EastNorth max = proj.latlon2eastNorth(bounds.getMax());
    252         return (int) Math.ceil(Math.abs(max.getY() - min.getY()) / scale);
     245        LatLon bottomRight = new LatLon(worldBounds.getMinLat(), worldBounds.getMaxLon());
     246        return latLonToTileXY(bottomRight.toCoordinate(), zoom).getYIndex();
    253247    }
    254248
     
    354348
    355349    private double getDegreesPerTile(int zoom) {
    356         return getDegreesPerTile(zoom, Main.getProjection());
    357     }
    358 
    359     private double getDegreesPerTile(int zoom, Projection proj) {
    360         Bounds bounds = proj.getWorldBoundsLatLon();
    361         EastNorth min = proj.latlon2eastNorth(bounds.getMin());
    362         EastNorth max = proj.latlon2eastNorth(bounds.getMax());
     350        Projection proj = Main.getProjection();
     351        EastNorth min = proj.latlon2eastNorth(worldBounds.getMin());
     352        EastNorth max = proj.latlon2eastNorth(worldBounds.getMax());
     353
    363354        int tilesPerZoom = (int) Math.pow(2, zoom - 1);
    364355        return Math.max(
     
    368359    }
    369360
     361    /**
     362     * returns world bounds, but detect situation, when default bounds are provided (-90, -180, 90, 180), and projection
     363     * returns very close values for both min and max X. To work around this problem, cap this projection on north and south
     364     * pole, the same way they are capped in Mercator projection, so conversions should work properly
     365     */
     366    private final static Bounds getWorldBounds() {
     367        Projection proj = Main.getProjection();
     368        Bounds bounds = proj.getWorldBoundsLatLon();
     369        EastNorth min = proj.latlon2eastNorth(bounds.getMin());
     370        EastNorth max = proj.latlon2eastNorth(bounds.getMax());
     371
     372        if (Math.abs(min.getX() - max.getX()) < 1 && bounds.equals(new Bounds(new LatLon(-90, -180), new LatLon(90, 180)))) {
     373            return new Bounds(
     374                    new LatLon(OsmMercator.MIN_LAT, bounds.getMinLon()),
     375                    new LatLon(OsmMercator.MAX_LAT, bounds.getMaxLon())
     376                    );
     377        }
     378        return bounds;
     379    }
     380
    370381    @Override
    371382    public String getTileId(int zoom, int tilex, int tiley) {
Note: See TracChangeset for help on using the changeset viewer.