source: josm/trunk/test/unit/org/openstreetmap/josm/data/imagery/WMTSTileSourceTest.java@ 13742

Last change on this file since 13742 was 13742, checked in by wiktorn, 6 years ago

Checkstyle fixes

  • Property svn:eol-style set to native
File size: 20.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.imagery;
3
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertTrue;
6
7import java.io.File;
8import java.io.IOException;
9import java.net.MalformedURLException;
10import java.nio.file.Files;
11import java.nio.file.Paths;
12import java.util.ArrayList;
13import java.util.Arrays;
14import java.util.List;
15import java.util.concurrent.TimeUnit;
16
17import org.junit.ClassRule;
18import org.junit.Ignore;
19import org.junit.Rule;
20import org.junit.Test;
21import org.openstreetmap.gui.jmapviewer.tilesources.TemplatedTMSTileSource;
22import org.openstreetmap.josm.Main;
23import org.openstreetmap.josm.TestUtils;
24import org.openstreetmap.josm.data.Bounds;
25import org.openstreetmap.josm.data.coor.LatLon;
26import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
27import org.openstreetmap.josm.data.imagery.WMTSTileSource.WMTSGetCapabilitiesException;
28import org.openstreetmap.josm.data.projection.Projections;
29import org.openstreetmap.josm.spi.preferences.Config;
30import org.openstreetmap.josm.testutils.JOSMTestRules;
31
32import com.github.tomakehurst.wiremock.client.WireMock;
33import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
34import com.github.tomakehurst.wiremock.junit.WireMockRule;
35
36import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
37
38/**
39 * Unit tests for class {@link WMTSTileSource}.
40 */
41public class WMTSTileSourceTest {
42
43 /**
44 * Setup test.
45 */
46 @ClassRule
47 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
48 public static JOSMTestRules test = new JOSMTestRules().preferences().platform().projection().timeout((int) TimeUnit.MINUTES.toMillis(5));
49
50 @Rule
51 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
52 public WireMockRule tileServer = new WireMockRule(WireMockConfiguration.options().dynamicPort());
53
54 private ImageryInfo testImageryTMS = new ImageryInfo("test imagery", "http://localhost", "tms", null, null);
55 private ImageryInfo testImageryPSEUDO_MERCATOR = getImagery(TestUtils.getTestDataRoot() + "wmts/getcapabilities-pseudo-mercator.xml");
56 private ImageryInfo testImageryTOPO_PL = getImagery(TestUtils.getTestDataRoot() + "wmts/getcapabilities-TOPO.xml");
57 private ImageryInfo testImageryORTO_PL = getImagery(TestUtils.getTestDataRoot() + "wmts/getcapabilities-ORTO.xml");
58 private ImageryInfo testImageryWIEN = getImagery(TestUtils.getTestDataRoot() + "wmts/getCapabilities-wien.xml");
59 private ImageryInfo testImageryWALLONIE = getImagery(TestUtils.getTestDataRoot() + "wmts/WMTSCapabilities-Wallonie.xml");
60 private ImageryInfo testImageryOntario = getImagery(TestUtils.getTestDataRoot() + "wmts/WMTSCapabilities-Ontario.xml");
61 private ImageryInfo testImageryGeoAdminCh = getImagery(TestUtils.getTestDataRoot() + "wmts/WMTSCapabilities-GeoAdminCh.xml");
62 private ImageryInfo testImagery12168 = getImagery(TestUtils.getTestDataRoot() + "wmts/bug12168-WMTSCapabilities.xml");
63 private ImageryInfo testLotsOfLayers = getImagery(TestUtils.getTestDataRoot() + "wmts/getCapabilities-lots-of-layers.xml");
64 private ImageryInfo testDuplicateTags = getImagery(TestUtils.getTestDataRoot() + "wmts/bug12573-wmts-identifier.xml");
65 private ImageryInfo testMissingStyleIdentifer = getImagery(TestUtils.getTestDataRoot() + "wmts/bug12573-wmts-missing-style-identifier.xml");
66 private ImageryInfo testMultipleTileMatrixForLayer = getImagery(TestUtils.getTestDataRoot() +
67 "wmts/bug13975-multiple-tile-matrices-for-one-layer-projection.xml");
68
69 private static ImageryInfo getImagery(String path) {
70 try {
71 ImageryInfo ret = new ImageryInfo(
72 "test",
73 new File(path).toURI().toURL().toString()
74 );
75 ret.setImageryType(ImageryType.WMTS);
76 return ret;
77 } catch (MalformedURLException e) {
78 e.printStackTrace();
79 return null;
80 }
81 }
82
83 @Test
84 public void testPseudoMercator() throws IOException, WMTSGetCapabilitiesException {
85 Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
86 WMTSTileSource testSource = new WMTSTileSource(testImageryPSEUDO_MERCATOR);
87 testSource.initProjection(Main.getProjection());
88
89 verifyMercatorTile(testSource, 0, 0, 1);
90 verifyMercatorTile(testSource, 0, 0, 2);
91 verifyMercatorTile(testSource, 1, 1, 2);
92 for (int x = 0; x < 4; x++) {
93 for (int y = 0; y < 4; y++) {
94 verifyMercatorTile(testSource, x, y, 3);
95 }
96 }
97 for (int x = 0; x < 8; x++) {
98 for (int y = 0; y < 4; y++) {
99 verifyMercatorTile(testSource, x, y, 4);
100 }
101 }
102
103 verifyMercatorTile(testSource, 2 << 9 - 1, 2 << 8 - 1, 10);
104
105 assertEquals("TileXMax", 1, testSource.getTileXMax(0));
106 assertEquals("TileYMax", 1, testSource.getTileYMax(0));
107 assertEquals("TileXMax", 2, testSource.getTileXMax(1));
108 assertEquals("TileYMax", 2, testSource.getTileYMax(1));
109 assertEquals("TileXMax", 4, testSource.getTileXMax(2));
110 assertEquals("TileYMax", 4, testSource.getTileYMax(2));
111 }
112
113 @Test
114 public void testWALLONIE() throws IOException, WMTSGetCapabilitiesException {
115 Main.setProjection(Projections.getProjectionByCode("EPSG:31370"));
116 WMTSTileSource testSource = new WMTSTileSource(testImageryWALLONIE);
117 testSource.initProjection(Main.getProjection());
118
119 assertEquals("http://geoservices.wallonie.be/arcgis/rest/services/DONNEES_BASE/FOND_PLAN_ANNOTATIONS_2012_RW_NB/"
120 + "MapServer/WMTS/tile/1.0.0/DONNEES_BASE_FOND_PLAN_ANNOTATIONS_2012_RW_NB/default/default028mm/5/1219/1063.png",
121 testSource.getTileUrl(5, 1063, 1219));
122
123 // +bounds=2.54,49.51,6.4,51.5
124 Bounds wallonieBounds = new Bounds(
125 new LatLon(49.485372459967245, 2.840548314430268),
126 new LatLon(50.820959517561256, 6.427849693016202)
127 );
128 verifyBounds(wallonieBounds, testSource, 5, 1063, 1219);
129 verifyBounds(wallonieBounds, testSource, 10, 17724, 20324);
130 }
131
132 @Test
133 @Ignore("disable this test, needs further working") // XXX
134 public void testWALLONIENoMatrixDimension() throws IOException, WMTSGetCapabilitiesException {
135 Main.setProjection(Projections.getProjectionByCode("EPSG:31370"));
136 WMTSTileSource testSource = new WMTSTileSource(getImagery("test/data/wmts/WMTSCapabilities-Wallonie-nomatrixdimension.xml"));
137 testSource.initProjection(Main.getProjection());
138
139 Bounds wallonieBounds = new Bounds(
140 new LatLon(49.485372459967245, 2.840548314430268),
141 new LatLon(50.820959517561256, 6.427849693016202)
142 );
143
144 verifyBounds(wallonieBounds, testSource, 6, 1063, 1219);
145 verifyBounds(wallonieBounds, testSource, 11, 17724, 20324);
146 }
147
148 private void verifyBounds(Bounds bounds, WMTSTileSource testSource, int z, int x, int y) {
149 LatLon ret = CoordinateConversion.coorToLL(testSource.tileXYToLatLon(x, y, z));
150 assertTrue(ret.toDisplayString() + " doesn't lie within: " + bounds.toString(), bounds.contains(ret));
151 int tileXmax = testSource.getTileXMax(z);
152 int tileYmax = testSource.getTileYMax(z);
153 assertTrue("tile x: " + x + " is greater than allowed max: " + tileXmax, tileXmax >= x);
154 assertTrue("tile y: " + y + " is greater than allowed max: " + tileYmax, tileYmax >= y);
155 }
156
157 @Test
158 public void testWIEN() throws IOException, WMTSGetCapabilitiesException {
159 Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
160 WMTSTileSource testSource = new WMTSTileSource(testImageryWIEN);
161 testSource.initProjection(Main.getProjection());
162 int zoomOffset = 10;
163
164 verifyMercatorTile(testSource, 0, 0, 1, zoomOffset);
165 verifyMercatorTile(testSource, 1105, 709, 2, zoomOffset);
166 verifyMercatorTile(testSource, 1, 1, 1, zoomOffset);
167 verifyMercatorTile(testSource, 2, 2, 1, zoomOffset);
168 verifyMercatorTile(testSource, 0, 0, 2, zoomOffset);
169 verifyMercatorTile(testSource, 1, 1, 2, zoomOffset);
170
171 for (int x = 0; x < 4; x++) {
172 for (int y = 0; y < 4; y++) {
173 verifyMercatorTile(testSource, x, y, 3, zoomOffset);
174 }
175 }
176 for (int x = 0; x < 8; x++) {
177 for (int y = 0; y < 4; y++) {
178 verifyMercatorTile(testSource, x, y, 4, zoomOffset);
179 }
180 }
181
182 verifyMercatorTile(testSource, 2 << 9 - 1, 2 << 8 - 1, 2, zoomOffset);
183
184 verifyMercatorMax(testSource, 1, zoomOffset);
185 verifyMercatorMax(testSource, 2, zoomOffset);
186 verifyMercatorMax(testSource, 3, zoomOffset);
187 }
188
189 private void verifyMercatorMax(WMTSTileSource testSource, int zoom, int zoomOffset) {
190 TemplatedTMSTileSource verifier = new TemplatedTMSTileSource(testImageryTMS);
191 int result = testSource.getTileXMax(zoom);
192 int expected = verifier.getTileXMax(zoom + zoomOffset);
193 assertTrue("TileXMax expected: " + expected + " got: " + result, Math.abs(result - expected) < 5);
194 result = testSource.getTileYMax(zoom);
195 expected = verifier.getTileYMax(zoom + zoomOffset);
196 assertTrue("TileYMax expected: " + expected + " got: " + result, Math.abs(result - expected) < 5);
197 }
198
199 @Test
200 public void testGeoportalTOPOPL() throws IOException, WMTSGetCapabilitiesException {
201 Main.setProjection(Projections.getProjectionByCode("EPSG:4326"));
202 WMTSTileSource testSource = new WMTSTileSource(testImageryTOPO_PL);
203 testSource.initProjection(Main.getProjection());
204 verifyTile(new LatLon(56, 12), testSource, 0, 0, 1);
205 verifyTile(new LatLon(56, 12), testSource, 0, 0, 2);
206 verifyTile(new LatLon(51.13231917844218, 16.867680821557823), testSource, 1, 1, 1);
207
208 assertEquals("TileXMax", 2, testSource.getTileXMax(0));
209 assertEquals("TileYMax", 1, testSource.getTileYMax(0));
210 assertEquals("TileXMax", 3, testSource.getTileXMax(1));
211 assertEquals("TileYMax", 2, testSource.getTileYMax(1));
212 assertEquals("TileXMax", 6, testSource.getTileXMax(2));
213 assertEquals("TileYMax", 4, testSource.getTileYMax(2));
214 assertEquals(
215 "http://mapy.geoportal.gov.pl/wss/service/WMTS/guest/wmts/TOPO?SERVICE=WMTS&REQUEST=GetTile&"
216 + "VERSION=1.0.0&LAYER=MAPA TOPOGRAFICZNA&STYLE=default&FORMAT=image/jpeg&tileMatrixSet=EPSG:4326&"
217 + "tileMatrix=EPSG:4326:0&tileRow=1&tileCol=1",
218 testSource.getTileUrl(0, 1, 1));
219 }
220
221 @Test
222 public void testGeoportalORTOPL4326() throws IOException, WMTSGetCapabilitiesException {
223 Main.setProjection(Projections.getProjectionByCode("EPSG:4326"));
224 WMTSTileSource testSource = new WMTSTileSource(testImageryORTO_PL);
225 testSource.initProjection(Main.getProjection());
226 verifyTile(new LatLon(53.60205873528009, 19.552206794646956), testSource, 12412, 3941, 13);
227 verifyTile(new LatLon(49.79005619189761, 22.778262259134397), testSource, 17714, 10206, 13);
228 }
229
230 @Test
231 public void testGeoportalORTOPL2180() throws IOException, WMTSGetCapabilitiesException {
232 Main.setProjection(Projections.getProjectionByCode("EPSG:2180"));
233 WMTSTileSource testSource = new WMTSTileSource(testImageryORTO_PL);
234 testSource.initProjection(Main.getProjection());
235
236 verifyTile(new LatLon(53.59940948387726, 19.560544913270064), testSource, 6453, 3140, 13);
237 verifyTile(new LatLon(49.782984840526055, 22.790064966993445), testSource, 9932, 9305, 13);
238 }
239
240 @Test
241 public void testTicket12168() throws IOException, WMTSGetCapabilitiesException {
242 Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
243 WMTSTileSource testSource = new WMTSTileSource(testImagery12168);
244 testSource.initProjection(Main.getProjection());
245 assertEquals(
246 "http://www.ngi.be/cartoweb/1.0.0/topo/default/3857/7/1/1.png",
247 testSource.getTileUrl(0, 1, 1));
248 }
249
250 @Test
251 public void testTwoTileSetsForOneProjection() throws Exception {
252 Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
253 ImageryInfo ontario = getImagery(TestUtils.getTestDataRoot() + "wmts/WMTSCapabilities-Ontario.xml");
254 ontario.setDefaultLayers(Arrays.asList(new DefaultLayer[] {
255 new DefaultLayer(ImageryType.WMTS, "Basemap_Imagery_2014", null, "default028mm")
256 }));
257 WMTSTileSource testSource = new WMTSTileSource(ontario);
258 testSource.initProjection(Main.getProjection());
259 assertEquals(
260 "http://maps.ottawa.ca/arcgis/rest/services/Basemap_Imagery_2014/MapServer/WMTS/tile/1.0.0/Basemap_Imagery_2014/default/"
261 + "default028mm/4/2932/2371.jpg",
262 testSource.getTileUrl(4, 2371, 2932));
263 verifyTile(new LatLon(45.4601306, -75.7617187), testSource, 2372, 2932, 4);
264 verifyTile(new LatLon(45.4602510, -75.7617187), testSource, 607232, 750591, 12);
265 }
266
267 @Test
268 public void testTwoTileSetsForOneProjectionSecondLayer() throws Exception {
269 Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
270 ImageryInfo ontario = getImagery(TestUtils.getTestDataRoot() + "wmts/WMTSCapabilities-Ontario.xml");
271 ontario.setDefaultLayers(Arrays.asList(new DefaultLayer[] {
272 new DefaultLayer(ImageryType.WMTS, "Basemap_Imagery_2014", null, "GoogleMapsCompatible")
273 }));
274 WMTSTileSource testSource = new WMTSTileSource(ontario);
275 testSource.initProjection(Main.getProjection());
276 assertEquals(
277 "http://maps.ottawa.ca/arcgis/rest/services/Basemap_Imagery_2014/MapServer/WMTS/tile/1.0.0/Basemap_Imagery_2014/default/"
278 + "GoogleMapsCompatible/4/2932/2371.jpg",
279 testSource.getTileUrl(4, 2371, 2932));
280 verifyMercatorTile(testSource, 74, 91, 8);
281 verifyMercatorTile(testSource, 37952, 46912, 17);
282 }
283
284 @Test
285 public void testManyLayersScrollbars() throws Exception {
286 Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
287 WMTSTileSource testSource = new WMTSTileSource(testLotsOfLayers);
288 testSource.initProjection(Main.getProjection());
289 }
290
291 @Test
292 public void testParserForDuplicateTags() throws Exception {
293 Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
294 WMTSTileSource testSource = new WMTSTileSource(testDuplicateTags);
295 testSource.initProjection(Main.getProjection());
296 assertEquals(
297 "http://tile.informatievlaanderen.be/ws/raadpleegdiensten/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=grb_bsk&"
298 + "STYLE=&FORMAT=image/png&tileMatrixSet=GoogleMapsVL&tileMatrix=1&tileRow=1&tileCol=1",
299 testSource.getTileUrl(1, 1, 1)
300 );
301 }
302
303 @Test
304 public void testParserForMissingStyleIdentifier() throws Exception {
305 Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
306 WMTSTileSource testSource = new WMTSTileSource(testMissingStyleIdentifer);
307 testSource.initProjection(Main.getProjection());
308 }
309
310 @Test
311 public void testForMultipleTileMatricesForOneLayerProjection() throws Exception {
312 Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
313 ImageryInfo copy = new ImageryInfo(testMultipleTileMatrixForLayer);
314 List<DefaultLayer> defaultLayers = new ArrayList<>(1);
315 defaultLayers.add(new DefaultLayer(ImageryType.WMTS, "Mashhad_BaseMap_1", null, "default028mm"));
316 copy.setDefaultLayers(defaultLayers);
317 WMTSTileSource testSource = new WMTSTileSource(copy);
318 testSource.initProjection(Main.getProjection());
319 assertEquals(
320 "http://188.253.0.155:6080/arcgis/rest/services/Mashhad_BaseMap_1/MapServer/WMTS/tile/1.0.0/Mashhad_BaseMap_1"
321 + "/default/default028mm/1/3/2",
322 testSource.getTileUrl(1, 2, 3)
323 );
324 }
325
326 /**
327 * Test WMTS dimension.
328 * @throws IOException if any I/O error occurs
329 * @throws WMTSGetCapabilitiesException if any error occurs
330 */
331 @Test
332 public void testDimension() throws IOException, WMTSGetCapabilitiesException {
333 Main.setProjection(Projections.getProjectionByCode("EPSG:21781"));
334 ImageryInfo info = new ImageryInfo(testImageryGeoAdminCh);
335 List<DefaultLayer> defaultLayers = new ArrayList<>(1);
336 defaultLayers.add(new DefaultLayer(ImageryType.WMTS, "ch.are.agglomerationen_isolierte_staedte", null, "21781_26"));
337 info.setDefaultLayers(defaultLayers);
338 WMTSTileSource testSource = new WMTSTileSource(info);
339 testSource.initProjection(Main.getProjection());
340 assertEquals(
341 "http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte/default/20140101/21781/1/3/2.png",
342 testSource.getTileUrl(1, 2, 3)
343 );
344 }
345
346 @Test
347 public void testDefaultLayer() throws Exception {
348 // https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/1.0.0/WMTSCapabilities.xml
349 // do not use withFileBody as it needs different directory layout :(
350
351 tileServer.stubFor(
352 WireMock.get("/getcapabilities.xml")
353 .willReturn(
354 WireMock.aResponse()
355 .withBody(Files.readAllBytes(
356 Paths.get(TestUtils.getTestDataRoot() + "wmts/getCapabilities-lots-of-layers.xml"))
357 )
358 )
359 );
360
361 tileServer.stubFor(
362 WireMock.get("//maps")
363 .willReturn(
364 WireMock.aResponse().withBody(
365 "<?xml version='1.0' encoding='UTF-8'?>\n" +
366 "<imagery xmlns=\"http://josm.openstreetmap.de/maps-1.0\">\n" +
367 "<entry>\n" +
368 "<name>Landsat</name>\n" +
369 "<id>landsat</id>\n" +
370 "<type>wmts</type>\n" +
371 "<url><![CDATA[" + tileServer.url("/getcapabilities.xml") + "]]></url>\n" +
372 "<defaultLayers>" +
373 "<layer name=\"GEOGRAPHICALGRIDSYSTEMS.MAPS\" />" +
374 "</defaultLayers>" +
375 "</entry>\n" +
376 "</imagery>"
377 )));
378
379 Config.getPref().putList("imagery.layers.sites", Arrays.asList(tileServer.url("//maps")));
380 ImageryLayerInfo.instance.loadDefaults(true, null, false);
381
382 assertEquals(1, ImageryLayerInfo.instance.getDefaultLayers().size());
383 ImageryInfo wmtsImageryInfo = ImageryLayerInfo.instance.getDefaultLayers().get(0);
384 assertEquals(1, wmtsImageryInfo.getDefaultLayers().size());
385 assertEquals("GEOGRAPHICALGRIDSYSTEMS.MAPS", wmtsImageryInfo.getDefaultLayers().get(0).getLayerName());
386 WMTSTileSource tileSource = new WMTSTileSource(wmtsImageryInfo);
387 tileSource.initProjection(Projections.getProjectionByCode("EPSG:3857"));
388 assertEquals("http://wxs.ign.fr/61fs25ymczag0c67naqvvmap/geoportail/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&"
389 + "LAYER=GEOGRAPHICALGRIDSYSTEMS.MAPS"
390 + "&STYLE=normal&FORMAT=image/jpeg&tileMatrixSet=PM&tileMatrix=1&tileRow=1&tileCol=1", tileSource.getTileUrl(1, 1, 1));
391
392 }
393
394 private void verifyTile(LatLon expected, WMTSTileSource source, int x, int y, int z) {
395 LatLon ll = CoordinateConversion.coorToLL(source.tileXYToLatLon(x, y, z));
396 assertEquals("Latitude", expected.lat(), ll.lat(), 1e-05);
397 assertEquals("Longitude", expected.lon(), ll.lon(), 1e-05);
398 }
399
400 private void verifyMercatorTile(WMTSTileSource testSource, int x, int y, int z) {
401 verifyMercatorTile(testSource, x, y, z, 0);
402 }
403
404 private void verifyMercatorTile(WMTSTileSource testSource, int x, int y, int z, int zoomOffset) {
405 TemplatedTMSTileSource verifier = new TemplatedTMSTileSource(testImageryTMS);
406 LatLon result = CoordinateConversion.coorToLL(testSource.tileXYToLatLon(x, y, z));
407 LatLon expected = CoordinateConversion.coorToLL(verifier.tileXYToLatLon(x, y, z + zoomOffset));
408 assertEquals("Longitude", LatLon.normalizeLon(expected.lon() - result.lon()), 0.0, 1e-04);
409 assertEquals("Latitude", expected.lat(), result.lat(), 1e-04);
410 }
411}
Note: See TracBrowser for help on using the repository browser.