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,350 @@
|
|
|
1
|
+
# This file is part of the MapProxy project.
|
|
2
|
+
# Copyright (C) 2010 Omniscale <http://omniscale.de>
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
from __future__ import division
|
|
17
|
+
|
|
18
|
+
from mapproxy.compat.image import Image, transform_uses_center
|
|
19
|
+
from mapproxy.image import ImageSource, image_filter
|
|
20
|
+
from mapproxy.srs import make_lin_transf, bbox_equals
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ImageTransformer(object):
|
|
24
|
+
"""
|
|
25
|
+
Transform images between different bbox and spatial reference systems.
|
|
26
|
+
|
|
27
|
+
:note: The transformation doesn't make a real transformation for each pixel,
|
|
28
|
+
but a mesh transformation (see `PIL Image.transform`_).
|
|
29
|
+
It will divide the target image into rectangles (a mesh). The
|
|
30
|
+
source coordinates for each rectangle vertex will be calculated.
|
|
31
|
+
The quadrilateral will then be transformed with the source coordinates
|
|
32
|
+
into the destination quad (affine).
|
|
33
|
+
|
|
34
|
+
The number of quads is calculated dynamically to keep the deviation in
|
|
35
|
+
the image transformation below one pixel.
|
|
36
|
+
|
|
37
|
+
.. _PIL Image.transform:
|
|
38
|
+
http://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.transform
|
|
39
|
+
|
|
40
|
+
::
|
|
41
|
+
|
|
42
|
+
src quad dst quad
|
|
43
|
+
.----. <- coord- .----.
|
|
44
|
+
/ / transformation | |
|
|
45
|
+
/ / | |
|
|
46
|
+
.----. img-transformation -> .----.----
|
|
47
|
+
| | |
|
|
48
|
+
---------------.
|
|
49
|
+
large src image large dst image
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def __init__(self, src_srs, dst_srs, max_px_err=1):
|
|
53
|
+
"""
|
|
54
|
+
:param src_srs: the srs of the source image
|
|
55
|
+
:param dst_srs: the srs of the target image
|
|
56
|
+
:param resampling: the resampling method used for transformation
|
|
57
|
+
:type resampling: nearest|bilinear|bicubic
|
|
58
|
+
"""
|
|
59
|
+
self.src_srs = src_srs
|
|
60
|
+
self.dst_srs = dst_srs
|
|
61
|
+
self.dst_bbox = self.dst_size = None
|
|
62
|
+
self.max_px_err = max_px_err
|
|
63
|
+
|
|
64
|
+
def transform(self, src_img, src_bbox, dst_size, dst_bbox, image_opts):
|
|
65
|
+
"""
|
|
66
|
+
Transforms the `src_img` between the source and destination SRS
|
|
67
|
+
of this ``ImageTransformer`` instance.
|
|
68
|
+
|
|
69
|
+
When the ``src_srs`` and ``dst_srs`` are equal the image will be cropped
|
|
70
|
+
and not transformed. If the `src_bbox` and `dst_bbox` are equal,
|
|
71
|
+
the `src_img` itself will be returned.
|
|
72
|
+
|
|
73
|
+
:param src_img: the source image for the transformation
|
|
74
|
+
:param src_bbox: the bbox of the src_img
|
|
75
|
+
:param dst_size: the size of the result image (in pizel)
|
|
76
|
+
:type dst_size: ``(int(width), int(height))``
|
|
77
|
+
:param dst_bbox: the bbox of the result image
|
|
78
|
+
:return: the transformed image
|
|
79
|
+
:rtype: `ImageSource`
|
|
80
|
+
"""
|
|
81
|
+
if self._no_transformation_needed(src_img.size, src_bbox, dst_size, dst_bbox):
|
|
82
|
+
return src_img
|
|
83
|
+
|
|
84
|
+
if self.src_srs == self.dst_srs:
|
|
85
|
+
result = self._transform_simple(src_img, src_bbox, dst_size, dst_bbox,
|
|
86
|
+
image_opts)
|
|
87
|
+
else:
|
|
88
|
+
result = self._transform(src_img, src_bbox, dst_size, dst_bbox, image_opts)
|
|
89
|
+
|
|
90
|
+
result.cacheable = src_img.cacheable
|
|
91
|
+
return result
|
|
92
|
+
|
|
93
|
+
def _transform_simple(self, src_img, src_bbox, dst_size, dst_bbox, image_opts):
|
|
94
|
+
"""
|
|
95
|
+
Do a simple crop/extent transformation.
|
|
96
|
+
"""
|
|
97
|
+
src_quad = (0, 0, src_img.size[0], src_img.size[1])
|
|
98
|
+
to_src_px = make_lin_transf(src_bbox, src_quad)
|
|
99
|
+
minx, miny = to_src_px((dst_bbox[0], dst_bbox[3]))
|
|
100
|
+
maxx, maxy = to_src_px((dst_bbox[2], dst_bbox[1]))
|
|
101
|
+
|
|
102
|
+
src_res = ((src_bbox[0]-src_bbox[2])/src_img.size[0],
|
|
103
|
+
(src_bbox[1]-src_bbox[3])/src_img.size[1])
|
|
104
|
+
dst_res = ((dst_bbox[0]-dst_bbox[2])/dst_size[0],
|
|
105
|
+
(dst_bbox[1]-dst_bbox[3])/dst_size[1])
|
|
106
|
+
|
|
107
|
+
tenth_px_res = (abs(dst_res[0]/(dst_size[0]*10)),
|
|
108
|
+
abs(dst_res[1]/(dst_size[1]*10)))
|
|
109
|
+
if (abs(src_res[0]-dst_res[0]) < tenth_px_res[0] and
|
|
110
|
+
abs(src_res[1]-dst_res[1]) < tenth_px_res[1]):
|
|
111
|
+
# rounding might result in subpixel inaccuracy
|
|
112
|
+
# this exact resolutioni match should only happen in clients with
|
|
113
|
+
# fixed resolutions like OpenLayers
|
|
114
|
+
minx = int(round(minx))
|
|
115
|
+
miny = int(round(miny))
|
|
116
|
+
result = src_img.as_image().crop((minx, miny,
|
|
117
|
+
minx+dst_size[0], miny+dst_size[1]))
|
|
118
|
+
else:
|
|
119
|
+
img = img_for_resampling(src_img.as_image(), image_opts.resampling)
|
|
120
|
+
result = img.transform(dst_size, Image.EXTENT,
|
|
121
|
+
(minx, miny, maxx, maxy),
|
|
122
|
+
image_filter[image_opts.resampling])
|
|
123
|
+
return ImageSource(result, size=dst_size, image_opts=image_opts)
|
|
124
|
+
|
|
125
|
+
def _transform(self, src_img, src_bbox, dst_size, dst_bbox, image_opts):
|
|
126
|
+
"""
|
|
127
|
+
Do a 'real' transformation with a transformed mesh (see above).
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
# more recent versions of Pillow use center coordinates for
|
|
131
|
+
# transformations, we manually need to add half a pixel otherwise
|
|
132
|
+
if transform_uses_center():
|
|
133
|
+
use_center_px = False
|
|
134
|
+
else:
|
|
135
|
+
use_center_px = True
|
|
136
|
+
|
|
137
|
+
meshes = transform_meshes(
|
|
138
|
+
src_size=src_img.size,
|
|
139
|
+
src_bbox=src_bbox,
|
|
140
|
+
src_srs=self.src_srs,
|
|
141
|
+
dst_size=dst_size,
|
|
142
|
+
dst_bbox=dst_bbox,
|
|
143
|
+
dst_srs=self.dst_srs,
|
|
144
|
+
max_px_err=self.max_px_err,
|
|
145
|
+
use_center_px=use_center_px,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
img = img_for_resampling(src_img.as_image(), image_opts.resampling)
|
|
149
|
+
result = img.transform(dst_size, Image.MESH, meshes,
|
|
150
|
+
image_filter[image_opts.resampling])
|
|
151
|
+
|
|
152
|
+
if False:
|
|
153
|
+
# draw mesh for debuging
|
|
154
|
+
from PIL import ImageDraw
|
|
155
|
+
draw = ImageDraw.Draw(result)
|
|
156
|
+
for g, _ in meshes:
|
|
157
|
+
draw.rectangle(g, fill=None, outline=(255, 0, 0))
|
|
158
|
+
|
|
159
|
+
return ImageSource(result, size=dst_size, image_opts=image_opts)
|
|
160
|
+
|
|
161
|
+
def _no_transformation_needed(self, src_size, src_bbox, dst_size, dst_bbox):
|
|
162
|
+
"""
|
|
163
|
+
>>> src_bbox = (-2504688.5428486541, 1252344.271424327,
|
|
164
|
+
... -1252344.271424327, 2504688.5428486541)
|
|
165
|
+
>>> dst_bbox = (-2504688.5431999983, 1252344.2704,
|
|
166
|
+
... -1252344.2719999983, 2504688.5416000001)
|
|
167
|
+
>>> from mapproxy.srs import SRS
|
|
168
|
+
>>> t = ImageTransformer(SRS(900913), SRS(900913))
|
|
169
|
+
>>> t._no_transformation_needed((256, 256), src_bbox, (256, 256), dst_bbox)
|
|
170
|
+
True
|
|
171
|
+
"""
|
|
172
|
+
xres = (dst_bbox[2]-dst_bbox[0])/dst_size[0]
|
|
173
|
+
yres = (dst_bbox[3]-dst_bbox[1])/dst_size[1]
|
|
174
|
+
return (src_size == dst_size and
|
|
175
|
+
self.src_srs == self.dst_srs and
|
|
176
|
+
bbox_equals(src_bbox, dst_bbox, xres/10, yres/10))
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def transform_meshes(
|
|
180
|
+
src_size, src_bbox, src_srs,
|
|
181
|
+
dst_size, dst_bbox, dst_srs,
|
|
182
|
+
max_px_err=1,
|
|
183
|
+
use_center_px=False,
|
|
184
|
+
):
|
|
185
|
+
"""
|
|
186
|
+
transform_meshes creates a list of QUAD transformation parameters for PIL's
|
|
187
|
+
MESH image transformation.
|
|
188
|
+
|
|
189
|
+
Each QUAD is a rectangle in the destination image, like ``(0, 0, 100, 100)`` and
|
|
190
|
+
a list of four pixel coordinates in the source image that match the destination rectangle.
|
|
191
|
+
The four points form a quadliteral (i.e. not a rectangle).
|
|
192
|
+
PIL's image transform uses affine transformation to fill each rectangle in the destination
|
|
193
|
+
image with data from the source quadliteral.
|
|
194
|
+
|
|
195
|
+
The number of QUADs is calculated dynamically to keep the deviation in the image
|
|
196
|
+
transformation below one pixel. Image transformations for large map scales can be transformed with
|
|
197
|
+
1-4 QUADs most of the time. For low scales, transform_meshes can generate a few hundred QUADs.
|
|
198
|
+
|
|
199
|
+
It generates a maximum of one QUAD per 50 pixel.
|
|
200
|
+
"""
|
|
201
|
+
src_bbox = src_srs.align_bbox(src_bbox)
|
|
202
|
+
dst_bbox = dst_srs.align_bbox(dst_bbox)
|
|
203
|
+
src_rect = (0, 0, src_size[0], src_size[1])
|
|
204
|
+
dst_rect = (0, 0, dst_size[0], dst_size[1])
|
|
205
|
+
to_src_px = make_lin_transf(src_bbox, src_rect)
|
|
206
|
+
to_src_w = make_lin_transf(src_rect, src_bbox)
|
|
207
|
+
to_dst_w = make_lin_transf(dst_rect, dst_bbox)
|
|
208
|
+
meshes = []
|
|
209
|
+
|
|
210
|
+
if use_center_px:
|
|
211
|
+
px_offset = 0.5
|
|
212
|
+
else:
|
|
213
|
+
px_offset = 0.0
|
|
214
|
+
|
|
215
|
+
def dst_quad_to_src(quad):
|
|
216
|
+
src_quad = []
|
|
217
|
+
for dst_px in [(quad[0], quad[1]), (quad[0], quad[3]),
|
|
218
|
+
(quad[2], quad[3]), (quad[2], quad[1])]:
|
|
219
|
+
dst_w = to_dst_w(
|
|
220
|
+
(dst_px[0] + px_offset, dst_px[1] + px_offset))
|
|
221
|
+
src_w = dst_srs.transform_to(src_srs, dst_w)
|
|
222
|
+
src_px = to_src_px(src_w)
|
|
223
|
+
src_quad.extend(src_px)
|
|
224
|
+
|
|
225
|
+
return quad, src_quad
|
|
226
|
+
|
|
227
|
+
res = (dst_bbox[2] - dst_bbox[0]) / dst_size[0]
|
|
228
|
+
max_err = max_px_err * res
|
|
229
|
+
|
|
230
|
+
def is_good(quad, src_quad):
|
|
231
|
+
w = quad[2] - quad[0]
|
|
232
|
+
h = quad[3] - quad[1]
|
|
233
|
+
|
|
234
|
+
if w < 50 or h < 50:
|
|
235
|
+
return True
|
|
236
|
+
|
|
237
|
+
xc = quad[0] + w / 2.0 - 0.5
|
|
238
|
+
yc = quad[1] + h / 2.0 - 0.5
|
|
239
|
+
|
|
240
|
+
# coordinate for the center of the quad
|
|
241
|
+
dst_w = to_dst_w((xc, yc))
|
|
242
|
+
|
|
243
|
+
# actual coordinate for the center of the quad
|
|
244
|
+
src_px = center_quad_transform(quad, src_quad)
|
|
245
|
+
real_dst_w = src_srs.transform_to(dst_srs, to_src_w(src_px))
|
|
246
|
+
|
|
247
|
+
err = max(abs(dst_w[0] - real_dst_w[0]), abs(dst_w[1] - real_dst_w[1]))
|
|
248
|
+
return err < max_err
|
|
249
|
+
|
|
250
|
+
# recursively add meshes. divide each quad into four sub quad till
|
|
251
|
+
# accuracy is good enough.
|
|
252
|
+
def add_meshes(quads):
|
|
253
|
+
for quad in quads:
|
|
254
|
+
quad, src_quad = dst_quad_to_src(quad)
|
|
255
|
+
if is_good(quad, src_quad):
|
|
256
|
+
meshes.append((quad, src_quad))
|
|
257
|
+
else:
|
|
258
|
+
add_meshes(divide_quad(quad))
|
|
259
|
+
|
|
260
|
+
add_meshes([(0, 0, dst_size[0], dst_size[1])])
|
|
261
|
+
return meshes
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def center_quad_transform(quad, src_quad):
|
|
265
|
+
"""
|
|
266
|
+
center_quad_transfrom transforms the center pixel coordinates
|
|
267
|
+
from ``quad`` to ``src_quad`` by using affine transformation
|
|
268
|
+
as used by PIL.Image.transform.
|
|
269
|
+
"""
|
|
270
|
+
w = quad[2] - quad[0]
|
|
271
|
+
h = quad[3] - quad[1]
|
|
272
|
+
|
|
273
|
+
nw = src_quad[0:2]
|
|
274
|
+
sw = src_quad[2:4]
|
|
275
|
+
se = src_quad[4:6]
|
|
276
|
+
ne = src_quad[6:8]
|
|
277
|
+
x0, y0 = nw
|
|
278
|
+
As = 1.0 / w
|
|
279
|
+
At = 1.0 / h
|
|
280
|
+
|
|
281
|
+
a0 = x0
|
|
282
|
+
a1 = (ne[0] - x0) * As
|
|
283
|
+
a2 = (sw[0] - x0) * At
|
|
284
|
+
a3 = (se[0] - sw[0] - ne[0] + x0) * As * At
|
|
285
|
+
a4 = y0
|
|
286
|
+
a5 = (ne[1] - y0) * As
|
|
287
|
+
a6 = (sw[1] - y0) * At
|
|
288
|
+
a7 = (se[1] - sw[1] - ne[1] + y0) * As * At
|
|
289
|
+
|
|
290
|
+
x = w / 2.0 - 0.5
|
|
291
|
+
y = h / 2.0 - 0.5
|
|
292
|
+
|
|
293
|
+
return (
|
|
294
|
+
a0 + a1*x + a2*y + a3*x*y,
|
|
295
|
+
a4 + a5*x + a6*y + a7*x*y
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def img_for_resampling(img, resampling):
|
|
300
|
+
"""
|
|
301
|
+
Convert P images to RGB(A) for non-NEAREST resamplings.
|
|
302
|
+
"""
|
|
303
|
+
resampling = image_filter[resampling]
|
|
304
|
+
if img.mode == 'P' and resampling != Image.NEAREST:
|
|
305
|
+
img.load() # load to get actual palette mode
|
|
306
|
+
if img.palette is not None:
|
|
307
|
+
# palette can still be None for cropped images
|
|
308
|
+
img = img.convert(img.palette.mode)
|
|
309
|
+
else:
|
|
310
|
+
img = img.convert('RGBA')
|
|
311
|
+
return img
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def divide_quad(quad):
|
|
315
|
+
"""
|
|
316
|
+
divide_quad in up to four sub quads. Only divide horizontal if quad is twice as wide then high,
|
|
317
|
+
and vertical vice versa.
|
|
318
|
+
PIL.Image.transform expects that the lower-right corner
|
|
319
|
+
of a quad overlaps by one pixel.
|
|
320
|
+
|
|
321
|
+
>>> divide_quad((0, 0, 500, 500))
|
|
322
|
+
[(0, 0, 250, 250), (250, 0, 500, 250), (0, 250, 250, 500), (250, 250, 500, 500)]
|
|
323
|
+
>>> divide_quad((0, 0, 2000, 500))
|
|
324
|
+
[(0, 0, 1000, 500), (1000, 0, 2000, 500)]
|
|
325
|
+
>>> divide_quad((100, 200, 200, 500))
|
|
326
|
+
[(100, 200, 200, 350), (100, 350, 200, 500)]
|
|
327
|
+
|
|
328
|
+
"""
|
|
329
|
+
w = quad[2] - quad[0]
|
|
330
|
+
h = quad[3] - quad[1]
|
|
331
|
+
xc = int(quad[0] + w/2)
|
|
332
|
+
yc = int(quad[1] + h/2)
|
|
333
|
+
|
|
334
|
+
if w > 2*h:
|
|
335
|
+
return [
|
|
336
|
+
(quad[0], quad[1], xc, quad[3]),
|
|
337
|
+
(xc, quad[1], quad[2], quad[3]),
|
|
338
|
+
]
|
|
339
|
+
if h > 2*w:
|
|
340
|
+
return [
|
|
341
|
+
(quad[0], quad[1], quad[2], yc),
|
|
342
|
+
(quad[0], yc, quad[2], quad[3]),
|
|
343
|
+
]
|
|
344
|
+
|
|
345
|
+
return [
|
|
346
|
+
(quad[0], quad[1], xc, yc),
|
|
347
|
+
(xc, quad[1], quad[2], yc),
|
|
348
|
+
(quad[0], yc, xc, quad[3]),
|
|
349
|
+
(xc, yc, quad[2], quad[3]),
|
|
350
|
+
]
|