Index: trunk/test/data/regress/15730/capabilities.xml =================================================================== --- trunk/test/data/regress/15730/capabilities.xml (revision 13712) +++ trunk/test/data/regress/15730/capabilities.xml (revision 13733) Index: trunk/test/data/wms/geofabrik-osm-inspector.xml =================================================================== --- trunk/test/data/wms/geofabrik-osm-inspector.xml (revision 13733) +++ trunk/test/data/wms/geofabrik-osm-inspector.xml (revision 13733) @@ -0,0 +1,367 @@ + + + + + + + WMS + Geofabrik Tools: OSM Inspector (Geometry) + OSM Inspector is a debugging tool for OpenStreetMap data. + + Geofabrik + OpenStreetMap + OSM + OSM Inspector + + + + + Jochen Topf + Geofabrik GmbH + + +49-721-1803560-0 + info@geofabrik.de + + 2048 + 2048 + + + + + + text/xml + + + + + + + + + image/png + image/jpeg + image/png; mode=8bit + application/x-pdf + image/svg+xml + image/tiff + + + + + + + + + text/html + application/vnd.ogc.gml + text/plain + + + + + + + + + text/xml + + + + + + + + + image/png + image/jpeg + image/png; mode=8bit + + + + + + + + + text/xml + + + + + + + + + + XML + INIMAGE + BLANK + + + + geofabrik_tools_osminspector_geometry + Geofabrik Tools: OSM Inspector (Geometry) + OSM Inspector is a debugging tool for OpenStreetMap data. + + Geofabrik + OpenStreetMap + OSM + OSM Inspector + + EPSG:4326 + EPSG:900913 + + -180 + 180 + -83 + 83 + + + + Geofabrik GmbH/OpenStreetMap Contributors + + + + long_segments + Long segments + Segments (direct connection between two nodes in a way) longer than 20 km. + + datasrc=OSM + min=2 + max=22 + + EPSG:4326 + EPSG:900913 + + -180 + 180 + -89 + 84.6946 + + + + 1 + 2e+08 + + + ways_with_long_segments + Ways with long segments + Ways containing segments longer than 20 km. + + datasrc=OSM + min=2 + max=22 + label=tags + labelmin=10 + labelmax=22 + + EPSG:4326 + EPSG:900913 + + -180 + 180 + -89 + 84.6946 + + + + 1 + 2e+08 + + + long_ways + Long ways + Ways with more than 1900 nodes. The API allows a way to have up to 2000 nodes, but shorter ways are easier to edit. + + datasrc=OSM + min=4 + max=22 + label=tags + labelmin=10 + labelmax=22 + + EPSG:4326 + EPSG:900913 + + -176.788 + 176.947 + -83.335 + 82.9911 + + + + 1 + 1e+08 + + + single_node_in_way + Way with single node + Ways containing just a single node. This should not happen and needs to be fixed. + + datasrc=OSM + min=3 + max=22 + label=tags + labelmin=10 + labelmax=22 + + EPSG:4326 + EPSG:900913 + + -9.37981 + 112.258 + 14.8906 + 53.8984 + + + + 1 + 1e+08 + + + duplicate_node_in_way + Way with duplicate node + Ways containing a node twice (or more times) right next to each other. This should not happen and needs to be fixed. Subsequent nodes with the same location (but different ID) are flagged as errors, too. + + datasrc=OSM + min=4 + max=22 + + EPSG:4326 + EPSG:900913 + + -175.067 + 174.828 + -45.9067 + 73.4486 + + + + 1 + 5e+07 + + + duplicate_node_in_way_way + Way with duplicate node + Ways containing a node twice (or more times) right next to each other. This should not happen and needs to be fixed. Subsequent nodes with the same location (but different ID) are flagged as errors, too. + + datasrc=OSM + min=12 + max=22 + + EPSG:4326 + EPSG:900913 + + -175.067 + 174.829 + -45.907 + 73.4615 + + + + 1 + 200000 + + + self_intersection_ways + Self-intersecting ways + Ways that touch or intersect themselves. Only closed ways (where first and last nodes are the same) are tested. In most cases ways should not self-intersect, but there could be cases where it is ok. Check the tags before fixing. + + datasrc=OSM + min=6 + max=22 + + EPSG:4326 + EPSG:900913 + + -179.999 + 180 + -85.0546 + 87.0001 + + + + 1 + 1.25e+07 + + + self_intersection_points + Intersection points + Points where a way intersects itself. + + datasrc=OSM + min=10 + max=22 + + EPSG:4326 + EPSG:900913 + + -179.989 + 179.968 + -85.0542 + 87.0001 + + + + 1 + 750000 + + + + Index: trunk/test/data/wms/mapa-um-warszawa-pl.xml =================================================================== --- trunk/test/data/wms/mapa-um-warszawa-pl.xml (revision 13733) +++ trunk/test/data/wms/mapa-um-warszawa-pl.xml (revision 13733) @@ -0,0 +1,5105 @@ + + + + ]> + + + + OGC:WMS + Server WMS m.st. Warszawy + + Server WMS m.st. Warszawy + + + + GIS + WMS + Server + + + + + + + + Urząd m.st. Warszawy + Urząd m.st. Warszawy + + + + + postal +
Sandomierska 12
+ Warszawa + mazowieckie + + Polska +
+ + + + + ortofoto@um.warszawa.pl + +
+ + opłaty zgodnie z prawem + none +
+ + + + + + + + text/xml + + text/html + + application/vnd.ogc.wms_xml + + + + + + + + + + + + + image/png + + image/jpeg + + image/gif + + + + + + + + + + + + + text/xml + + text/html + + text/plain + + + + + + + + + + + + + + + application/vnd.ogc.se_xml + + + + + + + + + Server WMS m.st. Warszawy + EPSG:4326 + + + + + WMS/Raster_foto2012_8m + Raster - Fotoplan 2012 - piksel 8m + Fotoplan z 2012 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2012_10cm + Raster - Fotoplan 2012 - piksel 10cm + Fotoplan z 2012 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Cmentarze_kwatery + Religia - Cmentarze - Kwatery + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Historia_granica_1992 + Historia - Granica Warszawy 1992 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Historia_granica1939_1945 + Historia - Granica Warszawy 1945 (dekretowa) + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Inne_Obszary_ogr_uzytk + Inne - Obszar ograniczonego użytkowania + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Inne_Strefa_Z1 + Inne - Strefa ograniczeń zabudowy + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Komunikacja_koleje_glowne + Komunikacja - Linie kolejowe + Główne linie kolejowe + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Komunikacja_Metro_wejscia + Komunikacje - Wejścia do Metra + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Komunikacja_PrzystankiSKM + Komunikacja - Przystanki SKM + Przystanki Szybkiej Kolei Miejskiej + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Komunikacja_PrzystankiWKD + Komunikacja - Przystanki WKD + Przystanki Warszawskiej Kolei Dojazdowej + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Komunikacja_PrzystankiZTM + Komunikacja - Przystanki ZTM + Przystanki autobusowe i tramwajowe + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Komunikacja_StacjeMetro + Komunikacja - Stacje Metra + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Komunikacja_Strefa_płatnego_parkowania + Komunikacja - Strefa płatnego parkowania + Strefa płatnego parkowania + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Komunikacja_Tramwaje + Komunikacja - Linie tramwajowe + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Kultura_Biblioteki + Kultura - Biblioteki + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Kultura_Domy_kultury + Kultura - Domy Kultury + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Kultura_Kina + Kultura - Kina + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Kultura_Muzea + Kultura - Muzea + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Kultura_Teatry + Kultura - Teatry + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Nieruchomosci_na_sprzedaz_ogloszone + Nieruchomości na sprzedaż - przetargi ogłoszone + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Nieruchomosci_na_sprzedaz_planowane + Nieruchomości na sprzedaż - planowane do zbycia + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Nieruchomosci_na_sprzedaz_przygotowywane + Nieruchomości na sprzedaż - przeznaczone do zbycia + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/OpiekaSpoleczna_osrodki_pomocy_spolecznej + Opieka Społeczna - Ośrodki Pomocy Społecznej + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/OpiekaZdrowotna_placowki_terapii_uzaleznien + Opieka Zdrowotna - Placówki Terapii Uzależnień + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2011_10cm + Raster - Fotoplan 2011 - piksel 10cm + Fotoplan z 2011 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2011_16m + Raster - Fotoplan 2011 - piksel 16m + Fotoplan z 2011 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2011_32m + Raster - Fotoplan 2011 - piksel 32m + Fotoplan z 2011 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2011_4m + Raster - Fotoplan 2011 - piksel 4m + Fotoplan z 2011 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2011_8m + Raster - Fotoplan 2011 - piksel 8m + Fotoplan z 2011 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/OpiekaZdrowotna_poradnie_zdrowia_psychicznego + Opieka Zdrowotna - Poradnie Zdrowia Psychicznego + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/OpiekaZdrowotna_poradnie_psych_pedagogiczne + Opieka Zdrowotna - Poradnie Psychologiczno-Pedagogiczne + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/OpiekaSpoleczna_zlobki + Opieka Społeczna - złobki i kluby dziecięce + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/OpiekaZdrowotna_Szpitale + Opieka zdrowotna - Szpitale + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_budynki do zachowania + Plany zagospodarowania - budynki do zachowania + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_budynki_wpisane_do_rejestru_zabytkow + Plany zagospodarowania - budynki wpisane do rejestru zabytków + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_ciagi_piesze + Plany zagospodarowania - ciągi piesze + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_dominanta_wysokosciowa + Plany zagospodarowania - dominanty wysokościowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_dominanty_przestrzenne + Plany zagospodarowania - dominanty przestrzenne + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_granice_obszarow_objetych_ochrona_konserwatorska + Plany zagospodarowania - granice obszarów objętych ochroną konserwatorską + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_granice_obszarow_objetych_ochrona_srodowiska + Plany zagospodarowania - granice obszarów objętych ochroną środowiska + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_granice_obszaru_objetego_planem + Plany zagospodarowania - granice obszaru objętego planem + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_metro + Plany zagospodarowania - metro + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_napowietrzne_linie_EE + Plany zagospodarowania - napowietrzne linie EE + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_nieprzekraczalna_granica_pochowkow + Plany zagospodarowania - nieprzekraczalne granice pochówków + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_nieprzekraczalna_linia_zabudowy_podziemii + Plany zagospodarowania - nieprzekraczalne linie zabudowy podziemii + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_nieprzekraczalna_linia_zabudowy_przewieszen + Plany zagospodarowania - nieprzekraczalne linie zabudowy przewieszeń + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_nieprzekraczalna_linia_zabudowy_zwyzki + Plany zagospodarowania - nieprzekraczalne linie zabudowy zwyżki + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_nieprzekraczalne_linie_zabudowy + Plany zagospodarowania - nieprzekraczalne linie zabudowy + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_obiekty_wpisane_do_rejestru_zabytkow + Plany zagospodarowania - obiekty wpisane do rejestru zabytków + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_obowiazujace_linie_zabudowy + Plany zagospodarowania - obowiązujące linie zabudowy + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_osie_kompozycyjne + Plany zagospodarowania - osie kompozycyjne + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_osie_widokowe + Plany zagospodarowania - osie widokowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_parkingi_na_poziomie_terenu + Plany zagospodarowania - parkingi na poziomie terenu + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_parkingi_podziemne + Plany zagospodarowania - parkingi podziemne + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_parkingi_zatokowe + Plany zagospodarowania - parkingi zatokowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_place_miejskie + Plany zagospodarowania - place miejskie + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_pomnik_przyrody_nieozywionej + Plany zagospodarowania - pomniki przyrody nieożywionej + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_pomniki + Plany zagospodarowania - pomniki + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_pomniki_przyrody + Plany zagospodarowania - pomniki przyrody + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_sciezki_rowerowe + Plany zagospodarowania - ścieżki rowerowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_strefy_archeologiczne + Plany zagospodarowania - strefy archeologiczne + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_strefy_ograniczen + Plany zagospodarowania - strefy ograniczeń + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_tereny_o_roznych-zasadach_zagospodarowania + Plany zagospodarowania - tereny o różnych zasadach zagospodarowania + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_tereny_zamkniete + Plany zagospodarowania - tereny zamknięte + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Ramka_Zasadnicza_0250 + Geodezja - Sekcje ZMM 1:250 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Ramka_Zasadnicza_0500 + Geodezja - Sekcje ZMM 1:500 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Ramka_Zasadnicza_1000 + Geodezja - Sekcje ZMM 1:1000 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Ramka_Zasadnicza_2000 + Geodezja - Sekcje ZMM 1:2000 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_orto2010_8m + Raster - Ortofotomapa 2010 - piksel 8m + Ortofotomapa z 2010 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_orto2010_4m + Raster - Ortofotomapa 2010 - piksel 4m + Ortofotomapa z 2010 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_orto2010_32m + Raster - Ortofotomapa 2010 - piksel 32m + Ortofotomapa z 2010 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_orto2010_16m + Raster - Ortofotomapa 2010 - piksel 16m + Ortofotomapa z 2010 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_orto2010_10cm + Raster - Ortofotomapa 2010 - piksel 10 cm + Ortofotomapa z 2010 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_orto1945 + Raster - Ortofoto 1945 + Ortofotomapa zniszczonej Warszawy z roku 1945 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2012_32m + Raster - Fotoplan 2012 - piksel 32m + Fotoplan z 2012 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2012_4m + Raster - Fotoplan 2012 - piksel 4m + Fotoplan z 2012 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/studium_uwarunkowan + Raster - Studium uwarunkowań + Studium uwarunkowań i kierunków zagospodarowania przestrzennego, dostępne w skalach od 1:256 000 do 1:8 000. + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Zagrozenia_waly_ppow + Zagrożenia - Wały przeciwpowodziowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/serwisy_ibombo_samoobs + Rowery-Serwisy_ibombo_samooblugowe + Rowerowe serwisy samoobsługowe Ibombo + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/serwisy_rowerowe + Rowery-srwisy_rowerowe + Serwisy rowerowe + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Komunikacja_msi_granica_1_strefy_taxi + Komunikacja - Granica 1. Strefy TAXI + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2015_16m + Raster - Fotoplan 2015 - piksel 16m + Fotoplan z 2015 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2015_32m + Raster - Fotoplan 2015 - piksel 32m + Fotoplan z 2015 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2015_4m + Raster - Fotoplan 2015 - piksel 4m + Fotoplan z 2015 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2015_8m + Raster - Fotoplan 2015 - piksel 8m + Fotoplan z 2015 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2014_10cm + Raster - Fotoplan 2014 - piksel 10cm + Fotoplan z 2014 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2014_16m + Raster - Fotoplan 2014 - piksel 16m + Fotoplan z 2014 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2014_32m + Raster - Fotoplan 2014 - piksel 32m + Fotoplan z 2014 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2014_4m + Raster - Fotoplan 2014 - piksel 4m + Fotoplan z 2014 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2014_8m + Raster - Fotoplan 2014 - piksel 8m + Fotoplan z 2014 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2015_10cm + Raster - Fotoplan 2015 - piksel 10cm + Fotoplan z 2015 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/ENOM_Place_Skwery + ENOM_Place_Skwery + Obiekty liniowe nazewnictwa m.st. Warszawy + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/ENOM_Punkty_Adresowe + ENOM_Punkty_Adresowe + Punkty Adresowe m.st Warszawy + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2016_32m + Raster - Fotoplan 2016 - piksel 32m + Fotoplan z 2016 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2016_4m + Raster - Fotoplan 2016 - piksel 4m + Fotoplan z 2016 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2016_8m + Raster - Fotoplan 2016 - piksel 8m + Fotoplan z 2016 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Baza_noclegowa_Akademiki + Baza noclegowa - Akademiki + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Baza_noclegowa_Apartamenty + Baza noclegowa - Apartamenty + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Zielen_Grupy_krzewow + Zieleń - Grupy krzewów + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Zielen_Zywoploty + Zieleń - Żywopłoty + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Zielen_Pomniki_przyrody + Zieleń - Pomniki przyrody + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Zielen_Kwietniki + Zieleń - Kwietniki + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Zielen_Pnacza + Zieleń - Pnącza + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Zielen_Trawniki + Zieleń - Trawniki + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Administracja_Ambasady + Administracja - Ambasady + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Koryto_wisly + Raster - Koryto Wisły + Ortofotomapa z pikselem 5 cm dla koryta Wisły wykonana w roku 2015. + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Arch_Decyzje_warunki_zabudowy + Decyzje o warunkach zabudowy + Warstwa wydanych decyzji o warunkach zabudowy od sakli 1:40000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_plan_39 + Raster - Plan 1939 + Plan Warszawy z 1939 r. widoczny w zakresie skal 1:250 - 1:50000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Administracja_Biura_Urzedu + Administracja - Biura Urzędu Miasta + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Administracja_Konsulaty + Administracja - Konsulaty + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Administracja_Sady + Administracja - Sądy + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Administracja_Urzedy_Dzielnic + Administracja - Urzędy dzielnic + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Administracja_Urzedy_Skarbowe + Administracja - Urzędy Skarbowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Administracja_USC + Administracja - USC + Urzędy Stanu Cywilnego + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Administracja_ZUS + Administracja - Placówki ZUS + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Baza_noclegowa_Campingi + Baza noclegowa - Campingi + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Baza_noclegowa_Hotele + Baza noclegowa - Hotele + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Baza_noclegowa_Schroniska + Baza noclegowa - Schroniska + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Bezpieczenstwo_Policja + Bezpieczeństwo - Posterunki Policji + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Bezpieczenstwo_PSP + Bezpieczeństwo - Jednostki Straży Pożarnej + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Cmentarze_groby + Religia - Cmentarze - Groby + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Cmentarze_POI + Religia - Cmentarzei - Ważne miejsca + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Cmentarze_zasiegi + Religia - Cmentarze + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Edukacja_Gimnazja + Edukacja - Gimnazja + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Edukacja_Licea + Edukacja - Licea + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Edukacja_Przedszkola + Edukacja - Przedszkola + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Edukacja_SzkolyPodstawowe + Edukacja - Szkoły Podstawowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Edukacja_SzkolyPodstawoweObwody + Edukacja - Obwody Szkół Podstawowych + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Edukacja_SzkolyPolicealne + Edukacja - Szkoły Policealne + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Edukacja_Technika + Edukacja - Technika + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Edukacja_WyzszeUczelnie + Edukacja - Uczelnie Wyższe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Geodezja_Obszary_msi + Geodezja - Obszary MSI + Obszary Miejskiejgo Systemu Informacji + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Historia_granica_1916 + Historia - Granica Warszawy 1916 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Historia_granica_1938 + Historia - Granica Warszawy 1938 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Historia_granica_1930 + Historia - Granica Warszawy 1930 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Historia_granica_1951 + Historia - Granica Warszawy 1951 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Historia_granica_1957 + Historia - Granica Warszawy 1957 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Historia_granica_1978 + Historia - Granica Warszawy 1978 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Historia_ulice_1939_liniowe + Historia - Ulice istniejące w 1939 roku + Ulice istniejące w 1939 roku widoczne w skalach 1:250 - 1:32000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Historia_ulice_1939_glowne + Historia - Ulice główne istniejące w 1939 roku + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Historia_ulice_1939_powierzchniowe + Historia - Place istniejące w 1939 roku + Nazwy placów w 1939 roku widoczny w skalach 1:250 - 1:8000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Inne_Strefa_Z2 + Inne - Strefa ograniczeń przeznaczenia + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Komunikacja_DworceKolejowe + Komunikacja - Dworce kolejowe + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Komunikacja_Parkingi_P_R + Komunikacja - Parkingi P+R + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Komunikacja_PrzystankiKM(PKP) + Komunikacja - Przystanki KM (PKP) + Przystanki Kolei Mazowieckich (PKP) + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Ramka_Sekcje_2000 + Geodezja - Ramka Ortofoto Sekcje 1:2000 + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto1935 + Raster - Fotoplan z 1935 roku + Fotoplan z 1935 roku + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2012_16m + Raster - Fotoplan 2012 - piksel 16m + Fotoplan z 2012 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Religia_koscioly_kaplice + Religia - Kościoły i kaplice + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Bieżnia + Sport - Bieżnie + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Fitness + Sport - Kluby Fitness + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Hala_sportowa + Sport - Hale Sportowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Inne + Sport - Inne obiekty + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Korty_tenisowe + Sport - Korty Tenisowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Koszykowka + Sport - Boiska do koszykówki + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Kregielnie + Sport - Kręgielnie + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Lodowiska + Sport - Lodowiska + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Pchnięcie_kulą + Sport - Boiska do pchnięcia kulą + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Pilka_nozna_1 + Sport - Boiska do piłki nożnej + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Pilka_reczna + Sport - Boiska do piłki ręcznej + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Plywalnie + Sport - Pływalnie kryte + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Plywalnie_odkryte + Sport - Pływalnie odkryte + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Sale_gimnastyczne + Sport - Sale gimnastyczne + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Sale_i_pawilony_spec + Sport - Sale i pawilony specjalistyczne + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Scianka_wspinaczkowa + Sport - Ścianki wspinaczkowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Siatkowka + Sport - Boiska do siatkówki + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Silownie + Sport - Siłownie + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Skatepark + Sport - Skateparki + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Skok_w_dal + Sport - Boiska do skoku w dal + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Skok_wzwyż + Sport - Boiska do skoku wzwyż + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Sporty_lodziowe + Sport - Sporty łodziowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Squash + Sport - Boiska do squasha + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Stadiony_LA + Sport - Stadiony lekkoatletyczne + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Strzelnice + Sport - Strzelnice + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Sport_Tory + Sport - Tory + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Turystyka_punkty_informacyjne_msi + Turystyka - Punkty Informacyjne Miejskiego Systemu Informacji + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Turystyka_Punkty_IT + Turystyka - Punkty Informacji Turystycznej + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Zielen_Krzewy + Zieleń - Krzewy + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Geodezja_Dzialki + Geodezja_Dzialki + Warstwa z granicami działek ewidencyjnych z pzgik prowadzonego przez m.st. Warszawa. Wykorzystanie danych zgodnie z Ustawą Prawo Geodezyjne i Kartograficzne. Dane są widoczne w kalach większych niz 1:4000 + + + EGIB + działki + ewidencja + + + + + + EPSG:2178 + + EPSG:2180 + + EPSG:4326 + + + + + + + + + + + + + + + WMS/Arch_Dcyzje_pozwolenia_na_budowe + Decyzje o pozwoleniu na budowę + Warstwa wydanych decyzji o pozwoleniu na budowę od skali 1:40000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Zielen_Drzewa + Zieleń - Drzewa + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/Zielen_Grupy_drzew + Zieleń - Grupy drzew + + + + + EPSG:2178 + + EPSG:4326 + + + + + + + + + + + + + WMS/UP_cieplownicza + UP-ciepłownicza + Sieć ciepłownicza - od skali 1:2000. Dane z ODGiK m.st. Warszawy + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/UP_elektroenergetyczna + UP-elektroenergetyczna + Sieć elektroenergetyczna - od skali 1:2000. Dane z ODGiK m.st. Warszawy + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/UP_elem_naziemne + UP-elementy naziemne + Elementy naziemne urządzen poedziemnych - od skali 1:2000. Dane z ODGiK m.st. Warszawy + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/UP_gazowa + UP-gazowa + Sieć gazowa - od skali 1:2000. Dane z ODGiK m.st. Warszawy + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/UP_kanalizacyjna + UP-kanalizacyjna + Sieć kanalizacyjna - od skali 1:2000. Dane z ODGiK m.st. Warszawy + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/UP_projekty_ZUD + UP-projekty-ZUD + Projekty ZUD - od skali 1:2000. Dane z ODGiK m.st. Warszawy + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/UP_specjalna + UP-specjalna + Sieć specjalna - od skali 1:2000. Dane z ODGiK m.st. Warszawy + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/UP_telekomunikacyjna + UP-telekomunikacyjna + Sieć telekomunikacyjna - od skali 1:2000. Dane z ODGiK m.st. Warszawy + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/UP_wodociagowa + UP-wodociągowa + Sieć wodociągowa - od skali 1:2000. Dane z ODGiK m.st. Warszawy + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Edukacja_SzkolyBranzowe + Edukacja - Szkoły branżowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Religia_parafie_rzymsko_katolickie + Religia - Parafie rzymskokatolickie + Parafie rzymskokatolickie + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Geodezja_Granice_Dzielnic + Geodezja - Granice dzielnic + Granice dzielnic + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2016_10cm + Raster - Fotoplan 2016 - piksel 10cm + Fotoplan z 2016 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2016_16m + Raster - Fotoplan 2016 - piksel 16m + Fotoplan z 2016 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000 + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/ENOM_Ulice + ENOM_Ulice + Obiekty liniowe nazewnictwa m.st. Warszawy + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_linie rozgraniczajace + Plany zagospodarowania - linie rozgraniczające + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Plany_plany_zasiegi + Plany zagospodarowania - zasięgi planów + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + + WMS/Raster_foto2017_8cm + Raster - Fotoplan 2017 - piksel 8cm + Fotoplan z 2017 roku z pikselem 8cm dla zakresu skal od 0 do 1:30000 + + + + EPSG:2178 + + EPSG:2180 + + EPSG:4326 + + + + + + + + + + + + + + + WMS/Rowery_trasy_rowerowe + Rowery-Trasy rowerowe + + + + + EPSG:2178 + + EPSG:4326 + + EPSG:2180 + + + + + + + + + + + + + + +
+ Index: trunk/test/unit/org/openstreetmap/josm/TestUtils.java =================================================================== --- trunk/test/unit/org/openstreetmap/josm/TestUtils.java (revision 13712) +++ trunk/test/unit/org/openstreetmap/josm/TestUtils.java (revision 13733) @@ -15,4 +15,8 @@ import java.security.AccessController; import java.security.PrivilegedAction; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.temporal.Temporal; import java.util.Arrays; import java.util.Collection; @@ -38,4 +42,7 @@ import org.openstreetmap.josm.tools.JosmRuntimeException; import org.openstreetmap.josm.tools.Utils; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -380,3 +387,46 @@ } } + + /** + * Return WireMock server serving files under ticker directory + * @param ticketId Ticket numeric identifier + * @return WireMock HTTP server on dynamic port + */ + public static WireMockServer getWireMockServer(int ticketId) { + return new WireMockServer( + WireMockConfiguration.options() + .dynamicPort() + .usingFilesUnderDirectory(getRegressionDataDir(ticketId)) + ); + } + + /** + * Return WireMock server serving files under ticker directory + * @return WireMock HTTP server on dynamic port + */ + public static WireMockServer getWireMockServer() { + return new WireMockServer( + WireMockConfiguration.options() + .dynamicPort() + ); + } + /** + * Renders Temporal to RFC 1123 Date Time + * @param time + * @return string representation according to RFC1123 of time + */ + public static String getHTTPDate(Temporal time) { + return DateTimeFormatter.RFC_1123_DATE_TIME.withZone(ZoneOffset.UTC).format(time); + } + + /** + * Renders java time stamp to RFC 1123 Date Time + * @param time + * @return string representation according to RFC1123 of time + */ + public static String getHTTPDate(long time) { + return getHTTPDate(Instant.ofEpochMilli(time)); + } + + } Index: trunk/test/unit/org/openstreetmap/josm/actions/AddImageryLayerActionTest.java =================================================================== --- trunk/test/unit/org/openstreetmap/josm/actions/AddImageryLayerActionTest.java (revision 13712) +++ trunk/test/unit/org/openstreetmap/josm/actions/AddImageryLayerActionTest.java (revision 13733) @@ -70,9 +70,16 @@ @Test public void testActionPerformedEnabledWms() { - wireMockRule.stubFor(get(urlEqualTo("/wms?VERSION=1.1.1&SERVICE=WMS&REQUEST=GetCapabilities")) + wireMockRule.stubFor(get(urlEqualTo("/wms?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.1")) .willReturn(aResponse() - .withStatus(200) - .withHeader("Content-Type", "text/xml") - .withBodyFile("imagery/wms-capabilities.xml"))); + .withStatus(200) + .withHeader("Content-Type", "text/xml") + .withBodyFile("imagery/wms-capabilities.xml"))); + wireMockRule.stubFor(get(urlEqualTo("/wms?SERVICE=WMS&REQUEST=GetCapabilities")) + .willReturn(aResponse() + .withStatus(404))); + wireMockRule.stubFor(get(urlEqualTo("/wms?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.3.0")) + .willReturn(aResponse() + .withStatus(404))); + new AddImageryLayerAction(new ImageryInfo("localhost", "http://localhost:" + wireMockRule.port() + "/wms?", "wms_endpoint", null, null)).actionPerformed(null); Index: trunk/test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java =================================================================== --- trunk/test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java (revision 13712) +++ trunk/test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java (revision 13733) @@ -14,4 +14,5 @@ import org.junit.Rule; import org.junit.Test; +import org.openstreetmap.josm.data.imagery.TileJobOptions; import org.openstreetmap.josm.testutils.JOSMTestRules; import org.openstreetmap.josm.tools.Logging; @@ -54,5 +55,5 @@ Task(ICacheAccess cache, URL url, AtomicInteger counter) { - super(cache, 1, 1, null); + super(cache, new TileJobOptions(1, 1, null, 10)); this.url = url; this.counter = counter; Index: trunk/test/unit/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJobTest.java =================================================================== --- trunk/test/unit/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJobTest.java (revision 13712) +++ trunk/test/unit/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJobTest.java (revision 13733) @@ -2,6 +2,8 @@ package org.openstreetmap.josm.data.cache; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.io.IOException; @@ -9,12 +11,21 @@ import java.net.URL; import java.nio.charset.StandardCharsets; +import java.util.concurrent.TimeUnit; import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.apache.commons.jcs.engine.behavior.ICacheElement; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.openstreetmap.josm.TestUtils; import org.openstreetmap.josm.data.cache.ICachedLoaderListener.LoadResult; +import org.openstreetmap.josm.data.imagery.TileJobOptions; import org.openstreetmap.josm.testutils.JOSMTestRules; import org.openstreetmap.josm.tools.Logging; + +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import com.github.tomakehurst.wiremock.matching.UrlPattern; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -25,14 +36,26 @@ public class JCSCachedTileLoaderJobTest { + /** + * mocked tile server + */ + @Rule + public WireMockRule tileServer = new WireMockRule(WireMockConfiguration.options() + .dynamicPort()); + private static class TestCachedTileLoaderJob extends JCSCachedTileLoaderJob { private String url; private String key; - TestCachedTileLoaderJob(String url, String key) throws IOException { - super(getCache(), 30000, 30000, null); + TestCachedTileLoaderJob(String url, String key) { + this(url, key, (int) TimeUnit.DAYS.toSeconds(1)); + } + + TestCachedTileLoaderJob(String url, String key, int minimumExpiry) { + super(getCache(), new TileJobOptions(30000, 30000, null, minimumExpiry)); this.url = url; this.key = key; } + @Override @@ -52,5 +75,5 @@ @Override protected CacheEntry createCacheEntry(byte[] content) { - return new CacheEntry("dummy".getBytes(StandardCharsets.UTF_8)); + return new CacheEntry(content); } } @@ -60,4 +83,5 @@ private boolean ready; private LoadResult result; + private byte[] data; @Override @@ -66,4 +90,7 @@ this.ready = true; this.result = result; + if (data != null) { + this.data = data.content; + } this.notifyAll(); } @@ -113,16 +140,5 @@ String key = "key_unknown_host"; TestCachedTileLoaderJob job = new TestCachedTileLoaderJob("http://unkownhost.unkownhost/unkown", key); - Listener listener = new Listener(); - job.submit(listener, true); - synchronized (listener) { - while (!listener.ready) { - try { - listener.wait(); - } catch (InterruptedException e1) { - // do nothing, still wait - Logging.trace(e1); - } - } - } + Listener listener = submitJob(job); assertEquals(LoadResult.FAILURE, listener.result); // because response will be cached, and that is checked below assertEquals("java.net.UnknownHostException: unkownhost.unkownhost", listener.attributes.getErrorMessage()); @@ -135,38 +151,328 @@ job = new TestCachedTileLoaderJob("http://unkownhost.unkownhost/unkown", key); - listener = new Listener(); - job.submit(listener, true); + listener = submitJob(job); + assertEquals(LoadResult.SUCCESS, listener.result); + assertFalse(job.isCacheElementValid()); + } + + private void doTestStatusCode(int responseCode) throws IOException { + TestCachedTileLoaderJob job = getStatusLoaderJob(responseCode); + Listener listener = submitJob(job); + assertEquals(responseCode, listener.attributes.getResponseCode()); + } + + private Listener submitJob(TestCachedTileLoaderJob job) throws IOException { + return submitJob(job, true); + } + + private Listener submitJob(TestCachedTileLoaderJob job, boolean force) throws IOException { + Listener listener = new Listener(); + job.submit(listener, force); synchronized (listener) { while (!listener.ready) { try { listener.wait(); - } catch (InterruptedException e1) { + } catch (InterruptedException e) { // do nothing, wait - Logging.trace(e1); + Logging.trace(e); } } } - assertEquals(LoadResult.SUCCESS, listener.result); - assertFalse(job.isCacheElementValid()); - } - - @SuppressFBWarnings(value = "WA_NOT_IN_LOOP") - private void doTestStatusCode(int responseCode) throws IOException, InterruptedException { - TestCachedTileLoaderJob job = getStatusLoaderJob(responseCode); - Listener listener = new Listener(); - job.submit(listener, true); - synchronized (listener) { - if (!listener.ready) { - listener.wait(); - } - } - assertEquals(responseCode, listener.attributes.getResponseCode()); - } - - private static TestCachedTileLoaderJob getStatusLoaderJob(int responseCode) throws IOException { + return listener; + } + + /** + * That no requst is made when entry is in cache and force == false + * @throws IOException + */ + @Test + public void testNoRequestMadeWhenEntryInCache() throws IOException { + ICacheAccess cache = getCache(); + long expires = TimeUnit.DAYS.toMillis(1); + long testStart = System.currentTimeMillis(); + cache.put("test", + new CacheEntry("cached entry".getBytes(StandardCharsets.UTF_8)), + createEntryAttributes(expires, 200, testStart, "eTag") + ); + createHeadGetStub(WireMock.urlEqualTo("/test"), expires, testStart, "eTag", "mock entry"); + + TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test"); + Listener listener = submitJob(job, false); + tileServer.verify(0, WireMock.getRequestedFor(WireMock.anyUrl())); + assertArrayEquals("cached entry".getBytes(StandardCharsets.UTF_8), listener.data); + } + + /** + * that request is made, when object is in cache, but force mode is used + * @throws IOException + */ + @Test + public void testRequestMadeWhenEntryInCacheAndForce() throws IOException { + ICacheAccess cache = getCache(); + long expires = TimeUnit.DAYS.toMillis(1); + long testStart = System.currentTimeMillis(); + cache.put("test", + new CacheEntry("cached dummy".getBytes(StandardCharsets.UTF_8)), + createEntryAttributes(expires, 200, testStart + expires, "eTag") + ); + createHeadGetStub(WireMock.urlEqualTo("/test"), expires, testStart, "eTag", "mock entry"); + + TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test"); + Listener listener = submitJob(job, true); + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data); + } + + /** + * Mock returns no cache-control / expires headers + * Expire time should be set to DEFAULT_EXPIRE_TIME + * @throws IOException + */ + @Test + public void testSettingMinimumExpiryWhenNoExpires() throws IOException { + long testStart = System.currentTimeMillis(); + tileServer.stubFor( + WireMock.get(WireMock.urlEqualTo("/test")) + .willReturn(WireMock.aResponse() + .withBody("mock entry") + ) + ); + + TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test"); + Listener listener = submitJob(job, false); + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + + assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " + + JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME + " (DEFAULT_EXPIRE_TIME)", + listener.attributes.getExpirationTime() >= testStart + JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME); + + assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " + + JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME + " (DEFAULT_EXPIRE_TIME)", + listener.attributes.getExpirationTime() <= System.currentTimeMillis() + JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME); + + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data); + } + + /** + * Mock returns expires headers, but Cache-Control + * Expire time should be set to max-age + * @throws IOException + */ + @Test + public void testSettingExpireByMaxAge() throws IOException { + long testStart = System.currentTimeMillis(); + long expires = TimeUnit.DAYS.toSeconds(1); + tileServer.stubFor( + WireMock.get(WireMock.urlEqualTo("/test")) + .willReturn(WireMock.aResponse() + .withHeader("Cache-control", "max-age=" + expires) + .withBody("mock entry") + ) + ); + + TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test"); + Listener listener = submitJob(job, false); + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + + assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " + + TimeUnit.SECONDS.toMillis(expires) + " (max-age)", + listener.attributes.getExpirationTime() >= testStart + TimeUnit.SECONDS.toMillis(expires)); + + assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " + + TimeUnit.SECONDS.toMillis(expires) + " (max-age)", + listener.attributes.getExpirationTime() <= System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(expires)); + + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data); + } + + /** + * mock returns expiration: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10 + * minimum expire time: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 2 + * @throws IOException + */ + @Test + public void testSettingMinimumExpiryByMinimumExpiryTimeLessThanDefault() throws IOException { + long testStart = System.currentTimeMillis(); + int minimumExpiryTimeSeconds = (int)(JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 2); + + createHeadGetStub(WireMock.urlEqualTo("/test"), (JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10), testStart, "eTag", "mock entry"); + + TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test", minimumExpiryTimeSeconds); + Listener listener = submitJob(job, false); + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data); + + + assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " + + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)", + listener.attributes.getExpirationTime() >= testStart + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) ); + + assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " + + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)", + listener.attributes.getExpirationTime() <= System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds)); + } + + /** + * mock returns expiration: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10 + * minimum expire time: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME * 2 + * @throws IOException + */ + + @Test + public void testSettingMinimumExpiryByMinimumExpiryTimeGreaterThanDefault() throws IOException { + long testStart = System.currentTimeMillis(); + int minimumExpiryTimeSeconds = (int)(JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME * 2); + + createHeadGetStub(WireMock.urlEqualTo("/test"), (JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10), testStart, "eTag", "mock entry"); + + TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test", minimumExpiryTimeSeconds); + Listener listener = submitJob(job, false); + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data); + + + assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " + + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)", + listener.attributes.getExpirationTime() >= testStart + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) ); + + assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " + + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)", + listener.attributes.getExpirationTime() <= System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds)); + } + + /** + * Check if verifying cache entries using HEAD requests work properly + * @throws IOException + */ + @Test + public void testCheckUsingHead() throws IOException { + ICacheAccess cache = getCache(); + long expires = TimeUnit.DAYS.toMillis(1); + long testStart = System.currentTimeMillis(); + cache.put("test", + new CacheEntry("cached dummy".getBytes(StandardCharsets.UTF_8)), + createEntryAttributes(-1 * expires, 200, testStart, "eTag--gzip") // Jetty adds --gzip to etags when compressing output + ); + + tileServer.stubFor( + WireMock.get(WireMock.urlEqualTo("/test")) + .willReturn(WireMock.aResponse() + .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires)) + .withHeader("Last-Modified", Long.toString(testStart)) + .withHeader("ETag", "eTag") // Jetty adds "--gzip" suffix for compressed content + .withBody("mock entry") + ) + ); + tileServer.stubFor( + WireMock.head(WireMock.urlEqualTo("/test")) + .willReturn(WireMock.aResponse() + .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires)) + .withHeader("Last-Modified", Long.toString(testStart)) + .withHeader("ETag", "eTag--gzip") // but doesn't add to uncompressed + ) + ); + + TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test"); + Listener listener = submitJob(job, false); // cache entry is expired, no need to force refetch + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data); + + // cache entry should be retrieved from cache + listener = submitJob(job, false); + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data); + + // invalidate entry in cache + ICacheElement cacheEntry = cache.getCacheElement("test"); + CacheEntryAttributes attributes = (CacheEntryAttributes)cacheEntry.getElementAttributes(); + attributes.setExpirationTime(testStart - TimeUnit.DAYS.toMillis(1)); + cache.put("test", cacheEntry.getVal(), attributes); + + // because cache entry is invalid - HEAD request shall be made + tileServer.verify(0, WireMock.headRequestedFor(WireMock.urlEqualTo("/test"))); // no head requests were made until now + listener = submitJob(job, false); + tileServer.verify(1, WireMock.headRequestedFor(WireMock.urlEqualTo("/test"))); // verify head requests were made + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); // verify no more get requests were made + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data); + assertTrue(listener.attributes.getExpirationTime() >= testStart + expires); + + // cache entry should be retrieved from cache + listener = submitJob(job, false); // cache entry is expired, no need to force refetch + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data); + } + + /** + * Check if server returns 304 - it will update cache attributes and not ask again for it + * @throws IOException + */ + @Test + public void testCheckUsing304() throws IOException { + ICacheAccess cache = getCache(); + long expires = TimeUnit.DAYS.toMillis(1); + long testStart = System.currentTimeMillis(); + cache.put("test", + new CacheEntry("cached dummy".getBytes(StandardCharsets.UTF_8)), + createEntryAttributes(-1 * expires, 200, testStart, "eTag") + ); + + tileServer.stubFor( + WireMock.get(WireMock.urlEqualTo("/test")) + .willReturn(WireMock.status(304) + .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires)) + .withHeader("Last-Modified", Long.toString(testStart)) + .withHeader("ETag", "eTag") + ) + ); + + TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test"); + Listener listener = submitJob(job, false); + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + assertArrayEquals("cached dummy".getBytes(StandardCharsets.UTF_8), listener.data); + assertTrue(testStart + expires <= listener.attributes.getExpirationTime()); + listener = submitJob(job, false); + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); // no more requests were made + } + + private void createHeadGetStub(UrlPattern url, long expires, long lastModified, String eTag, String body) { + tileServer.stubFor( + WireMock.get(url) + .willReturn(WireMock.aResponse() + .withHeader("Expires", TestUtils.getHTTPDate(lastModified + expires)) + .withHeader("Last-Modified", Long.toString(lastModified)) + .withHeader("ETag", eTag) + .withBody(body) + ) + ); + tileServer.stubFor( + WireMock.head(url) + .willReturn(WireMock.aResponse() + .withHeader("Expires", TestUtils.getHTTPDate(lastModified + expires)) + .withHeader("Last-Modified", Long.toString(lastModified)) + .withHeader("ETag", eTag) + ) + ); + } + + private CacheEntryAttributes createEntryAttributes(long maxAge, int responseCode, String eTag) { + long validTo = maxAge + System.currentTimeMillis(); + return createEntryAttributes(maxAge, responseCode, validTo, eTag); + } + + private CacheEntryAttributes createEntryAttributes(long expirationTime, int responseCode, long lastModification, String eTag) { + CacheEntryAttributes entryAttributes = new CacheEntryAttributes(); + entryAttributes.setExpirationTime(lastModification + expirationTime); + entryAttributes.setResponseCode(responseCode); + entryAttributes.setLastModification(lastModification); + entryAttributes.setEtag(eTag); + return entryAttributes; + } + + private static TestCachedTileLoaderJob getStatusLoaderJob(int responseCode) { return new TestCachedTileLoaderJob("http://httpstat.us/" + responseCode, "key_" + responseCode); } - private static ICacheAccess getCache() throws IOException { + private static ICacheAccess getCache() { return JCSCacheManager.getCache("test"); } Index: trunk/test/unit/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJobTest.java =================================================================== --- trunk/test/unit/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJobTest.java (revision 13712) +++ trunk/test/unit/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJobTest.java (revision 13733) @@ -2,13 +2,35 @@ package org.openstreetmap.josm.data.imagery; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; +import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.openstreetmap.gui.jmapviewer.Tile; +import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener; +import org.openstreetmap.gui.jmapviewer.tilesources.TMSTileSource; +import org.openstreetmap.josm.TestUtils; +import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry; +import org.openstreetmap.josm.data.cache.CacheEntryAttributes; +import org.openstreetmap.josm.data.cache.JCSCacheManager; import org.openstreetmap.josm.testutils.JOSMTestRules; +import org.openstreetmap.josm.tools.Logging; import org.openstreetmap.josm.tools.Utils; + +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import com.github.tomakehurst.wiremock.junit.WireMockRule; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -24,5 +46,97 @@ @Rule @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") - public JOSMTestRules test = new JOSMTestRules(); + public JOSMTestRules test = new JOSMTestRules().preferences(); + + /** + * mocked tile server + */ + @Rule + public WireMockRule tileServer = new WireMockRule(WireMockConfiguration.options() + .dynamicPort()); + + @Before + public void clearCache() throws Exception { + getCache().clear(); + } + + private static ICacheAccess getCache() { + return JCSCacheManager.getCache("test"); + } + + private static class TestCachedTileLoaderJob extends TMSCachedTileLoaderJob { + private String url; + private String key; + + TestCachedTileLoaderJob(TileLoaderListener listener, Tile tile, String key) throws IOException { + this(listener, tile, key, (int) TimeUnit.DAYS.toSeconds(1)); + } + + TestCachedTileLoaderJob(TileLoaderListener listener, Tile tile, String key, int minimumExpiry) throws IOException { + super(listener, tile, getCache(), new TileJobOptions(30000, 30000, null, minimumExpiry), + (ThreadPoolExecutor) Executors.newFixedThreadPool(1)); + + this.url = tile.getUrl(); + this.key = key; + } + + @Override + public URL getUrl() { + try { + return new URL(url); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + @Override + protected BufferedImageCacheEntry createCacheEntry(byte[] content) { + return new BufferedImageCacheEntry(content); + } + + public CacheEntryAttributes getAttributes() { + return attributes; + } + + @Override + public boolean isObjectLoadable() { + // use implementation from grand parent, to avoid calling getImage on dummy data + if (cacheData == null) { + return false; + } + return cacheData.getContent().length > 0; } + } + + private static class Listener implements TileLoaderListener { + private CacheEntryAttributes attributes; + private boolean ready; + private byte[] data; + + + @Override + public synchronized void tileLoadingFinished(Tile tile, boolean success) { + ready = true; + this.notifyAll(); + } + } + + private static class MockTile extends Tile { + MockTile(String url) { + super(new MockTileSource(url), 0, 0, 0); + } + } + + private static class MockTileSource extends TMSTileSource { + private final String url; + + public MockTileSource(String url) { + super(new ImageryInfo("mock")); + this.url = url; + } + + @Override + public String getTileUrl(int zoom, int tilex, int tiley) throws IOException { + return url; + } + } /** @@ -53,3 +167,148 @@ assertEquals(expected, Utils.strip(m.group(1))); } + + private TestCachedTileLoaderJob submitJob(MockTile tile, String key, boolean force) throws IOException { + return submitJob(tile, key, 0, force); + } + + private TestCachedTileLoaderJob submitJob(MockTile tile, String key, int minimumExpiry, boolean force) throws IOException { + Listener listener = new Listener(); + TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(listener, tile, key, minimumExpiry); + job.submit(force); + synchronized (listener) { + while (!listener.ready) { + try { + listener.wait(); + } catch (InterruptedException e) { + // do nothing, wait + Logging.trace(e); + } + } + } + return job; + } + + /** + * When tile server doesn't return any Expires/Cache-Control headers, expire should be at least MINIMUM_EXPIRES + * @throws IOException + */ + @Test + public void testNoCacheHeaders() throws IOException { + long testStart = System.currentTimeMillis(); + tileServer.stubFor( + WireMock.get(WireMock.urlEqualTo("/test")) + .willReturn(WireMock.aResponse() + .withBody("mock entry") + ) + ); + + TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", false); + assertExpirationAtLeast(testStart + TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get(), job); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent()); + job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile + // only one request to tile server should be made, second should come from cache + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent()); + } + + /** + * When tile server doesn't return any Expires/Cache-Control headers, expire should be at least minimumExpires parameter + * @throws IOException + */ + @Test + public void testNoCacheHeadersMinimumExpires() throws IOException { + noCacheHeadersMinimumExpires((int) TimeUnit.MILLISECONDS.toSeconds(TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get() * 2)); + } + + /** + * When tile server doesn't return any Expires/Cache-Control headers, expire should be at least minimumExpires parameter, + * which is larger than MAXIMUM_EXPIRES + * @throws IOException + */ + + @Test + public void testNoCacheHeadersMinimumExpiresLargerThanMaximum() throws IOException { + noCacheHeadersMinimumExpires((int) TimeUnit.MILLISECONDS.toSeconds(TMSCachedTileLoaderJob.MAXIMUM_EXPIRES.get() * 2)); + } + + private void noCacheHeadersMinimumExpires(int minimumExpires) throws IOException { + long testStart = System.currentTimeMillis(); + tileServer.stubFor( + WireMock.get(WireMock.urlEqualTo("/test")) + .willReturn(WireMock.aResponse() + .withBody("mock entry") + ) + ); + TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", minimumExpires, false); + assertExpirationAtLeast(testStart + minimumExpires, job); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent()); + job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile + // only one request to tile server should be made, second should come from cache + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent()); + } + + /** + * When tile server returns Expires header shorter than MINIMUM_EXPIRES, we should cache if for at least MINIMUM_EXPIRES + * @throws IOException + */ + @Test + public void testShortExpire() throws IOException { + long testStart = System.currentTimeMillis(); + long expires = TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get() / 2; + tileServer.stubFor( + WireMock.get(WireMock.urlEqualTo("/test")) + .willReturn(WireMock.aResponse() + .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires)) + .withBody("mock entry") + ) + ); + TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", false); + assertExpirationAtLeast(testStart + TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get(), job); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent()); + job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile + // only one request to tile server should be made, second should come from cache + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent()); + } + + private void assertExpirationAtLeast(long duration, TestCachedTileLoaderJob job) { + assertTrue( + "Expiration time shorter by " + + -1 * (job.getAttributes().getExpirationTime() - duration) + + " than expected", + job.getAttributes().getExpirationTime() >= duration); + } + + private void assertExpirationAtMost(long duration, TestCachedTileLoaderJob job) { + assertTrue( + "Expiration time longer by " + + (job.getAttributes().getExpirationTime() - duration) + + " than expected", + job.getAttributes().getExpirationTime() <= duration); + } + + + @Test + public void testLongExpire() throws IOException { + long testStart = System.currentTimeMillis(); + long expires = TMSCachedTileLoaderJob.MAXIMUM_EXPIRES.get() * 2; + tileServer.stubFor( + WireMock.get(WireMock.urlEqualTo("/test")) + .willReturn(WireMock.aResponse() + .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires)) + .withBody("mock entry") + ) + ); + TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", false); + // give 1 second margin + assertExpirationAtMost(testStart + TMSCachedTileLoaderJob.MAXIMUM_EXPIRES.get() + TimeUnit.SECONDS.toMillis(1), job); + + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent()); + job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile + // only one request to tile server should be made, second should come from cache + tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); + assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent()); + } + } Index: trunk/test/unit/org/openstreetmap/josm/data/imagery/WMSEndpointTileSourceTest.java =================================================================== --- trunk/test/unit/org/openstreetmap/josm/data/imagery/WMSEndpointTileSourceTest.java (revision 13733) +++ trunk/test/unit/org/openstreetmap/josm/data/imagery/WMSEndpointTileSourceTest.java (revision 13733) @@ -0,0 +1,72 @@ +// License: GPL. For details, see LICENSE file. +package org.openstreetmap.josm.data.imagery; + +import static org.junit.Assert.assertEquals; + +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.junit.Rule; +import org.junit.Test; +import org.openstreetmap.josm.Main; +import org.openstreetmap.josm.TestUtils; +import org.openstreetmap.josm.data.projection.Projections; +import org.openstreetmap.josm.spi.preferences.Config; +import org.openstreetmap.josm.testutils.JOSMTestRules; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.client.WireMock; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +public class WMSEndpointTileSourceTest { + /** + * Setup test + */ + @Rule + @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") + public JOSMTestRules test = new JOSMTestRules().platform().projection(); + + @Test + public void testDefaultLayerSetInMaps() throws Exception { + WireMockServer getCapabilitiesMock = TestUtils.getWireMockServer(); + String getCapabilitiesBody = new String(Files.readAllBytes(Paths.get(TestUtils.getTestDataRoot() + "wms/geofabrik-osm-inspector.xml")), "UTF-8"); + // do not use withFileBody as it needs different directory layout :( + getCapabilitiesMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody(getCapabilitiesBody))); + getCapabilitiesMock.start(); + + WireMockServer mapsMock = TestUtils.getWireMockServer(); + mapsMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody( + "\n" + + "\n" + + "\n" + + "OSM Inspector: Geometry\n" + + "OSM_Inspector-Geometry\n" + + "wms_endpoint\n" + + "\n" + + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAB5UlEQVQ4y4WTwWsTURDGfy8W1yYmXZOqtGJJFyGw6KF7CEigwYuS0kthrYUi4i0iORS9BU9hQdA/ILcixVBrwENKLz1FUBB0wWOwYFAqxUNYTZq6BfM8yC5d05iBObz3vfnmm3kz4sqDh/zP7szdlG5I+Of1zQ1xFA8xxI4GH2cjg4Cl+UUJcC4SJq6c7FPkKRlIoPQk0+NnuDwxHrhvuYd83+8OVuBlHouE/eDXzW8+/qO9DyHB0vyiVHoy2INSNiPdeg23XuPs3icmIoofPKXGmFJjjEUjgf4EFNi2TT6fJ5FI0Gg0ePrkMRfnbvn41QsJgEAJAQUdbYZyuQxAcvoSpmnydesFAF+cn8f2KUCw/fGt6GgzWJbF706bVCoFwGxyktnk5N8kB79QepL1zQ3xbOulCJWyGbkQHZWlbEZ6JIZhBDI1nQ5Np8P2zi4t9zAwGyNe3QALti11XSedTvsPYrEY73f3Bk+irusAnI6qrNy7z43sNUbFCQC6LYdCoYBbr/k1/2sh690HUalUaH7eIRxXA+6RFItF3HqN6+dP9REIb5lK2Yy0bdsHDMMgl8vRbTkAhOMqlmVhmibLq2ui7xsf1d+IV+0D3zVNw7KsPiXVapXnd2/Lodu4vLomTNMcSvIHY6bDkqJtEqIAAAAASUVORK5CYII=\n" + + "© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA\n" + + "http://tools.geofabrik.de/osmi/\n" + + "18\n" + + "true\n" + + "" + + "" + + "" + + "\n" + + "" + ))); + mapsMock.start(); + Config.getPref().put("josm.url", mapsMock.url("/")); + ImageryLayerInfo.instance.loadDefaults(true, null, false); + assertEquals(1, ImageryLayerInfo.instance.getDefaultLayers().size()); + ImageryInfo wmsImageryInfo = ImageryLayerInfo.instance.getDefaultLayers().get(0); + assertEquals("single_node_in_way", wmsImageryInfo.getDefaultLayers().get(0).getLayerName()); + WMSEndpointTileSource tileSource = new WMSEndpointTileSource(wmsImageryInfo, Main.getProjection()); + tileSource.initProjection(Projections.getProjectionByCode("EPSG:3857")); + assertEquals("https://tools.geofabrik.de/osmi/views/geometry/wxs?FORMAT=image/png&TRANSPARENT=TRUE&VERSION=1.1.1&SERVICE=WMS&REQUEST=GetMap&" + + "LAYERS=single_node_in_way&STYLES=default&" + + "SRS=EPSG:3857&WIDTH=512&HEIGHT=512&" + + "BBOX=20037506.6204108,-60112521.5836107,60112521.5836107,-20037506.6204108", tileSource.getTileUrl(1, 1, 1)); + + } +} Index: trunk/test/unit/org/openstreetmap/josm/data/imagery/WMTSTileSourceTest.java =================================================================== --- trunk/test/unit/org/openstreetmap/josm/data/imagery/WMTSTileSourceTest.java (revision 13712) +++ trunk/test/unit/org/openstreetmap/josm/data/imagery/WMTSTileSourceTest.java (revision 13733) @@ -8,9 +8,12 @@ import java.io.IOException; import java.net.MalformedURLException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Collection; - +import java.util.Arrays; +import java.util.List; + +import org.junit.ClassRule; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; import org.openstreetmap.gui.jmapviewer.tilesources.TemplatedTMSTileSource; @@ -19,6 +22,12 @@ import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.coor.LatLon; +import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType; +import org.openstreetmap.josm.data.imagery.WMTSTileSource.WMTSGetCapabilitiesException; import org.openstreetmap.josm.data.projection.Projections; +import org.openstreetmap.josm.spi.preferences.Config; import org.openstreetmap.josm.testutils.JOSMTestRules; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.client.WireMock; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -28,4 +37,11 @@ */ public class WMTSTileSourceTest { + + /** + * Setup test. + */ + @ClassRule + @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") + public static JOSMTestRules test = new JOSMTestRules().preferences().platform(); private ImageryInfo testImageryTMS = new ImageryInfo("test imagery", "http://localhost", "tms", null, null); @@ -44,17 +60,13 @@ "wmts/bug13975-multiple-tile-matrices-for-one-layer-projection.xml"); - /** - * Setup test. - */ - @Rule - @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") - public JOSMTestRules test = new JOSMTestRules(); private static ImageryInfo getImagery(String path) { try { - return new ImageryInfo( + ImageryInfo ret = new ImageryInfo( "test", new File(path).toURI().toURL().toString() ); + ret.setImageryType(ImageryType.WMTS); + return ret; } catch (MalformedURLException e) { e.printStackTrace(); @@ -64,5 +76,5 @@ @Test - public void testPseudoMercator() throws IOException { + public void testPseudoMercator() throws IOException, WMTSGetCapabilitiesException { Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); WMTSTileSource testSource = new WMTSTileSource(testImageryPSEUDO_MERCATOR); @@ -94,5 +106,5 @@ @Test - public void testWALLONIE() throws IOException { + public void testWALLONIE() throws IOException, WMTSGetCapabilitiesException { Main.setProjection(Projections.getProjectionByCode("EPSG:31370")); WMTSTileSource testSource = new WMTSTileSource(testImageryWALLONIE); @@ -114,5 +126,5 @@ @Test @Ignore("disable this test, needs further working") // XXX - public void testWALLONIENoMatrixDimension() throws IOException { + public void testWALLONIENoMatrixDimension() throws IOException, WMTSGetCapabilitiesException { Main.setProjection(Projections.getProjectionByCode("EPSG:31370")); WMTSTileSource testSource = new WMTSTileSource(getImagery("test/data/wmts/WMTSCapabilities-Wallonie-nomatrixdimension.xml")); @@ -138,5 +150,5 @@ @Test - public void testWIEN() throws IOException { + public void testWIEN() throws IOException, WMTSGetCapabilitiesException { Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); WMTSTileSource testSource = new WMTSTileSource(testImageryWIEN); @@ -180,5 +192,5 @@ @Test - public void testGeoportalTOPOPL() throws IOException { + public void testGeoportalTOPOPL() throws IOException, WMTSGetCapabilitiesException { Main.setProjection(Projections.getProjectionByCode("EPSG:4326")); WMTSTileSource testSource = new WMTSTileSource(testImageryTOPO_PL); @@ -202,5 +214,5 @@ @Test - public void testGeoportalORTOPL4326() throws IOException { + public void testGeoportalORTOPL4326() throws IOException, WMTSGetCapabilitiesException { Main.setProjection(Projections.getProjectionByCode("EPSG:4326")); WMTSTileSource testSource = new WMTSTileSource(testImageryORTO_PL); @@ -211,5 +223,5 @@ @Test - public void testGeoportalORTOPL2180() throws IOException { + public void testGeoportalORTOPL2180() throws IOException, WMTSGetCapabilitiesException { Main.setProjection(Projections.getProjectionByCode("EPSG:2180")); WMTSTileSource testSource = new WMTSTileSource(testImageryORTO_PL); @@ -221,5 +233,5 @@ @Test - public void testTicket12168() throws IOException { + public void testTicket12168() throws IOException, WMTSGetCapabilitiesException { Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); WMTSTileSource testSource = new WMTSTileSource(testImagery12168); @@ -231,15 +243,36 @@ @Test - @Ignore("disabled as this needs user action") // XXX public void testTwoTileSetsForOneProjection() throws Exception { Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); - WMTSTileSource testSource = new WMTSTileSource(testImageryOntario); - testSource.initProjection(Main.getProjection()); - verifyTile(new LatLon(45.4105023, -75.7153702), testSource, 303751, 375502, 12); - verifyTile(new LatLon(45.4601306, -75.7617187), testSource, 1186, 1466, 4); - } - - @Test - @Ignore("disabled as this needs user action") // XXX + ImageryInfo ontario = getImagery(TestUtils.getTestDataRoot() + "wmts/WMTSCapabilities-Ontario.xml"); + ontario.setDefaultLayers(Arrays.asList(new DefaultLayer[] { + new DefaultLayer(ImageryType.WMTS, "Basemap_Imagery_2014", null, "default028mm") + })); + WMTSTileSource testSource = new WMTSTileSource(ontario); + testSource.initProjection(Main.getProjection()); + assertEquals( + "http://maps.ottawa.ca/arcgis/rest/services/Basemap_Imagery_2014/MapServer/WMTS/tile/1.0.0/Basemap_Imagery_2014/default/default028mm/4/2932/2371.jpg", + testSource.getTileUrl(4, 2371, 2932)); + verifyTile(new LatLon(45.4601306, -75.7617187), testSource, 2372, 2932, 4); + verifyTile(new LatLon(45.4602510, -75.7617187), testSource, 607232, 750591, 12); + } + + @Test + public void testTwoTileSetsForOneProjectionSecondLayer() throws Exception { + Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); + ImageryInfo ontario = getImagery(TestUtils.getTestDataRoot() + "wmts/WMTSCapabilities-Ontario.xml"); + ontario.setDefaultLayers(Arrays.asList(new DefaultLayer[] { + new DefaultLayer(ImageryType.WMTS, "Basemap_Imagery_2014", null, "GoogleMapsCompatible") + })); + WMTSTileSource testSource = new WMTSTileSource(ontario); + testSource.initProjection(Main.getProjection()); + assertEquals( + "http://maps.ottawa.ca/arcgis/rest/services/Basemap_Imagery_2014/MapServer/WMTS/tile/1.0.0/Basemap_Imagery_2014/default/GoogleMapsCompatible/4/2932/2371.jpg", + testSource.getTileUrl(4, 2371, 2932)); + verifyMercatorTile(testSource, 74, 91, 8); + verifyMercatorTile(testSource, 37952, 46912, 17); + } + + @Test public void testManyLayersScrollbars() throws Exception { Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); @@ -271,6 +304,6 @@ Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); ImageryInfo copy = new ImageryInfo(testMultipleTileMatrixForLayer); - Collection defaultLayers = new ArrayList<>(1); - defaultLayers.add(new WMTSDefaultLayer("Mashhad_BaseMap_1", "default028mm")); + List defaultLayers = new ArrayList<>(1); + defaultLayers.add(new DefaultLayer(ImageryType.WMTS, "Mashhad_BaseMap_1", null, "default028mm")); copy.setDefaultLayers(defaultLayers); WMTSTileSource testSource = new WMTSTileSource(copy); @@ -286,11 +319,12 @@ * Test WMTS dimension. * @throws IOException if any I/O error occurs + * @throws WMTSGetCapabilitiesException */ @Test - public void testDimension() throws IOException { + public void testDimension() throws IOException, WMTSGetCapabilitiesException { Main.setProjection(Projections.getProjectionByCode("EPSG:21781")); ImageryInfo info = new ImageryInfo(testImageryGeoAdminCh); - Collection defaultLayers = new ArrayList<>(1); - defaultLayers.add(new WMTSDefaultLayer("ch.are.agglomerationen_isolierte_staedte", "21781_26")); + List defaultLayers = new ArrayList<>(1); + defaultLayers.add(new DefaultLayer(ImageryType.WMTS, "ch.are.agglomerationen_isolierte_staedte", null, "21781_26")); info.setDefaultLayers(defaultLayers); WMTSTileSource testSource = new WMTSTileSource(info); @@ -300,4 +334,45 @@ testSource.getTileUrl(1, 2, 3) ); + } + + @Test + public void testDefaultLayer() throws Exception { + // https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/1.0.0/WMTSCapabilities.xml + WireMockServer getCapabilitiesMock = TestUtils.getWireMockServer(); + String getCapabilitiesBody = new String(Files.readAllBytes(Paths.get(TestUtils.getTestDataRoot() + "wmts/getCapabilities-lots-of-layers.xml")), "UTF-8"); + // do not use withFileBody as it needs different directory layout :( + getCapabilitiesMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody(getCapabilitiesBody))); + getCapabilitiesMock.start(); + + WireMockServer mapsMock = TestUtils.getWireMockServer(); + mapsMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody( + "\n" + + "\n" + + "\n" + + "Landsat\n" + + "landsat\n" + + "wmts\n" + + "\n" + + "" + + "" + + "" + + "\n" + + "" + ))); + mapsMock.start(); + Config.getPref().put("josm.url", mapsMock.url("/")); + + ImageryLayerInfo.instance.loadDefaults(true, null, false); + + assertEquals(1, ImageryLayerInfo.instance.getDefaultLayers().size()); + ImageryInfo wmtsImageryInfo = ImageryLayerInfo.instance.getDefaultLayers().get(0); + assertEquals(1, wmtsImageryInfo.getDefaultLayers().size()); + assertEquals("GEOGRAPHICALGRIDSYSTEMS.MAPS", wmtsImageryInfo.getDefaultLayers().get(0).getLayerName()); + WMTSTileSource tileSource = new WMTSTileSource(wmtsImageryInfo); + tileSource.initProjection(Projections.getProjectionByCode("EPSG:3857")); + assertEquals("http://wxs.ign.fr/61fs25ymczag0c67naqvvmap/geoportail/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&" + + "LAYER=GEOGRAPHICALGRIDSYSTEMS.MAPS" + + "&STYLE=normal&FORMAT=image/jpeg&tileMatrixSet=PM&tileMatrix=1&tileRow=1&tileCol=1", tileSource.getTileUrl(1, 1, 1)); + } Index: trunk/test/unit/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayerTest.java =================================================================== --- trunk/test/unit/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayerTest.java (revision 13712) +++ trunk/test/unit/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayerTest.java (revision 13733) @@ -120,5 +120,6 @@ return new TileLoaderFactory() { @Override - public TileLoader makeTileLoader(TileLoaderListener listener, Map headers) { + public TileLoader makeTileLoader(TileLoaderListener listener, Map headers, + long minimumExpiryTime) { return null; } Index: trunk/test/unit/org/openstreetmap/josm/gui/layer/WMTSLayerTest.java =================================================================== --- trunk/test/unit/org/openstreetmap/josm/gui/layer/WMTSLayerTest.java (revision 13712) +++ trunk/test/unit/org/openstreetmap/josm/gui/layer/WMTSLayerTest.java (revision 13733) @@ -22,5 +22,5 @@ @Rule @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") - public JOSMTestRules test = new JOSMTestRules().timeout(20000); + public JOSMTestRules test = new JOSMTestRules().preferences().timeout(20000); /** Index: trunk/test/unit/org/openstreetmap/josm/io/imagery/WMSImageryTest.java =================================================================== --- trunk/test/unit/org/openstreetmap/josm/io/imagery/WMSImageryTest.java (revision 13712) +++ trunk/test/unit/org/openstreetmap/josm/io/imagery/WMSImageryTest.java (revision 13733) @@ -6,5 +6,8 @@ import java.io.IOException; -import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; import org.junit.Rule; @@ -13,4 +16,7 @@ import org.openstreetmap.josm.io.imagery.WMSImagery.WMSGetCapabilitiesException; import org.openstreetmap.josm.testutils.JOSMTestRules; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.client.WireMock; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -26,5 +32,5 @@ @Rule @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") - public JOSMTestRules test = new JOSMTestRules(); + public JOSMTestRules test = new JOSMTestRules().platform().projection(); /** @@ -49,10 +55,23 @@ @Test public void testTicket15730() throws IOException, WMSGetCapabilitiesException { - try (InputStream is = TestUtils.getRegressionDataStream(15730, "capabilities.xml")) { - WMSImagery wms = new WMSImagery(); - wms.parseCapabilities(null, is); - assertEquals(1, wms.getLayers().size()); - assertTrue(wms.getLayers().get(0).abstr.startsWith("South Carolina NAIP Imagery 2017 Resolution: 100CM ")); - } + WireMockServer wm = TestUtils.getWireMockServer(15730); + wm.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBodyFile("capabilities.xml"))); + wm.start(); + WMSImagery wms = new WMSImagery(wm.url("capabilities.xml")); + assertEquals(1, wms.getLayers().size()); + assertTrue(wms.getLayers().get(0).getAbstract().startsWith("South Carolina NAIP Imagery 2017 Resolution: 100CM ")); + wm.shutdown(); + } + + @Test + public void testNestedLayers() throws Exception { + WireMockServer getCapabilitiesMock = TestUtils.getWireMockServer(); + String getCapabilitiesBody = new String(Files.readAllBytes(Paths.get(TestUtils.getTestDataRoot() + "wms/mapa-um-warszawa-pl.xml")), "UTF-8"); + getCapabilitiesMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody(getCapabilitiesBody))); + getCapabilitiesMock.start(); + WMSImagery wmsi = new WMSImagery(getCapabilitiesMock.url("/serwis")); + assertEquals(1, wmsi.getLayers().size()); + assertEquals("Server WMS m.st. Warszawy", wmsi.getLayers().get(0).toString()); + assertEquals(202, wmsi.getLayers().get(0).getChildren().size()); } @@ -64,9 +83,17 @@ @Test public void testTicket16248() throws IOException, WMSGetCapabilitiesException { - try (InputStream is = TestUtils.getRegressionDataStream(16248, "capabilities.xml")) { - WMSImagery wms = new WMSImagery(); - wms.parseCapabilities(null, is); - assertEquals("http://wms.hgis.cartomatic.pl/topo/3857/m25k", wms.getServiceUrl().toExternalForm()); - } + Path capabilitiesPath = Paths.get(TestUtils.getRegressionDataFile(16248, "capabilities.xml")); + WireMockServer getCapabilitiesMock = TestUtils.getWireMockServer(); + getCapabilitiesMock.stubFor( + WireMock.get(WireMock.anyUrl()) + .willReturn(WireMock.aResponse().withBody(Files.readAllBytes(capabilitiesPath)))); + getCapabilitiesMock.start(); + WMSImagery wms = new WMSImagery(getCapabilitiesMock.url("any")); + assertEquals("http://wms.hgis.cartomatic.pl/topo/3857/m25k", wms.buildRootUrl()); + assertEquals("wms.hgis.cartomatic.pl", wms.getLayers().get(0).getName()); + assertEquals("http://wms.hgis.cartomatic.pl/topo/3857/m25kFORMAT=image/png&TRANSPARENT=TRUE&VERSION=1.1.1&SERVICE=WMS&REQUEST=GetMap&" + + "LAYERS=wms.hgis.cartomatic.pl&STYLES=&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}", + wms.buildGetMapUrl(wms.getLayers(), (List)null, true)); } } +