MapProxy 2.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- MapProxy-2.1.0.dist-info/AUTHORS.txt +33 -0
- MapProxy-2.1.0.dist-info/COPYING.txt +60 -0
- MapProxy-2.1.0.dist-info/LICENSE.txt +202 -0
- MapProxy-2.1.0.dist-info/METADATA +165 -0
- MapProxy-2.1.0.dist-info/RECORD +459 -0
- MapProxy-2.1.0.dist-info/WHEEL +5 -0
- MapProxy-2.1.0.dist-info/entry_points.txt +4 -0
- MapProxy-2.1.0.dist-info/top_level.txt +1 -0
- mapproxy/__init__.py +0 -0
- mapproxy/cache/__init__.py +36 -0
- mapproxy/cache/azureblob.py +145 -0
- mapproxy/cache/base.py +120 -0
- mapproxy/cache/compact.py +665 -0
- mapproxy/cache/couchdb.py +301 -0
- mapproxy/cache/dummy.py +36 -0
- mapproxy/cache/file.py +200 -0
- mapproxy/cache/geopackage.py +647 -0
- mapproxy/cache/legend.py +87 -0
- mapproxy/cache/mbtiles.py +411 -0
- mapproxy/cache/meta.py +80 -0
- mapproxy/cache/path.py +261 -0
- mapproxy/cache/redis.py +152 -0
- mapproxy/cache/renderd.py +100 -0
- mapproxy/cache/riak.py +206 -0
- mapproxy/cache/s3.py +209 -0
- mapproxy/cache/tile.py +736 -0
- mapproxy/client/__init__.py +0 -0
- mapproxy/client/arcgis.py +82 -0
- mapproxy/client/cgi.py +141 -0
- mapproxy/client/http.py +295 -0
- mapproxy/client/log.py +33 -0
- mapproxy/client/tile.py +158 -0
- mapproxy/client/wms.py +255 -0
- mapproxy/compat/__init__.py +0 -0
- mapproxy/compat/image.py +86 -0
- mapproxy/config/__init__.py +22 -0
- mapproxy/config/config-schema.json +813 -0
- mapproxy/config/config.py +213 -0
- mapproxy/config/coverage.py +108 -0
- mapproxy/config/defaults.py +102 -0
- mapproxy/config/loader.py +2399 -0
- mapproxy/config/spec.py +657 -0
- mapproxy/config/validator.py +242 -0
- mapproxy/config_template/__init__.py +0 -0
- mapproxy/config_template/base_config/config.wsgi +10 -0
- mapproxy/config_template/base_config/full_example.yaml +598 -0
- mapproxy/config_template/base_config/full_seed_example.yaml +79 -0
- mapproxy/config_template/base_config/log.ini +35 -0
- mapproxy/config_template/base_config/mapproxy.yaml +60 -0
- mapproxy/config_template/base_config/seed.yaml +27 -0
- mapproxy/exception.py +149 -0
- mapproxy/featureinfo.py +251 -0
- mapproxy/grid.py +1199 -0
- mapproxy/image/__init__.py +549 -0
- mapproxy/image/fonts/DejaVuSans.ttf +0 -0
- mapproxy/image/fonts/DejaVuSansMono.ttf +0 -0
- mapproxy/image/fonts/LICENSE +99 -0
- mapproxy/image/fonts/__init__.py +0 -0
- mapproxy/image/mask.py +79 -0
- mapproxy/image/merge.py +323 -0
- mapproxy/image/message.py +357 -0
- mapproxy/image/opts.py +185 -0
- mapproxy/image/tile.py +171 -0
- mapproxy/image/transform.py +350 -0
- mapproxy/layer.py +489 -0
- mapproxy/multiapp.py +230 -0
- mapproxy/proj.py +309 -0
- mapproxy/request/__init__.py +18 -0
- mapproxy/request/arcgis.py +268 -0
- mapproxy/request/base.py +466 -0
- mapproxy/request/tile.py +131 -0
- mapproxy/request/wms/__init__.py +829 -0
- mapproxy/request/wms/exception.py +107 -0
- mapproxy/request/wmts.py +442 -0
- mapproxy/response.py +237 -0
- mapproxy/script/__init__.py +0 -0
- mapproxy/script/conf/__init__.py +0 -0
- mapproxy/script/conf/app.py +222 -0
- mapproxy/script/conf/caches.py +44 -0
- mapproxy/script/conf/geopackage.py +136 -0
- mapproxy/script/conf/layers.py +54 -0
- mapproxy/script/conf/seeds.py +36 -0
- mapproxy/script/conf/sources.py +88 -0
- mapproxy/script/conf/utils.py +148 -0
- mapproxy/script/defrag.py +187 -0
- mapproxy/script/export.py +337 -0
- mapproxy/script/grids.py +198 -0
- mapproxy/script/scales.py +134 -0
- mapproxy/script/util.py +410 -0
- mapproxy/script/wms_capabilities.py +160 -0
- mapproxy/seed/__init__.py +0 -0
- mapproxy/seed/cachelock.py +127 -0
- mapproxy/seed/cleanup.py +191 -0
- mapproxy/seed/config.py +481 -0
- mapproxy/seed/script.py +391 -0
- mapproxy/seed/seeder.py +551 -0
- mapproxy/seed/spec.py +66 -0
- mapproxy/seed/util.py +266 -0
- mapproxy/service/__init__.py +14 -0
- mapproxy/service/base.py +45 -0
- mapproxy/service/demo.py +364 -0
- mapproxy/service/kml.py +333 -0
- mapproxy/service/ows.py +39 -0
- mapproxy/service/template_helper.py +55 -0
- mapproxy/service/templates/demo/capabilities_demo.html +18 -0
- mapproxy/service/templates/demo/demo.html +181 -0
- mapproxy/service/templates/demo/openlayers-demo.cfg +16 -0
- mapproxy/service/templates/demo/static/img/blank.gif +0 -0
- mapproxy/service/templates/demo/static/img/east-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/north-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/south-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/west-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-minus-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-plus-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-world-mini.png +0 -0
- mapproxy/service/templates/demo/static/logo.png +0 -0
- mapproxy/service/templates/demo/static/ol.css +345 -0
- mapproxy/service/templates/demo/static/ol.js +4 -0
- mapproxy/service/templates/demo/static/proj4.min.js +1 -0
- mapproxy/service/templates/demo/static/proj4defs.js +1 -0
- mapproxy/service/templates/demo/static/site.css +137 -0
- mapproxy/service/templates/demo/static/theme/default/framedCloud.css +0 -0
- mapproxy/service/templates/demo/static/theme/default/google.css +17 -0
- mapproxy/service/templates/demo/static/theme/default/ie6-style.css +10 -0
- mapproxy/service/templates/demo/static/theme/default/style.css +482 -0
- mapproxy/service/templates/demo/static.html +34 -0
- mapproxy/service/templates/demo/tms_demo.html +117 -0
- mapproxy/service/templates/demo/wms_demo.html +144 -0
- mapproxy/service/templates/demo/wmts_demo.html +118 -0
- mapproxy/service/templates/tms_capabilities.xml +13 -0
- mapproxy/service/templates/tms_exception.xml +4 -0
- mapproxy/service/templates/tms_root_resource.xml +7 -0
- mapproxy/service/templates/tms_tilemap_capabilities.xml +14 -0
- mapproxy/service/templates/wms100capabilities.xml +112 -0
- mapproxy/service/templates/wms100exception.xml +4 -0
- mapproxy/service/templates/wms110capabilities.xml +152 -0
- mapproxy/service/templates/wms110exception.xml +5 -0
- mapproxy/service/templates/wms111capabilities.xml +183 -0
- mapproxy/service/templates/wms111exception.xml +5 -0
- mapproxy/service/templates/wms130capabilities.xml +326 -0
- mapproxy/service/templates/wms130exception.xml +8 -0
- mapproxy/service/templates/wmts100capabilities.xml +155 -0
- mapproxy/service/templates/wmts100exception.xml +9 -0
- mapproxy/service/tile.py +540 -0
- mapproxy/service/wms.py +868 -0
- mapproxy/service/wmts.py +387 -0
- mapproxy/source/__init__.py +83 -0
- mapproxy/source/arcgis.py +39 -0
- mapproxy/source/error.py +40 -0
- mapproxy/source/mapnik.py +262 -0
- mapproxy/source/tile.py +97 -0
- mapproxy/source/wms.py +273 -0
- mapproxy/srs.py +734 -0
- mapproxy/template.py +54 -0
- mapproxy/test/__init__.py +0 -0
- mapproxy/test/conftest.py +8 -0
- mapproxy/test/helper.py +255 -0
- mapproxy/test/http.py +511 -0
- mapproxy/test/image.py +219 -0
- mapproxy/test/mocker.py +2291 -0
- mapproxy/test/schemas/inspire/common/1.0/common.xsd +1461 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_bul.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_cze.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_dan.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_dut.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_eng.xsd +155 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_est.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_fin.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_fre.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_ger.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_gle.xsd +109 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_gre.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_hun.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_ita.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_lav.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_lit.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_mlt.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_pol.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_por.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_rum.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_slo.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_slv.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_spa.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_swe.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/network.xsd +521 -0
- mapproxy/test/schemas/inspire/inspire_vs/1.0/inspire_vs.xsd +19 -0
- mapproxy/test/schemas/kml/2.2.0/ReadMe.txt +14 -0
- mapproxy/test/schemas/kml/2.2.0/atom-author-link.xsd +66 -0
- mapproxy/test/schemas/kml/2.2.0/ogckml22.xsd +1646 -0
- mapproxy/test/schemas/kml/2.2.0/xAL.xsd +1680 -0
- mapproxy/test/schemas/ows/1.1.0/ReadMe.txt +87 -0
- mapproxy/test/schemas/ows/1.1.0/ows19115subset.xsd +235 -0
- mapproxy/test/schemas/ows/1.1.0/owsAll.xsd +23 -0
- mapproxy/test/schemas/ows/1.1.0/owsCommon.xsd +157 -0
- mapproxy/test/schemas/ows/1.1.0/owsContents.xsd +86 -0
- mapproxy/test/schemas/ows/1.1.0/owsDataIdentification.xsd +127 -0
- mapproxy/test/schemas/ows/1.1.0/owsDomainType.xsd +279 -0
- mapproxy/test/schemas/ows/1.1.0/owsExceptionReport.xsd +76 -0
- mapproxy/test/schemas/ows/1.1.0/owsGetCapabilities.xsd +112 -0
- mapproxy/test/schemas/ows/1.1.0/owsGetResourceByID.xsd +51 -0
- mapproxy/test/schemas/ows/1.1.0/owsInputOutputData.xsd +59 -0
- mapproxy/test/schemas/ows/1.1.0/owsManifest.xsd +125 -0
- mapproxy/test/schemas/ows/1.1.0/owsOperationsMetadata.xsd +140 -0
- mapproxy/test/schemas/ows/1.1.0/owsServiceIdentification.xsd +60 -0
- mapproxy/test/schemas/ows/1.1.0/owsServiceProvider.xsd +47 -0
- mapproxy/test/schemas/sld/1.1.0/sld_capabilities.xsd +27 -0
- mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.dtd +353 -0
- mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.xml +188 -0
- mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.dtd +524 -0
- mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.xml +260 -0
- mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.dtd +273 -0
- mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.xml +303 -0
- mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.dtd +6 -0
- mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.xml +33 -0
- mapproxy/test/schemas/wms/1.1.1/OGC-exception.xsd +68 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd +274 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd +5 -0
- mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.dtd +276 -0
- mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.xml +303 -0
- mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.dtd +6 -0
- mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.xml +33 -0
- mapproxy/test/schemas/wms/1.3.0/ReadMe.txt +8 -0
- mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xml +277 -0
- mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xsd +611 -0
- mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xml +34 -0
- mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xsd +28 -0
- mapproxy/test/schemas/wmsc/1.1.1/OGC-exception.xsd +68 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_MS_Capabilities.dtd +283 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_exception_1_1_1.dtd +5 -0
- mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.dtd +276 -0
- mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.xml +303 -0
- mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.dtd +6 -0
- mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.xml +33 -0
- mapproxy/test/schemas/wmts/1.0/ReadMe.txt +32 -0
- mapproxy/test/schemas/wmts/1.0/wmts.xsd +28 -0
- mapproxy/test/schemas/wmts/1.0/wmtsAbstract.wsdl +151 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_request.xsd +38 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_response.xsd +564 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_request.xsd +57 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_response.xsd +72 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetTile_request.xsd +91 -0
- mapproxy/test/schemas/wmts/1.0/wmtsKVP.xsd +76 -0
- mapproxy/test/schemas/wmts/1.0/wmtsPayload_response.xsd +70 -0
- mapproxy/test/schemas/xlink/1.0.0/ReadMe.txt +6 -0
- mapproxy/test/schemas/xlink/1.0.0/xlinks.xsd +122 -0
- mapproxy/test/schemas/xml.xsd +287 -0
- mapproxy/test/system/__init__.py +98 -0
- mapproxy/test/system/fixture/arcgis.yaml +57 -0
- mapproxy/test/system/fixture/auth.yaml +70 -0
- mapproxy/test/system/fixture/cache.mbtiles +0 -0
- mapproxy/test/system/fixture/cache_azureblob.yaml +59 -0
- mapproxy/test/system/fixture/cache_band_merge.yaml +73 -0
- mapproxy/test/system/fixture/cache_bulk_meta_tiles.yaml +24 -0
- mapproxy/test/system/fixture/cache_coverage.yaml +84 -0
- mapproxy/test/system/fixture/cache_data/dop_cache_EPSG3857/00/000/000/000/000/000/000.png +0 -0
- mapproxy/test/system/fixture/cache_data/wms_cache_EPSG900913/01/000/000/000/000/000/001.jpeg +0 -0
- mapproxy/test/system/fixture/cache_data/wms_cache_transparent_EPSG900913/01/000/000/000/000/000/001.png +0 -0
- mapproxy/test/system/fixture/cache_geopackage.yaml +56 -0
- mapproxy/test/system/fixture/cache_grid_names.yaml +50 -0
- mapproxy/test/system/fixture/cache_mbtiles.yaml +28 -0
- mapproxy/test/system/fixture/cache_s3.yaml +58 -0
- mapproxy/test/system/fixture/cache_source.yaml +81 -0
- mapproxy/test/system/fixture/combined_sources.yaml +130 -0
- mapproxy/test/system/fixture/coverage.yaml +77 -0
- mapproxy/test/system/fixture/demo.yaml +135 -0
- mapproxy/test/system/fixture/dimension.yaml +59 -0
- mapproxy/test/system/fixture/disable_storage.yaml +25 -0
- mapproxy/test/system/fixture/empty_ogrdata.geojson +1 -0
- mapproxy/test/system/fixture/formats.yaml +72 -0
- mapproxy/test/system/fixture/inspire.yaml +101 -0
- mapproxy/test/system/fixture/inspire_full.yaml +124 -0
- mapproxy/test/system/fixture/kml_layer.yaml +66 -0
- mapproxy/test/system/fixture/layer.yaml +260 -0
- mapproxy/test/system/fixture/layergroups.yaml +57 -0
- mapproxy/test/system/fixture/layergroups_root.yaml +106 -0
- mapproxy/test/system/fixture/legendgraphic.yaml +93 -0
- mapproxy/test/system/fixture/mapnik_source.yaml +66 -0
- mapproxy/test/system/fixture/mapproxy_export.yaml +12 -0
- mapproxy/test/system/fixture/mapserver.yaml +23 -0
- mapproxy/test/system/fixture/minimal_cgi.py +16 -0
- mapproxy/test/system/fixture/mixed_mode.yaml +49 -0
- mapproxy/test/system/fixture/multi_cache_layers.yaml +111 -0
- mapproxy/test/system/fixture/multiapp1.yaml +20 -0
- mapproxy/test/system/fixture/multiapp2.yaml +19 -0
- mapproxy/test/system/fixture/renderd_client.yaml +55 -0
- mapproxy/test/system/fixture/scalehints.yaml +70 -0
- mapproxy/test/system/fixture/seed.yaml +94 -0
- mapproxy/test/system/fixture/seed_mapproxy.yaml +39 -0
- mapproxy/test/system/fixture/seed_old.yaml +12 -0
- mapproxy/test/system/fixture/seed_timeouts.yaml +12 -0
- mapproxy/test/system/fixture/seed_timeouts_mapproxy.yaml +27 -0
- mapproxy/test/system/fixture/seedonly.yaml +51 -0
- mapproxy/test/system/fixture/sld.yaml +35 -0
- mapproxy/test/system/fixture/source_errors.yaml +84 -0
- mapproxy/test/system/fixture/source_errors_raise.yaml +82 -0
- mapproxy/test/system/fixture/tileservice_origin.yaml +26 -0
- mapproxy/test/system/fixture/tileservice_refresh.yaml +59 -0
- mapproxy/test/system/fixture/tilesource_minmax_res.yaml +22 -0
- mapproxy/test/system/fixture/util-conf-base-grids.yaml +5 -0
- mapproxy/test/system/fixture/util-conf-overwrite.yaml +13 -0
- mapproxy/test/system/fixture/util-conf-wms-111-cap.xml +90 -0
- mapproxy/test/system/fixture/util_grids.yaml +29 -0
- mapproxy/test/system/fixture/util_wms_capabilities111.xml +130 -0
- mapproxy/test/system/fixture/util_wms_capabilities130.xml +100 -0
- mapproxy/test/system/fixture/util_wms_capabilities_service_exception.xml +5 -0
- mapproxy/test/system/fixture/watermark.yaml +50 -0
- mapproxy/test/system/fixture/wms_srs_extent.yaml +39 -0
- mapproxy/test/system/fixture/wms_versions.yaml +38 -0
- mapproxy/test/system/fixture/wmts.yaml +134 -0
- mapproxy/test/system/fixture/wmts_dimensions.yaml +57 -0
- mapproxy/test/system/fixture/xslt_featureinfo.yaml +54 -0
- mapproxy/test/system/fixture/xslt_featureinfo_input.yaml +51 -0
- mapproxy/test/system/test_arcgis.py +156 -0
- mapproxy/test/system/test_auth.py +1133 -0
- mapproxy/test/system/test_behind_proxy.py +75 -0
- mapproxy/test/system/test_bulk_meta_tiles.py +106 -0
- mapproxy/test/system/test_cache_azureblob.py +127 -0
- mapproxy/test/system/test_cache_band_merge.py +103 -0
- mapproxy/test/system/test_cache_coverage.py +168 -0
- mapproxy/test/system/test_cache_geopackage.py +144 -0
- mapproxy/test/system/test_cache_grid_names.py +89 -0
- mapproxy/test/system/test_cache_mbtiles.py +85 -0
- mapproxy/test/system/test_cache_s3.py +115 -0
- mapproxy/test/system/test_cache_source.py +146 -0
- mapproxy/test/system/test_combined_sources.py +335 -0
- mapproxy/test/system/test_coverage.py +140 -0
- mapproxy/test/system/test_decorate_img.py +214 -0
- mapproxy/test/system/test_demo.py +56 -0
- mapproxy/test/system/test_demo_with_extra_service.py +57 -0
- mapproxy/test/system/test_dimensions.py +279 -0
- mapproxy/test/system/test_disable_storage.py +42 -0
- mapproxy/test/system/test_formats.py +219 -0
- mapproxy/test/system/test_inspire_vs.py +173 -0
- mapproxy/test/system/test_kml.py +264 -0
- mapproxy/test/system/test_layergroups.py +160 -0
- mapproxy/test/system/test_legendgraphic.py +308 -0
- mapproxy/test/system/test_mapnik.py +162 -0
- mapproxy/test/system/test_mapserver.py +83 -0
- mapproxy/test/system/test_mixed_mode_format.py +201 -0
- mapproxy/test/system/test_multi_cache_layers.py +169 -0
- mapproxy/test/system/test_multiapp.py +92 -0
- mapproxy/test/system/test_refresh.py +206 -0
- mapproxy/test/system/test_renderd_client.py +304 -0
- mapproxy/test/system/test_response_headers.py +54 -0
- mapproxy/test/system/test_scalehints.py +140 -0
- mapproxy/test/system/test_seed.py +425 -0
- mapproxy/test/system/test_seed_only.py +93 -0
- mapproxy/test/system/test_sld.py +120 -0
- mapproxy/test/system/test_source_errors.py +377 -0
- mapproxy/test/system/test_tilesource_minmax_res.py +54 -0
- mapproxy/test/system/test_tms.py +277 -0
- mapproxy/test/system/test_tms_origin.py +46 -0
- mapproxy/test/system/test_util_conf.py +434 -0
- mapproxy/test/system/test_util_export.py +210 -0
- mapproxy/test/system/test_util_grids.py +88 -0
- mapproxy/test/system/test_util_wms_capabilities.py +182 -0
- mapproxy/test/system/test_watermark.py +91 -0
- mapproxy/test/system/test_wms.py +1616 -0
- mapproxy/test/system/test_wms_srs_extent.py +165 -0
- mapproxy/test/system/test_wms_version.py +85 -0
- mapproxy/test/system/test_wmsc.py +116 -0
- mapproxy/test/system/test_wmts.py +334 -0
- mapproxy/test/system/test_wmts_dimensions.py +206 -0
- mapproxy/test/system/test_wmts_restful.py +198 -0
- mapproxy/test/system/test_xslt_featureinfo.py +423 -0
- mapproxy/test/test_http_helper.py +217 -0
- mapproxy/test/unit/__init__.py +0 -0
- mapproxy/test/unit/epsg +2 -0
- mapproxy/test/unit/polygons/polygons.dbf +0 -0
- mapproxy/test/unit/polygons/polygons.shp +0 -0
- mapproxy/test/unit/polygons/polygons.shx +0 -0
- mapproxy/test/unit/test_async.py +242 -0
- mapproxy/test/unit/test_auth.py +430 -0
- mapproxy/test/unit/test_cache.py +1356 -0
- mapproxy/test/unit/test_cache_azureblob.py +97 -0
- mapproxy/test/unit/test_cache_compact.py +324 -0
- mapproxy/test/unit/test_cache_couchdb.py +118 -0
- mapproxy/test/unit/test_cache_geopackage.py +256 -0
- mapproxy/test/unit/test_cache_redis.py +123 -0
- mapproxy/test/unit/test_cache_riak.py +80 -0
- mapproxy/test/unit/test_cache_s3.py +93 -0
- mapproxy/test/unit/test_cache_tile.py +477 -0
- mapproxy/test/unit/test_client.py +488 -0
- mapproxy/test/unit/test_client_arcgis.py +74 -0
- mapproxy/test/unit/test_client_cgi.py +140 -0
- mapproxy/test/unit/test_collections.py +116 -0
- mapproxy/test/unit/test_concat_legends.py +37 -0
- mapproxy/test/unit/test_conf_loader.py +1267 -0
- mapproxy/test/unit/test_conf_validator.py +427 -0
- mapproxy/test/unit/test_config.py +118 -0
- mapproxy/test/unit/test_decorate_img.py +185 -0
- mapproxy/test/unit/test_exceptions.py +270 -0
- mapproxy/test/unit/test_featureinfo.py +313 -0
- mapproxy/test/unit/test_file_lock_load.py +49 -0
- mapproxy/test/unit/test_geom.py +512 -0
- mapproxy/test/unit/test_grid.py +1279 -0
- mapproxy/test/unit/test_image.py +1051 -0
- mapproxy/test/unit/test_image_mask.py +181 -0
- mapproxy/test/unit/test_image_messages.py +209 -0
- mapproxy/test/unit/test_image_options.py +160 -0
- mapproxy/test/unit/test_isodate.py +118 -0
- mapproxy/test/unit/test_multiapp.py +163 -0
- mapproxy/test/unit/test_ogr_reader.py +51 -0
- mapproxy/test/unit/test_request.py +745 -0
- mapproxy/test/unit/test_request_wmts.py +178 -0
- mapproxy/test/unit/test_response.py +78 -0
- mapproxy/test/unit/test_seed.py +365 -0
- mapproxy/test/unit/test_seed_cachelock.py +91 -0
- mapproxy/test/unit/test_srs.py +215 -0
- mapproxy/test/unit/test_tiled_source.py +122 -0
- mapproxy/test/unit/test_tilefilter.py +31 -0
- mapproxy/test/unit/test_times.py +25 -0
- mapproxy/test/unit/test_timeutils.py +50 -0
- mapproxy/test/unit/test_util_conf_utils.py +75 -0
- mapproxy/test/unit/test_utils.py +476 -0
- mapproxy/test/unit/test_wms_capabilities.py +44 -0
- mapproxy/test/unit/test_wms_layer.py +113 -0
- mapproxy/test/unit/test_yaml.py +68 -0
- mapproxy/tilefilter.py +61 -0
- mapproxy/util/__init__.py +0 -0
- mapproxy/util/async_.py +229 -0
- mapproxy/util/collections.py +134 -0
- mapproxy/util/coverage.py +337 -0
- mapproxy/util/ext/__init__.py +14 -0
- mapproxy/util/ext/dictspec/__init__.py +1 -0
- mapproxy/util/ext/dictspec/spec.py +131 -0
- mapproxy/util/ext/dictspec/test/__init__.py +0 -0
- mapproxy/util/ext/dictspec/test/test_validator.py +278 -0
- mapproxy/util/ext/dictspec/validator.py +194 -0
- mapproxy/util/ext/local.py +198 -0
- mapproxy/util/ext/lockfile.py +140 -0
- mapproxy/util/ext/odict.py +321 -0
- mapproxy/util/ext/serving.py +491 -0
- mapproxy/util/ext/tempita/__init__.py +1093 -0
- mapproxy/util/ext/tempita/_looper.py +163 -0
- mapproxy/util/ext/tempita/string_utils.py +24 -0
- mapproxy/util/ext/wmsparse/__init__.py +3 -0
- mapproxy/util/ext/wmsparse/duration.py +600 -0
- mapproxy/util/ext/wmsparse/parse.py +307 -0
- mapproxy/util/ext/wmsparse/test/__init__.py +0 -0
- mapproxy/util/ext/wmsparse/test/test_parse.py +111 -0
- mapproxy/util/ext/wmsparse/test/test_util.py +23 -0
- mapproxy/util/ext/wmsparse/test/wms-example-111.xml +90 -0
- mapproxy/util/ext/wmsparse/test/wms-example-130.xml +120 -0
- mapproxy/util/ext/wmsparse/test/wms-large-111.xml +2114 -0
- mapproxy/util/ext/wmsparse/test/wms_nasa_cap.xml +386 -0
- mapproxy/util/ext/wmsparse/util.py +189 -0
- mapproxy/util/fs.py +164 -0
- mapproxy/util/geom.py +307 -0
- mapproxy/util/lib.py +117 -0
- mapproxy/util/lock.py +171 -0
- mapproxy/util/ogr.py +247 -0
- mapproxy/util/py.py +75 -0
- mapproxy/util/times.py +78 -0
- mapproxy/util/yaml.py +58 -0
- mapproxy/version.py +33 -0
- mapproxy/wsgiapp.py +167 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# This file is part of the MapProxy project.
|
|
2
|
+
# Copyright (C) 2010 Omniscale <http://omniscale.de>
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
from __future__ import division
|
|
17
|
+
|
|
18
|
+
from contextlib import contextmanager
|
|
19
|
+
from io import BytesIO
|
|
20
|
+
|
|
21
|
+
import pytest
|
|
22
|
+
|
|
23
|
+
from mapproxy.compat.image import Image, ImageDraw, ImageColor
|
|
24
|
+
from mapproxy.request.wms import WMS111MapRequest
|
|
25
|
+
from mapproxy.request.wmts import WMTS100TileRequest
|
|
26
|
+
from mapproxy.test.image import check_format, is_transparent
|
|
27
|
+
from mapproxy.test.http import mock_httpd
|
|
28
|
+
from mapproxy.test.system import SysTest
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.fixture(scope="module")
|
|
32
|
+
def config_file():
|
|
33
|
+
return "mixed_mode.yaml"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class TestWMS(SysTest):
|
|
37
|
+
|
|
38
|
+
def setup_method(self):
|
|
39
|
+
self.common_map_req = WMS111MapRequest(
|
|
40
|
+
url="/service?",
|
|
41
|
+
param=dict(
|
|
42
|
+
service="WMS",
|
|
43
|
+
version="1.1.1",
|
|
44
|
+
bbox="0,0,180,80",
|
|
45
|
+
width="200",
|
|
46
|
+
height="200",
|
|
47
|
+
layers="mixed_mode",
|
|
48
|
+
srs="EPSG:4326",
|
|
49
|
+
format="image/png",
|
|
50
|
+
styles="",
|
|
51
|
+
request="GetMap",
|
|
52
|
+
transparent="true",
|
|
53
|
+
),
|
|
54
|
+
)
|
|
55
|
+
self.expected_base_path = "/service?SERVICE=WMS&REQUEST=GetMap&HEIGHT=256"\
|
|
56
|
+
"&SRS=EPSG%3A900913&styles=&VERSION=1.1.1&WIDTH=512"\
|
|
57
|
+
"&BBOX=-20037508.3428,0.0,20037508.3428,20037508.3428"
|
|
58
|
+
|
|
59
|
+
def test_mixed_mode(self, app, cache_dir):
|
|
60
|
+
req_format = "png"
|
|
61
|
+
transparent = "True"
|
|
62
|
+
with create_mixed_mode_img((512, 256)) as img:
|
|
63
|
+
expected_req = (
|
|
64
|
+
{
|
|
65
|
+
"path": self.expected_base_path
|
|
66
|
+
+ "&layers=mixedsource"
|
|
67
|
+
+ "&format=image%2F"
|
|
68
|
+
+ req_format
|
|
69
|
+
+ "&transparent="
|
|
70
|
+
+ transparent
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"body": img.read(),
|
|
74
|
+
"headers": {"content-type": "image/" + req_format},
|
|
75
|
+
},
|
|
76
|
+
)
|
|
77
|
+
with mock_httpd(
|
|
78
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
79
|
+
):
|
|
80
|
+
self.common_map_req.params["format"] = "image/" + req_format
|
|
81
|
+
resp = app.get(self.common_map_req)
|
|
82
|
+
|
|
83
|
+
assert resp.content_type == "image/" + req_format
|
|
84
|
+
check_format(BytesIO(resp.body), req_format)
|
|
85
|
+
# GetMap Request is fully within the opaque tile
|
|
86
|
+
assert not is_transparent(resp.body)
|
|
87
|
+
|
|
88
|
+
# check cache formats
|
|
89
|
+
for f, format in [
|
|
90
|
+
["mixed_cache_EPSG900913/01/000/000/000/000/000/001.mixed", "png"],
|
|
91
|
+
["mixed_cache_EPSG900913/01/000/000/001/000/000/001.mixed", "jpeg"],
|
|
92
|
+
]:
|
|
93
|
+
assert cache_dir.join(f).check()
|
|
94
|
+
check_format(cache_dir.join(f).read_binary(), format)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class TestTMS(SysTest):
|
|
98
|
+
|
|
99
|
+
def setup_method(self):
|
|
100
|
+
self.expected_base_path = "/service?SERVICE=WMS&REQUEST=GetMap&HEIGHT=256"\
|
|
101
|
+
"&SRS=EPSG%3A900913&styles=&VERSION=1.1.1&WIDTH=512"\
|
|
102
|
+
"&BBOX=-20037508.3428,-20037508.3428,20037508.3428,0.0"
|
|
103
|
+
|
|
104
|
+
def test_mixed_mode(self, app, cache_dir):
|
|
105
|
+
with create_mixed_mode_img((512, 256)) as img:
|
|
106
|
+
expected_req = (
|
|
107
|
+
{
|
|
108
|
+
"path": self.expected_base_path
|
|
109
|
+
+ "&layers=mixedsource"
|
|
110
|
+
+ "&format=image%2Fpng"
|
|
111
|
+
+ "&transparent=True"
|
|
112
|
+
},
|
|
113
|
+
{"body": img.read(), "headers": {"content-type": "image/png"}},
|
|
114
|
+
)
|
|
115
|
+
with mock_httpd(
|
|
116
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
117
|
+
):
|
|
118
|
+
resp = app.get("/tms/1.0.0/mixed_mode/0/0/0.png")
|
|
119
|
+
assert resp.content_type == "image/png"
|
|
120
|
+
assert is_transparent(resp.body)
|
|
121
|
+
|
|
122
|
+
resp = app.get("/tms/1.0.0/mixed_mode/0/1/0.png")
|
|
123
|
+
|
|
124
|
+
assert resp.content_type == "image/jpeg"
|
|
125
|
+
assert cache_dir.join(
|
|
126
|
+
"mixed_cache_EPSG900913/01/000/000/000/000/000/000.mixed"
|
|
127
|
+
).check()
|
|
128
|
+
assert cache_dir.join(
|
|
129
|
+
"mixed_cache_EPSG900913/01/000/000/001/000/000/000.mixed"
|
|
130
|
+
).check()
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class TestWMTS(SysTest):
|
|
134
|
+
|
|
135
|
+
def setup_method(self):
|
|
136
|
+
self.common_tile_req = WMTS100TileRequest(
|
|
137
|
+
url="/service?",
|
|
138
|
+
param=dict(
|
|
139
|
+
service="WMTS",
|
|
140
|
+
version="1.0.0",
|
|
141
|
+
tilerow="0",
|
|
142
|
+
tilecol="0",
|
|
143
|
+
tilematrix="01",
|
|
144
|
+
tilematrixset="GLOBAL_MERCATOR",
|
|
145
|
+
layer="mixed_mode",
|
|
146
|
+
format="image/png",
|
|
147
|
+
style="",
|
|
148
|
+
request="GetTile",
|
|
149
|
+
transparent="True",
|
|
150
|
+
),
|
|
151
|
+
)
|
|
152
|
+
self.expected_base_path = "/service?SERVICE=WMS&REQUEST=GetMap&HEIGHT=256"\
|
|
153
|
+
"&SRS=EPSG%3A900913&styles=&VERSION=1.1.1&WIDTH=512"\
|
|
154
|
+
"&BBOX=-20037508.3428,0.0,20037508.3428,20037508.3428"
|
|
155
|
+
|
|
156
|
+
def test_mixed_mode(self, app, cache_dir):
|
|
157
|
+
with create_mixed_mode_img((512, 256)) as img:
|
|
158
|
+
expected_req = (
|
|
159
|
+
{
|
|
160
|
+
"path": self.expected_base_path
|
|
161
|
+
+ "&layers=mixedsource"
|
|
162
|
+
+ "&format=image%2Fpng"
|
|
163
|
+
+ "&transparent=True"
|
|
164
|
+
},
|
|
165
|
+
{"body": img.read(), "headers": {"content-type": "image/png"}},
|
|
166
|
+
)
|
|
167
|
+
with mock_httpd(
|
|
168
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
169
|
+
):
|
|
170
|
+
resp = app.get(self.common_tile_req)
|
|
171
|
+
assert resp.content_type == "image/png"
|
|
172
|
+
assert is_transparent(resp.body)
|
|
173
|
+
|
|
174
|
+
self.common_tile_req.params["tilecol"] = "1"
|
|
175
|
+
resp = app.get(self.common_tile_req)
|
|
176
|
+
assert resp.content_type == "image/jpeg"
|
|
177
|
+
assert cache_dir.join(
|
|
178
|
+
"mixed_cache_EPSG900913/01/000/000/000/000/000/001.mixed"
|
|
179
|
+
).check()
|
|
180
|
+
assert cache_dir.join(
|
|
181
|
+
"mixed_cache_EPSG900913/01/000/000/001/000/000/001.mixed"
|
|
182
|
+
).check()
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@contextmanager
|
|
186
|
+
def create_mixed_mode_img(size, format="png"):
|
|
187
|
+
img = Image.new("RGBA", size)
|
|
188
|
+
|
|
189
|
+
# draw a black rectangle into the image, rect_width = 3/4 img_width
|
|
190
|
+
# thus 1/4 of the image is transparent and with square tiles, one of two
|
|
191
|
+
# tiles (img size = 512x256) will be fully opaque and the other
|
|
192
|
+
# has transparency
|
|
193
|
+
draw = ImageDraw.Draw(img)
|
|
194
|
+
w, h = size
|
|
195
|
+
red_color = ImageColor.getrgb("red")
|
|
196
|
+
draw.rectangle((w / 4, 0, w, h), fill=red_color)
|
|
197
|
+
|
|
198
|
+
data = BytesIO()
|
|
199
|
+
img.save(data, format)
|
|
200
|
+
data.seek(0)
|
|
201
|
+
yield data
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# -:- encoding: utf8 -:-
|
|
2
|
+
# This file is part of the MapProxy project.
|
|
3
|
+
# Copyright (C) 2015 Omniscale <http://omniscale.de>
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
from __future__ import division
|
|
18
|
+
|
|
19
|
+
from io import BytesIO
|
|
20
|
+
|
|
21
|
+
import pytest
|
|
22
|
+
|
|
23
|
+
from mapproxy.request.wmts import WMTS100TileRequest, WMTS100CapabilitiesRequest
|
|
24
|
+
from mapproxy.request.wms import WMS111CapabilitiesRequest
|
|
25
|
+
from mapproxy.test.image import is_png, create_tmp_image
|
|
26
|
+
from mapproxy.test.http import MockServ
|
|
27
|
+
from mapproxy.test.helper import validate_with_xsd
|
|
28
|
+
from mapproxy.test.system import SysTest
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.fixture(scope="module")
|
|
32
|
+
def config_file():
|
|
33
|
+
return "multi_cache_layers.yaml"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
ns_wmts = {
|
|
37
|
+
"wmts": "http://www.opengis.net/wmts/1.0",
|
|
38
|
+
"ows": "http://www.opengis.net/ows/1.1",
|
|
39
|
+
"xlink": "http://www.w3.org/1999/xlink",
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
TEST_TILE = create_tmp_image((256, 256))
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class TestMultiCacheLayer(SysTest):
|
|
47
|
+
|
|
48
|
+
def setup_method(self):
|
|
49
|
+
self.common_cap_req = WMTS100CapabilitiesRequest(
|
|
50
|
+
url="/service?",
|
|
51
|
+
param=dict(service="WMTS", version="1.0.0", request="GetCapabilities"),
|
|
52
|
+
)
|
|
53
|
+
self.common_tile_req = WMTS100TileRequest(
|
|
54
|
+
url="/service?",
|
|
55
|
+
param=dict(
|
|
56
|
+
service="WMTS",
|
|
57
|
+
version="1.0.0",
|
|
58
|
+
tilerow="0",
|
|
59
|
+
tilecol="0",
|
|
60
|
+
tilematrix="01",
|
|
61
|
+
tilematrixset="GLOBAL_WEBMERCATOR",
|
|
62
|
+
layer="multi_cache",
|
|
63
|
+
format="image/png",
|
|
64
|
+
style="",
|
|
65
|
+
request="GetTile",
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def test_image_config(self, app):
|
|
70
|
+
resp = app.get("/tms/1.0.0/")
|
|
71
|
+
assert "http://localhost/tms/1.0.0/cache_image/EPSG25832" in resp
|
|
72
|
+
|
|
73
|
+
def test_tms_capabilities(self, app):
|
|
74
|
+
resp = app.get("/tms/1.0.0/")
|
|
75
|
+
assert "http://localhost/tms/1.0.0/multi_cache/EPSG25832" in resp
|
|
76
|
+
assert "http://localhost/tms/1.0.0/multi_cache/EPSG3857" in resp
|
|
77
|
+
assert "http://localhost/tms/1.0.0/multi_cache/CRS84" in resp
|
|
78
|
+
assert "http://localhost/tms/1.0.0/multi_cache/EPSG31467" in resp
|
|
79
|
+
assert "http://localhost/tms/1.0.0/cache/EPSG25832" in resp
|
|
80
|
+
xml = resp.lxml
|
|
81
|
+
assert xml.xpath("count(//TileMap)") == 8
|
|
82
|
+
|
|
83
|
+
def test_wmts_capabilities(self, app):
|
|
84
|
+
req = str(self.common_cap_req)
|
|
85
|
+
resp = app.get(req)
|
|
86
|
+
assert resp.content_type == "application/xml"
|
|
87
|
+
xml = resp.lxml
|
|
88
|
+
|
|
89
|
+
assert validate_with_xsd(
|
|
90
|
+
xml, xsd_name="wmts/1.0/wmtsGetCapabilities_response.xsd"
|
|
91
|
+
)
|
|
92
|
+
assert set(
|
|
93
|
+
xml.xpath("//wmts:Layer/ows:Identifier/text()", namespaces=ns_wmts)
|
|
94
|
+
) == set(["cache", "multi_cache", "cache_image"])
|
|
95
|
+
assert set(
|
|
96
|
+
xml.xpath(
|
|
97
|
+
"//wmts:Contents/wmts:TileMatrixSet/ows:Identifier/text()",
|
|
98
|
+
namespaces=ns_wmts,
|
|
99
|
+
)
|
|
100
|
+
) == set(["gk3", "GLOBAL_WEBMERCATOR", "utm32", "InspireCrs84Quad"])
|
|
101
|
+
|
|
102
|
+
def test_wms_capabilities(self, app):
|
|
103
|
+
req = WMS111CapabilitiesRequest(url="/service?")
|
|
104
|
+
resp = app.get(req)
|
|
105
|
+
assert resp.content_type == "application/vnd.ogc.wms_xml"
|
|
106
|
+
xml = resp.lxml
|
|
107
|
+
assert (
|
|
108
|
+
xml.xpath(
|
|
109
|
+
"//GetMap//OnlineResource/@xlink:href",
|
|
110
|
+
namespaces=dict(xlink="http://www.w3.org/1999/xlink"),
|
|
111
|
+
)[0]
|
|
112
|
+
== "http://localhost/service?"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
layer_names = set(xml.xpath("//Layer/Layer/Name/text()"))
|
|
116
|
+
expected_names = set(["wms_only", "cache", "cache_image"])
|
|
117
|
+
assert layer_names == expected_names
|
|
118
|
+
|
|
119
|
+
def test_get_tile_webmerc(self, app):
|
|
120
|
+
serv = MockServ(42423, bbox_aware_query_comparator=True)
|
|
121
|
+
serv.expects(
|
|
122
|
+
"/service?layers=foo,bar&width=256&version=1.1.1&bbox=-20037508.3428,0.0,0.0,20037508.3428&service=WMS&format=image%2Fpng&styles=&srs=EPSG%3A3857&request=GetMap&height=256" # noqa
|
|
123
|
+
).returns(TEST_TILE)
|
|
124
|
+
with serv:
|
|
125
|
+
resp = app.get(str(self.common_tile_req))
|
|
126
|
+
assert resp.content_type == "image/png"
|
|
127
|
+
data = BytesIO(resp.body)
|
|
128
|
+
assert is_png(data)
|
|
129
|
+
|
|
130
|
+
def test_get_tile_utm(self, app):
|
|
131
|
+
serv = MockServ(42423, bbox_aware_query_comparator=True)
|
|
132
|
+
serv.expects(
|
|
133
|
+
"/service?layers=foo,bar&width=256&version=1.1.1&bbox=-46133.17,5675047.40429,580038.965712,6301219.54&service=WMS&format=image%2Fpng&styles=&srs=EPSG%3A25832&request=GetMap&height=256" # noqa
|
|
134
|
+
).returns(TEST_TILE)
|
|
135
|
+
self.common_tile_req.params["tilematrixset"] = "utm32"
|
|
136
|
+
|
|
137
|
+
with serv:
|
|
138
|
+
resp = app.get(str(self.common_tile_req))
|
|
139
|
+
assert resp.content_type == "image/png"
|
|
140
|
+
data = BytesIO(resp.body)
|
|
141
|
+
assert is_png(data)
|
|
142
|
+
|
|
143
|
+
def test_get_tile_cascaded_cache(self, app):
|
|
144
|
+
serv = MockServ(42423, bbox_aware_query_comparator=True, unordered=True)
|
|
145
|
+
# gk3 cache requests UTM tiles
|
|
146
|
+
serv.expects(
|
|
147
|
+
"/service?layers=foo,bar&width=256&version=1.1.1&bbox=423495.931784,5596775.88732,501767.448748,5675047.40429&service=WMS&format=image%2Fpng&styles=&srs=EPSG%3A25832&request=GetMap&height=256" # noqa
|
|
148
|
+
).returns(TEST_TILE)
|
|
149
|
+
serv.expects(
|
|
150
|
+
"/service?layers=foo,bar&width=256&version=1.1.1&bbox=345224.41482,5596775.88732,423495.931784,5675047.40429&service=WMS&format=image%2Fpng&styles=&srs=EPSG%3A25832&request=GetMap&height=256" # noqa
|
|
151
|
+
).returns(TEST_TILE)
|
|
152
|
+
serv.expects(
|
|
153
|
+
"/service?layers=foo,bar&width=256&version=1.1.1&bbox=345224.41482,5518504.37036,423495.931784,5596775.88732&service=WMS&format=image%2Fpng&styles=&srs=EPSG%3A25832&request=GetMap&height=256" # noqa
|
|
154
|
+
).returns(TEST_TILE)
|
|
155
|
+
serv.expects(
|
|
156
|
+
"/service?layers=foo,bar&width=256&version=1.1.1&bbox=423495.931784,5518504.37036,501767.448748,5596775.88732&service=WMS&format=image%2Fpng&styles=&srs=EPSG%3A25832&request=GetMap&height=256" # noqa
|
|
157
|
+
).returns(TEST_TILE)
|
|
158
|
+
serv.expects(
|
|
159
|
+
"/service?layers=foo,bar&width=256&version=1.1.1&bbox=345224.41482,5440232.8534,423495.931784,5518504.37036&service=WMS&format=image%2Fpng&styles=&srs=EPSG%3A25832&request=GetMap&height=256" # noqa
|
|
160
|
+
).returns(TEST_TILE)
|
|
161
|
+
serv.expects(
|
|
162
|
+
"/service?layers=foo,bar&width=256&version=1.1.1&bbox=423495.931784,5440232.8534,501767.448748,5518504.37036&service=WMS&format=image%2Fpng&styles=&srs=EPSG%3A25832&request=GetMap&height=256" # noqa
|
|
163
|
+
).returns(TEST_TILE)
|
|
164
|
+
self.common_tile_req.params["tilematrixset"] = "gk3"
|
|
165
|
+
with serv:
|
|
166
|
+
resp = app.get(str(self.common_tile_req))
|
|
167
|
+
assert resp.content_type == "image/png"
|
|
168
|
+
data = BytesIO(resp.body)
|
|
169
|
+
assert is_png(data)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# This file is part of the MapProxy project.
|
|
2
|
+
# Copyright (C) 2010 Omniscale <http://omniscale.de>
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
from __future__ import division
|
|
17
|
+
|
|
18
|
+
import io
|
|
19
|
+
import os
|
|
20
|
+
import shutil
|
|
21
|
+
|
|
22
|
+
import pytest
|
|
23
|
+
|
|
24
|
+
from mapproxy.multiapp import make_wsgi_app
|
|
25
|
+
|
|
26
|
+
from mapproxy.test.system import SysTest, WSGITestApp
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TestMultiapp(SysTest):
|
|
30
|
+
|
|
31
|
+
@pytest.fixture(scope="class")
|
|
32
|
+
def app(self, base_dir):
|
|
33
|
+
app = make_wsgi_app(base_dir.strpath, allow_listing=False)
|
|
34
|
+
return WSGITestApp(app, use_unicode=False)
|
|
35
|
+
|
|
36
|
+
@pytest.fixture(scope="class")
|
|
37
|
+
def base_dir(self, tmpdir_factory):
|
|
38
|
+
dir = tmpdir_factory.mktemp("base_dir")
|
|
39
|
+
|
|
40
|
+
fixture_dir = os.path.join(os.path.dirname(__file__), "fixture")
|
|
41
|
+
shutil.copy(os.path.join(fixture_dir, "multiapp1.yaml"), dir.strpath)
|
|
42
|
+
shutil.copy(os.path.join(fixture_dir, "multiapp2.yaml"), dir.strpath)
|
|
43
|
+
|
|
44
|
+
return dir
|
|
45
|
+
|
|
46
|
+
def test_index_without_list(self, app):
|
|
47
|
+
resp = app.get("/")
|
|
48
|
+
assert "MapProxy" in resp
|
|
49
|
+
assert "multiapp1" not in resp
|
|
50
|
+
|
|
51
|
+
def test_index_with_list(self, app):
|
|
52
|
+
try:
|
|
53
|
+
app.app.list_apps = True
|
|
54
|
+
resp = app.get("/")
|
|
55
|
+
assert "MapProxy" in resp
|
|
56
|
+
assert "multiapp1" in resp
|
|
57
|
+
finally:
|
|
58
|
+
app.app.list_apps = False
|
|
59
|
+
|
|
60
|
+
def test_unknown_app(self, app):
|
|
61
|
+
app.get("/unknownapp", status=404)
|
|
62
|
+
# assert status == 404 Not Found in app.get
|
|
63
|
+
|
|
64
|
+
def test_known_app(self, app):
|
|
65
|
+
resp = app.get("/multiapp1")
|
|
66
|
+
assert "demo" in resp
|
|
67
|
+
|
|
68
|
+
def test_reloading(self, app, base_dir):
|
|
69
|
+
resp = app.get("/multiapp1")
|
|
70
|
+
assert "demo" in resp
|
|
71
|
+
app_config = base_dir.join("multiapp1.yaml").strpath
|
|
72
|
+
|
|
73
|
+
replace_text_in_file(app_config, " demo:", " #demo:", ts_delta=5)
|
|
74
|
+
|
|
75
|
+
resp = app.get("/multiapp1")
|
|
76
|
+
assert "demo" not in resp
|
|
77
|
+
|
|
78
|
+
replace_text_in_file(app_config, " #demo:", " demo:", ts_delta=10)
|
|
79
|
+
|
|
80
|
+
resp = app.get("/multiapp1")
|
|
81
|
+
assert "demo" in resp
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def replace_text_in_file(filename, old, new, ts_delta=2):
|
|
85
|
+
text = io.open(filename, encoding="utf-8").read()
|
|
86
|
+
text = text.replace(old, new)
|
|
87
|
+
io.open(filename, "w", encoding="utf-8").write(text)
|
|
88
|
+
|
|
89
|
+
# file timestamps are not precise enough (1sec)
|
|
90
|
+
# add larger delta to force reload
|
|
91
|
+
m_time = os.path.getmtime(filename)
|
|
92
|
+
os.utime(filename, (m_time + ts_delta, m_time + ts_delta))
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# This file is part of the MapProxy project.
|
|
2
|
+
# Copyright (C) 2010-2012 Omniscale <http://omniscale.de>
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import time
|
|
17
|
+
|
|
18
|
+
from io import BytesIO
|
|
19
|
+
import pytest
|
|
20
|
+
|
|
21
|
+
from mapproxy.compat.image import Image
|
|
22
|
+
from mapproxy.test.image import tmp_image
|
|
23
|
+
from mapproxy.test.http import mock_httpd
|
|
24
|
+
from mapproxy.test.system import SysTest
|
|
25
|
+
from mapproxy.util.times import timestamp_from_isodate
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@pytest.fixture(scope="module")
|
|
29
|
+
def config_file():
|
|
30
|
+
return "tileservice_refresh.yaml"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class TestRefresh(SysTest):
|
|
34
|
+
|
|
35
|
+
def test_refresh_tile_1s(self, app, cache_dir):
|
|
36
|
+
with tmp_image((256, 256), format="jpeg") as img:
|
|
37
|
+
expected_req = (
|
|
38
|
+
{
|
|
39
|
+
"path": r"/service?LAYERs=bar&SERVICE=WMS&FORMAT=image%2Fjpeg"
|
|
40
|
+
"&REQUEST=GetMap&HEIGHT=256&SRS=EPSG%3A900913&styles="
|
|
41
|
+
"&VERSION=1.1.1&BBOX=-20037508.3428,-20037508.3428,0.0,0.0"
|
|
42
|
+
"&WIDTH=256"
|
|
43
|
+
},
|
|
44
|
+
{"body": img.read(), "headers": {"content-type": "image/jpeg"}},
|
|
45
|
+
)
|
|
46
|
+
with mock_httpd(
|
|
47
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
48
|
+
):
|
|
49
|
+
resp = app.get("/tiles/wms_cache/1/0/0.jpeg")
|
|
50
|
+
assert resp.content_type == "image/jpeg"
|
|
51
|
+
file_path = cache_dir.join(
|
|
52
|
+
"wms_cache_EPSG900913/01/000/000/000/000/000/000.jpeg"
|
|
53
|
+
)
|
|
54
|
+
assert file_path.check()
|
|
55
|
+
t1 = file_path.mtime()
|
|
56
|
+
# file_path.remove()
|
|
57
|
+
# assert not file_path.check()
|
|
58
|
+
resp = app.get("/tiles/wms_cache/1/0/0.jpeg")
|
|
59
|
+
assert resp.content_type == "image/jpeg"
|
|
60
|
+
assert file_path.check()
|
|
61
|
+
t2 = file_path.mtime()
|
|
62
|
+
# tile is expired after 1 sec, so it will be fetched again from mock server
|
|
63
|
+
time.sleep(1.2)
|
|
64
|
+
with mock_httpd(
|
|
65
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
66
|
+
):
|
|
67
|
+
resp = app.get("/tiles/wms_cache/1/0/0.jpeg")
|
|
68
|
+
assert resp.content_type == "image/jpeg"
|
|
69
|
+
assert file_path.check()
|
|
70
|
+
t3 = file_path.mtime()
|
|
71
|
+
assert t2 == t1
|
|
72
|
+
assert t3 > t2
|
|
73
|
+
|
|
74
|
+
def test_refresh_tile_mtime(self, app, cache_dir):
|
|
75
|
+
with tmp_image((256, 256), format="jpeg") as img:
|
|
76
|
+
expected_req = (
|
|
77
|
+
{
|
|
78
|
+
"path": r"/service?LAYERs=bar&SERVICE=WMS&FORMAT=image%2Fjpeg"
|
|
79
|
+
"&REQUEST=GetMap&HEIGHT=256&SRS=EPSG%3A900913&styles="
|
|
80
|
+
"&VERSION=1.1.1&BBOX=-20037508.3428,-20037508.3428,0.0,0.0"
|
|
81
|
+
"&WIDTH=256"
|
|
82
|
+
},
|
|
83
|
+
{"body": img.read(), "headers": {"content-type": "image/jpeg"}},
|
|
84
|
+
)
|
|
85
|
+
with mock_httpd(
|
|
86
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
87
|
+
):
|
|
88
|
+
resp = app.get("/tiles/wms_cache_isotime/1/0/0.jpeg")
|
|
89
|
+
assert resp.content_type == "image/jpeg"
|
|
90
|
+
file_path = cache_dir.join(
|
|
91
|
+
"wms_cache_isotime_EPSG900913/01/000/000/000/000/000/000.jpeg"
|
|
92
|
+
)
|
|
93
|
+
assert file_path.check()
|
|
94
|
+
timestamp = timestamp_from_isodate("2009-02-15T23:31:30")
|
|
95
|
+
file_path.setmtime(timestamp + 1.2)
|
|
96
|
+
t1 = file_path.mtime()
|
|
97
|
+
resp = app.get("/tiles/wms_cache_isotime/1/0/0.jpeg")
|
|
98
|
+
assert resp.content_type == "image/jpeg"
|
|
99
|
+
t2 = file_path.mtime()
|
|
100
|
+
file_path.setmtime(timestamp - 1.2)
|
|
101
|
+
with mock_httpd(
|
|
102
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
103
|
+
):
|
|
104
|
+
resp = app.get("/tiles/wms_cache_isotime/1/0/0.jpeg")
|
|
105
|
+
assert resp.content_type == "image/jpeg"
|
|
106
|
+
assert file_path.check()
|
|
107
|
+
t3 = file_path.mtime()
|
|
108
|
+
assert t2 == t1
|
|
109
|
+
assert t3 > t2
|
|
110
|
+
|
|
111
|
+
def test_refresh_tile_source_error_no_stale(self, app, cache_dir):
|
|
112
|
+
source_request = {
|
|
113
|
+
"path": r"/service?LAYERs=bar&SERVICE=WMS&FORMAT=image%2Fpng"
|
|
114
|
+
"&REQUEST=GetMap&HEIGHT=256&SRS=EPSG%3A900913&styles="
|
|
115
|
+
"&VERSION=1.1.1&BBOX=-20037508.3428,-20037508.3428,0.0,0.0"
|
|
116
|
+
"&WIDTH=256"
|
|
117
|
+
}
|
|
118
|
+
with tmp_image((256, 256), format="png") as img:
|
|
119
|
+
expected_req = (
|
|
120
|
+
source_request,
|
|
121
|
+
{"body": img.read(), "headers": {"content-type": "image/png"}},
|
|
122
|
+
)
|
|
123
|
+
with mock_httpd(
|
|
124
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
125
|
+
):
|
|
126
|
+
resp = app.get("/tiles/wms_cache_png/1/0/0.png")
|
|
127
|
+
assert resp.content_type == "image/png"
|
|
128
|
+
img.seek(0)
|
|
129
|
+
assert resp.body == img.read()
|
|
130
|
+
resp = app.get("/tiles/wms_cache_png/1/0/0.png")
|
|
131
|
+
assert resp.content_type == "image/png"
|
|
132
|
+
img.seek(0)
|
|
133
|
+
assert resp.body == img.read()
|
|
134
|
+
# tile is expired after 1 sec, so it will be requested again from mock server
|
|
135
|
+
time.sleep(1.2)
|
|
136
|
+
expected_req = (
|
|
137
|
+
source_request,
|
|
138
|
+
{"body": "", "status": 404},
|
|
139
|
+
)
|
|
140
|
+
with mock_httpd(
|
|
141
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
142
|
+
):
|
|
143
|
+
resp = app.get("/tiles/wms_cache_png/1/0/0.png")
|
|
144
|
+
assert resp.content_type == "image/png"
|
|
145
|
+
# error handler for 404 does not authorise stale tiles, so transparent tile will be rendered
|
|
146
|
+
resp_img = Image.open(BytesIO(resp.body))
|
|
147
|
+
# check response transparency
|
|
148
|
+
assert resp_img.getbands() == ('R', 'G', 'B', 'A')
|
|
149
|
+
assert resp_img.getextrema()[3] == (0, 0)
|
|
150
|
+
|
|
151
|
+
expected_req = (
|
|
152
|
+
source_request,
|
|
153
|
+
{"body": "", "status": 405},
|
|
154
|
+
)
|
|
155
|
+
with mock_httpd(
|
|
156
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
157
|
+
):
|
|
158
|
+
resp = app.get("/tiles/wms_cache_png/1/0/0.png")
|
|
159
|
+
assert resp.content_type == "image/png"
|
|
160
|
+
# error handler for 405 does not authorise stale tiles, so red tile will be rendered
|
|
161
|
+
resp_img = Image.open(BytesIO(resp.body))
|
|
162
|
+
# check response red color
|
|
163
|
+
assert resp_img.getbands() == ('R', 'G', 'B')
|
|
164
|
+
assert resp_img.getextrema() == ((255, 255), (0, 0), (0, 0))
|
|
165
|
+
|
|
166
|
+
def test_refresh_tile_source_error_stale(self, app, cache_dir):
|
|
167
|
+
with tmp_image((256, 256), format="jpeg") as img:
|
|
168
|
+
expected_req = (
|
|
169
|
+
{
|
|
170
|
+
"path": r"/service?LAYERs=bar&SERVICE=WMS&FORMAT=image%2Fjpeg"
|
|
171
|
+
"&REQUEST=GetMap&HEIGHT=256&SRS=EPSG%3A900913&styles="
|
|
172
|
+
"&VERSION=1.1.1&BBOX=-20037508.3428,-20037508.3428,0.0,0.0"
|
|
173
|
+
"&WIDTH=256"
|
|
174
|
+
},
|
|
175
|
+
{"body": img.read(), "headers": {"content-type": "image/jpeg"}},
|
|
176
|
+
)
|
|
177
|
+
with mock_httpd(
|
|
178
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
179
|
+
):
|
|
180
|
+
resp = app.get("/tiles/wms_cache/1/0/0.jpeg")
|
|
181
|
+
assert resp.content_type == "image/jpeg"
|
|
182
|
+
img.seek(0)
|
|
183
|
+
assert resp.body == img.read()
|
|
184
|
+
resp = app.get("/tiles/wms_cache/1/0/0.jpeg")
|
|
185
|
+
assert resp.content_type == "image/jpeg"
|
|
186
|
+
img.seek(0)
|
|
187
|
+
assert resp.body == img.read()
|
|
188
|
+
# tile is expired after 1 sec, so it will be fetched again from mock server
|
|
189
|
+
time.sleep(1.2)
|
|
190
|
+
expected_req = (
|
|
191
|
+
{
|
|
192
|
+
"path": r"/service?LAYERs=bar&SERVICE=WMS&FORMAT=image%2Fjpeg"
|
|
193
|
+
"&REQUEST=GetMap&HEIGHT=256&SRS=EPSG%3A900913&styles="
|
|
194
|
+
"&VERSION=1.1.1&BBOX=-20037508.3428,-20037508.3428,0.0,0.0"
|
|
195
|
+
"&WIDTH=256"
|
|
196
|
+
},
|
|
197
|
+
{"body": "", "status": 406},
|
|
198
|
+
)
|
|
199
|
+
with mock_httpd(
|
|
200
|
+
("localhost", 42423), [expected_req], bbox_aware_query_comparator=True
|
|
201
|
+
):
|
|
202
|
+
resp = app.get("/tiles/wms_cache/1/0/0.jpeg")
|
|
203
|
+
assert resp.content_type == "image/jpeg"
|
|
204
|
+
# Check that initial non empty img is served as a stale tile
|
|
205
|
+
img.seek(0)
|
|
206
|
+
assert resp.body == img.read()
|