Ticket #12186: TemplatedWMSTileSource.patch

File TemplatedWMSTileSource.patch, 5.7 KB (added by bastiK, 10 years ago)
  • src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java

     
    2121import org.openstreetmap.gui.jmapviewer.interfaces.TemplatedTileSource;
    2222import org.openstreetmap.gui.jmapviewer.tilesources.TMSTileSource;
    2323import org.openstreetmap.josm.Main;
     24import org.openstreetmap.josm.data.Bounds;
    2425import org.openstreetmap.josm.data.ProjectionBounds;
    2526import org.openstreetmap.josm.data.coor.EastNorth;
    2627import org.openstreetmap.josm.data.coor.LatLon;
     
    3738public class TemplatedWMSTileSource extends TMSTileSource implements TemplatedTileSource {
    3839    private final Map<String, String> headers = new ConcurrentHashMap<>();
    3940    private final Set<String> serverProjections;
    40     private EastNorth topLeftCorner;
     41    private EastNorth anchorPosition;
     42    private int[] tileXMin;
     43    private int[] tileYMin;
    4144    private int[] tileXMax;
    4245    private int[] tileYMax;
    4346    private double[] degreesPerTile;
     
    8891        initProjection(Main.getProjection());
    8992    }
    9093
     94    private void initAnchorPosition(Projection proj) {
     95        Bounds worldBounds = proj.getWorldBoundsLatLon();
     96        EastNorth min = proj.latlon2eastNorth(worldBounds.getMin());
     97        EastNorth max = proj.latlon2eastNorth(worldBounds.getMax());
     98        this.anchorPosition = new EastNorth(min.east(), max.north());
     99    }
     100
    91101    /**
    92102     * Initializes class with projection in JOSM. This call is needed every time projection changes.
    93103     * @param proj new projection that shall be used for computations
    94104     */
    95105    public void initProjection(Projection proj) {
     106        initAnchorPosition(proj);
    96107        ProjectionBounds worldBounds = proj.getWorldBoundsBoxEastNorth();
    97         EastNorth min = worldBounds.getMin();
    98         EastNorth max = worldBounds.getMax();
    99         this.topLeftCorner = new EastNorth(min.east(), max.north());
    100108
     109        EastNorth topLeft = new EastNorth(worldBounds.getMin().east(), worldBounds.getMax().north());
    101110        EastNorth bottomRight = new EastNorth(worldBounds.getMax().east(), worldBounds.getMin().north());
    102111
    103112        // use 256 as "tile size" to keep the scale in line with default tiles in Mercator projection
    104113        double crsScale = 256 * 0.28e-03 / proj.getMetersPerUnit();
     114        tileXMin = new int[getMaxZoom() + 1];
     115        tileYMin = new int[getMaxZoom() + 1];
    105116        tileXMax = new int[getMaxZoom() + 1];
    106117        tileYMax = new int[getMaxZoom() + 1];
    107118        degreesPerTile = new double[getMaxZoom() + 1];
     
    110121            // use well known scale set "GoogleCompatibile" from OGC WMTS spec to calculate number of tiles per zoom level
    111122            // this makes the zoom levels "glued" to standard TMS zoom levels
    112123            degreesPerTile[zoom] = (SCALE_DENOMINATOR_ZOOM_LEVEL_1 / Math.pow(2, zoom - 1)) * crsScale;
     124            TileXY minTileIndex = eastNorthToTileXY(topLeft, zoom);
     125            tileXMin[zoom] = minTileIndex.getXIndex();
     126            tileYMin[zoom] = minTileIndex.getYIndex();
    113127            TileXY maxTileIndex = eastNorthToTileXY(bottomRight, zoom);
    114128            tileXMax[zoom] = maxTileIndex.getXIndex();
    115129            tileYMax[zoom] = maxTileIndex.getYIndex();
     130            //System.err.println("z:"+zoom+" xmin="+tileXMin[zoom]+" xmax="+tileXMax[zoom]+" ymin="+tileYMin[zoom]+" ymax="+tileYMax[zoom]);
    116131        }
    117132    }
    118133
     
    246261    private TileXY eastNorthToTileXY(EastNorth enPoint, int zoom) {
    247262        double scale = getDegreesPerTile(zoom);
    248263        return new TileXY(
    249                 (enPoint.east() - topLeftCorner.east()) / scale,
    250                 (topLeftCorner.north() - enPoint.north()) / scale
     264                (enPoint.east() - anchorPosition.east()) / scale,
     265                (anchorPosition.north() - enPoint.north()) / scale
    251266                );
    252267    }
    253268
     
    263278
    264279    @Override
    265280    public int getTileXMin(int zoom) {
    266         return 0;
     281        return tileXMin[zoom];
    267282    }
    268283
    269284    @Override
     
    273288
    274289    @Override
    275290    public int getTileYMin(int zoom) {
    276         return 0;
     291        return tileYMin[zoom];
    277292    }
    278293
    279294    @Override
     
    281296        double scale = getDegreesPerTile(zoom) / getTileSize();
    282297        EastNorth point = Main.getProjection().latlon2eastNorth(new LatLon(lat, lon));
    283298        return new Point(
    284                     (int) Math.round((point.east() - topLeftCorner.east())   / scale),
    285                     (int) Math.round((topLeftCorner.north() - point.north()) / scale)
     299                    (int) Math.round((point.east() - anchorPosition.east())   / scale),
     300                    (int) Math.round((anchorPosition.north() - point.north()) / scale)
    286301                );
    287302    }
    288303
     
    301316        double scale = getDegreesPerTile(zoom) / getTileSize();
    302317        Projection proj = Main.getProjection();
    303318        EastNorth ret = new EastNorth(
    304                 topLeftCorner.east() + x * scale,
    305                 topLeftCorner.north() - y * scale
     319                anchorPosition.east() + x * scale,
     320                anchorPosition.north() - y * scale
    306321                );
    307322        return proj.eastNorth2latlon(ret).toCoordinate();
    308323    }
     
    349364    protected EastNorth getTileEastNorth(int x, int y, int z) {
    350365        double scale = getDegreesPerTile(z);
    351366        return new EastNorth(
    352                         topLeftCorner.east() + x * scale,
    353                         topLeftCorner.north() - y * scale
     367                        anchorPosition.east() + x * scale,
     368                        anchorPosition.north() - y * scale
    354369                        );
    355370    }
    356371