MapProxy 2.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- MapProxy-2.1.0.dist-info/AUTHORS.txt +33 -0
- MapProxy-2.1.0.dist-info/COPYING.txt +60 -0
- MapProxy-2.1.0.dist-info/LICENSE.txt +202 -0
- MapProxy-2.1.0.dist-info/METADATA +165 -0
- MapProxy-2.1.0.dist-info/RECORD +459 -0
- MapProxy-2.1.0.dist-info/WHEEL +5 -0
- MapProxy-2.1.0.dist-info/entry_points.txt +4 -0
- MapProxy-2.1.0.dist-info/top_level.txt +1 -0
- mapproxy/__init__.py +0 -0
- mapproxy/cache/__init__.py +36 -0
- mapproxy/cache/azureblob.py +145 -0
- mapproxy/cache/base.py +120 -0
- mapproxy/cache/compact.py +665 -0
- mapproxy/cache/couchdb.py +301 -0
- mapproxy/cache/dummy.py +36 -0
- mapproxy/cache/file.py +200 -0
- mapproxy/cache/geopackage.py +647 -0
- mapproxy/cache/legend.py +87 -0
- mapproxy/cache/mbtiles.py +411 -0
- mapproxy/cache/meta.py +80 -0
- mapproxy/cache/path.py +261 -0
- mapproxy/cache/redis.py +152 -0
- mapproxy/cache/renderd.py +100 -0
- mapproxy/cache/riak.py +206 -0
- mapproxy/cache/s3.py +209 -0
- mapproxy/cache/tile.py +736 -0
- mapproxy/client/__init__.py +0 -0
- mapproxy/client/arcgis.py +82 -0
- mapproxy/client/cgi.py +141 -0
- mapproxy/client/http.py +295 -0
- mapproxy/client/log.py +33 -0
- mapproxy/client/tile.py +158 -0
- mapproxy/client/wms.py +255 -0
- mapproxy/compat/__init__.py +0 -0
- mapproxy/compat/image.py +86 -0
- mapproxy/config/__init__.py +22 -0
- mapproxy/config/config-schema.json +813 -0
- mapproxy/config/config.py +213 -0
- mapproxy/config/coverage.py +108 -0
- mapproxy/config/defaults.py +102 -0
- mapproxy/config/loader.py +2399 -0
- mapproxy/config/spec.py +657 -0
- mapproxy/config/validator.py +242 -0
- mapproxy/config_template/__init__.py +0 -0
- mapproxy/config_template/base_config/config.wsgi +10 -0
- mapproxy/config_template/base_config/full_example.yaml +598 -0
- mapproxy/config_template/base_config/full_seed_example.yaml +79 -0
- mapproxy/config_template/base_config/log.ini +35 -0
- mapproxy/config_template/base_config/mapproxy.yaml +60 -0
- mapproxy/config_template/base_config/seed.yaml +27 -0
- mapproxy/exception.py +149 -0
- mapproxy/featureinfo.py +251 -0
- mapproxy/grid.py +1199 -0
- mapproxy/image/__init__.py +549 -0
- mapproxy/image/fonts/DejaVuSans.ttf +0 -0
- mapproxy/image/fonts/DejaVuSansMono.ttf +0 -0
- mapproxy/image/fonts/LICENSE +99 -0
- mapproxy/image/fonts/__init__.py +0 -0
- mapproxy/image/mask.py +79 -0
- mapproxy/image/merge.py +323 -0
- mapproxy/image/message.py +357 -0
- mapproxy/image/opts.py +185 -0
- mapproxy/image/tile.py +171 -0
- mapproxy/image/transform.py +350 -0
- mapproxy/layer.py +489 -0
- mapproxy/multiapp.py +230 -0
- mapproxy/proj.py +309 -0
- mapproxy/request/__init__.py +18 -0
- mapproxy/request/arcgis.py +268 -0
- mapproxy/request/base.py +466 -0
- mapproxy/request/tile.py +131 -0
- mapproxy/request/wms/__init__.py +829 -0
- mapproxy/request/wms/exception.py +107 -0
- mapproxy/request/wmts.py +442 -0
- mapproxy/response.py +237 -0
- mapproxy/script/__init__.py +0 -0
- mapproxy/script/conf/__init__.py +0 -0
- mapproxy/script/conf/app.py +222 -0
- mapproxy/script/conf/caches.py +44 -0
- mapproxy/script/conf/geopackage.py +136 -0
- mapproxy/script/conf/layers.py +54 -0
- mapproxy/script/conf/seeds.py +36 -0
- mapproxy/script/conf/sources.py +88 -0
- mapproxy/script/conf/utils.py +148 -0
- mapproxy/script/defrag.py +187 -0
- mapproxy/script/export.py +337 -0
- mapproxy/script/grids.py +198 -0
- mapproxy/script/scales.py +134 -0
- mapproxy/script/util.py +410 -0
- mapproxy/script/wms_capabilities.py +160 -0
- mapproxy/seed/__init__.py +0 -0
- mapproxy/seed/cachelock.py +127 -0
- mapproxy/seed/cleanup.py +191 -0
- mapproxy/seed/config.py +481 -0
- mapproxy/seed/script.py +391 -0
- mapproxy/seed/seeder.py +551 -0
- mapproxy/seed/spec.py +66 -0
- mapproxy/seed/util.py +266 -0
- mapproxy/service/__init__.py +14 -0
- mapproxy/service/base.py +45 -0
- mapproxy/service/demo.py +364 -0
- mapproxy/service/kml.py +333 -0
- mapproxy/service/ows.py +39 -0
- mapproxy/service/template_helper.py +55 -0
- mapproxy/service/templates/demo/capabilities_demo.html +18 -0
- mapproxy/service/templates/demo/demo.html +181 -0
- mapproxy/service/templates/demo/openlayers-demo.cfg +16 -0
- mapproxy/service/templates/demo/static/img/blank.gif +0 -0
- mapproxy/service/templates/demo/static/img/east-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/north-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/south-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/west-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-minus-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-plus-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-world-mini.png +0 -0
- mapproxy/service/templates/demo/static/logo.png +0 -0
- mapproxy/service/templates/demo/static/ol.css +345 -0
- mapproxy/service/templates/demo/static/ol.js +4 -0
- mapproxy/service/templates/demo/static/proj4.min.js +1 -0
- mapproxy/service/templates/demo/static/proj4defs.js +1 -0
- mapproxy/service/templates/demo/static/site.css +137 -0
- mapproxy/service/templates/demo/static/theme/default/framedCloud.css +0 -0
- mapproxy/service/templates/demo/static/theme/default/google.css +17 -0
- mapproxy/service/templates/demo/static/theme/default/ie6-style.css +10 -0
- mapproxy/service/templates/demo/static/theme/default/style.css +482 -0
- mapproxy/service/templates/demo/static.html +34 -0
- mapproxy/service/templates/demo/tms_demo.html +117 -0
- mapproxy/service/templates/demo/wms_demo.html +144 -0
- mapproxy/service/templates/demo/wmts_demo.html +118 -0
- mapproxy/service/templates/tms_capabilities.xml +13 -0
- mapproxy/service/templates/tms_exception.xml +4 -0
- mapproxy/service/templates/tms_root_resource.xml +7 -0
- mapproxy/service/templates/tms_tilemap_capabilities.xml +14 -0
- mapproxy/service/templates/wms100capabilities.xml +112 -0
- mapproxy/service/templates/wms100exception.xml +4 -0
- mapproxy/service/templates/wms110capabilities.xml +152 -0
- mapproxy/service/templates/wms110exception.xml +5 -0
- mapproxy/service/templates/wms111capabilities.xml +183 -0
- mapproxy/service/templates/wms111exception.xml +5 -0
- mapproxy/service/templates/wms130capabilities.xml +326 -0
- mapproxy/service/templates/wms130exception.xml +8 -0
- mapproxy/service/templates/wmts100capabilities.xml +155 -0
- mapproxy/service/templates/wmts100exception.xml +9 -0
- mapproxy/service/tile.py +540 -0
- mapproxy/service/wms.py +868 -0
- mapproxy/service/wmts.py +387 -0
- mapproxy/source/__init__.py +83 -0
- mapproxy/source/arcgis.py +39 -0
- mapproxy/source/error.py +40 -0
- mapproxy/source/mapnik.py +262 -0
- mapproxy/source/tile.py +97 -0
- mapproxy/source/wms.py +273 -0
- mapproxy/srs.py +734 -0
- mapproxy/template.py +54 -0
- mapproxy/test/__init__.py +0 -0
- mapproxy/test/conftest.py +8 -0
- mapproxy/test/helper.py +255 -0
- mapproxy/test/http.py +511 -0
- mapproxy/test/image.py +219 -0
- mapproxy/test/mocker.py +2291 -0
- mapproxy/test/schemas/inspire/common/1.0/common.xsd +1461 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_bul.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_cze.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_dan.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_dut.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_eng.xsd +155 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_est.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_fin.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_fre.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_ger.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_gle.xsd +109 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_gre.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_hun.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_ita.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_lav.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_lit.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_mlt.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_pol.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_por.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_rum.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_slo.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_slv.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_spa.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_swe.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/network.xsd +521 -0
- mapproxy/test/schemas/inspire/inspire_vs/1.0/inspire_vs.xsd +19 -0
- mapproxy/test/schemas/kml/2.2.0/ReadMe.txt +14 -0
- mapproxy/test/schemas/kml/2.2.0/atom-author-link.xsd +66 -0
- mapproxy/test/schemas/kml/2.2.0/ogckml22.xsd +1646 -0
- mapproxy/test/schemas/kml/2.2.0/xAL.xsd +1680 -0
- mapproxy/test/schemas/ows/1.1.0/ReadMe.txt +87 -0
- mapproxy/test/schemas/ows/1.1.0/ows19115subset.xsd +235 -0
- mapproxy/test/schemas/ows/1.1.0/owsAll.xsd +23 -0
- mapproxy/test/schemas/ows/1.1.0/owsCommon.xsd +157 -0
- mapproxy/test/schemas/ows/1.1.0/owsContents.xsd +86 -0
- mapproxy/test/schemas/ows/1.1.0/owsDataIdentification.xsd +127 -0
- mapproxy/test/schemas/ows/1.1.0/owsDomainType.xsd +279 -0
- mapproxy/test/schemas/ows/1.1.0/owsExceptionReport.xsd +76 -0
- mapproxy/test/schemas/ows/1.1.0/owsGetCapabilities.xsd +112 -0
- mapproxy/test/schemas/ows/1.1.0/owsGetResourceByID.xsd +51 -0
- mapproxy/test/schemas/ows/1.1.0/owsInputOutputData.xsd +59 -0
- mapproxy/test/schemas/ows/1.1.0/owsManifest.xsd +125 -0
- mapproxy/test/schemas/ows/1.1.0/owsOperationsMetadata.xsd +140 -0
- mapproxy/test/schemas/ows/1.1.0/owsServiceIdentification.xsd +60 -0
- mapproxy/test/schemas/ows/1.1.0/owsServiceProvider.xsd +47 -0
- mapproxy/test/schemas/sld/1.1.0/sld_capabilities.xsd +27 -0
- mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.dtd +353 -0
- mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.xml +188 -0
- mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.dtd +524 -0
- mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.xml +260 -0
- mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.dtd +273 -0
- mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.xml +303 -0
- mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.dtd +6 -0
- mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.xml +33 -0
- mapproxy/test/schemas/wms/1.1.1/OGC-exception.xsd +68 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd +274 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd +5 -0
- mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.dtd +276 -0
- mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.xml +303 -0
- mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.dtd +6 -0
- mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.xml +33 -0
- mapproxy/test/schemas/wms/1.3.0/ReadMe.txt +8 -0
- mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xml +277 -0
- mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xsd +611 -0
- mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xml +34 -0
- mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xsd +28 -0
- mapproxy/test/schemas/wmsc/1.1.1/OGC-exception.xsd +68 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_MS_Capabilities.dtd +283 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_exception_1_1_1.dtd +5 -0
- mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.dtd +276 -0
- mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.xml +303 -0
- mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.dtd +6 -0
- mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.xml +33 -0
- mapproxy/test/schemas/wmts/1.0/ReadMe.txt +32 -0
- mapproxy/test/schemas/wmts/1.0/wmts.xsd +28 -0
- mapproxy/test/schemas/wmts/1.0/wmtsAbstract.wsdl +151 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_request.xsd +38 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_response.xsd +564 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_request.xsd +57 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_response.xsd +72 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetTile_request.xsd +91 -0
- mapproxy/test/schemas/wmts/1.0/wmtsKVP.xsd +76 -0
- mapproxy/test/schemas/wmts/1.0/wmtsPayload_response.xsd +70 -0
- mapproxy/test/schemas/xlink/1.0.0/ReadMe.txt +6 -0
- mapproxy/test/schemas/xlink/1.0.0/xlinks.xsd +122 -0
- mapproxy/test/schemas/xml.xsd +287 -0
- mapproxy/test/system/__init__.py +98 -0
- mapproxy/test/system/fixture/arcgis.yaml +57 -0
- mapproxy/test/system/fixture/auth.yaml +70 -0
- mapproxy/test/system/fixture/cache.mbtiles +0 -0
- mapproxy/test/system/fixture/cache_azureblob.yaml +59 -0
- mapproxy/test/system/fixture/cache_band_merge.yaml +73 -0
- mapproxy/test/system/fixture/cache_bulk_meta_tiles.yaml +24 -0
- mapproxy/test/system/fixture/cache_coverage.yaml +84 -0
- mapproxy/test/system/fixture/cache_data/dop_cache_EPSG3857/00/000/000/000/000/000/000.png +0 -0
- mapproxy/test/system/fixture/cache_data/wms_cache_EPSG900913/01/000/000/000/000/000/001.jpeg +0 -0
- mapproxy/test/system/fixture/cache_data/wms_cache_transparent_EPSG900913/01/000/000/000/000/000/001.png +0 -0
- mapproxy/test/system/fixture/cache_geopackage.yaml +56 -0
- mapproxy/test/system/fixture/cache_grid_names.yaml +50 -0
- mapproxy/test/system/fixture/cache_mbtiles.yaml +28 -0
- mapproxy/test/system/fixture/cache_s3.yaml +58 -0
- mapproxy/test/system/fixture/cache_source.yaml +81 -0
- mapproxy/test/system/fixture/combined_sources.yaml +130 -0
- mapproxy/test/system/fixture/coverage.yaml +77 -0
- mapproxy/test/system/fixture/demo.yaml +135 -0
- mapproxy/test/system/fixture/dimension.yaml +59 -0
- mapproxy/test/system/fixture/disable_storage.yaml +25 -0
- mapproxy/test/system/fixture/empty_ogrdata.geojson +1 -0
- mapproxy/test/system/fixture/formats.yaml +72 -0
- mapproxy/test/system/fixture/inspire.yaml +101 -0
- mapproxy/test/system/fixture/inspire_full.yaml +124 -0
- mapproxy/test/system/fixture/kml_layer.yaml +66 -0
- mapproxy/test/system/fixture/layer.yaml +260 -0
- mapproxy/test/system/fixture/layergroups.yaml +57 -0
- mapproxy/test/system/fixture/layergroups_root.yaml +106 -0
- mapproxy/test/system/fixture/legendgraphic.yaml +93 -0
- mapproxy/test/system/fixture/mapnik_source.yaml +66 -0
- mapproxy/test/system/fixture/mapproxy_export.yaml +12 -0
- mapproxy/test/system/fixture/mapserver.yaml +23 -0
- mapproxy/test/system/fixture/minimal_cgi.py +16 -0
- mapproxy/test/system/fixture/mixed_mode.yaml +49 -0
- mapproxy/test/system/fixture/multi_cache_layers.yaml +111 -0
- mapproxy/test/system/fixture/multiapp1.yaml +20 -0
- mapproxy/test/system/fixture/multiapp2.yaml +19 -0
- mapproxy/test/system/fixture/renderd_client.yaml +55 -0
- mapproxy/test/system/fixture/scalehints.yaml +70 -0
- mapproxy/test/system/fixture/seed.yaml +94 -0
- mapproxy/test/system/fixture/seed_mapproxy.yaml +39 -0
- mapproxy/test/system/fixture/seed_old.yaml +12 -0
- mapproxy/test/system/fixture/seed_timeouts.yaml +12 -0
- mapproxy/test/system/fixture/seed_timeouts_mapproxy.yaml +27 -0
- mapproxy/test/system/fixture/seedonly.yaml +51 -0
- mapproxy/test/system/fixture/sld.yaml +35 -0
- mapproxy/test/system/fixture/source_errors.yaml +84 -0
- mapproxy/test/system/fixture/source_errors_raise.yaml +82 -0
- mapproxy/test/system/fixture/tileservice_origin.yaml +26 -0
- mapproxy/test/system/fixture/tileservice_refresh.yaml +59 -0
- mapproxy/test/system/fixture/tilesource_minmax_res.yaml +22 -0
- mapproxy/test/system/fixture/util-conf-base-grids.yaml +5 -0
- mapproxy/test/system/fixture/util-conf-overwrite.yaml +13 -0
- mapproxy/test/system/fixture/util-conf-wms-111-cap.xml +90 -0
- mapproxy/test/system/fixture/util_grids.yaml +29 -0
- mapproxy/test/system/fixture/util_wms_capabilities111.xml +130 -0
- mapproxy/test/system/fixture/util_wms_capabilities130.xml +100 -0
- mapproxy/test/system/fixture/util_wms_capabilities_service_exception.xml +5 -0
- mapproxy/test/system/fixture/watermark.yaml +50 -0
- mapproxy/test/system/fixture/wms_srs_extent.yaml +39 -0
- mapproxy/test/system/fixture/wms_versions.yaml +38 -0
- mapproxy/test/system/fixture/wmts.yaml +134 -0
- mapproxy/test/system/fixture/wmts_dimensions.yaml +57 -0
- mapproxy/test/system/fixture/xslt_featureinfo.yaml +54 -0
- mapproxy/test/system/fixture/xslt_featureinfo_input.yaml +51 -0
- mapproxy/test/system/test_arcgis.py +156 -0
- mapproxy/test/system/test_auth.py +1133 -0
- mapproxy/test/system/test_behind_proxy.py +75 -0
- mapproxy/test/system/test_bulk_meta_tiles.py +106 -0
- mapproxy/test/system/test_cache_azureblob.py +127 -0
- mapproxy/test/system/test_cache_band_merge.py +103 -0
- mapproxy/test/system/test_cache_coverage.py +168 -0
- mapproxy/test/system/test_cache_geopackage.py +144 -0
- mapproxy/test/system/test_cache_grid_names.py +89 -0
- mapproxy/test/system/test_cache_mbtiles.py +85 -0
- mapproxy/test/system/test_cache_s3.py +115 -0
- mapproxy/test/system/test_cache_source.py +146 -0
- mapproxy/test/system/test_combined_sources.py +335 -0
- mapproxy/test/system/test_coverage.py +140 -0
- mapproxy/test/system/test_decorate_img.py +214 -0
- mapproxy/test/system/test_demo.py +56 -0
- mapproxy/test/system/test_demo_with_extra_service.py +57 -0
- mapproxy/test/system/test_dimensions.py +279 -0
- mapproxy/test/system/test_disable_storage.py +42 -0
- mapproxy/test/system/test_formats.py +219 -0
- mapproxy/test/system/test_inspire_vs.py +173 -0
- mapproxy/test/system/test_kml.py +264 -0
- mapproxy/test/system/test_layergroups.py +160 -0
- mapproxy/test/system/test_legendgraphic.py +308 -0
- mapproxy/test/system/test_mapnik.py +162 -0
- mapproxy/test/system/test_mapserver.py +83 -0
- mapproxy/test/system/test_mixed_mode_format.py +201 -0
- mapproxy/test/system/test_multi_cache_layers.py +169 -0
- mapproxy/test/system/test_multiapp.py +92 -0
- mapproxy/test/system/test_refresh.py +206 -0
- mapproxy/test/system/test_renderd_client.py +304 -0
- mapproxy/test/system/test_response_headers.py +54 -0
- mapproxy/test/system/test_scalehints.py +140 -0
- mapproxy/test/system/test_seed.py +425 -0
- mapproxy/test/system/test_seed_only.py +93 -0
- mapproxy/test/system/test_sld.py +120 -0
- mapproxy/test/system/test_source_errors.py +377 -0
- mapproxy/test/system/test_tilesource_minmax_res.py +54 -0
- mapproxy/test/system/test_tms.py +277 -0
- mapproxy/test/system/test_tms_origin.py +46 -0
- mapproxy/test/system/test_util_conf.py +434 -0
- mapproxy/test/system/test_util_export.py +210 -0
- mapproxy/test/system/test_util_grids.py +88 -0
- mapproxy/test/system/test_util_wms_capabilities.py +182 -0
- mapproxy/test/system/test_watermark.py +91 -0
- mapproxy/test/system/test_wms.py +1616 -0
- mapproxy/test/system/test_wms_srs_extent.py +165 -0
- mapproxy/test/system/test_wms_version.py +85 -0
- mapproxy/test/system/test_wmsc.py +116 -0
- mapproxy/test/system/test_wmts.py +334 -0
- mapproxy/test/system/test_wmts_dimensions.py +206 -0
- mapproxy/test/system/test_wmts_restful.py +198 -0
- mapproxy/test/system/test_xslt_featureinfo.py +423 -0
- mapproxy/test/test_http_helper.py +217 -0
- mapproxy/test/unit/__init__.py +0 -0
- mapproxy/test/unit/epsg +2 -0
- mapproxy/test/unit/polygons/polygons.dbf +0 -0
- mapproxy/test/unit/polygons/polygons.shp +0 -0
- mapproxy/test/unit/polygons/polygons.shx +0 -0
- mapproxy/test/unit/test_async.py +242 -0
- mapproxy/test/unit/test_auth.py +430 -0
- mapproxy/test/unit/test_cache.py +1356 -0
- mapproxy/test/unit/test_cache_azureblob.py +97 -0
- mapproxy/test/unit/test_cache_compact.py +324 -0
- mapproxy/test/unit/test_cache_couchdb.py +118 -0
- mapproxy/test/unit/test_cache_geopackage.py +256 -0
- mapproxy/test/unit/test_cache_redis.py +123 -0
- mapproxy/test/unit/test_cache_riak.py +80 -0
- mapproxy/test/unit/test_cache_s3.py +93 -0
- mapproxy/test/unit/test_cache_tile.py +477 -0
- mapproxy/test/unit/test_client.py +488 -0
- mapproxy/test/unit/test_client_arcgis.py +74 -0
- mapproxy/test/unit/test_client_cgi.py +140 -0
- mapproxy/test/unit/test_collections.py +116 -0
- mapproxy/test/unit/test_concat_legends.py +37 -0
- mapproxy/test/unit/test_conf_loader.py +1267 -0
- mapproxy/test/unit/test_conf_validator.py +427 -0
- mapproxy/test/unit/test_config.py +118 -0
- mapproxy/test/unit/test_decorate_img.py +185 -0
- mapproxy/test/unit/test_exceptions.py +270 -0
- mapproxy/test/unit/test_featureinfo.py +313 -0
- mapproxy/test/unit/test_file_lock_load.py +49 -0
- mapproxy/test/unit/test_geom.py +512 -0
- mapproxy/test/unit/test_grid.py +1279 -0
- mapproxy/test/unit/test_image.py +1051 -0
- mapproxy/test/unit/test_image_mask.py +181 -0
- mapproxy/test/unit/test_image_messages.py +209 -0
- mapproxy/test/unit/test_image_options.py +160 -0
- mapproxy/test/unit/test_isodate.py +118 -0
- mapproxy/test/unit/test_multiapp.py +163 -0
- mapproxy/test/unit/test_ogr_reader.py +51 -0
- mapproxy/test/unit/test_request.py +745 -0
- mapproxy/test/unit/test_request_wmts.py +178 -0
- mapproxy/test/unit/test_response.py +78 -0
- mapproxy/test/unit/test_seed.py +365 -0
- mapproxy/test/unit/test_seed_cachelock.py +91 -0
- mapproxy/test/unit/test_srs.py +215 -0
- mapproxy/test/unit/test_tiled_source.py +122 -0
- mapproxy/test/unit/test_tilefilter.py +31 -0
- mapproxy/test/unit/test_times.py +25 -0
- mapproxy/test/unit/test_timeutils.py +50 -0
- mapproxy/test/unit/test_util_conf_utils.py +75 -0
- mapproxy/test/unit/test_utils.py +476 -0
- mapproxy/test/unit/test_wms_capabilities.py +44 -0
- mapproxy/test/unit/test_wms_layer.py +113 -0
- mapproxy/test/unit/test_yaml.py +68 -0
- mapproxy/tilefilter.py +61 -0
- mapproxy/util/__init__.py +0 -0
- mapproxy/util/async_.py +229 -0
- mapproxy/util/collections.py +134 -0
- mapproxy/util/coverage.py +337 -0
- mapproxy/util/ext/__init__.py +14 -0
- mapproxy/util/ext/dictspec/__init__.py +1 -0
- mapproxy/util/ext/dictspec/spec.py +131 -0
- mapproxy/util/ext/dictspec/test/__init__.py +0 -0
- mapproxy/util/ext/dictspec/test/test_validator.py +278 -0
- mapproxy/util/ext/dictspec/validator.py +194 -0
- mapproxy/util/ext/local.py +198 -0
- mapproxy/util/ext/lockfile.py +140 -0
- mapproxy/util/ext/odict.py +321 -0
- mapproxy/util/ext/serving.py +491 -0
- mapproxy/util/ext/tempita/__init__.py +1093 -0
- mapproxy/util/ext/tempita/_looper.py +163 -0
- mapproxy/util/ext/tempita/string_utils.py +24 -0
- mapproxy/util/ext/wmsparse/__init__.py +3 -0
- mapproxy/util/ext/wmsparse/duration.py +600 -0
- mapproxy/util/ext/wmsparse/parse.py +307 -0
- mapproxy/util/ext/wmsparse/test/__init__.py +0 -0
- mapproxy/util/ext/wmsparse/test/test_parse.py +111 -0
- mapproxy/util/ext/wmsparse/test/test_util.py +23 -0
- mapproxy/util/ext/wmsparse/test/wms-example-111.xml +90 -0
- mapproxy/util/ext/wmsparse/test/wms-example-130.xml +120 -0
- mapproxy/util/ext/wmsparse/test/wms-large-111.xml +2114 -0
- mapproxy/util/ext/wmsparse/test/wms_nasa_cap.xml +386 -0
- mapproxy/util/ext/wmsparse/util.py +189 -0
- mapproxy/util/fs.py +164 -0
- mapproxy/util/geom.py +307 -0
- mapproxy/util/lib.py +117 -0
- mapproxy/util/lock.py +171 -0
- mapproxy/util/ogr.py +247 -0
- mapproxy/util/py.py +75 -0
- mapproxy/util/times.py +78 -0
- mapproxy/util/yaml.py +58 -0
- mapproxy/version.py +33 -0
- mapproxy/wsgiapp.py +167 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# -------------------------------
|
|
2
|
+
# MapProxy example configuration.
|
|
3
|
+
# -------------------------------
|
|
4
|
+
#
|
|
5
|
+
# This is a minimal MapProxy configuration.
|
|
6
|
+
# See full_example.yaml and the documentation for more options.
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
# Starts the following services:
|
|
10
|
+
# Demo:
|
|
11
|
+
# http://localhost:8080/demo
|
|
12
|
+
# WMS:
|
|
13
|
+
# capabilities: http://localhost:8080/service?REQUEST=GetCapabilities
|
|
14
|
+
# WMTS:
|
|
15
|
+
# capabilities: http://localhost:8080/wmts/1.0.0/WMTSCapabilities.xml
|
|
16
|
+
# first tile: http://localhost:8080/wmts/osm/webmercator/0/0/0.png
|
|
17
|
+
# Tile service (compatible with OSM/etc.)
|
|
18
|
+
# first tile: http://localhost:8080/tiles/osm/webmercator/0/0/0.png
|
|
19
|
+
# TMS:
|
|
20
|
+
# note: TMS is not compatible with OSM/Google Maps/etc.
|
|
21
|
+
# first tile: http://localhost:8080/tms/1.0.0/osm/webmercator/0/0/0.png
|
|
22
|
+
# KML:
|
|
23
|
+
# initial doc: http://localhost:8080/kml/osm/webmercator
|
|
24
|
+
|
|
25
|
+
services:
|
|
26
|
+
demo:
|
|
27
|
+
tms:
|
|
28
|
+
use_grid_names: true
|
|
29
|
+
# origin for /tiles service
|
|
30
|
+
origin: 'nw'
|
|
31
|
+
kml:
|
|
32
|
+
use_grid_names: true
|
|
33
|
+
wmts:
|
|
34
|
+
wms:
|
|
35
|
+
md:
|
|
36
|
+
title: MapProxy WMS Proxy
|
|
37
|
+
abstract: This is a minimal MapProxy example.
|
|
38
|
+
|
|
39
|
+
layers:
|
|
40
|
+
- name: osm
|
|
41
|
+
title: OSM
|
|
42
|
+
sources: [osm_cache]
|
|
43
|
+
|
|
44
|
+
caches:
|
|
45
|
+
osm_cache:
|
|
46
|
+
grids: [webmercator]
|
|
47
|
+
sources: [osm_wms]
|
|
48
|
+
|
|
49
|
+
sources:
|
|
50
|
+
osm_wms:
|
|
51
|
+
type: wms
|
|
52
|
+
req:
|
|
53
|
+
url: http://example.org/service?
|
|
54
|
+
layers: osm
|
|
55
|
+
|
|
56
|
+
grids:
|
|
57
|
+
webmercator:
|
|
58
|
+
base: GLOBAL_WEBMERCATOR
|
|
59
|
+
|
|
60
|
+
globals:
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# ---------------------------------------
|
|
2
|
+
# MapProxy example seeding configuration.
|
|
3
|
+
# ---------------------------------------
|
|
4
|
+
#
|
|
5
|
+
# This is a minimal MapProxy seeding configuration.
|
|
6
|
+
# See full_seed_example.yaml and the documentation for more options.
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
seeds:
|
|
10
|
+
myseed1:
|
|
11
|
+
caches: [osm_cache]
|
|
12
|
+
# grids: []
|
|
13
|
+
# coverages: []
|
|
14
|
+
levels:
|
|
15
|
+
to: 10
|
|
16
|
+
refresh_before:
|
|
17
|
+
time: 2013-10-10T12:35:00
|
|
18
|
+
|
|
19
|
+
cleanups:
|
|
20
|
+
myclean1:
|
|
21
|
+
caches: [osm_cache]
|
|
22
|
+
remove_before:
|
|
23
|
+
days: 14
|
|
24
|
+
levels:
|
|
25
|
+
from: 11
|
|
26
|
+
|
|
27
|
+
coverages:
|
mapproxy/exception.py
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
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
|
+
Service exception handling (WMS exceptions, XML, in_image, etc.).
|
|
18
|
+
"""
|
|
19
|
+
from html import escape
|
|
20
|
+
|
|
21
|
+
from mapproxy.response import Response
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class RequestError(Exception):
|
|
25
|
+
"""
|
|
26
|
+
Exception for all request related errors.
|
|
27
|
+
|
|
28
|
+
:ivar internal: True if the error was an internal error, ie. the request itself
|
|
29
|
+
was valid (e.g. the source server is unreachable
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, message, code=None, request=None, internal=False, status=None):
|
|
33
|
+
Exception.__init__(self, message)
|
|
34
|
+
self.msg = message
|
|
35
|
+
self.code = code
|
|
36
|
+
self.request = request
|
|
37
|
+
self.internal = internal
|
|
38
|
+
self.status = status
|
|
39
|
+
|
|
40
|
+
def render(self):
|
|
41
|
+
"""
|
|
42
|
+
Return a response with the rendered exception.
|
|
43
|
+
The rendering is delegated to the ``exception_handler`` that issued
|
|
44
|
+
the ``RequestError``.
|
|
45
|
+
|
|
46
|
+
:rtype: `Response`
|
|
47
|
+
"""
|
|
48
|
+
if self.request is not None:
|
|
49
|
+
handler = self.request.exception_handler
|
|
50
|
+
resp = handler.render(self)
|
|
51
|
+
elif self.status is not None:
|
|
52
|
+
resp = Response(self.msg, status=self.status)
|
|
53
|
+
else:
|
|
54
|
+
resp = Response('internal error: %s' % self.msg, status=500)
|
|
55
|
+
resp.cache_headers(no_cache=True)
|
|
56
|
+
return resp
|
|
57
|
+
|
|
58
|
+
def __str__(self):
|
|
59
|
+
return 'RequestError("%s", code=%r, request=%r)' % (self.msg, self.code,
|
|
60
|
+
self.request)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ExceptionHandler(object):
|
|
64
|
+
"""
|
|
65
|
+
Base class for exception handler.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
def render(self, request_error):
|
|
69
|
+
"""
|
|
70
|
+
Return a response with the rendered exception.
|
|
71
|
+
|
|
72
|
+
:param request_error: the exception to render
|
|
73
|
+
:type request_error: `RequestError`
|
|
74
|
+
:rtype: `Response`
|
|
75
|
+
"""
|
|
76
|
+
raise NotImplementedError()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _not_implemented(*args, **kw):
|
|
80
|
+
raise NotImplementedError()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class XMLExceptionHandler(ExceptionHandler):
|
|
84
|
+
"""
|
|
85
|
+
Mixin class for tempita-based template renderer.
|
|
86
|
+
"""
|
|
87
|
+
template_file = None
|
|
88
|
+
"""The filename of the tempita xml template"""
|
|
89
|
+
|
|
90
|
+
content_type = None
|
|
91
|
+
"""
|
|
92
|
+
The mime type of the exception response (use this or mimetype).
|
|
93
|
+
The content_type is sent as defined here.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
status_code = 200
|
|
97
|
+
"""
|
|
98
|
+
The HTTP status code.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
status_codes = {}
|
|
102
|
+
"""
|
|
103
|
+
Mapping of exceptionCodes to status_codes. If not defined
|
|
104
|
+
status_code is used.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
mimetype = None
|
|
108
|
+
"""
|
|
109
|
+
The mime type of the exception response. (use this or content_type).
|
|
110
|
+
A character encoding might be added to the mimetype (like text/xml;charset=UTF-8)
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
template_func = _not_implemented
|
|
114
|
+
"""
|
|
115
|
+
Function that returns the named template.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
def render(self, request_error):
|
|
119
|
+
"""
|
|
120
|
+
Render the template of this exception handler. Passes the
|
|
121
|
+
``request_error.msg`` and ``request_error.code`` to the template.
|
|
122
|
+
|
|
123
|
+
:type request_error: `RequestError`
|
|
124
|
+
"""
|
|
125
|
+
status_code = self.status_codes.get(request_error.code, self.status_code)
|
|
126
|
+
# escape &<> in error message (e.g. URL params)
|
|
127
|
+
msg = escape(request_error.msg)
|
|
128
|
+
result = self.template.substitute(exception=msg,
|
|
129
|
+
code=request_error.code)
|
|
130
|
+
return Response(result, mimetype=self.mimetype, content_type=self.content_type,
|
|
131
|
+
status=status_code)
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def template(self):
|
|
135
|
+
"""
|
|
136
|
+
The template for this ExceptionHandler.
|
|
137
|
+
"""
|
|
138
|
+
return self.template_func(self.template_file)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class PlainExceptionHandler(ExceptionHandler):
|
|
142
|
+
mimetype = 'text/plain'
|
|
143
|
+
status_code = 404
|
|
144
|
+
|
|
145
|
+
def render(self, request_error):
|
|
146
|
+
if request_error.internal:
|
|
147
|
+
self.status_code = 500
|
|
148
|
+
return Response(request_error.msg, status=self.status_code,
|
|
149
|
+
mimetype=self.mimetype)
|
mapproxy/featureinfo.py
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
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
|
+
import copy
|
|
17
|
+
import json
|
|
18
|
+
|
|
19
|
+
from functools import reduce
|
|
20
|
+
from io import StringIO, BytesIO
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
from lxml import etree, html
|
|
24
|
+
|
|
25
|
+
has_xslt_support = True
|
|
26
|
+
except ImportError:
|
|
27
|
+
has_xslt_support = False
|
|
28
|
+
etree = html = None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class FeatureInfoDoc(object):
|
|
32
|
+
content_type = None
|
|
33
|
+
|
|
34
|
+
def as_etree(self):
|
|
35
|
+
raise NotImplementedError()
|
|
36
|
+
|
|
37
|
+
def as_string(self):
|
|
38
|
+
raise NotImplementedError()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class TextFeatureInfoDoc(FeatureInfoDoc):
|
|
42
|
+
info_type = "text"
|
|
43
|
+
|
|
44
|
+
def __init__(self, content):
|
|
45
|
+
self.content = content
|
|
46
|
+
|
|
47
|
+
def as_string(self):
|
|
48
|
+
return self.content
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def combine(cls, docs):
|
|
52
|
+
result_content = [doc.as_string() for doc in docs]
|
|
53
|
+
return cls(b"\n".join(result_content))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class XMLFeatureInfoDoc(FeatureInfoDoc):
|
|
57
|
+
info_type = "xml"
|
|
58
|
+
defaultEncoding = "UTF-8"
|
|
59
|
+
|
|
60
|
+
def __init__(self, content):
|
|
61
|
+
if isinstance(content, (str, bytes)):
|
|
62
|
+
self._str_content = content
|
|
63
|
+
self._etree = None
|
|
64
|
+
else:
|
|
65
|
+
self._str_content = None
|
|
66
|
+
if hasattr(content, "getroottree"):
|
|
67
|
+
content = content.getroottree()
|
|
68
|
+
self._etree = content
|
|
69
|
+
assert hasattr(content, "getroot"), "expected etree like object"
|
|
70
|
+
|
|
71
|
+
def as_string(self):
|
|
72
|
+
if self._str_content is None:
|
|
73
|
+
self._str_content = self._serialize_etree()
|
|
74
|
+
return self._str_content
|
|
75
|
+
|
|
76
|
+
def as_etree(self):
|
|
77
|
+
if self._etree is None:
|
|
78
|
+
self._etree = self._parse_content()
|
|
79
|
+
return self._etree
|
|
80
|
+
|
|
81
|
+
def _serialize_etree(self):
|
|
82
|
+
encoding = self._etree.docinfo.encoding if \
|
|
83
|
+
self._etree.docinfo.encoding else self.defaultEncoding
|
|
84
|
+
return etree.tostring(self._etree, encoding=encoding, xml_declaration=False)
|
|
85
|
+
|
|
86
|
+
def _parse_content(self):
|
|
87
|
+
doc = as_io(self._str_content)
|
|
88
|
+
return etree.parse(doc)
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def combine(cls, docs):
|
|
92
|
+
if etree is None:
|
|
93
|
+
return TextFeatureInfoDoc.combine(docs)
|
|
94
|
+
doc = docs.pop(0)
|
|
95
|
+
result_tree = copy.deepcopy(doc.as_etree())
|
|
96
|
+
for doc in docs:
|
|
97
|
+
tree = doc.as_etree()
|
|
98
|
+
result_tree.getroot().extend(tree.getroot().iterchildren())
|
|
99
|
+
|
|
100
|
+
return cls(result_tree)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class HTMLFeatureInfoDoc(XMLFeatureInfoDoc):
|
|
104
|
+
info_type = "html"
|
|
105
|
+
|
|
106
|
+
def _parse_content(self):
|
|
107
|
+
root = html.document_fromstring(self._str_content)
|
|
108
|
+
return root
|
|
109
|
+
|
|
110
|
+
def _serialize_etree(self):
|
|
111
|
+
return html.tostring(self._etree)
|
|
112
|
+
|
|
113
|
+
@classmethod
|
|
114
|
+
def combine(cls, docs):
|
|
115
|
+
if etree is None:
|
|
116
|
+
return TextFeatureInfoDoc.combine(docs)
|
|
117
|
+
|
|
118
|
+
doc = docs.pop(0)
|
|
119
|
+
result_tree = copy.deepcopy(doc.as_etree())
|
|
120
|
+
|
|
121
|
+
for doc in docs:
|
|
122
|
+
tree = doc.as_etree()
|
|
123
|
+
|
|
124
|
+
try:
|
|
125
|
+
body = tree.body.getchildren()
|
|
126
|
+
except IndexError:
|
|
127
|
+
body = tree.getchildren()
|
|
128
|
+
result_tree.body.extend(body)
|
|
129
|
+
|
|
130
|
+
return cls(result_tree)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class JSONFeatureInfoDoc(FeatureInfoDoc):
|
|
134
|
+
info_type = "json"
|
|
135
|
+
|
|
136
|
+
def __init__(self, content):
|
|
137
|
+
self.content = content
|
|
138
|
+
|
|
139
|
+
def as_string(self):
|
|
140
|
+
return self.content
|
|
141
|
+
|
|
142
|
+
@classmethod
|
|
143
|
+
def combine(cls, docs):
|
|
144
|
+
contents = []
|
|
145
|
+
for d in docs:
|
|
146
|
+
content = d.content
|
|
147
|
+
if not isinstance(content, str):
|
|
148
|
+
content = content.decode('UTF-8')
|
|
149
|
+
result = json.loads(content)
|
|
150
|
+
if result:
|
|
151
|
+
contents.append(result)
|
|
152
|
+
if not contents:
|
|
153
|
+
return cls(json.dumps({}))
|
|
154
|
+
combined = reduce(lambda a, b: merge_dict(a, b), contents)
|
|
155
|
+
return cls(json.dumps(combined))
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def merge_dict(base, other):
|
|
159
|
+
"""
|
|
160
|
+
Return `base` dict with values from `conf` merged in.
|
|
161
|
+
"""
|
|
162
|
+
for k, v in other.items():
|
|
163
|
+
if k not in base:
|
|
164
|
+
base[k] = v
|
|
165
|
+
else:
|
|
166
|
+
if isinstance(base[k], dict):
|
|
167
|
+
merge_dict(base[k], v)
|
|
168
|
+
elif isinstance(base[k], list):
|
|
169
|
+
base[k].extend(v)
|
|
170
|
+
else:
|
|
171
|
+
base[k] = v
|
|
172
|
+
return base
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def create_featureinfo_doc(content, info_format):
|
|
176
|
+
info_type = featureinfo_type(info_format)
|
|
177
|
+
if info_type == "xml":
|
|
178
|
+
return XMLFeatureInfoDoc(content)
|
|
179
|
+
if info_type == "html":
|
|
180
|
+
return HTMLFeatureInfoDoc(content)
|
|
181
|
+
if info_type == "json":
|
|
182
|
+
return JSONFeatureInfoDoc(content)
|
|
183
|
+
|
|
184
|
+
return TextFeatureInfoDoc(content)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def featureinfo_type(info_format):
|
|
188
|
+
info_format = info_format.split(";", 1)[
|
|
189
|
+
0
|
|
190
|
+
].strip() # remove mime options like charset
|
|
191
|
+
if info_format in ("text/xml", "application/xml",
|
|
192
|
+
"application/gml+xml", "application/vnd.ogc.gml"):
|
|
193
|
+
return "xml"
|
|
194
|
+
if info_format == "text/html":
|
|
195
|
+
return "html"
|
|
196
|
+
if info_format == "application/json":
|
|
197
|
+
return "json"
|
|
198
|
+
|
|
199
|
+
return "text"
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class XSLTransformer(object):
|
|
203
|
+
|
|
204
|
+
def __init__(self, xsltscript, info_format=None):
|
|
205
|
+
self.xsltscript = xsltscript
|
|
206
|
+
self.info_type = featureinfo_type(info_format or "text/xml")
|
|
207
|
+
|
|
208
|
+
def transform(self, input_doc):
|
|
209
|
+
input_tree = input_doc.as_etree()
|
|
210
|
+
xslt_tree = etree.parse(self.xsltscript)
|
|
211
|
+
transform = etree.XSLT(xslt_tree)
|
|
212
|
+
output_tree = transform(input_tree)
|
|
213
|
+
if self.info_type == "html":
|
|
214
|
+
return HTMLFeatureInfoDoc(output_tree)
|
|
215
|
+
else:
|
|
216
|
+
return XMLFeatureInfoDoc(output_tree)
|
|
217
|
+
|
|
218
|
+
__call__ = transform
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def as_io(doc):
|
|
222
|
+
if isinstance(doc, str):
|
|
223
|
+
return StringIO(doc)
|
|
224
|
+
else:
|
|
225
|
+
return BytesIO(doc)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def combine_docs(docs, transformer=None):
|
|
229
|
+
"""
|
|
230
|
+
Combine multiple FeatureInfoDocs.
|
|
231
|
+
|
|
232
|
+
Combines as text, if the type of the docs differ.
|
|
233
|
+
Otherwise the type specifix combine is called.
|
|
234
|
+
|
|
235
|
+
Returns the combined document and the info_type (text, xml or json).
|
|
236
|
+
info_type is None if the output is transformed, as the type is dependent on the
|
|
237
|
+
transformer.
|
|
238
|
+
"""
|
|
239
|
+
if len(set(d.info_type for d in docs)) > 1:
|
|
240
|
+
# more then one info_type, combine as plain text
|
|
241
|
+
doc = TextFeatureInfoDoc.combine(docs)
|
|
242
|
+
infotype = "text"
|
|
243
|
+
else:
|
|
244
|
+
# all same type, combine with type specific handler
|
|
245
|
+
infotype = docs[0].info_type
|
|
246
|
+
doc = docs[0].combine(docs)
|
|
247
|
+
|
|
248
|
+
if transformer:
|
|
249
|
+
doc = transformer(doc)
|
|
250
|
+
infotype = None # defined by transformer
|
|
251
|
+
return doc.as_string(), infotype
|