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,1267 @@
|
|
|
1
|
+
# -:- encoding: UTF8 -:-
|
|
2
|
+
# This file is part of the MapProxy project.
|
|
3
|
+
# Copyright (C) 2010 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
|
+
import copy
|
|
20
|
+
import time
|
|
21
|
+
from unittest import SkipTest
|
|
22
|
+
|
|
23
|
+
import yaml
|
|
24
|
+
import pytest
|
|
25
|
+
|
|
26
|
+
from mapproxy.config.coverage import load_coverage
|
|
27
|
+
from mapproxy.config.loader import (
|
|
28
|
+
ProxyConfiguration,
|
|
29
|
+
load_configuration,
|
|
30
|
+
merge_dict,
|
|
31
|
+
ConfigurationError,
|
|
32
|
+
)
|
|
33
|
+
from mapproxy.cache.tile import TileManager
|
|
34
|
+
from mapproxy.config.spec import validate_options
|
|
35
|
+
from mapproxy.layer import MapExtent
|
|
36
|
+
from mapproxy.seed.spec import validate_seed_conf
|
|
37
|
+
from mapproxy.srs import SRS
|
|
38
|
+
from mapproxy.test.helper import TempFile
|
|
39
|
+
from mapproxy.test.unit.test_grid import assert_almost_equal_bbox
|
|
40
|
+
from mapproxy.util.coverage import coverage
|
|
41
|
+
from mapproxy.util.geom import EmptyGeometryError
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class TestLayerConfiguration(object):
|
|
45
|
+
def _test_conf(self, yaml_part):
|
|
46
|
+
base = {'sources': {'s': {'type': 'wms', 'req': {'url': ''}}}}
|
|
47
|
+
base.update(yaml.safe_load(yaml_part))
|
|
48
|
+
return base
|
|
49
|
+
|
|
50
|
+
def test_legacy_ordered(self):
|
|
51
|
+
conf = self._test_conf('''
|
|
52
|
+
layers:
|
|
53
|
+
- one:
|
|
54
|
+
title: Layer One
|
|
55
|
+
sources: [s]
|
|
56
|
+
- two:
|
|
57
|
+
title: Layer Two
|
|
58
|
+
sources: [s]
|
|
59
|
+
- three:
|
|
60
|
+
title: Layer Three
|
|
61
|
+
sources: [s]
|
|
62
|
+
''')
|
|
63
|
+
with pytest.warns(RuntimeWarning):
|
|
64
|
+
conf = ProxyConfiguration(conf)
|
|
65
|
+
root = conf.wms_root_layer.wms_layer()
|
|
66
|
+
|
|
67
|
+
# no root layer defined
|
|
68
|
+
assert root.title is None
|
|
69
|
+
assert root.name is None
|
|
70
|
+
layers = root.child_layers()
|
|
71
|
+
|
|
72
|
+
# names are in order
|
|
73
|
+
assert layers.keys() == ['one', 'two', 'three']
|
|
74
|
+
|
|
75
|
+
assert len(layers) == 3
|
|
76
|
+
assert layers['one'].title == 'Layer One'
|
|
77
|
+
assert layers['two'].title == 'Layer Two'
|
|
78
|
+
assert layers['three'].title == 'Layer Three'
|
|
79
|
+
|
|
80
|
+
layers_conf = conf.layers
|
|
81
|
+
assert len(layers_conf) == 3
|
|
82
|
+
|
|
83
|
+
def test_legacy_unordered(self):
|
|
84
|
+
conf = self._test_conf('''
|
|
85
|
+
layers:
|
|
86
|
+
one:
|
|
87
|
+
title: Layer One
|
|
88
|
+
sources: [s]
|
|
89
|
+
two:
|
|
90
|
+
title: Layer Two
|
|
91
|
+
sources: [s]
|
|
92
|
+
three:
|
|
93
|
+
title: Layer Three
|
|
94
|
+
sources: [s]
|
|
95
|
+
''')
|
|
96
|
+
with pytest.warns(RuntimeWarning):
|
|
97
|
+
conf = ProxyConfiguration(conf)
|
|
98
|
+
root = conf.wms_root_layer.wms_layer()
|
|
99
|
+
|
|
100
|
+
# no root layer defined
|
|
101
|
+
assert root.title is None
|
|
102
|
+
assert root.name is None
|
|
103
|
+
layers = root.child_layers()
|
|
104
|
+
|
|
105
|
+
# names might not be in order
|
|
106
|
+
# layers.keys() != ['one', 'two', 'three']
|
|
107
|
+
|
|
108
|
+
assert len(layers) == 3
|
|
109
|
+
assert layers['one'].title == 'Layer One'
|
|
110
|
+
assert layers['two'].title == 'Layer Two'
|
|
111
|
+
assert layers['three'].title == 'Layer Three'
|
|
112
|
+
|
|
113
|
+
def test_with_root(self):
|
|
114
|
+
conf = self._test_conf('''
|
|
115
|
+
layers:
|
|
116
|
+
name: root
|
|
117
|
+
title: Root Layer
|
|
118
|
+
layers:
|
|
119
|
+
- name: one
|
|
120
|
+
title: Layer One
|
|
121
|
+
sources: [s]
|
|
122
|
+
- name: two
|
|
123
|
+
title: Layer Two
|
|
124
|
+
sources: [s]
|
|
125
|
+
''')
|
|
126
|
+
conf = ProxyConfiguration(conf)
|
|
127
|
+
root = conf.wms_root_layer.wms_layer()
|
|
128
|
+
|
|
129
|
+
assert root.title == 'Root Layer'
|
|
130
|
+
assert root.name == 'root'
|
|
131
|
+
layers = root.child_layers()
|
|
132
|
+
|
|
133
|
+
# names are in order
|
|
134
|
+
assert layers.keys() == ['root', 'one', 'two']
|
|
135
|
+
|
|
136
|
+
assert len(layers) == 3
|
|
137
|
+
assert layers['root'].title == 'Root Layer'
|
|
138
|
+
assert layers['one'].title == 'Layer One'
|
|
139
|
+
assert layers['two'].title == 'Layer Two'
|
|
140
|
+
|
|
141
|
+
layers_conf = conf.layers
|
|
142
|
+
assert len(layers_conf) == 2
|
|
143
|
+
|
|
144
|
+
def test_with_unnamed_root(self):
|
|
145
|
+
conf = self._test_conf('''
|
|
146
|
+
layers:
|
|
147
|
+
title: Root Layer
|
|
148
|
+
layers:
|
|
149
|
+
- name: one
|
|
150
|
+
title: Layer One
|
|
151
|
+
sources: [s]
|
|
152
|
+
- name: two
|
|
153
|
+
title: Layer Two
|
|
154
|
+
sources: [s]
|
|
155
|
+
''')
|
|
156
|
+
conf = ProxyConfiguration(conf)
|
|
157
|
+
root = conf.wms_root_layer.wms_layer()
|
|
158
|
+
|
|
159
|
+
assert root.title == 'Root Layer'
|
|
160
|
+
assert root.name is None
|
|
161
|
+
|
|
162
|
+
layers = root.child_layers()
|
|
163
|
+
# names are in order
|
|
164
|
+
assert layers.keys() == ['one', 'two']
|
|
165
|
+
|
|
166
|
+
def test_without_root(self):
|
|
167
|
+
conf = self._test_conf('''
|
|
168
|
+
layers:
|
|
169
|
+
- name: one
|
|
170
|
+
title: Layer One
|
|
171
|
+
sources: [s]
|
|
172
|
+
- name: two
|
|
173
|
+
title: Layer Two
|
|
174
|
+
sources: [s]
|
|
175
|
+
''')
|
|
176
|
+
conf = ProxyConfiguration(conf)
|
|
177
|
+
root = conf.wms_root_layer.wms_layer()
|
|
178
|
+
|
|
179
|
+
assert root.title is None
|
|
180
|
+
assert root.name is None
|
|
181
|
+
|
|
182
|
+
layers = root.child_layers()
|
|
183
|
+
# names are in order
|
|
184
|
+
assert layers.keys() == ['one', 'two']
|
|
185
|
+
|
|
186
|
+
def test_hierarchy(self):
|
|
187
|
+
conf = self._test_conf('''
|
|
188
|
+
layers:
|
|
189
|
+
title: Root Layer
|
|
190
|
+
layers:
|
|
191
|
+
- name: one
|
|
192
|
+
title: Layer One
|
|
193
|
+
layers:
|
|
194
|
+
- name: onea
|
|
195
|
+
title: Layer One A
|
|
196
|
+
sources: [s]
|
|
197
|
+
- name: oneb
|
|
198
|
+
title: Layer One B
|
|
199
|
+
layers:
|
|
200
|
+
- name: oneba
|
|
201
|
+
title: Layer One B A
|
|
202
|
+
sources: [s]
|
|
203
|
+
- name: onebb
|
|
204
|
+
title: Layer One B B
|
|
205
|
+
sources: [s]
|
|
206
|
+
- name: two
|
|
207
|
+
title: Layer Two
|
|
208
|
+
sources: [s]
|
|
209
|
+
''')
|
|
210
|
+
conf = ProxyConfiguration(conf)
|
|
211
|
+
root = conf.wms_root_layer.wms_layer()
|
|
212
|
+
|
|
213
|
+
assert root.title == 'Root Layer'
|
|
214
|
+
assert root.name is None
|
|
215
|
+
|
|
216
|
+
layers = root.child_layers()
|
|
217
|
+
# names are in order
|
|
218
|
+
assert layers.keys() == ['one', 'onea', 'oneb', 'oneba', 'onebb', 'two']
|
|
219
|
+
|
|
220
|
+
layers_conf = conf.layers
|
|
221
|
+
assert len(layers_conf) == 4
|
|
222
|
+
assert layers_conf.keys() == ['onea', 'oneba', 'onebb', 'two']
|
|
223
|
+
assert layers_conf['onea'].conf['title'] == 'Layer One A'
|
|
224
|
+
assert layers_conf['onea'].conf['name'] == 'onea'
|
|
225
|
+
assert layers_conf['onea'].conf['sources'] == ['s']
|
|
226
|
+
|
|
227
|
+
def test_hierarchy_root_is_list(self):
|
|
228
|
+
conf = self._test_conf('''
|
|
229
|
+
layers:
|
|
230
|
+
- title: Root Layer
|
|
231
|
+
layers:
|
|
232
|
+
- name: one
|
|
233
|
+
title: Layer One
|
|
234
|
+
sources: [s]
|
|
235
|
+
- name: two
|
|
236
|
+
title: Layer Two
|
|
237
|
+
sources: [s]
|
|
238
|
+
''')
|
|
239
|
+
conf = ProxyConfiguration(conf)
|
|
240
|
+
root = conf.wms_root_layer.wms_layer()
|
|
241
|
+
|
|
242
|
+
assert root.title == 'Root Layer'
|
|
243
|
+
assert root.name is None
|
|
244
|
+
|
|
245
|
+
layers = root.child_layers()
|
|
246
|
+
# names are in order
|
|
247
|
+
assert layers.keys() == ['one', 'two']
|
|
248
|
+
|
|
249
|
+
def test_without_sources_or_layers(self):
|
|
250
|
+
conf = self._test_conf('''
|
|
251
|
+
services:
|
|
252
|
+
wms:
|
|
253
|
+
layers:
|
|
254
|
+
title: Root Layer
|
|
255
|
+
layers:
|
|
256
|
+
- name: one
|
|
257
|
+
title: Layer One
|
|
258
|
+
''')
|
|
259
|
+
conf = ProxyConfiguration(conf)
|
|
260
|
+
assert conf.wms_root_layer.wms_layer() is None
|
|
261
|
+
try:
|
|
262
|
+
conf.services.services()
|
|
263
|
+
except ConfigurationError:
|
|
264
|
+
# found no WMS layer
|
|
265
|
+
pass
|
|
266
|
+
else:
|
|
267
|
+
assert False, 'expected ConfigurationError'
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class TestGridConfiguration(object):
|
|
271
|
+
def test_default_grids(self):
|
|
272
|
+
conf = {}
|
|
273
|
+
conf = ProxyConfiguration(conf)
|
|
274
|
+
grid = conf.grids['GLOBAL_MERCATOR'].tile_grid()
|
|
275
|
+
assert grid.srs == SRS(900913)
|
|
276
|
+
|
|
277
|
+
grid = conf.grids['GLOBAL_GEODETIC'].tile_grid()
|
|
278
|
+
assert grid.srs == SRS(4326)
|
|
279
|
+
|
|
280
|
+
def test_simple(self):
|
|
281
|
+
conf = {'grids': {'grid': {'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55]}}}
|
|
282
|
+
conf = ProxyConfiguration(conf)
|
|
283
|
+
grid = conf.grids['grid'].tile_grid()
|
|
284
|
+
assert grid.srs == SRS(4326)
|
|
285
|
+
|
|
286
|
+
def test_with_base(self):
|
|
287
|
+
conf = {'grids': {
|
|
288
|
+
'base_grid': {'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55]},
|
|
289
|
+
'grid': {'base': 'base_grid'}
|
|
290
|
+
}}
|
|
291
|
+
conf = ProxyConfiguration(conf)
|
|
292
|
+
grid = conf.grids['grid'].tile_grid()
|
|
293
|
+
assert grid.srs == SRS(4326)
|
|
294
|
+
|
|
295
|
+
def test_with_num_levels(self):
|
|
296
|
+
conf = {'grids': {'grid': {'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55], 'num_levels': 8}}}
|
|
297
|
+
conf = ProxyConfiguration(conf)
|
|
298
|
+
grid = conf.grids['grid'].tile_grid()
|
|
299
|
+
assert len(grid.resolutions) == 8
|
|
300
|
+
|
|
301
|
+
def test_with_bbox_srs(self):
|
|
302
|
+
conf = {'grids': {'grid': {'srs': 'EPSG:25832', 'bbox': [5, 50, 10, 55], 'bbox_srs': 'EPSG:4326'}}}
|
|
303
|
+
conf = ProxyConfiguration(conf)
|
|
304
|
+
grid = conf.grids['grid'].tile_grid()
|
|
305
|
+
assert_almost_equal_bbox([213372, 5538660, 571666, 6102110], grid.bbox, 1)
|
|
306
|
+
|
|
307
|
+
def test_with_min_res(self):
|
|
308
|
+
conf = {'grids': {'grid': {'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55], 'min_res': 0.0390625}}}
|
|
309
|
+
conf = ProxyConfiguration(conf)
|
|
310
|
+
grid = conf.grids['grid'].tile_grid()
|
|
311
|
+
assert_almost_equal_bbox([5, 50, 10, 55], grid.bbox)
|
|
312
|
+
assert grid.resolution(0) == 0.0390625
|
|
313
|
+
assert grid.resolution(1) == 0.01953125
|
|
314
|
+
|
|
315
|
+
def test_with_max_res(self):
|
|
316
|
+
conf = {'grids': {'grid': {'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55], 'max_res': 0.0048828125}}}
|
|
317
|
+
conf = ProxyConfiguration(conf)
|
|
318
|
+
grid = conf.grids['grid'].tile_grid()
|
|
319
|
+
assert_almost_equal_bbox([5, 50, 10, 55], grid.bbox)
|
|
320
|
+
assert grid.resolution(0) == 0.01953125
|
|
321
|
+
assert grid.resolution(1) == 0.01953125/2
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
class TestWMSSourceConfiguration(object):
|
|
325
|
+
def test_simple_grid(self):
|
|
326
|
+
conf_dict = {
|
|
327
|
+
'grids': {
|
|
328
|
+
'grid': {'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55]},
|
|
329
|
+
},
|
|
330
|
+
'sources': {
|
|
331
|
+
'osm': {
|
|
332
|
+
'type': 'wms',
|
|
333
|
+
'req': {
|
|
334
|
+
'url': 'http://localhost/service?',
|
|
335
|
+
'layers': 'base',
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
'caches': {
|
|
340
|
+
'osm': {
|
|
341
|
+
'sources': ['osm'],
|
|
342
|
+
'grids': ['grid'],
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
conf = ProxyConfiguration(conf_dict)
|
|
348
|
+
|
|
349
|
+
caches = conf.caches['osm'].caches()
|
|
350
|
+
assert len(caches) == 1
|
|
351
|
+
grid, extent, manager = caches[0]
|
|
352
|
+
|
|
353
|
+
assert grid.srs == SRS(4326)
|
|
354
|
+
assert grid.bbox == (5.0, 50.0, 10.0, 55.0)
|
|
355
|
+
|
|
356
|
+
assert isinstance(manager, TileManager)
|
|
357
|
+
|
|
358
|
+
def check_source_layers(self, conf_dict, layers):
|
|
359
|
+
conf = ProxyConfiguration(conf_dict)
|
|
360
|
+
caches = conf.caches['osm'].caches()
|
|
361
|
+
assert len(caches) == 1
|
|
362
|
+
grid, extent, manager = caches[0]
|
|
363
|
+
source_layers = manager.sources[0].client.request_template.params.layers
|
|
364
|
+
assert source_layers == layers
|
|
365
|
+
|
|
366
|
+
def test_tagged_source(self):
|
|
367
|
+
conf_dict = {
|
|
368
|
+
'sources': {
|
|
369
|
+
'osm': {
|
|
370
|
+
'type': 'wms',
|
|
371
|
+
'req': {
|
|
372
|
+
'url': 'http://localhost/service?',
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
'caches': {
|
|
377
|
+
'osm': {
|
|
378
|
+
'sources': ['osm:base,roads'],
|
|
379
|
+
'grids': ['GLOBAL_MERCATOR'],
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
self.check_source_layers(conf_dict, ['base', 'roads'])
|
|
384
|
+
|
|
385
|
+
def test_tagged_source_with_layers(self):
|
|
386
|
+
conf_dict = {
|
|
387
|
+
'sources': {
|
|
388
|
+
'osm': {
|
|
389
|
+
'type': 'wms',
|
|
390
|
+
'req': {
|
|
391
|
+
'url': 'http://localhost/service?',
|
|
392
|
+
'layers': 'base,roads,poi'
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
'caches': {
|
|
397
|
+
'osm': {
|
|
398
|
+
'sources': ['osm:base,roads'],
|
|
399
|
+
'grids': ['GLOBAL_MERCATOR'],
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
self.check_source_layers(conf_dict, ['base', 'roads'])
|
|
404
|
+
|
|
405
|
+
def test_tagged_source_with_layers_missing(self):
|
|
406
|
+
conf_dict = {
|
|
407
|
+
'sources': {
|
|
408
|
+
'osm': {
|
|
409
|
+
'type': 'wms',
|
|
410
|
+
'req': {
|
|
411
|
+
'url': 'http://localhost/service?',
|
|
412
|
+
'layers': 'base,poi'
|
|
413
|
+
},
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
'caches': {
|
|
417
|
+
'osm': {
|
|
418
|
+
'sources': ['osm:base,roads'],
|
|
419
|
+
'grids': ['GLOBAL_MERCATOR'],
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
conf = ProxyConfiguration(conf_dict)
|
|
424
|
+
try:
|
|
425
|
+
conf.caches['osm'].caches()
|
|
426
|
+
except ConfigurationError as ex:
|
|
427
|
+
assert 'base,roads' in ex.args[0]
|
|
428
|
+
assert ('base,poi' in ex.args[0] or 'poi,base' in ex.args[0])
|
|
429
|
+
else:
|
|
430
|
+
assert False, 'expected ConfigurationError'
|
|
431
|
+
|
|
432
|
+
def test_tagged_source_on_non_wms_source(self):
|
|
433
|
+
conf_dict = {
|
|
434
|
+
'sources': {
|
|
435
|
+
'osm': {
|
|
436
|
+
'type': 'tile',
|
|
437
|
+
'url': 'http://example.org/'
|
|
438
|
+
},
|
|
439
|
+
},
|
|
440
|
+
'caches': {
|
|
441
|
+
'osm': {
|
|
442
|
+
'sources': ['osm:base,roads'],
|
|
443
|
+
'grids': ['GLOBAL_MERCATOR'],
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
conf = ProxyConfiguration(conf_dict)
|
|
448
|
+
try:
|
|
449
|
+
conf.caches['osm'].caches()
|
|
450
|
+
except ConfigurationError as ex:
|
|
451
|
+
assert 'osm:base,roads' in ex.args[0]
|
|
452
|
+
else:
|
|
453
|
+
assert False, 'expected ConfigurationError'
|
|
454
|
+
|
|
455
|
+
def test_layer_tagged_source(self):
|
|
456
|
+
conf_dict = {
|
|
457
|
+
'layers': [
|
|
458
|
+
{
|
|
459
|
+
'name': 'osm',
|
|
460
|
+
'title': 'OSM',
|
|
461
|
+
'sources': ['osm:base,roads']
|
|
462
|
+
}
|
|
463
|
+
],
|
|
464
|
+
'sources': {
|
|
465
|
+
'osm': {
|
|
466
|
+
'type': 'wms',
|
|
467
|
+
'req': {
|
|
468
|
+
'url': 'http://localhost/service?',
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
}
|
|
473
|
+
conf = ProxyConfiguration(conf_dict)
|
|
474
|
+
wms_layer = conf.layers['osm'].wms_layer()
|
|
475
|
+
layers = wms_layer.map_layers[0].client.request_template.params.layers
|
|
476
|
+
assert layers == ['base', 'roads']
|
|
477
|
+
|
|
478
|
+
def test_tagged_source_encoding(self):
|
|
479
|
+
conf_dict = {
|
|
480
|
+
'layers': [
|
|
481
|
+
{
|
|
482
|
+
'name': 'osm',
|
|
483
|
+
'title': 'OSM',
|
|
484
|
+
'sources': [u'osm:☃']
|
|
485
|
+
}
|
|
486
|
+
],
|
|
487
|
+
'sources': {
|
|
488
|
+
'osm': {
|
|
489
|
+
'type': 'wms',
|
|
490
|
+
'req': {
|
|
491
|
+
'url': 'http://localhost/service?',
|
|
492
|
+
},
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
'caches': {
|
|
496
|
+
'osm': {
|
|
497
|
+
'sources': [u'osm:☃'],
|
|
498
|
+
'grids': ['GLOBAL_MERCATOR'],
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
# from source
|
|
503
|
+
conf = ProxyConfiguration(conf_dict)
|
|
504
|
+
wms_layer = conf.layers['osm'].wms_layer()
|
|
505
|
+
layers = wms_layer.map_layers[0].client.request_template.params.layers
|
|
506
|
+
assert layers == [u'☃']
|
|
507
|
+
# from cache
|
|
508
|
+
self.check_source_layers(conf_dict, [u'☃'])
|
|
509
|
+
|
|
510
|
+
def test_https_source_insecure(self):
|
|
511
|
+
conf_dict = {
|
|
512
|
+
'sources': {
|
|
513
|
+
'osm': {
|
|
514
|
+
'type': 'wms',
|
|
515
|
+
'http': {'ssl_no_cert_checks': True},
|
|
516
|
+
'req': {
|
|
517
|
+
'url': 'https://foo:bar@localhost/service?',
|
|
518
|
+
'layers': 'base',
|
|
519
|
+
},
|
|
520
|
+
},
|
|
521
|
+
},
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
conf = ProxyConfiguration(conf_dict)
|
|
525
|
+
try:
|
|
526
|
+
conf.sources['osm'].source({'format': 'image/png'})
|
|
527
|
+
except ImportError:
|
|
528
|
+
raise SkipTest('no ssl support')
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
class TestBandMergeConfig(object):
|
|
532
|
+
|
|
533
|
+
def test_invalid_band(self):
|
|
534
|
+
conf_dict = {
|
|
535
|
+
'caches': {
|
|
536
|
+
'osm': {
|
|
537
|
+
'sources': {'f': [{'source': 'foo', 'band': 1}]},
|
|
538
|
+
'grids': ['GLOBAL_WEBMERCATOR'],
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
errors, informal_only = validate_options(conf_dict)
|
|
543
|
+
assert len(errors) == 1
|
|
544
|
+
assert "unknown 'f' in caches" in errors[0]
|
|
545
|
+
|
|
546
|
+
def test_no_band_cache(self):
|
|
547
|
+
conf_dict = {
|
|
548
|
+
'caches': {
|
|
549
|
+
'osm': {
|
|
550
|
+
'sources': {'l': [{'source': 'foo'}]},
|
|
551
|
+
'grids': ['GLOBAL_WEBMERCATOR'],
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
errors, informal_only = validate_options(conf_dict)
|
|
556
|
+
assert len(errors) == 1
|
|
557
|
+
assert "missing 'band', not in caches" in errors[0], errors
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
def load_services(conf_file):
|
|
561
|
+
conf = load_configuration(conf_file)
|
|
562
|
+
return conf.configured_services()
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
class TestConfLoading(object):
|
|
566
|
+
yaml_string = b"""
|
|
567
|
+
services:
|
|
568
|
+
wms:
|
|
569
|
+
|
|
570
|
+
layers:
|
|
571
|
+
- name: osm
|
|
572
|
+
title: OSM
|
|
573
|
+
sources: [osm]
|
|
574
|
+
|
|
575
|
+
sources:
|
|
576
|
+
osm:
|
|
577
|
+
type: wms
|
|
578
|
+
supported_srs: ['EPSG:31467']
|
|
579
|
+
req:
|
|
580
|
+
url: http://foo
|
|
581
|
+
layers: base
|
|
582
|
+
"""
|
|
583
|
+
|
|
584
|
+
def test_loading(self):
|
|
585
|
+
with TempFile() as tf:
|
|
586
|
+
with open(tf, 'wb') as f:
|
|
587
|
+
f.write(self.yaml_string)
|
|
588
|
+
services = load_services(tf)
|
|
589
|
+
assert 'service' in services[0].names
|
|
590
|
+
|
|
591
|
+
def test_loading_broken_yaml(self):
|
|
592
|
+
with TempFile() as tf:
|
|
593
|
+
with open(tf, 'wb') as f:
|
|
594
|
+
f.write(b'\tbroken:foo')
|
|
595
|
+
try:
|
|
596
|
+
load_services(tf)
|
|
597
|
+
except ConfigurationError:
|
|
598
|
+
pass
|
|
599
|
+
else:
|
|
600
|
+
assert False, 'expected configuration error'
|
|
601
|
+
|
|
602
|
+
def test_loading_extra_service(self):
|
|
603
|
+
""" Test registration of extra service """
|
|
604
|
+
|
|
605
|
+
my_yaml_string = b"""
|
|
606
|
+
services:
|
|
607
|
+
my_extra_service:
|
|
608
|
+
foo: bar
|
|
609
|
+
|
|
610
|
+
layers:
|
|
611
|
+
- name: osm
|
|
612
|
+
title: OSM
|
|
613
|
+
sources: [osm]
|
|
614
|
+
|
|
615
|
+
sources:
|
|
616
|
+
osm:
|
|
617
|
+
type: wms
|
|
618
|
+
supported_srs: ['EPSG:31467']
|
|
619
|
+
req:
|
|
620
|
+
url: http://foo
|
|
621
|
+
layers: base
|
|
622
|
+
"""
|
|
623
|
+
from mapproxy.config.loader import plugin_services, register_service_configuration
|
|
624
|
+
from mapproxy.service.base import Server
|
|
625
|
+
|
|
626
|
+
class MyExtraServiceServer(Server):
|
|
627
|
+
names = ('my_extra_service',)
|
|
628
|
+
|
|
629
|
+
def __init__(self):
|
|
630
|
+
pass
|
|
631
|
+
|
|
632
|
+
def my_extra_service_method(serviceConfiguration, conf):
|
|
633
|
+
return MyExtraServiceServer()
|
|
634
|
+
|
|
635
|
+
try:
|
|
636
|
+
with TempFile() as tf:
|
|
637
|
+
with open(tf, 'wb') as f:
|
|
638
|
+
f.write(my_yaml_string)
|
|
639
|
+
|
|
640
|
+
register_service_configuration('my_extra_service', my_extra_service_method,
|
|
641
|
+
'my_extra_service', {'foo': str()})
|
|
642
|
+
conf = load_configuration(tf, ignore_warnings=False)
|
|
643
|
+
services = conf.configured_services()
|
|
644
|
+
assert 'my_extra_service' in services[0].names
|
|
645
|
+
|
|
646
|
+
finally:
|
|
647
|
+
plugin_services.clear()
|
|
648
|
+
|
|
649
|
+
def test_loading_extra_source(self):
|
|
650
|
+
""" Test registration of extra source """
|
|
651
|
+
|
|
652
|
+
my_yaml_string = b"""
|
|
653
|
+
services:
|
|
654
|
+
wms:
|
|
655
|
+
|
|
656
|
+
layers:
|
|
657
|
+
- name: osm
|
|
658
|
+
title: OSM
|
|
659
|
+
sources: [osm]
|
|
660
|
+
|
|
661
|
+
sources:
|
|
662
|
+
osm:
|
|
663
|
+
type: my_extra_source
|
|
664
|
+
foo: bar
|
|
665
|
+
"""
|
|
666
|
+
from mapproxy.config.loader import source_configuration_types, register_source_configuration
|
|
667
|
+
from mapproxy.config.loader import SourceConfiguration
|
|
668
|
+
|
|
669
|
+
class my_source_configuration(SourceConfiguration):
|
|
670
|
+
source_type = ('my_extra_source',)
|
|
671
|
+
|
|
672
|
+
def source(self, params=None):
|
|
673
|
+
class MySource(object):
|
|
674
|
+
def __init__(self):
|
|
675
|
+
self.extent = None
|
|
676
|
+
return MySource()
|
|
677
|
+
|
|
678
|
+
source_configuration_types_before = copy.copy(source_configuration_types)
|
|
679
|
+
try:
|
|
680
|
+
with TempFile() as tf:
|
|
681
|
+
with open(tf, 'wb') as f:
|
|
682
|
+
f.write(my_yaml_string)
|
|
683
|
+
|
|
684
|
+
register_source_configuration('my_extra_source', my_source_configuration,
|
|
685
|
+
'my_extra_source', {'foo': str()})
|
|
686
|
+
conf = load_configuration(tf, ignore_warnings=False)
|
|
687
|
+
|
|
688
|
+
assert conf.sources['osm'].source_type == ('my_extra_source',)
|
|
689
|
+
|
|
690
|
+
finally:
|
|
691
|
+
source_configuration_types = source_configuration_types_before
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
class TestConfImport(object):
|
|
695
|
+
|
|
696
|
+
yaml_string = """
|
|
697
|
+
services:
|
|
698
|
+
wms:
|
|
699
|
+
# ======= overwritten max_output_pixels:
|
|
700
|
+
max_output_pixels: [4000, 4000]
|
|
701
|
+
|
|
702
|
+
layers:
|
|
703
|
+
- name: Zones_A
|
|
704
|
+
title: Zones_A
|
|
705
|
+
# ======= overwritten sources and layers:
|
|
706
|
+
sources: []
|
|
707
|
+
layers:
|
|
708
|
+
- name: layerA1
|
|
709
|
+
title: layer A 1
|
|
710
|
+
sources: [osm_cache]
|
|
711
|
+
- name: layerA2
|
|
712
|
+
title: layer A 2
|
|
713
|
+
sources: [osm_cache]
|
|
714
|
+
# ======= overwritten add Zones_B:
|
|
715
|
+
- name: Zones_B
|
|
716
|
+
title: Zones_B
|
|
717
|
+
sources: [cache-Zones_B]
|
|
718
|
+
- name: osm
|
|
719
|
+
# ======= overwritten sources:
|
|
720
|
+
sources: [overwritten_source]
|
|
721
|
+
|
|
722
|
+
caches:
|
|
723
|
+
cache-Zones_B:
|
|
724
|
+
sources: ['src_mymap:Zones_B']
|
|
725
|
+
grids: [webmercator]
|
|
726
|
+
cache:
|
|
727
|
+
type: file
|
|
728
|
+
directory_layout: mp
|
|
729
|
+
|
|
730
|
+
sources:
|
|
731
|
+
overwritten_source:
|
|
732
|
+
type: wms
|
|
733
|
+
req:
|
|
734
|
+
url: http://localhost/qgis/overwritten_source?
|
|
735
|
+
transparent: true
|
|
736
|
+
layers: osm
|
|
737
|
+
|
|
738
|
+
globals:
|
|
739
|
+
http:
|
|
740
|
+
client_timeout: 1
|
|
741
|
+
# ======= overwritten headers:
|
|
742
|
+
headers:
|
|
743
|
+
baz: quux
|
|
744
|
+
|
|
745
|
+
grids:
|
|
746
|
+
webmercator:
|
|
747
|
+
base: GLOBAL_WEBMERCATOR
|
|
748
|
+
srs: EPSG:3857
|
|
749
|
+
# ======= overwritten tile size:
|
|
750
|
+
tile_size: [1024, 1024]
|
|
751
|
+
"""
|
|
752
|
+
|
|
753
|
+
yaml_parent = """
|
|
754
|
+
layers:
|
|
755
|
+
- name: Zones_A
|
|
756
|
+
title: Zones_A
|
|
757
|
+
sources: [cache-Zones_A]
|
|
758
|
+
- name: osm
|
|
759
|
+
# ======= overwritten title:
|
|
760
|
+
title: overwritten
|
|
761
|
+
|
|
762
|
+
sources:
|
|
763
|
+
src_mymap:
|
|
764
|
+
type: wms
|
|
765
|
+
req:
|
|
766
|
+
url: http://localhost/qgis/mymap?
|
|
767
|
+
transparent: true
|
|
768
|
+
|
|
769
|
+
caches:
|
|
770
|
+
cache-Zones_A:
|
|
771
|
+
sources: ['src_mymap:Zones_A']
|
|
772
|
+
grids: [webmercator]
|
|
773
|
+
cache:
|
|
774
|
+
type: file
|
|
775
|
+
directory_layout: mp
|
|
776
|
+
|
|
777
|
+
grids:
|
|
778
|
+
grid_alaska_4326:
|
|
779
|
+
# ======= overwritten bbox:
|
|
780
|
+
bbox: [-180, 60, -100, 70]
|
|
781
|
+
|
|
782
|
+
globals:
|
|
783
|
+
http:
|
|
784
|
+
client_timeout: 2
|
|
785
|
+
# ======= overwritten headers:
|
|
786
|
+
headers:
|
|
787
|
+
foo: bar
|
|
788
|
+
bar: qux
|
|
789
|
+
baz: qax
|
|
790
|
+
"""
|
|
791
|
+
|
|
792
|
+
yaml_grand_parent = """
|
|
793
|
+
services:
|
|
794
|
+
demo:
|
|
795
|
+
tms:
|
|
796
|
+
use_grid_names: true
|
|
797
|
+
origin: 'nw'
|
|
798
|
+
kml:
|
|
799
|
+
use_grid_names: true
|
|
800
|
+
wmts:
|
|
801
|
+
wms:
|
|
802
|
+
image_formats: ['image/jpeg', 'image/png']
|
|
803
|
+
srs: [ 'EPSG:3857' ]
|
|
804
|
+
max_output_pixels: [2000, 2000]
|
|
805
|
+
|
|
806
|
+
layers:
|
|
807
|
+
- name: osm
|
|
808
|
+
title: Omniscale OSM WMS - osm.omniscale.net
|
|
809
|
+
sources: [osm_cache]
|
|
810
|
+
|
|
811
|
+
caches:
|
|
812
|
+
osm_cache:
|
|
813
|
+
grids: [webmercator]
|
|
814
|
+
sources: [osm_wms]
|
|
815
|
+
|
|
816
|
+
sources:
|
|
817
|
+
osm_wms:
|
|
818
|
+
type: wms
|
|
819
|
+
req:
|
|
820
|
+
url: https://maps.omniscale.net/v2/demo/style.default/service?
|
|
821
|
+
layers: osm
|
|
822
|
+
|
|
823
|
+
grids:
|
|
824
|
+
webmercator:
|
|
825
|
+
base: GLOBAL_WEBMERCATOR
|
|
826
|
+
srs: EPSG:3857
|
|
827
|
+
bbox_srs: EPSG:3857
|
|
828
|
+
tile_size: [512, 512]
|
|
829
|
+
|
|
830
|
+
grid_alaska_4326:
|
|
831
|
+
srs: EPSG:4326
|
|
832
|
+
origin: sw
|
|
833
|
+
bbox: [-167, 53, -141, 67]
|
|
834
|
+
bbox_srs: 'EPSG:4326'
|
|
835
|
+
|
|
836
|
+
globals:
|
|
837
|
+
http:
|
|
838
|
+
client_timeout: 3
|
|
839
|
+
method: GET
|
|
840
|
+
headers:
|
|
841
|
+
bar: baz
|
|
842
|
+
"""
|
|
843
|
+
|
|
844
|
+
def test_loading(self):
|
|
845
|
+
with TempFile() as gp:
|
|
846
|
+
open(gp, 'wb').write(self.yaml_grand_parent.encode('utf-8'))
|
|
847
|
+
self.yaml_parent = """
|
|
848
|
+
base:
|
|
849
|
+
- %s
|
|
850
|
+
%s
|
|
851
|
+
""" % (gp, self.yaml_parent)
|
|
852
|
+
|
|
853
|
+
with TempFile() as p:
|
|
854
|
+
open(p, 'wb').write(self.yaml_parent.encode("utf-8"))
|
|
855
|
+
|
|
856
|
+
self.yaml_string = """
|
|
857
|
+
base: [%s]
|
|
858
|
+
%s
|
|
859
|
+
""" % (p, self.yaml_string)
|
|
860
|
+
|
|
861
|
+
with TempFile() as cfg:
|
|
862
|
+
open(cfg, 'wb').write(self.yaml_string.encode("utf-8"))
|
|
863
|
+
|
|
864
|
+
config = load_configuration(cfg)
|
|
865
|
+
|
|
866
|
+
http = config.globals.get_value('http')
|
|
867
|
+
assert http['client_timeout'] == 1
|
|
868
|
+
assert http['headers']['bar'] == 'qux'
|
|
869
|
+
assert http['headers']['foo'] == 'bar'
|
|
870
|
+
assert http['headers']['baz'] == 'quux'
|
|
871
|
+
assert http['method'] == 'GET'
|
|
872
|
+
|
|
873
|
+
grid_webmercator = config.grids['webmercator']
|
|
874
|
+
assert grid_webmercator is not None
|
|
875
|
+
assert grid_webmercator.tile_grid().tile_size == (1024, 1024)
|
|
876
|
+
assert grid_webmercator.conf['srs'] == 'EPSG:3857'
|
|
877
|
+
assert grid_webmercator.conf['bbox_srs'] == 'EPSG:3857'
|
|
878
|
+
|
|
879
|
+
grid_alaska = config.grids['grid_alaska_4326']
|
|
880
|
+
assert grid_alaska is not None
|
|
881
|
+
assert grid_alaska.conf['bbox'] == [-180.0, 60.0, -100.0, 70.0]
|
|
882
|
+
assert grid_alaska.conf['srs'] == 'EPSG:4326'
|
|
883
|
+
assert grid_alaska.conf['bbox_srs'] == 'EPSG:4326'
|
|
884
|
+
assert grid_alaska.conf['origin'] == 'sw'
|
|
885
|
+
|
|
886
|
+
wms = config.services.conf['wms']
|
|
887
|
+
assert wms is not None
|
|
888
|
+
assert wms['max_output_pixels'] == [4000, 4000]
|
|
889
|
+
assert wms['image_formats'] == ['image/jpeg', 'image/png']
|
|
890
|
+
|
|
891
|
+
layers = config.layers
|
|
892
|
+
assert layers['osm'].conf['title'] == 'overwritten'
|
|
893
|
+
assert layers['osm'].conf['sources'] == ['overwritten_source']
|
|
894
|
+
assert layers['Zones_A'].conf['sources'] == []
|
|
895
|
+
assert layers['layerA1'].conf['sources'] == ['osm_cache']
|
|
896
|
+
assert layers['layerA2'].conf['sources'] == ['osm_cache']
|
|
897
|
+
assert layers['Zones_B'].conf['sources'] == ['cache-Zones_B']
|
|
898
|
+
|
|
899
|
+
config_files = config.config_files()
|
|
900
|
+
assert set(config_files.keys()) == set([gp, p, cfg])
|
|
901
|
+
assert abs(config_files[gp] - time.time()) < 10
|
|
902
|
+
assert abs(config_files[p] - time.time()) < 10
|
|
903
|
+
assert abs(config_files[cfg] - time.time()) < 10
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
class TestConfMerger(object):
|
|
907
|
+
def test_empty_base(self):
|
|
908
|
+
a = {'a': 1, 'b': [12, 13]}
|
|
909
|
+
b = {}
|
|
910
|
+
m = merge_dict(a, b)
|
|
911
|
+
assert a == m
|
|
912
|
+
|
|
913
|
+
def test_empty_conf(self):
|
|
914
|
+
a = {}
|
|
915
|
+
b = {'a': 1, 'b': [12, 13]}
|
|
916
|
+
m = merge_dict(a, b)
|
|
917
|
+
assert b == m
|
|
918
|
+
|
|
919
|
+
def test_differ(self):
|
|
920
|
+
a = {'a': 12}
|
|
921
|
+
b = {'b': 42}
|
|
922
|
+
m = merge_dict(a, b)
|
|
923
|
+
assert {'a': 12, 'b': 42} == m
|
|
924
|
+
|
|
925
|
+
def test_recursive(self):
|
|
926
|
+
a = {'a': {'aa': 12, 'a': {'aaa': 100}}}
|
|
927
|
+
b = {'a': {'aa': 11, 'ab': 13, 'a': {'aaa': 101, 'aab': 101}}}
|
|
928
|
+
m = merge_dict(a, b)
|
|
929
|
+
assert {'a': {'aa': 12, 'ab': 13, 'a': {'aaa': 100, 'aab': 101}}} == m
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
class TestLoadConfiguration(object):
|
|
933
|
+
def test_with_warnings(object):
|
|
934
|
+
with TempFile() as f:
|
|
935
|
+
open(f, 'wb').write(b"""
|
|
936
|
+
services:
|
|
937
|
+
unknown:
|
|
938
|
+
""")
|
|
939
|
+
load_configuration(f) # defaults to ignore_warnings=True
|
|
940
|
+
|
|
941
|
+
with pytest.raises(ConfigurationError):
|
|
942
|
+
load_configuration(f, ignore_warnings=False)
|
|
943
|
+
|
|
944
|
+
def test_load_default_cache_coverage(object):
|
|
945
|
+
with TempFile() as f:
|
|
946
|
+
open(f, 'wb').write(b"""
|
|
947
|
+
services:
|
|
948
|
+
my_extra_service:
|
|
949
|
+
foo: bar
|
|
950
|
+
|
|
951
|
+
layers:
|
|
952
|
+
- name: temp
|
|
953
|
+
title: temp
|
|
954
|
+
sources: [temp]
|
|
955
|
+
|
|
956
|
+
caches:
|
|
957
|
+
temp:
|
|
958
|
+
grids: [grid]
|
|
959
|
+
sources: []
|
|
960
|
+
cache:
|
|
961
|
+
type: geopackage
|
|
962
|
+
|
|
963
|
+
grids:
|
|
964
|
+
grid:
|
|
965
|
+
srs: 'EPSG:4326'
|
|
966
|
+
bbox: [-180, -90, 180, 90]
|
|
967
|
+
""")
|
|
968
|
+
config = load_configuration(f) # defaults to ignore_warnings=True
|
|
969
|
+
cache = config.caches['temp']
|
|
970
|
+
assert cache.coverage() is None
|
|
971
|
+
assert cache.caches()[0][1] == MapExtent((-180, -90, 180, 90), SRS(4326))
|
|
972
|
+
|
|
973
|
+
def test_load_cache_coverage(object):
|
|
974
|
+
with TempFile() as f:
|
|
975
|
+
open(f, 'wb').write(b"""
|
|
976
|
+
services:
|
|
977
|
+
my_extra_service:
|
|
978
|
+
foo: bar
|
|
979
|
+
|
|
980
|
+
layers:
|
|
981
|
+
- name: temp
|
|
982
|
+
title: temp
|
|
983
|
+
sources: [temp]
|
|
984
|
+
|
|
985
|
+
parts:
|
|
986
|
+
coverages:
|
|
987
|
+
test_coverage: &test_coverage
|
|
988
|
+
bbox: [-50, -50, 50, 50]
|
|
989
|
+
srs: EPSG:4326
|
|
990
|
+
|
|
991
|
+
caches:
|
|
992
|
+
temp:
|
|
993
|
+
sources: []
|
|
994
|
+
cache:
|
|
995
|
+
type: geopackage
|
|
996
|
+
coverage: *test_coverage
|
|
997
|
+
""")
|
|
998
|
+
config = load_configuration(f) # defaults to ignore_warnings=True
|
|
999
|
+
assert config.caches['temp'].coverage() == coverage([-50, -50, 50, 50], SRS(4326))
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
class TestImageOptions(object):
|
|
1003
|
+
def test_default_format(self):
|
|
1004
|
+
conf_dict = {
|
|
1005
|
+
}
|
|
1006
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1007
|
+
image_opts = conf.globals.image_options.image_opts({}, 'image/png')
|
|
1008
|
+
assert image_opts.format == 'image/png'
|
|
1009
|
+
assert image_opts.mode is None
|
|
1010
|
+
assert image_opts.colors == 256
|
|
1011
|
+
assert image_opts.transparent is None
|
|
1012
|
+
assert image_opts.resampling == 'bicubic'
|
|
1013
|
+
|
|
1014
|
+
def test_default_format_paletted_false(self):
|
|
1015
|
+
conf_dict = {'globals': {'image': {'paletted': False}}}
|
|
1016
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1017
|
+
image_opts = conf.globals.image_options.image_opts({}, 'image/png')
|
|
1018
|
+
assert image_opts.format == 'image/png'
|
|
1019
|
+
assert image_opts.mode is None
|
|
1020
|
+
assert image_opts.colors is None
|
|
1021
|
+
assert image_opts.transparent is None
|
|
1022
|
+
assert image_opts.resampling == 'bicubic'
|
|
1023
|
+
|
|
1024
|
+
def test_update_default_format(self):
|
|
1025
|
+
conf_dict = {'globals': {'image': {'formats': {
|
|
1026
|
+
'image/png': {'colors': 16, 'resampling_method': 'nearest',
|
|
1027
|
+
'encoding_options': {'quantizer': 'mediancut'}}
|
|
1028
|
+
}}}}
|
|
1029
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1030
|
+
image_opts = conf.globals.image_options.image_opts({}, 'image/png')
|
|
1031
|
+
assert image_opts.format == 'image/png'
|
|
1032
|
+
assert image_opts.mode is None
|
|
1033
|
+
assert image_opts.colors == 16
|
|
1034
|
+
assert image_opts.transparent is None
|
|
1035
|
+
assert image_opts.resampling == 'nearest'
|
|
1036
|
+
assert image_opts.encoding_options['quantizer'] == 'mediancut'
|
|
1037
|
+
|
|
1038
|
+
def test_custom_format(self):
|
|
1039
|
+
conf_dict = {'globals': {'image': {'resampling_method': 'bilinear',
|
|
1040
|
+
'formats': {
|
|
1041
|
+
'image/foo': {'mode': 'RGBA', 'colors': 42}
|
|
1042
|
+
}
|
|
1043
|
+
}}}
|
|
1044
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1045
|
+
image_opts = conf.globals.image_options.image_opts({}, 'image/foo')
|
|
1046
|
+
assert image_opts.format == 'image/foo'
|
|
1047
|
+
assert image_opts.mode == 'RGBA'
|
|
1048
|
+
assert image_opts.colors == 42
|
|
1049
|
+
assert image_opts.transparent is None
|
|
1050
|
+
assert image_opts.resampling == 'bilinear'
|
|
1051
|
+
|
|
1052
|
+
def test_format_grid(self):
|
|
1053
|
+
conf_dict = {
|
|
1054
|
+
'globals': {
|
|
1055
|
+
'image': {
|
|
1056
|
+
'resampling_method': 'bilinear',
|
|
1057
|
+
}
|
|
1058
|
+
},
|
|
1059
|
+
'caches': {
|
|
1060
|
+
'test': {
|
|
1061
|
+
'sources': [],
|
|
1062
|
+
'grids': ['GLOBAL_MERCATOR'],
|
|
1063
|
+
'format': 'image/png',
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1068
|
+
image_opts = conf.caches['test'].image_opts()
|
|
1069
|
+
assert image_opts.format == 'image/png'
|
|
1070
|
+
assert image_opts.mode is None
|
|
1071
|
+
assert image_opts.colors == 256
|
|
1072
|
+
assert image_opts.transparent is None
|
|
1073
|
+
assert image_opts.resampling == 'bilinear'
|
|
1074
|
+
|
|
1075
|
+
def test_custom_format_grid(self):
|
|
1076
|
+
conf_dict = {
|
|
1077
|
+
'globals': {
|
|
1078
|
+
'image': {
|
|
1079
|
+
'resampling_method': 'bilinear',
|
|
1080
|
+
'formats': {
|
|
1081
|
+
'png8': {'mode': 'P', 'colors': 256},
|
|
1082
|
+
'image/png': {'mode': 'RGBA', 'transparent': True}
|
|
1083
|
+
},
|
|
1084
|
+
}
|
|
1085
|
+
},
|
|
1086
|
+
'caches': {
|
|
1087
|
+
'test': {
|
|
1088
|
+
'sources': [],
|
|
1089
|
+
'grids': ['GLOBAL_MERCATOR'],
|
|
1090
|
+
'format': 'png8',
|
|
1091
|
+
'image': {
|
|
1092
|
+
'colors': 16,
|
|
1093
|
+
}
|
|
1094
|
+
},
|
|
1095
|
+
'test2': {
|
|
1096
|
+
'sources': [],
|
|
1097
|
+
'grids': ['GLOBAL_MERCATOR'],
|
|
1098
|
+
'format': 'image/png',
|
|
1099
|
+
'image': {
|
|
1100
|
+
'colors': 8,
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1106
|
+
image_opts = conf.caches['test'].image_opts()
|
|
1107
|
+
assert image_opts.format == 'image/png'
|
|
1108
|
+
assert image_opts.mode == 'P'
|
|
1109
|
+
assert image_opts.colors == 16
|
|
1110
|
+
assert image_opts.transparent is None
|
|
1111
|
+
assert image_opts.resampling == 'bilinear'
|
|
1112
|
+
|
|
1113
|
+
image_opts = conf.caches['test2'].image_opts()
|
|
1114
|
+
assert image_opts.format == 'image/png'
|
|
1115
|
+
assert image_opts.mode == 'RGBA'
|
|
1116
|
+
assert image_opts.colors == 8
|
|
1117
|
+
assert image_opts.transparent is True
|
|
1118
|
+
assert image_opts.resampling == 'bilinear'
|
|
1119
|
+
|
|
1120
|
+
def test_custom_format_source(self):
|
|
1121
|
+
conf_dict = {
|
|
1122
|
+
'globals': {
|
|
1123
|
+
'image': {
|
|
1124
|
+
'resampling_method': 'bilinear',
|
|
1125
|
+
'formats': {
|
|
1126
|
+
'png8': {'mode': 'P', 'colors': 256, 'format': 'image/png'},
|
|
1127
|
+
'image/png': {'mode': 'RGBA', 'transparent': True}
|
|
1128
|
+
},
|
|
1129
|
+
}
|
|
1130
|
+
},
|
|
1131
|
+
'caches': {
|
|
1132
|
+
'test': {
|
|
1133
|
+
'sources': ['test_source'],
|
|
1134
|
+
'grids': ['GLOBAL_MERCATOR'],
|
|
1135
|
+
'format': 'png8',
|
|
1136
|
+
'image': {
|
|
1137
|
+
'colors': 16,
|
|
1138
|
+
}
|
|
1139
|
+
},
|
|
1140
|
+
},
|
|
1141
|
+
'sources': {
|
|
1142
|
+
'test_source': {
|
|
1143
|
+
'type': 'wms',
|
|
1144
|
+
'req': {
|
|
1145
|
+
'url': 'http://example.org/',
|
|
1146
|
+
'layers': 'foo',
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1152
|
+
_grid, _extent, tile_mgr = conf.caches['test'].caches()[0]
|
|
1153
|
+
image_opts = tile_mgr.image_opts
|
|
1154
|
+
assert image_opts.format == 'image/png'
|
|
1155
|
+
assert image_opts.mode == 'P'
|
|
1156
|
+
assert image_opts.colors == 16
|
|
1157
|
+
assert image_opts.transparent is None
|
|
1158
|
+
assert image_opts.resampling == 'bilinear'
|
|
1159
|
+
|
|
1160
|
+
image_opts = tile_mgr.sources[0].image_opts
|
|
1161
|
+
assert image_opts.format == 'image/png'
|
|
1162
|
+
assert image_opts.mode == 'P'
|
|
1163
|
+
assert image_opts.colors == 256
|
|
1164
|
+
assert image_opts.transparent is None
|
|
1165
|
+
assert image_opts.resampling == 'bilinear'
|
|
1166
|
+
|
|
1167
|
+
conf_dict['caches']['test']['request_format'] = 'image/tiff'
|
|
1168
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1169
|
+
_grid, _extent, tile_mgr = conf.caches['test'].caches()[0]
|
|
1170
|
+
image_opts = tile_mgr.image_opts
|
|
1171
|
+
assert image_opts.format == 'image/png'
|
|
1172
|
+
assert image_opts.mode == 'P'
|
|
1173
|
+
assert image_opts.colors == 16
|
|
1174
|
+
assert image_opts.transparent is None
|
|
1175
|
+
assert image_opts.resampling == 'bilinear'
|
|
1176
|
+
|
|
1177
|
+
image_opts = tile_mgr.sources[0].image_opts
|
|
1178
|
+
assert image_opts.format == 'image/tiff'
|
|
1179
|
+
assert image_opts.mode is None
|
|
1180
|
+
assert image_opts.colors is None
|
|
1181
|
+
assert image_opts.transparent is None
|
|
1182
|
+
assert image_opts.resampling == 'bilinear'
|
|
1183
|
+
|
|
1184
|
+
def test_encoding_options_errors(self):
|
|
1185
|
+
conf_dict = {
|
|
1186
|
+
'globals': {
|
|
1187
|
+
'image': {
|
|
1188
|
+
'formats': {
|
|
1189
|
+
'image/jpeg': {
|
|
1190
|
+
'encoding_options': {
|
|
1191
|
+
'foo': 'baz',
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
},
|
|
1195
|
+
}
|
|
1196
|
+
},
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
try:
|
|
1200
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1201
|
+
except ConfigurationError:
|
|
1202
|
+
pass
|
|
1203
|
+
else:
|
|
1204
|
+
raise Exception('expected ConfigurationError')
|
|
1205
|
+
|
|
1206
|
+
conf_dict['globals']['image']['formats']['image/jpeg']['encoding_options'] = {
|
|
1207
|
+
'quantizer': 'foo'
|
|
1208
|
+
}
|
|
1209
|
+
try:
|
|
1210
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1211
|
+
except ConfigurationError:
|
|
1212
|
+
pass
|
|
1213
|
+
else:
|
|
1214
|
+
raise Exception('expected ConfigurationError')
|
|
1215
|
+
|
|
1216
|
+
conf_dict['globals']['image']['formats']['image/jpeg']['encoding_options'] = {}
|
|
1217
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1218
|
+
try:
|
|
1219
|
+
conf.globals.image_options.image_opts({'encoding_options': {'quantizer': 'foo'}}, 'image/jpeg')
|
|
1220
|
+
except ConfigurationError:
|
|
1221
|
+
pass
|
|
1222
|
+
else:
|
|
1223
|
+
raise Exception('expected ConfigurationError')
|
|
1224
|
+
|
|
1225
|
+
conf_dict['globals']['image']['formats']['image/jpeg']['encoding_options'] = {
|
|
1226
|
+
'quantizer': 'fastoctree'
|
|
1227
|
+
}
|
|
1228
|
+
conf = ProxyConfiguration(conf_dict)
|
|
1229
|
+
|
|
1230
|
+
conf.globals.image_options.image_opts({}, 'image/jpeg')
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
class TestCoverageValidation(object):
|
|
1234
|
+
def test_union(self):
|
|
1235
|
+
conf = {
|
|
1236
|
+
'coverages': {
|
|
1237
|
+
'covname': {
|
|
1238
|
+
'union': [
|
|
1239
|
+
{'bbox': [0, 0, 10, 10], 'srs': 'EPSG:4326'},
|
|
1240
|
+
{'bbox': [10, 0, 20, 10], 'srs': 'EPSG:4326', 'unknown': True},
|
|
1241
|
+
],
|
|
1242
|
+
},
|
|
1243
|
+
},
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
errors, informal_only = validate_seed_conf(conf)
|
|
1247
|
+
assert informal_only
|
|
1248
|
+
assert len(errors) == 1
|
|
1249
|
+
assert errors[0] == "unknown 'unknown' in coverages.covname.union[1]"
|
|
1250
|
+
|
|
1251
|
+
|
|
1252
|
+
class TestLoadCoverage(object):
|
|
1253
|
+
def test_load_empty_geojson(self):
|
|
1254
|
+
with TempFile() as tf:
|
|
1255
|
+
with open(tf, 'wb') as f:
|
|
1256
|
+
f.write(b'{"type": "FeatureCollection", "features": []}')
|
|
1257
|
+
conf = {'datasource': tf, 'srs': 'EPSG:4326'}
|
|
1258
|
+
with pytest.raises(EmptyGeometryError):
|
|
1259
|
+
load_coverage(conf)
|
|
1260
|
+
|
|
1261
|
+
def test_load_empty_geojson_ogr(self):
|
|
1262
|
+
with TempFile() as tf:
|
|
1263
|
+
with open(tf, 'wb') as f:
|
|
1264
|
+
f.write(b'{"type": "FeatureCollection", "features": []}')
|
|
1265
|
+
conf = {'datasource': tf, 'where': '0 != 1', 'srs': 'EPSG:4326'}
|
|
1266
|
+
with pytest.raises(EmptyGeometryError):
|
|
1267
|
+
load_coverage(conf)
|