source: josm/trunk/src/org/openstreetmap/josm/data/imagery/AbstractWMSTileSource.java@ 11685

Last change on this file since 11685 was 11685, checked in by Don-vip, 7 years ago

partial revert of r11675 - causes test failure of TemplatedWMSTileSourceTest.testEPSG3857

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.imagery;
3
4import java.awt.Point;
5
6import org.openstreetmap.gui.jmapviewer.Tile;
7import org.openstreetmap.gui.jmapviewer.TileXY;
8import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
9import org.openstreetmap.gui.jmapviewer.tilesources.TMSTileSource;
10import org.openstreetmap.gui.jmapviewer.tilesources.TileSourceInfo;
11import org.openstreetmap.josm.Main;
12import org.openstreetmap.josm.data.Bounds;
13import org.openstreetmap.josm.data.ProjectionBounds;
14import org.openstreetmap.josm.data.coor.EastNorth;
15import org.openstreetmap.josm.data.coor.LatLon;
16import org.openstreetmap.josm.data.projection.Projection;
17
18/**
19 * Base class for different WMS tile sources those based on URL templates and those based on WMS endpoints
20 * @author Wiktor Niesiobędzki
21 * @since 10990
22 */
23public abstract class AbstractWMSTileSource extends TMSTileSource {
24
25 private EastNorth anchorPosition;
26 private int[] tileXMin;
27 private int[] tileYMin;
28 private int[] tileXMax;
29 private int[] tileYMax;
30 private double[] degreesPerTile;
31 private static final float SCALE_DENOMINATOR_ZOOM_LEVEL_1 = 559082264.0287178f;
32
33 /**
34 * Constructs a new {@code AbstractWMSTileSource}.
35 * @param info tile source info
36 */
37 public AbstractWMSTileSource(TileSourceInfo info) {
38 super(info);
39 }
40
41 private void initAnchorPosition(Projection proj) {
42 Bounds worldBounds = proj.getWorldBoundsLatLon();
43 EastNorth min = proj.latlon2eastNorth(worldBounds.getMin());
44 EastNorth max = proj.latlon2eastNorth(worldBounds.getMax());
45 this.anchorPosition = new EastNorth(min.east(), max.north());
46 }
47
48 /**
49 * Initializes class with current projection in JOSM. This call is needed every time projection changes.
50 */
51 public void initProjection() {
52 initProjection(Main.getProjection());
53 }
54
55 /**
56 * Initializes class with projection in JOSM. This call is needed every time projection changes.
57 * @param proj new projection that shall be used for computations
58 */
59 public void initProjection(Projection proj) {
60 initAnchorPosition(proj);
61 ProjectionBounds worldBounds = proj.getWorldBoundsBoxEastNorth();
62
63 EastNorth topLeft = new EastNorth(worldBounds.getMin().east(), worldBounds.getMax().north());
64 EastNorth bottomRight = new EastNorth(worldBounds.getMax().east(), worldBounds.getMin().north());
65
66 // use 256 as "tile size" to keep the scale in line with default tiles in Mercator projection
67 double crsScale = 256 * 0.28e-03 / proj.getMetersPerUnit();
68 tileXMin = new int[getMaxZoom() + 1];
69 tileYMin = new int[getMaxZoom() + 1];
70 tileXMax = new int[getMaxZoom() + 1];
71 tileYMax = new int[getMaxZoom() + 1];
72 degreesPerTile = new double[getMaxZoom() + 1];
73
74 for (int zoom = 1; zoom <= getMaxZoom(); zoom++) {
75 // use well known scale set "GoogleCompatibile" from OGC WMTS spec to calculate number of tiles per zoom level
76 // this makes the zoom levels "glued" to standard TMS zoom levels
77 degreesPerTile[zoom] = (SCALE_DENOMINATOR_ZOOM_LEVEL_1 / Math.pow(2d, zoom - 1d)) * crsScale;
78 TileXY minTileIndex = eastNorthToTileXY(topLeft, zoom);
79 tileXMin[zoom] = minTileIndex.getXIndex();
80 tileYMin[zoom] = minTileIndex.getYIndex();
81 TileXY maxTileIndex = eastNorthToTileXY(bottomRight, zoom);
82 tileXMax[zoom] = maxTileIndex.getXIndex();
83 tileYMax[zoom] = maxTileIndex.getYIndex();
84 }
85 }
86
87 @Override
88 public ICoordinate tileXYToLatLon(Tile tile) {
89 return tileXYToLatLon(tile.getXtile(), tile.getYtile(), tile.getZoom());
90 }
91
92 @Override
93 public ICoordinate tileXYToLatLon(TileXY xy, int zoom) {
94 return tileXYToLatLon(xy.getXIndex(), xy.getYIndex(), zoom);
95 }
96
97 @Override
98 public ICoordinate tileXYToLatLon(int x, int y, int zoom) {
99 return Main.getProjection().eastNorth2latlon(getTileEastNorth(x, y, zoom)).toCoordinate();
100 }
101
102 private TileXY eastNorthToTileXY(EastNorth enPoint, int zoom) {
103 double scale = getDegreesPerTile(zoom);
104 return new TileXY(
105 (enPoint.east() - anchorPosition.east()) / scale,
106 (anchorPosition.north() - enPoint.north()) / scale
107 );
108 }
109
110 @Override
111 public TileXY latLonToTileXY(double lat, double lon, int zoom) {
112 EastNorth enPoint = Main.getProjection().latlon2eastNorth(new LatLon(lat, lon));
113 return eastNorthToTileXY(enPoint, zoom);
114 }
115
116 @Override
117 public TileXY latLonToTileXY(ICoordinate point, int zoom) {
118 return latLonToTileXY(point.getLat(), point.getLon(), zoom);
119 }
120
121 @Override
122 public int getTileXMax(int zoom) {
123 return tileXMax[zoom];
124 }
125
126 @Override
127 public int getTileXMin(int zoom) {
128 return tileXMin[zoom];
129 }
130
131 @Override
132 public int getTileYMax(int zoom) {
133 return tileYMax[zoom];
134 }
135
136 @Override
137 public int getTileYMin(int zoom) {
138 return tileYMin[zoom];
139 }
140
141 @Override
142 public Point latLonToXY(double lat, double lon, int zoom) {
143 double scale = getDegreesPerTile(zoom) / getTileSize();
144 EastNorth point = Main.getProjection().latlon2eastNorth(new LatLon(lat, lon));
145 return new Point(
146 (int) Math.round((point.east() - anchorPosition.east()) / scale),
147 (int) Math.round((anchorPosition.north() - point.north()) / scale)
148 );
149 }
150
151 @Override
152 public Point latLonToXY(ICoordinate point, int zoom) {
153 return latLonToXY(point.getLat(), point.getLon(), zoom);
154 }
155
156 @Override
157 public ICoordinate xyToLatLon(Point point, int zoom) {
158 return xyToLatLon(point.x, point.y, zoom);
159 }
160
161 @Override
162 public ICoordinate xyToLatLon(int x, int y, int zoom) {
163 double scale = getDegreesPerTile(zoom) / getTileSize();
164 Projection proj = Main.getProjection();
165 EastNorth ret = new EastNorth(
166 anchorPosition.east() + x * scale,
167 anchorPosition.north() - y * scale
168 );
169 return proj.eastNorth2latlon(ret).toCoordinate();
170 }
171
172 protected EastNorth getTileEastNorth(int x, int y, int z) {
173 double scale = getDegreesPerTile(z);
174 return new EastNorth(
175 anchorPosition.east() + x * scale,
176 anchorPosition.north() - y * scale
177 );
178 }
179
180 private double getDegreesPerTile(int zoom) {
181 return degreesPerTile[zoom];
182 }
183
184}
Note: See TracBrowser for help on using the repository browser.