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
mapproxy/client/tile.py
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
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.client.http import retrieve_image
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TileClient(object):
|
|
20
|
+
def __init__(self, url_template, http_client=None, grid=None):
|
|
21
|
+
self.url_template = url_template
|
|
22
|
+
self.http_client = http_client
|
|
23
|
+
self.grid = grid
|
|
24
|
+
|
|
25
|
+
def get_tile(self, tile_coord, format=None):
|
|
26
|
+
url = self.url_template.substitute(tile_coord, format, self.grid)
|
|
27
|
+
if self.http_client:
|
|
28
|
+
return self.http_client.open_image(url)
|
|
29
|
+
else:
|
|
30
|
+
return retrieve_image(url)
|
|
31
|
+
|
|
32
|
+
def __repr__(self):
|
|
33
|
+
return '%s(%r)' % (self.__class__.__name__, self.url_template)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class TileURLTemplate(object):
|
|
37
|
+
"""
|
|
38
|
+
>>> t = TileURLTemplate('http://foo/tiles/%(z)s/%(x)d/%(y)s.png')
|
|
39
|
+
>>> t.substitute((7, 4, 3))
|
|
40
|
+
'http://foo/tiles/3/7/4.png'
|
|
41
|
+
|
|
42
|
+
>>> t = TileURLTemplate('http://foo/tiles/%(z)s/%(x)d/%(y)s.png')
|
|
43
|
+
>>> t.substitute((7, 4, 3))
|
|
44
|
+
'http://foo/tiles/3/7/4.png'
|
|
45
|
+
|
|
46
|
+
>>> t = TileURLTemplate('http://foo/tiles/%(tc_path)s.png')
|
|
47
|
+
>>> t.substitute((7, 4, 3))
|
|
48
|
+
'http://foo/tiles/03/000/000/007/000/000/004.png'
|
|
49
|
+
|
|
50
|
+
>>> t = TileURLTemplate('http://foo/tms/1.0.0/%(tms_path)s.%(format)s')
|
|
51
|
+
>>> t.substitute((7, 4, 3))
|
|
52
|
+
'http://foo/tms/1.0.0/3/7/4.png'
|
|
53
|
+
|
|
54
|
+
>>> t = TileURLTemplate('http://foo/tms/1.0.0/lyr/%(tms_path)s.%(format)s')
|
|
55
|
+
>>> t.substitute((7, 4, 3), 'jpeg')
|
|
56
|
+
'http://foo/tms/1.0.0/lyr/3/7/4.jpeg'
|
|
57
|
+
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def __init__(self, template, format='png'):
|
|
61
|
+
self.template = template
|
|
62
|
+
self.format = format
|
|
63
|
+
self.with_quadkey = True if '%(quadkey)' in template else False
|
|
64
|
+
self.with_tc_path = True if '%(tc_path)' in template else False
|
|
65
|
+
self.with_tms_path = True if '%(tms_path)' in template else False
|
|
66
|
+
self.with_arcgiscache_path = True if '%(arcgiscache_path)' in template else False
|
|
67
|
+
self.with_bbox = True if '%(bbox)' in template else False
|
|
68
|
+
|
|
69
|
+
def substitute(self, tile_coord, format=None, grid=None):
|
|
70
|
+
x, y, z = tile_coord
|
|
71
|
+
data = dict(x=x, y=y, z=z)
|
|
72
|
+
data['format'] = format or self.format
|
|
73
|
+
if self.with_quadkey:
|
|
74
|
+
data['quadkey'] = quadkey(tile_coord)
|
|
75
|
+
if self.with_tc_path:
|
|
76
|
+
data['tc_path'] = tilecache_path(tile_coord)
|
|
77
|
+
if self.with_tms_path:
|
|
78
|
+
data['tms_path'] = tms_path(tile_coord)
|
|
79
|
+
if self.with_arcgiscache_path:
|
|
80
|
+
data['arcgiscache_path'] = arcgiscache_path(tile_coord)
|
|
81
|
+
if self.with_bbox:
|
|
82
|
+
data['bbox'] = bbox(tile_coord, grid)
|
|
83
|
+
|
|
84
|
+
return self.template % data
|
|
85
|
+
|
|
86
|
+
def __repr__(self):
|
|
87
|
+
return '%s(%r, format=%r)' % (
|
|
88
|
+
self.__class__.__name__, self.template, self.format)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def tilecache_path(tile_coord):
|
|
92
|
+
"""
|
|
93
|
+
>>> tilecache_path((1234567, 87654321, 9))
|
|
94
|
+
'09/001/234/567/087/654/321'
|
|
95
|
+
"""
|
|
96
|
+
x, y, z = tile_coord
|
|
97
|
+
parts = ("%02d" % z,
|
|
98
|
+
"%03d" % int(x / 1000000),
|
|
99
|
+
"%03d" % (int(x / 1000) % 1000),
|
|
100
|
+
"%03d" % (int(x) % 1000),
|
|
101
|
+
"%03d" % int(y / 1000000),
|
|
102
|
+
"%03d" % (int(y / 1000) % 1000),
|
|
103
|
+
"%03d" % (int(y) % 1000))
|
|
104
|
+
return '/'.join(parts)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def quadkey(tile_coord):
|
|
108
|
+
"""
|
|
109
|
+
>>> quadkey((0, 0, 1))
|
|
110
|
+
'0'
|
|
111
|
+
>>> quadkey((1, 0, 1))
|
|
112
|
+
'1'
|
|
113
|
+
>>> quadkey((1, 2, 2))
|
|
114
|
+
'21'
|
|
115
|
+
"""
|
|
116
|
+
x, y, z = tile_coord
|
|
117
|
+
quadKey = ""
|
|
118
|
+
for i in range(z, 0, -1):
|
|
119
|
+
digit = 0
|
|
120
|
+
mask = 1 << (i-1)
|
|
121
|
+
if (x & mask) != 0:
|
|
122
|
+
digit += 1
|
|
123
|
+
if (y & mask) != 0:
|
|
124
|
+
digit += 2
|
|
125
|
+
quadKey += str(digit)
|
|
126
|
+
return quadKey
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def tms_path(tile_coord):
|
|
130
|
+
"""
|
|
131
|
+
>>> tms_path((1234567, 87654321, 9))
|
|
132
|
+
'9/1234567/87654321'
|
|
133
|
+
"""
|
|
134
|
+
return '%d/%d/%d' % (tile_coord[2], tile_coord[0], tile_coord[1])
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def arcgiscache_path(tile_coord):
|
|
138
|
+
"""
|
|
139
|
+
>>> arcgiscache_path((1234567, 87654321, 9))
|
|
140
|
+
'L09/R05397fb1/C0012d687'
|
|
141
|
+
"""
|
|
142
|
+
return 'L%02d/R%08x/C%08x' % (tile_coord[2], tile_coord[1], tile_coord[0])
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def bbox(tile_coord, grid):
|
|
146
|
+
"""
|
|
147
|
+
>>> from mapproxy.grid import tile_grid
|
|
148
|
+
>>> grid = tile_grid(4326, bbox=(0, -15, 10, -5))
|
|
149
|
+
>>> bbox((0, 0, 0), grid)
|
|
150
|
+
'0.00000000,-15.00000000,10.00000000,-5.00000000'
|
|
151
|
+
>>> bbox((0, 0, 1), grid)
|
|
152
|
+
'0.00000000,-15.00000000,5.00000000,-10.00000000'
|
|
153
|
+
|
|
154
|
+
>>> grid = tile_grid(4326, bbox=(0, -15, 10, -5), origin='nw')
|
|
155
|
+
>>> bbox((0, 0, 1), grid)
|
|
156
|
+
'0.00000000,-10.00000000,5.00000000,-5.00000000'
|
|
157
|
+
"""
|
|
158
|
+
return '%.8f,%.8f,%.8f,%.8f' % grid.tile_bbox(tile_coord)
|
mapproxy/client/wms.py
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
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
|
+
WMS clients for maps and information.
|
|
18
|
+
"""
|
|
19
|
+
import sys
|
|
20
|
+
|
|
21
|
+
from mapproxy.request.base import split_mime_type
|
|
22
|
+
from mapproxy.layer import InfoQuery
|
|
23
|
+
from mapproxy.source import SourceError
|
|
24
|
+
from mapproxy.client.http import HTTPClient
|
|
25
|
+
from mapproxy.srs import make_lin_transf, SRS, SupportedSRS
|
|
26
|
+
from mapproxy.image import ImageSource
|
|
27
|
+
from mapproxy.image.opts import ImageOptions
|
|
28
|
+
from mapproxy.featureinfo import create_featureinfo_doc
|
|
29
|
+
|
|
30
|
+
import logging
|
|
31
|
+
log = logging.getLogger('mapproxy.source.wms')
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class WMSClient(object):
|
|
35
|
+
def __init__(self, request_template, http_client=None,
|
|
36
|
+
http_method=None, lock=None, fwd_req_params=None):
|
|
37
|
+
self.request_template = request_template
|
|
38
|
+
self.http_client = http_client or HTTPClient()
|
|
39
|
+
self.http_method = http_method
|
|
40
|
+
self.lock = lock
|
|
41
|
+
self.fwd_req_params = fwd_req_params or set()
|
|
42
|
+
|
|
43
|
+
def retrieve(self, query, format):
|
|
44
|
+
log.debug(query)
|
|
45
|
+
if self.http_method == 'POST':
|
|
46
|
+
request_method = 'POST'
|
|
47
|
+
elif self.http_method == 'GET':
|
|
48
|
+
request_method = 'GET'
|
|
49
|
+
else: # 'AUTO'
|
|
50
|
+
if 'sld_body' in self.request_template.params:
|
|
51
|
+
request_method = 'POST'
|
|
52
|
+
else:
|
|
53
|
+
request_method = 'GET'
|
|
54
|
+
|
|
55
|
+
if request_method == 'POST':
|
|
56
|
+
url, data = self._query_data(query, format)
|
|
57
|
+
if isinstance(data, str):
|
|
58
|
+
data = data.encode('utf-8')
|
|
59
|
+
else:
|
|
60
|
+
url = self._query_url(query, format)
|
|
61
|
+
data = None
|
|
62
|
+
|
|
63
|
+
if self.lock:
|
|
64
|
+
with self.lock():
|
|
65
|
+
resp = self.http_client.open(url, data=data)
|
|
66
|
+
else:
|
|
67
|
+
resp = self.http_client.open(url, data=data)
|
|
68
|
+
self._check_resp(resp, url)
|
|
69
|
+
return resp
|
|
70
|
+
|
|
71
|
+
def _check_resp(self, resp, url):
|
|
72
|
+
if not resp.headers.get('Content-type', 'image/').startswith('image/'):
|
|
73
|
+
# log response depending on content-type
|
|
74
|
+
if resp.headers['Content-type'].startswith(('text/', 'application/vnd.ogc')):
|
|
75
|
+
log_size = 8000 # larger xml exception
|
|
76
|
+
else:
|
|
77
|
+
log_size = 100 # image?
|
|
78
|
+
data = resp.read(log_size+1)
|
|
79
|
+
|
|
80
|
+
truncated = ''
|
|
81
|
+
if len(data) == log_size+1:
|
|
82
|
+
data = data[:-1]
|
|
83
|
+
truncated = ' [output truncated]'
|
|
84
|
+
|
|
85
|
+
if sys.version_info >= (3, 5, 0):
|
|
86
|
+
data = data.decode('utf-8', 'backslashreplace')
|
|
87
|
+
else:
|
|
88
|
+
data = data.decode('ascii', 'ignore')
|
|
89
|
+
|
|
90
|
+
log.warning("no image returned from source WMS: {}, response was: '{}'{}".format(url, data, truncated))
|
|
91
|
+
raise SourceError('no image returned from source WMS: %s' % (url, ))
|
|
92
|
+
|
|
93
|
+
def _query_url(self, query, format):
|
|
94
|
+
return self._query_req(query, format).complete_url
|
|
95
|
+
|
|
96
|
+
def _query_data(self, query, format):
|
|
97
|
+
req = self._query_req(query, format)
|
|
98
|
+
return req.url.rstrip('?'), req.query_string
|
|
99
|
+
|
|
100
|
+
def _query_req(self, query, format):
|
|
101
|
+
req = self.request_template.copy()
|
|
102
|
+
req.params.bbox = query.bbox
|
|
103
|
+
req.params.size = query.size
|
|
104
|
+
req.params.srs = query.srs.srs_code
|
|
105
|
+
req.params.format = format
|
|
106
|
+
req.params.update(query.dimensions_for_params(self.fwd_req_params))
|
|
107
|
+
return req
|
|
108
|
+
|
|
109
|
+
def combined_client(self, other, query):
|
|
110
|
+
"""
|
|
111
|
+
Return a new WMSClient that combines this request with the `other`. Returns
|
|
112
|
+
``None`` if the clients are not combinable (e.g. different URLs).
|
|
113
|
+
"""
|
|
114
|
+
if self.request_template.url != other.request_template.url:
|
|
115
|
+
return None
|
|
116
|
+
|
|
117
|
+
new_req = self.request_template.copy()
|
|
118
|
+
new_req.params.layers = new_req.params.layers + other.request_template.params.layers
|
|
119
|
+
|
|
120
|
+
return WMSClient(new_req, http_client=self.http_client,
|
|
121
|
+
http_method=self.http_method, fwd_req_params=self.fwd_req_params)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class WMSInfoClient(object):
|
|
125
|
+
def __init__(self, request_template, supported_srs=None, http_client=None):
|
|
126
|
+
self.request_template = request_template
|
|
127
|
+
self.http_client = http_client or HTTPClient()
|
|
128
|
+
if not supported_srs and self.request_template.params.srs is not None:
|
|
129
|
+
supported_srs = SupportedSRS([SRS(self.request_template.params.srs)])
|
|
130
|
+
self.supported_srs = supported_srs
|
|
131
|
+
|
|
132
|
+
def get_info(self, query):
|
|
133
|
+
if self.supported_srs and query.srs not in self.supported_srs:
|
|
134
|
+
query = self._get_transformed_query(query)
|
|
135
|
+
resp = self._retrieve(query)
|
|
136
|
+
|
|
137
|
+
# use from template if available
|
|
138
|
+
info_format = self.request_template.params.get('info_format')
|
|
139
|
+
if not info_format:
|
|
140
|
+
# otherwise from response
|
|
141
|
+
info_format = resp.headers.get('Content-type', None)
|
|
142
|
+
if not info_format:
|
|
143
|
+
# otherwise from query
|
|
144
|
+
info_format = query.info_format
|
|
145
|
+
return create_featureinfo_doc(resp.read(), info_format)
|
|
146
|
+
|
|
147
|
+
def _get_transformed_query(self, query):
|
|
148
|
+
"""
|
|
149
|
+
Handle FI requests for unsupported SRS.
|
|
150
|
+
"""
|
|
151
|
+
req_srs = query.srs
|
|
152
|
+
req_bbox = query.bbox
|
|
153
|
+
req_coord = make_lin_transf((0, 0, query.size[0], query.size[1]), req_bbox)(query.pos)
|
|
154
|
+
|
|
155
|
+
info_srs = self.supported_srs.best_srs(req_srs)
|
|
156
|
+
info_bbox = req_srs.transform_bbox_to(info_srs, req_bbox)
|
|
157
|
+
# calculate new info_size to keep square pixels after transform_bbox_to
|
|
158
|
+
info_aratio = (info_bbox[3] - info_bbox[1])/(info_bbox[2] - info_bbox[0])
|
|
159
|
+
info_size = query.size[0], int(info_aratio*query.size[0])
|
|
160
|
+
|
|
161
|
+
info_coord = req_srs.transform_to(info_srs, req_coord)
|
|
162
|
+
info_pos = make_lin_transf((info_bbox), (0, 0, info_size[0], info_size[1]))(info_coord)
|
|
163
|
+
info_pos = int(round(info_pos[0])), int(round(info_pos[1]))
|
|
164
|
+
|
|
165
|
+
info_query = InfoQuery(
|
|
166
|
+
bbox=info_bbox,
|
|
167
|
+
size=info_size,
|
|
168
|
+
srs=info_srs,
|
|
169
|
+
pos=info_pos,
|
|
170
|
+
info_format=query.info_format,
|
|
171
|
+
feature_count=query.feature_count,
|
|
172
|
+
)
|
|
173
|
+
return info_query
|
|
174
|
+
|
|
175
|
+
def _retrieve(self, query):
|
|
176
|
+
url = self._query_url(query)
|
|
177
|
+
return self.http_client.open(url)
|
|
178
|
+
|
|
179
|
+
def _query_url(self, query):
|
|
180
|
+
req = self.request_template.copy()
|
|
181
|
+
req.params.bbox = query.bbox
|
|
182
|
+
req.params.size = query.size
|
|
183
|
+
req.params.pos = query.pos
|
|
184
|
+
if query.feature_count:
|
|
185
|
+
req.params['feature_count'] = query.feature_count
|
|
186
|
+
req.params['query_layers'] = req.params['layers']
|
|
187
|
+
if 'info_format' not in req.params and query.info_format:
|
|
188
|
+
req.params['info_format'] = query.info_format
|
|
189
|
+
if not req.params.format:
|
|
190
|
+
req.params.format = query.format or 'image/png'
|
|
191
|
+
req.params.srs = query.srs.srs_code
|
|
192
|
+
|
|
193
|
+
return req.complete_url
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
class WMSLegendClient(object):
|
|
197
|
+
def __init__(self, request_template, http_client=None):
|
|
198
|
+
self.request_template = request_template
|
|
199
|
+
self.http_client = http_client or HTTPClient()
|
|
200
|
+
|
|
201
|
+
def get_legend(self, query):
|
|
202
|
+
resp = self._retrieve(query)
|
|
203
|
+
format = split_mime_type(query.format)[1]
|
|
204
|
+
self._check_resp(resp, format)
|
|
205
|
+
if format == 'json':
|
|
206
|
+
return resp
|
|
207
|
+
else:
|
|
208
|
+
return ImageSource(resp, image_opts=ImageOptions(format=format))
|
|
209
|
+
|
|
210
|
+
def _retrieve(self, query):
|
|
211
|
+
url = self._query_url(query)
|
|
212
|
+
return self.http_client.open(url)
|
|
213
|
+
|
|
214
|
+
def _check_resp(self, resp, request_format):
|
|
215
|
+
if request_format == 'json':
|
|
216
|
+
if not resp.headers.get('Content-type') == 'application/json':
|
|
217
|
+
raise SourceError('no json returned from source WMS')
|
|
218
|
+
else:
|
|
219
|
+
if not resp.headers.get('Content-type', 'image/').startswith('image/'):
|
|
220
|
+
raise SourceError('no image returned from source WMS')
|
|
221
|
+
|
|
222
|
+
def _query_url(self, query):
|
|
223
|
+
req = self.request_template.copy()
|
|
224
|
+
if not req.params.format:
|
|
225
|
+
if query.format == 'json':
|
|
226
|
+
req.params.format = 'application/json'
|
|
227
|
+
else:
|
|
228
|
+
req.params.format = query.format or 'image/png'
|
|
229
|
+
if query.scale:
|
|
230
|
+
req.params['scale'] = query.scale
|
|
231
|
+
return req.complete_url
|
|
232
|
+
|
|
233
|
+
@property
|
|
234
|
+
def identifier(self):
|
|
235
|
+
return (self.request_template.url, self.request_template.params.layer)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class WMSLegendURLClient(object):
|
|
239
|
+
def __init__(self, static_url, http_client=None):
|
|
240
|
+
self.url = static_url
|
|
241
|
+
self.http_client = http_client or HTTPClient()
|
|
242
|
+
|
|
243
|
+
def get_legend(self, query):
|
|
244
|
+
resp = self.http_client.open(self.url)
|
|
245
|
+
format = split_mime_type(query.format)[1]
|
|
246
|
+
self._check_resp(resp)
|
|
247
|
+
return ImageSource(resp, image_opts=ImageOptions(format=format))
|
|
248
|
+
|
|
249
|
+
def _check_resp(self, resp):
|
|
250
|
+
if not resp.headers.get('Content-type', 'image/').startswith('image/'):
|
|
251
|
+
raise SourceError('no image returned from static LegendURL')
|
|
252
|
+
|
|
253
|
+
@property
|
|
254
|
+
def identifier(self):
|
|
255
|
+
return (self.url, None)
|
|
File without changes
|
mapproxy/compat/image.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
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
|
+
import warnings
|
|
17
|
+
|
|
18
|
+
__all__ = ['Image', 'ImageColor', 'ImageDraw', 'ImageFont', 'ImagePalette',
|
|
19
|
+
'ImageChops', 'quantize']
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
import PIL
|
|
23
|
+
from PIL import Image, ImageColor, ImageDraw, ImageFont, ImagePalette, ImageChops, ImageMath
|
|
24
|
+
from PIL.TiffImagePlugin import ImageFileDirectory_v2, TiffTags
|
|
25
|
+
# prevent pyflakes warnings
|
|
26
|
+
Image, ImageColor, ImageDraw, ImageFont, ImagePalette, ImageChops, ImageMath
|
|
27
|
+
ImageFileDirectory_v2, TiffTags
|
|
28
|
+
PIL_VERSION = getattr(PIL, '__version__') or getattr(PIL, 'PILLOW_VERSION')
|
|
29
|
+
PIL_VERSION_TUPLE = tuple(int(i) for i in PIL_VERSION.split("."))
|
|
30
|
+
except ImportError:
|
|
31
|
+
# allow MapProxy to start without PIL (for tilecache only).
|
|
32
|
+
# issue warning and raise ImportError on first use of
|
|
33
|
+
# a function that requires PIL
|
|
34
|
+
warnings.warn('PIL is not available')
|
|
35
|
+
|
|
36
|
+
class NoPIL(object):
|
|
37
|
+
def __getattr__(self, name):
|
|
38
|
+
if name.startswith('__'):
|
|
39
|
+
raise AttributeError()
|
|
40
|
+
raise ImportError('PIL is not available')
|
|
41
|
+
ImageDraw = ImageFont = ImagePalette = ImageChops = NoPIL()
|
|
42
|
+
# add some dummy stuff required on import/load time
|
|
43
|
+
Image = NoPIL()
|
|
44
|
+
Image.NEAREST = Image.BILINEAR = Image.BICUBIC = 1
|
|
45
|
+
Image.Image = NoPIL
|
|
46
|
+
ImageColor = NoPIL()
|
|
47
|
+
ImageFileDirectory_v2 = NoPIL()
|
|
48
|
+
TiffTags = NoPIL()
|
|
49
|
+
ImageMath = NoPIL()
|
|
50
|
+
ImageColor.getrgb = lambda x: x
|
|
51
|
+
PIL_VERSION = None
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def has_alpha_composite_support():
|
|
55
|
+
return hasattr(Image, 'alpha_composite')
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def transform_uses_center():
|
|
59
|
+
# transformation behavior changed with Pillow 3.4 to use pixel centers
|
|
60
|
+
# https://github.com/python-pillow/Pillow/commit/5232361718bae0f0ccda76bfd5b390ebf9179b18
|
|
61
|
+
if not PIL_VERSION or PIL_VERSION.startswith(('1.', '2.', '3.0', '3.1', '3.2', '3.3')):
|
|
62
|
+
return False
|
|
63
|
+
return True
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def quantize_pil(img, colors=256, alpha=False, defaults=None):
|
|
67
|
+
if hasattr(Image, 'FASTOCTREE'):
|
|
68
|
+
if not alpha:
|
|
69
|
+
img = img.convert('RGB')
|
|
70
|
+
img = img.quantize(colors, Image.FASTOCTREE)
|
|
71
|
+
else:
|
|
72
|
+
if alpha:
|
|
73
|
+
img.load() # split might fail if image is not loaded
|
|
74
|
+
alpha = img.split()[3]
|
|
75
|
+
img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=colors-1)
|
|
76
|
+
mask = Image.eval(alpha, lambda a: 255 if a <= 128 else 0)
|
|
77
|
+
img.paste(255, mask)
|
|
78
|
+
if defaults is not None:
|
|
79
|
+
defaults['transparency'] = 255
|
|
80
|
+
else:
|
|
81
|
+
img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=colors)
|
|
82
|
+
|
|
83
|
+
return img
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
quantize = quantize_pil
|
|
@@ -0,0 +1,22 @@
|
|
|
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.config.config import (
|
|
17
|
+
base_config, abspath, load_base_config, load_default_config,
|
|
18
|
+
finish_base_config, Options, local_base_config,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
__all__ = ['base_config', 'abspath', 'load_base_config', 'load_default_config',
|
|
22
|
+
'finish_base_config', 'Options', 'local_base_config']
|