MapProxy 1.16.1__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/__init__.py +0 -0
- mapproxy/cache/__init__.py +36 -0
- mapproxy/cache/azureblob.py +145 -0
- mapproxy/cache/base.py +111 -0
- mapproxy/cache/compact.py +664 -0
- mapproxy/cache/couchdb.py +295 -0
- mapproxy/cache/dummy.py +34 -0
- mapproxy/cache/file.py +185 -0
- mapproxy/cache/geopackage.py +609 -0
- mapproxy/cache/legend.py +83 -0
- mapproxy/cache/mbtiles.py +392 -0
- mapproxy/cache/meta.py +78 -0
- mapproxy/cache/path.py +250 -0
- mapproxy/cache/redis.py +88 -0
- mapproxy/cache/renderd.py +95 -0
- mapproxy/cache/riak.py +202 -0
- mapproxy/cache/s3.py +177 -0
- mapproxy/cache/tile.py +699 -0
- mapproxy/client/__init__.py +0 -0
- mapproxy/client/arcgis.py +79 -0
- mapproxy/client/cgi.py +139 -0
- mapproxy/client/http.py +315 -0
- mapproxy/client/log.py +33 -0
- mapproxy/client/tile.py +150 -0
- mapproxy/client/wms.py +254 -0
- mapproxy/compat/__init__.py +46 -0
- mapproxy/compat/image.py +79 -0
- mapproxy/compat/itertools.py +29 -0
- mapproxy/compat/modules.py +13 -0
- mapproxy/config/__init__.py +22 -0
- mapproxy/config/config.py +201 -0
- mapproxy/config/coverage.py +107 -0
- mapproxy/config/defaults.py +98 -0
- mapproxy/config/loader.py +2286 -0
- mapproxy/config/spec.py +644 -0
- mapproxy/config/validator.py +239 -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 +593 -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 +142 -0
- mapproxy/featureinfo.py +252 -0
- mapproxy/grid.py +1170 -0
- mapproxy/image/__init__.py +536 -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 +75 -0
- mapproxy/image/merge.py +316 -0
- mapproxy/image/message.py +347 -0
- mapproxy/image/opts.py +182 -0
- mapproxy/image/tile.py +167 -0
- mapproxy/image/transform.py +350 -0
- mapproxy/layer.py +470 -0
- mapproxy/multiapp.py +231 -0
- mapproxy/proj.py +302 -0
- mapproxy/request/__init__.py +18 -0
- mapproxy/request/arcgis.py +259 -0
- mapproxy/request/base.py +476 -0
- mapproxy/request/tile.py +128 -0
- mapproxy/request/wms/__init__.py +793 -0
- mapproxy/request/wms/exception.py +99 -0
- mapproxy/request/wmts.py +436 -0
- mapproxy/response.py +237 -0
- mapproxy/script/__init__.py +0 -0
- mapproxy/script/conf/__init__.py +0 -0
- mapproxy/script/conf/app.py +195 -0
- mapproxy/script/conf/caches.py +45 -0
- mapproxy/script/conf/layers.py +54 -0
- mapproxy/script/conf/seeds.py +37 -0
- mapproxy/script/conf/sources.py +86 -0
- mapproxy/script/conf/utils.py +143 -0
- mapproxy/script/defrag.py +184 -0
- mapproxy/script/export.py +333 -0
- mapproxy/script/grids.py +188 -0
- mapproxy/script/scales.py +126 -0
- mapproxy/script/util.py +406 -0
- mapproxy/script/wms_capabilities.py +152 -0
- mapproxy/seed/__init__.py +0 -0
- mapproxy/seed/cachelock.py +121 -0
- mapproxy/seed/cleanup.py +187 -0
- mapproxy/seed/config.py +469 -0
- mapproxy/seed/script.py +388 -0
- mapproxy/seed/seeder.py +538 -0
- mapproxy/seed/spec.py +64 -0
- mapproxy/seed/util.py +254 -0
- mapproxy/service/__init__.py +14 -0
- mapproxy/service/base.py +46 -0
- mapproxy/service/demo.py +356 -0
- mapproxy/service/kml.py +331 -0
- mapproxy/service/ows.py +38 -0
- mapproxy/service/template_helper.py +53 -0
- mapproxy/service/templates/demo/capabilities_demo.html +16 -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 +103 -0
- mapproxy/service/templates/demo/wms_demo.html +140 -0
- mapproxy/service/templates/demo/wmts_demo.html +110 -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 +536 -0
- mapproxy/service/wms.py +851 -0
- mapproxy/service/wmts.py +381 -0
- mapproxy/source/__init__.py +75 -0
- mapproxy/source/arcgis.py +39 -0
- mapproxy/source/error.py +39 -0
- mapproxy/source/mapnik.py +259 -0
- mapproxy/source/tile.py +96 -0
- mapproxy/source/wms.py +270 -0
- mapproxy/srs.py +726 -0
- mapproxy/template.py +54 -0
- mapproxy/test/__init__.py +0 -0
- mapproxy/test/conftest.py +7 -0
- mapproxy/test/helper.py +247 -0
- mapproxy/test/http.py +494 -0
- mapproxy/test/image.py +210 -0
- mapproxy/test/mocker.py +2268 -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_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 +100 -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 +30 -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 +1134 -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_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 +106 -0
- mapproxy/test/system/test_demo_with_extra_service.py +53 -0
- mapproxy/test/system/test_dimensions.py +278 -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 +262 -0
- mapproxy/test/system/test_layergroups.py +160 -0
- mapproxy/test/system/test_legendgraphic.py +308 -0
- mapproxy/test/system/test_mapnik.py +161 -0
- mapproxy/test/system/test_mapserver.py +81 -0
- mapproxy/test/system/test_mixed_mode_format.py +195 -0
- mapproxy/test/system/test_multi_cache_layers.py +167 -0
- mapproxy/test/system/test_multiapp.py +92 -0
- mapproxy/test/system/test_refresh.py +207 -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 +422 -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 +276 -0
- mapproxy/test/system/test_tms_origin.py +46 -0
- mapproxy/test/system/test_util_conf.py +304 -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 +1611 -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 +425 -0
- mapproxy/test/test_http_helper.py +219 -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 +245 -0
- mapproxy/test/unit/test_auth.py +419 -0
- mapproxy/test/unit/test_cache.py +1193 -0
- mapproxy/test/unit/test_cache_azureblob.py +94 -0
- mapproxy/test/unit/test_cache_compact.py +319 -0
- mapproxy/test/unit/test_cache_couchdb.py +114 -0
- mapproxy/test/unit/test_cache_geopackage.py +221 -0
- mapproxy/test/unit/test_cache_redis.py +67 -0
- mapproxy/test/unit/test_cache_riak.py +76 -0
- mapproxy/test/unit/test_cache_s3.py +84 -0
- mapproxy/test/unit/test_cache_tile.py +427 -0
- mapproxy/test/unit/test_client.py +479 -0
- mapproxy/test/unit/test_client_arcgis.py +73 -0
- mapproxy/test/unit/test_client_cgi.py +136 -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 +1061 -0
- mapproxy/test/unit/test_conf_validator.py +416 -0
- mapproxy/test/unit/test_config.py +117 -0
- mapproxy/test/unit/test_decorate_img.py +185 -0
- mapproxy/test/unit/test_exceptions.py +258 -0
- mapproxy/test/unit/test_featureinfo.py +291 -0
- mapproxy/test/unit/test_file_lock_load.py +49 -0
- mapproxy/test/unit/test_geom.py +503 -0
- mapproxy/test/unit/test_grid.py +1258 -0
- mapproxy/test/unit/test_image.py +1053 -0
- mapproxy/test/unit/test_image_mask.py +181 -0
- mapproxy/test/unit/test_image_messages.py +197 -0
- mapproxy/test/unit/test_image_options.py +160 -0
- mapproxy/test/unit/test_isodate.py +122 -0
- mapproxy/test/unit/test_multiapp.py +163 -0
- mapproxy/test/unit/test_ogr_reader.py +50 -0
- mapproxy/test/unit/test_request.py +745 -0
- mapproxy/test/unit/test_request_wmts.py +178 -0
- mapproxy/test/unit/test_response.py +79 -0
- mapproxy/test/unit/test_seed.py +365 -0
- mapproxy/test/unit/test_seed_cachelock.py +90 -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 +69 -0
- mapproxy/tilefilter.py +59 -0
- mapproxy/util/__init__.py +0 -0
- mapproxy/util/async_.py +227 -0
- mapproxy/util/collections.py +132 -0
- mapproxy/util/coverage.py +329 -0
- mapproxy/util/escape.py +10 -0
- mapproxy/util/ext/__init__.py +14 -0
- mapproxy/util/ext/dictspec/__init__.py +1 -0
- mapproxy/util/ext/dictspec/spec.py +124 -0
- mapproxy/util/ext/dictspec/test/__init__.py +0 -0
- mapproxy/util/ext/dictspec/test/test_validator.py +274 -0
- mapproxy/util/ext/dictspec/validator.py +189 -0
- mapproxy/util/ext/local.py +196 -0
- mapproxy/util/ext/lockfile.py +138 -0
- mapproxy/util/ext/odict.py +330 -0
- mapproxy/util/ext/serving.py +508 -0
- mapproxy/util/ext/tempita/__init__.py +1174 -0
- mapproxy/util/ext/tempita/_looper.py +163 -0
- mapproxy/util/ext/tempita/compat3.py +46 -0
- mapproxy/util/ext/wmsparse/__init__.py +3 -0
- mapproxy/util/ext/wmsparse/duration.py +597 -0
- mapproxy/util/ext/wmsparse/parse.py +305 -0
- mapproxy/util/ext/wmsparse/test/__init__.py +0 -0
- mapproxy/util/ext/wmsparse/test/test_parse.py +162 -0
- mapproxy/util/ext/wmsparse/test/test_util.py +23 -0
- mapproxy/util/ext/wmsparse/test/wms-large-111.xml +2114 -0
- mapproxy/util/ext/wmsparse/test/wms-omniscale-111.xml +90 -0
- mapproxy/util/ext/wmsparse/test/wms-omniscale-130.xml +120 -0
- mapproxy/util/ext/wmsparse/test/wms_nasa_cap.xml +386 -0
- mapproxy/util/ext/wmsparse/util.py +187 -0
- mapproxy/util/fs.py +156 -0
- mapproxy/util/geom.py +295 -0
- mapproxy/util/lib.py +115 -0
- mapproxy/util/lock.py +163 -0
- mapproxy/util/ogr.py +231 -0
- mapproxy/util/py.py +81 -0
- mapproxy/util/times.py +75 -0
- mapproxy/util/yaml.py +56 -0
- mapproxy/version.py +31 -0
- mapproxy/wsgiapp.py +164 -0
- mapproxy-1.16.1.dist-info/METADATA +151 -0
- mapproxy-1.16.1.dist-info/RECORD +458 -0
- mapproxy-1.16.1.dist-info/WHEEL +5 -0
- mapproxy-1.16.1.dist-info/entry_points.txt +3 -0
- mapproxy-1.16.1.dist-info/licenses/AUTHORS.txt +33 -0
- mapproxy-1.16.1.dist-info/licenses/COPYING.txt +60 -0
- mapproxy-1.16.1.dist-info/licenses/LICENSE.txt +202 -0
- mapproxy-1.16.1.dist-info/top_level.txt +1 -0
mapproxy/service/wmts.py
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# This file is part of the MapProxy project.
|
|
2
|
+
# Copyright (C) 2011 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
|
+
"""
|
|
17
|
+
WMS service handler
|
|
18
|
+
"""
|
|
19
|
+
from __future__ import print_function
|
|
20
|
+
|
|
21
|
+
import re
|
|
22
|
+
|
|
23
|
+
from functools import partial
|
|
24
|
+
|
|
25
|
+
from mapproxy.compat import iteritems, itervalues, iterkeys
|
|
26
|
+
from mapproxy.request.wmts import (
|
|
27
|
+
wmts_request, make_wmts_rest_request_parser,
|
|
28
|
+
URLTemplateConverter,
|
|
29
|
+
FeatureInfoURLTemplateConverter,
|
|
30
|
+
)
|
|
31
|
+
from mapproxy.layer import InfoQuery
|
|
32
|
+
from mapproxy.featureinfo import combine_docs
|
|
33
|
+
from mapproxy.service.base import Server
|
|
34
|
+
from mapproxy.response import Response
|
|
35
|
+
from mapproxy.exception import RequestError
|
|
36
|
+
from mapproxy.util.coverage import load_limited_to
|
|
37
|
+
from mapproxy.util.ext.odict import odict
|
|
38
|
+
|
|
39
|
+
from mapproxy.template import template_loader, bunch
|
|
40
|
+
env = {'bunch': bunch}
|
|
41
|
+
get_template = template_loader(__name__, 'templates', namespace=env)
|
|
42
|
+
|
|
43
|
+
import logging
|
|
44
|
+
log = logging.getLogger(__name__)
|
|
45
|
+
|
|
46
|
+
class WMTSServer(Server):
|
|
47
|
+
service = 'wmts'
|
|
48
|
+
|
|
49
|
+
def __init__(self, layers, md, request_parser=None, max_tile_age=None, info_formats={}):
|
|
50
|
+
Server.__init__(self)
|
|
51
|
+
self.request_parser = request_parser or wmts_request
|
|
52
|
+
self.md = md
|
|
53
|
+
self.max_tile_age = max_tile_age
|
|
54
|
+
self.layers, self.matrix_sets = self._matrix_sets(layers)
|
|
55
|
+
self.capabilities_class = Capabilities
|
|
56
|
+
self.fi_transformers = None
|
|
57
|
+
self.info_formats = info_formats
|
|
58
|
+
|
|
59
|
+
def _matrix_sets(self, layers):
|
|
60
|
+
sets = {}
|
|
61
|
+
layers_grids = odict()
|
|
62
|
+
for layer in layers.values():
|
|
63
|
+
grid = layer.grid
|
|
64
|
+
if not grid.supports_access_with_origin('nw'):
|
|
65
|
+
log.warning("skipping layer '%s' for WMTS, grid '%s' of cache '%s' is not compatible with WMTS",
|
|
66
|
+
layer.name, grid.name, layer.md['cache_name'])
|
|
67
|
+
continue
|
|
68
|
+
if grid.name not in sets:
|
|
69
|
+
try:
|
|
70
|
+
sets[grid.name] = TileMatrixSet(grid)
|
|
71
|
+
except AssertionError:
|
|
72
|
+
continue # TODO
|
|
73
|
+
layers_grids.setdefault(layer.name, odict())[grid.name] = layer
|
|
74
|
+
wmts_layers = odict()
|
|
75
|
+
for layer_name, layers in layers_grids.items():
|
|
76
|
+
wmts_layers[layer_name] = WMTSTileLayer(layers)
|
|
77
|
+
return wmts_layers, sets.values()
|
|
78
|
+
|
|
79
|
+
def capabilities(self, request):
|
|
80
|
+
service = self._service_md(request)
|
|
81
|
+
layers = self.authorized_tile_layers(request.http.environ)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
result = self.capabilities_class(service, layers, self.matrix_sets, info_formats=self.info_formats).render(request)
|
|
85
|
+
return Response(result, mimetype='application/xml')
|
|
86
|
+
|
|
87
|
+
def tile(self, request):
|
|
88
|
+
self.check_request(request)
|
|
89
|
+
|
|
90
|
+
tile_layer = self.layers[request.layer][request.tilematrixset]
|
|
91
|
+
if not request.format:
|
|
92
|
+
request.format = tile_layer.format
|
|
93
|
+
|
|
94
|
+
self.check_request_dimensions(tile_layer, request)
|
|
95
|
+
|
|
96
|
+
limited_to = self.authorize_tile_layer(tile_layer, request)
|
|
97
|
+
|
|
98
|
+
def decorate_img(image):
|
|
99
|
+
query_extent = tile_layer.grid.srs.srs_code, tile_layer.tile_bbox(request)
|
|
100
|
+
return self.decorate_img(image, 'wmts', [tile_layer.name], request.http.environ, query_extent)
|
|
101
|
+
|
|
102
|
+
tile = tile_layer.render(request, coverage=limited_to, decorate_img=decorate_img)
|
|
103
|
+
|
|
104
|
+
# set the content_type to tile.format and not to request.format ( to support mixed_mode)
|
|
105
|
+
resp = Response(tile.as_buffer(), content_type='image/' + tile.format)
|
|
106
|
+
resp.cache_headers(tile.timestamp, etag_data=(tile.timestamp, tile.size),
|
|
107
|
+
max_age=self.max_tile_age)
|
|
108
|
+
resp.make_conditional(request.http)
|
|
109
|
+
return resp
|
|
110
|
+
|
|
111
|
+
def featureinfo(self, request):
|
|
112
|
+
infos = []
|
|
113
|
+
self.check_request(request, self.info_formats)
|
|
114
|
+
|
|
115
|
+
tile_layer = self.layers[request.layer][request.tilematrixset]
|
|
116
|
+
if not request.format:
|
|
117
|
+
request.format = tile_layer.format
|
|
118
|
+
|
|
119
|
+
feature_count = None
|
|
120
|
+
# WMTS REST style request do not have request params
|
|
121
|
+
if hasattr(request, 'params'):
|
|
122
|
+
feature_count = request.params.get('feature_count', None)
|
|
123
|
+
|
|
124
|
+
bbox = tile_layer.grid.tile_bbox(request.tile)
|
|
125
|
+
query = InfoQuery(bbox, tile_layer.grid.tile_size, tile_layer.grid.srs, request.pos,
|
|
126
|
+
request.infoformat, feature_count=feature_count)
|
|
127
|
+
self.check_request_dimensions(tile_layer, request)
|
|
128
|
+
coverage = self.authorize_tile_layer(tile_layer, request, featureinfo=True)
|
|
129
|
+
|
|
130
|
+
if not tile_layer.info_sources:
|
|
131
|
+
raise RequestError('layer %s not queryable' % str(request.layer),
|
|
132
|
+
code='OperationNotSupported', request=request)
|
|
133
|
+
|
|
134
|
+
if coverage and not coverage.contains(query.coord, query.srs):
|
|
135
|
+
infos = []
|
|
136
|
+
else:
|
|
137
|
+
for source in tile_layer.info_sources:
|
|
138
|
+
info = source.get_info(query)
|
|
139
|
+
if info is None:
|
|
140
|
+
continue
|
|
141
|
+
infos.append(info)
|
|
142
|
+
|
|
143
|
+
mimetype = request.infoformat
|
|
144
|
+
|
|
145
|
+
if not infos:
|
|
146
|
+
return Response('', mimetype=mimetype)
|
|
147
|
+
|
|
148
|
+
resp, _ = combine_docs(infos)
|
|
149
|
+
|
|
150
|
+
return Response(resp, mimetype=mimetype)
|
|
151
|
+
|
|
152
|
+
def authorize_tile_layer(self, tile_layer, request, featureinfo=False):
|
|
153
|
+
if 'mapproxy.authorize' not in request.http.environ:
|
|
154
|
+
return
|
|
155
|
+
|
|
156
|
+
query_extent = tile_layer.grid.srs.srs_code, tile_layer.tile_bbox(request)
|
|
157
|
+
|
|
158
|
+
service = 'wmts'
|
|
159
|
+
key = 'tile'
|
|
160
|
+
if featureinfo:
|
|
161
|
+
service += '.featureinfo'
|
|
162
|
+
key = 'featureinfo'
|
|
163
|
+
|
|
164
|
+
result = request.http.environ['mapproxy.authorize'](service, [tile_layer.name],
|
|
165
|
+
query_extent=query_extent, environ=request.http.environ)
|
|
166
|
+
if result['authorized'] == 'unauthenticated':
|
|
167
|
+
raise RequestError('unauthorized', status=401)
|
|
168
|
+
if result['authorized'] == 'full':
|
|
169
|
+
return
|
|
170
|
+
if result['authorized'] == 'partial':
|
|
171
|
+
if result['layers'].get(tile_layer.name, {}).get(key, False) == True:
|
|
172
|
+
limited_to = result['layers'][tile_layer.name].get('limited_to')
|
|
173
|
+
if not limited_to:
|
|
174
|
+
limited_to = result.get('limited_to')
|
|
175
|
+
if limited_to:
|
|
176
|
+
return load_limited_to(limited_to)
|
|
177
|
+
else:
|
|
178
|
+
return None
|
|
179
|
+
raise RequestError('forbidden', status=403)
|
|
180
|
+
|
|
181
|
+
def authorized_tile_layers(self, env):
|
|
182
|
+
if 'mapproxy.authorize' in env:
|
|
183
|
+
result = env['mapproxy.authorize']('wmts', [l for l in self.layers],
|
|
184
|
+
query_extent=None, environ=env)
|
|
185
|
+
if result['authorized'] == 'unauthenticated':
|
|
186
|
+
raise RequestError('unauthorized', status=401)
|
|
187
|
+
if result['authorized'] == 'full':
|
|
188
|
+
return self.layers.values()
|
|
189
|
+
if result['authorized'] == 'none':
|
|
190
|
+
raise RequestError('forbidden', status=403)
|
|
191
|
+
allowed_layers = []
|
|
192
|
+
for layer in itervalues(self.layers):
|
|
193
|
+
if result['layers'].get(layer.name, {}).get('tile', False) == True:
|
|
194
|
+
allowed_layers.append(layer)
|
|
195
|
+
return allowed_layers
|
|
196
|
+
else:
|
|
197
|
+
return self.layers.values()
|
|
198
|
+
|
|
199
|
+
def check_request(self, request, info_formats=None):
|
|
200
|
+
request.make_request()
|
|
201
|
+
if request.layer not in self.layers:
|
|
202
|
+
raise RequestError('unknown layer: ' + str(request.layer),
|
|
203
|
+
code='InvalidParameterValue', request=request)
|
|
204
|
+
if request.tilematrixset not in self.layers[request.layer]:
|
|
205
|
+
raise RequestError('unknown tilematrixset: ' + str(request.tilematrixset),
|
|
206
|
+
code='InvalidParameterValue', request=request)
|
|
207
|
+
|
|
208
|
+
if info_formats is not None:
|
|
209
|
+
if '/' in request.infoformat: # mimetype
|
|
210
|
+
if request.infoformat not in self.info_formats.values():
|
|
211
|
+
raise RequestError('unknown infoformat: ' + str(request.infoformat),
|
|
212
|
+
code='InvalidParameterValue', request=request)
|
|
213
|
+
else: # RESTful suffix
|
|
214
|
+
if request.infoformat not in self.info_formats:
|
|
215
|
+
raise RequestError('unknown infoformat: ' + str(request.infoformat),
|
|
216
|
+
code='InvalidParameterValue', request=request)
|
|
217
|
+
# set mimetype as infoformat
|
|
218
|
+
request.infoformat = self.info_formats[request.infoformat]
|
|
219
|
+
|
|
220
|
+
def check_request_dimensions(self, tile_layer, request):
|
|
221
|
+
# allow arbitrary dimensions in KVP service
|
|
222
|
+
# actual used values are checked later in TileLayer
|
|
223
|
+
pass
|
|
224
|
+
|
|
225
|
+
def _service_md(self, tile_request):
|
|
226
|
+
md = dict(self.md)
|
|
227
|
+
md['url'] = tile_request.url
|
|
228
|
+
return md
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class WMTSRestServer(WMTSServer):
|
|
232
|
+
"""
|
|
233
|
+
OGC WMTS 1.0.0 RESTful Server
|
|
234
|
+
"""
|
|
235
|
+
service = None
|
|
236
|
+
names = ('wmts',)
|
|
237
|
+
request_methods = ('tile', 'capabilities')
|
|
238
|
+
default_template = '/{Layer}/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.{Format}'
|
|
239
|
+
default_info_template = '/{Layer}/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}/{I}/{J}.{InfoFormat}'
|
|
240
|
+
|
|
241
|
+
def __init__(self, layers, md, max_tile_age=None, template=None, fi_template=None, info_formats={}):
|
|
242
|
+
WMTSServer.__init__(self, layers, md)
|
|
243
|
+
self.max_tile_age = max_tile_age
|
|
244
|
+
self.template = template or self.default_template
|
|
245
|
+
self.fi_template = fi_template or self.default_info_template
|
|
246
|
+
self.info_formats = info_formats
|
|
247
|
+
self.url_converter = URLTemplateConverter(self.template)
|
|
248
|
+
self.fi_url_converter = FeatureInfoURLTemplateConverter(self.fi_template)
|
|
249
|
+
self.request_parser = make_wmts_rest_request_parser(self.url_converter, self.fi_url_converter)
|
|
250
|
+
self.capabilities_class = partial(RestfulCapabilities, url_converter=self.url_converter, fi_url_converter=self.fi_url_converter)
|
|
251
|
+
|
|
252
|
+
def check_request_dimensions(self, tile_layer, request):
|
|
253
|
+
# check that unknown dimension for this layer are set to default
|
|
254
|
+
if request.dimensions:
|
|
255
|
+
for dimension, value in iteritems(request.dimensions):
|
|
256
|
+
dimension = dimension.lower()
|
|
257
|
+
if dimension not in tile_layer.dimensions and value != 'default':
|
|
258
|
+
raise RequestError('unknown dimension: ' + str(dimension),
|
|
259
|
+
code='InvalidParameterValue', request=request)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class Capabilities(object):
|
|
263
|
+
"""
|
|
264
|
+
Renders WMS capabilities documents.
|
|
265
|
+
"""
|
|
266
|
+
def __init__(self, server_md, layers, matrix_sets, info_formats={}):
|
|
267
|
+
self.service = server_md
|
|
268
|
+
self.layers = layers
|
|
269
|
+
self.info_formats = info_formats
|
|
270
|
+
self.matrix_sets = matrix_sets
|
|
271
|
+
|
|
272
|
+
def render(self, _map_request):
|
|
273
|
+
return self._render_template(_map_request.capabilities_template)
|
|
274
|
+
|
|
275
|
+
def template_context(self):
|
|
276
|
+
return dict(service=bunch(default='', **self.service),
|
|
277
|
+
restful=False,
|
|
278
|
+
layers=self.layers,
|
|
279
|
+
info_formats=self.info_formats,
|
|
280
|
+
tile_matrix_sets=self.matrix_sets)
|
|
281
|
+
|
|
282
|
+
def _render_template(self, template):
|
|
283
|
+
template = get_template(template)
|
|
284
|
+
doc = template.substitute(**self.template_context())
|
|
285
|
+
# strip blank lines
|
|
286
|
+
doc = '\n'.join(l for l in doc.split('\n') if l.rstrip())
|
|
287
|
+
return doc
|
|
288
|
+
|
|
289
|
+
class RestfulCapabilities(Capabilities):
|
|
290
|
+
def __init__(self, server_md, layers, matrix_sets, url_converter, fi_url_converter, info_formats={}):
|
|
291
|
+
Capabilities.__init__(self, server_md, layers, matrix_sets, info_formats=info_formats)
|
|
292
|
+
self.url_converter = url_converter
|
|
293
|
+
self.fi_url_converter = fi_url_converter
|
|
294
|
+
|
|
295
|
+
def template_context(self):
|
|
296
|
+
return dict(service=bunch(default='', **self.service),
|
|
297
|
+
restful=True,
|
|
298
|
+
layers=self.layers,
|
|
299
|
+
info_formats=self.info_formats,
|
|
300
|
+
tile_matrix_sets=self.matrix_sets,
|
|
301
|
+
resource_template=self.url_converter.template,
|
|
302
|
+
fi_resource_template=self.fi_url_converter.template,
|
|
303
|
+
# dimension_key maps lowercase dimensions to the actual
|
|
304
|
+
# casing from the restful template
|
|
305
|
+
dimension_keys=dict((k.lower(), k) for k in self.url_converter.dimensions),
|
|
306
|
+
format_resource_template=format_resource_template,
|
|
307
|
+
format_info_resource_template=format_info_resource_template,
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
def format_resource_template(layer, template, service):
|
|
311
|
+
if '{Format}' in template:
|
|
312
|
+
template = template.replace('{Format}', layer.format)
|
|
313
|
+
|
|
314
|
+
if '{Layer}' in template:
|
|
315
|
+
template = template.replace('{Layer}', layer.name)
|
|
316
|
+
|
|
317
|
+
return service.url + template
|
|
318
|
+
|
|
319
|
+
def format_info_resource_template(layer, template, info_format, service):
|
|
320
|
+
if '{InfoFormat}' in template:
|
|
321
|
+
template = template.replace('{InfoFormat}', info_format)
|
|
322
|
+
|
|
323
|
+
if '{Layer}' in template:
|
|
324
|
+
template = template.replace('{Layer}', layer.name)
|
|
325
|
+
|
|
326
|
+
return service.url + template
|
|
327
|
+
|
|
328
|
+
class WMTSTileLayer(object):
|
|
329
|
+
"""
|
|
330
|
+
Wrap multiple TileLayers for the same cache but with different grids.
|
|
331
|
+
"""
|
|
332
|
+
def __init__(self, layers):
|
|
333
|
+
self.grids = [lyr.grid for lyr in layers.values()]
|
|
334
|
+
self.layers = layers
|
|
335
|
+
self._layer = layers[next(iterkeys(layers))]
|
|
336
|
+
|
|
337
|
+
def __getattr__(self, name):
|
|
338
|
+
return getattr(self._layer, name)
|
|
339
|
+
|
|
340
|
+
def __contains__(self, gridname):
|
|
341
|
+
return gridname in self.layers
|
|
342
|
+
|
|
343
|
+
def __getitem__(self, gridname):
|
|
344
|
+
return self.layers[gridname]
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
# calculated from well-known scale set GoogleCRS84Quad
|
|
349
|
+
METERS_PER_DEEGREE = 111319.4907932736
|
|
350
|
+
|
|
351
|
+
def meter_per_unit(srs):
|
|
352
|
+
if srs.is_latlong:
|
|
353
|
+
return METERS_PER_DEEGREE
|
|
354
|
+
return 1
|
|
355
|
+
|
|
356
|
+
class TileMatrixSet(object):
|
|
357
|
+
def __init__(self, grid):
|
|
358
|
+
self.grid = grid
|
|
359
|
+
self.name = grid.name
|
|
360
|
+
self.srs_name = grid.srs.srs_code
|
|
361
|
+
self.tile_matrices = list(self._tile_matrices())
|
|
362
|
+
|
|
363
|
+
def __iter__(self):
|
|
364
|
+
return iter(self.tile_matrices)
|
|
365
|
+
|
|
366
|
+
def _tile_matrices(self):
|
|
367
|
+
for level, res in self.grid.resolutions.iteritems():
|
|
368
|
+
origin = self.grid.origin_tile(level, 'ul')
|
|
369
|
+
bbox = self.grid.tile_bbox(origin)
|
|
370
|
+
topleft = bbox[0], bbox[3]
|
|
371
|
+
if self.grid.srs.is_axis_order_ne:
|
|
372
|
+
topleft = bbox[3], bbox[0]
|
|
373
|
+
grid_size = self.grid.grid_sizes[level]
|
|
374
|
+
scale_denom = res / (0.28 / 1000) * meter_per_unit(self.grid.srs)
|
|
375
|
+
yield bunch(
|
|
376
|
+
identifier=level,
|
|
377
|
+
topleft=topleft,
|
|
378
|
+
grid_size=grid_size,
|
|
379
|
+
scale_denom=scale_denom,
|
|
380
|
+
tile_size=self.grid.tile_size,
|
|
381
|
+
)
|
|
@@ -0,0 +1,75 @@
|
|
|
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
|
+
"""
|
|
17
|
+
Map/information sources for layers or tile cache.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from mapproxy.layer import (
|
|
21
|
+
MapLayer, MapExtent, DefaultMapExtent, MapError, MapBBOXError, BlankImage, InfoLayer
|
|
22
|
+
)
|
|
23
|
+
from mapproxy.image.message import message_image
|
|
24
|
+
from mapproxy.image.opts import ImageOptions
|
|
25
|
+
from mapproxy.srs import SRS
|
|
26
|
+
|
|
27
|
+
class SourceError(MapError):
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
class SourceBBOXError(SourceError, MapBBOXError):
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
class InvalidSourceQuery(SourceError):
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
class InfoSource(InfoLayer):
|
|
37
|
+
def get_info(self, query):
|
|
38
|
+
raise NotImplementedError
|
|
39
|
+
|
|
40
|
+
class LegendSource(object):
|
|
41
|
+
def get_legend(self, query):
|
|
42
|
+
raise NotImplementedError
|
|
43
|
+
|
|
44
|
+
class DebugSource(MapLayer):
|
|
45
|
+
def __init__(self):
|
|
46
|
+
MapLayer.__init__(self)
|
|
47
|
+
self.extent = DefaultMapExtent()
|
|
48
|
+
self.res_range = None
|
|
49
|
+
|
|
50
|
+
def get_map(self, query):
|
|
51
|
+
bbox = query.bbox
|
|
52
|
+
w = bbox[2] - bbox[0]
|
|
53
|
+
h = bbox[3] - bbox[1]
|
|
54
|
+
res_x = w/query.size[0]
|
|
55
|
+
res_y = h/query.size[1]
|
|
56
|
+
debug_info = "bbox: %r\nres: %.8f(%.8f)" % (bbox, res_x, res_y)
|
|
57
|
+
return message_image(debug_info, size=query.size,
|
|
58
|
+
image_opts=ImageOptions(transparent=True))
|
|
59
|
+
|
|
60
|
+
class DummySource(MapLayer):
|
|
61
|
+
supports_meta_tiles = True
|
|
62
|
+
|
|
63
|
+
"""
|
|
64
|
+
Source that always returns a blank image.
|
|
65
|
+
|
|
66
|
+
Used internally for 'offline' sources (e.g. seed_only).
|
|
67
|
+
"""
|
|
68
|
+
def __init__(self, coverage=None):
|
|
69
|
+
MapLayer.__init__(self)
|
|
70
|
+
self.image_opts.transparent = True
|
|
71
|
+
self.extent = MapExtent((-180, -90, 180, 90), SRS(4326))
|
|
72
|
+
self.extent = MapExtent(coverage.bbox, coverage.srs) if coverage else DefaultMapExtent()
|
|
73
|
+
|
|
74
|
+
def get_map(self, query):
|
|
75
|
+
raise BlankImage()
|
|
@@ -0,0 +1,39 @@
|
|
|
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 mapproxy.source.wms import WMSSource, WMSInfoSource
|
|
17
|
+
|
|
18
|
+
import logging
|
|
19
|
+
log = logging.getLogger('mapproxy.source.arcgis')
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ArcGISSource(WMSSource):
|
|
23
|
+
def __init__(self, client, image_opts=None, coverage=None,
|
|
24
|
+
res_range=None, supported_srs=None, supported_formats=None,
|
|
25
|
+
error_handler=None):
|
|
26
|
+
WMSSource.__init__(self, client, image_opts=image_opts,
|
|
27
|
+
coverage=coverage, res_range=res_range,
|
|
28
|
+
supported_srs=supported_srs,
|
|
29
|
+
supported_formats=supported_formats,
|
|
30
|
+
error_handler=error_handler)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ArcGISInfoSource(WMSInfoSource):
|
|
34
|
+
def __init__(self, client):
|
|
35
|
+
self.client = client
|
|
36
|
+
|
|
37
|
+
def get_info(self, query):
|
|
38
|
+
doc = self.client.get_info(query)
|
|
39
|
+
return doc
|
mapproxy/source/error.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# This file is part of the MapProxy project.
|
|
2
|
+
# Copyright (C) 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
|
+
from mapproxy.image.opts import ImageOptions
|
|
17
|
+
from mapproxy.image import BlankImageSource
|
|
18
|
+
|
|
19
|
+
class HTTPSourceErrorHandler(object):
|
|
20
|
+
def __init__(self):
|
|
21
|
+
self.response_error_codes = {}
|
|
22
|
+
|
|
23
|
+
def add_handler(self, http_code, color, cacheable=False, authorize_stale=False):
|
|
24
|
+
self.response_error_codes[http_code] = (color, cacheable, authorize_stale)
|
|
25
|
+
|
|
26
|
+
def handle(self, status_code, query):
|
|
27
|
+
color = cacheable = None
|
|
28
|
+
if status_code in self.response_error_codes:
|
|
29
|
+
color, cacheable, authorize_stale = self.response_error_codes[status_code]
|
|
30
|
+
elif 'other' in self.response_error_codes:
|
|
31
|
+
color, cacheable, authorize_stale = self.response_error_codes['other']
|
|
32
|
+
else:
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
transparent = len(color) == 4
|
|
36
|
+
image_opts = ImageOptions(bgcolor=color, transparent=transparent)
|
|
37
|
+
img_source = BlankImageSource(query.size, image_opts, cacheable=cacheable)
|
|
38
|
+
img_source.authorize_stale = authorize_stale
|
|
39
|
+
return img_source
|