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.
Files changed (459) hide show
  1. MapProxy-2.1.0.dist-info/AUTHORS.txt +33 -0
  2. MapProxy-2.1.0.dist-info/COPYING.txt +60 -0
  3. MapProxy-2.1.0.dist-info/LICENSE.txt +202 -0
  4. MapProxy-2.1.0.dist-info/METADATA +165 -0
  5. MapProxy-2.1.0.dist-info/RECORD +459 -0
  6. MapProxy-2.1.0.dist-info/WHEEL +5 -0
  7. MapProxy-2.1.0.dist-info/entry_points.txt +4 -0
  8. MapProxy-2.1.0.dist-info/top_level.txt +1 -0
  9. mapproxy/__init__.py +0 -0
  10. mapproxy/cache/__init__.py +36 -0
  11. mapproxy/cache/azureblob.py +145 -0
  12. mapproxy/cache/base.py +120 -0
  13. mapproxy/cache/compact.py +665 -0
  14. mapproxy/cache/couchdb.py +301 -0
  15. mapproxy/cache/dummy.py +36 -0
  16. mapproxy/cache/file.py +200 -0
  17. mapproxy/cache/geopackage.py +647 -0
  18. mapproxy/cache/legend.py +87 -0
  19. mapproxy/cache/mbtiles.py +411 -0
  20. mapproxy/cache/meta.py +80 -0
  21. mapproxy/cache/path.py +261 -0
  22. mapproxy/cache/redis.py +152 -0
  23. mapproxy/cache/renderd.py +100 -0
  24. mapproxy/cache/riak.py +206 -0
  25. mapproxy/cache/s3.py +209 -0
  26. mapproxy/cache/tile.py +736 -0
  27. mapproxy/client/__init__.py +0 -0
  28. mapproxy/client/arcgis.py +82 -0
  29. mapproxy/client/cgi.py +141 -0
  30. mapproxy/client/http.py +295 -0
  31. mapproxy/client/log.py +33 -0
  32. mapproxy/client/tile.py +158 -0
  33. mapproxy/client/wms.py +255 -0
  34. mapproxy/compat/__init__.py +0 -0
  35. mapproxy/compat/image.py +86 -0
  36. mapproxy/config/__init__.py +22 -0
  37. mapproxy/config/config-schema.json +813 -0
  38. mapproxy/config/config.py +213 -0
  39. mapproxy/config/coverage.py +108 -0
  40. mapproxy/config/defaults.py +102 -0
  41. mapproxy/config/loader.py +2399 -0
  42. mapproxy/config/spec.py +657 -0
  43. mapproxy/config/validator.py +242 -0
  44. mapproxy/config_template/__init__.py +0 -0
  45. mapproxy/config_template/base_config/config.wsgi +10 -0
  46. mapproxy/config_template/base_config/full_example.yaml +598 -0
  47. mapproxy/config_template/base_config/full_seed_example.yaml +79 -0
  48. mapproxy/config_template/base_config/log.ini +35 -0
  49. mapproxy/config_template/base_config/mapproxy.yaml +60 -0
  50. mapproxy/config_template/base_config/seed.yaml +27 -0
  51. mapproxy/exception.py +149 -0
  52. mapproxy/featureinfo.py +251 -0
  53. mapproxy/grid.py +1199 -0
  54. mapproxy/image/__init__.py +549 -0
  55. mapproxy/image/fonts/DejaVuSans.ttf +0 -0
  56. mapproxy/image/fonts/DejaVuSansMono.ttf +0 -0
  57. mapproxy/image/fonts/LICENSE +99 -0
  58. mapproxy/image/fonts/__init__.py +0 -0
  59. mapproxy/image/mask.py +79 -0
  60. mapproxy/image/merge.py +323 -0
  61. mapproxy/image/message.py +357 -0
  62. mapproxy/image/opts.py +185 -0
  63. mapproxy/image/tile.py +171 -0
  64. mapproxy/image/transform.py +350 -0
  65. mapproxy/layer.py +489 -0
  66. mapproxy/multiapp.py +230 -0
  67. mapproxy/proj.py +309 -0
  68. mapproxy/request/__init__.py +18 -0
  69. mapproxy/request/arcgis.py +268 -0
  70. mapproxy/request/base.py +466 -0
  71. mapproxy/request/tile.py +131 -0
  72. mapproxy/request/wms/__init__.py +829 -0
  73. mapproxy/request/wms/exception.py +107 -0
  74. mapproxy/request/wmts.py +442 -0
  75. mapproxy/response.py +237 -0
  76. mapproxy/script/__init__.py +0 -0
  77. mapproxy/script/conf/__init__.py +0 -0
  78. mapproxy/script/conf/app.py +222 -0
  79. mapproxy/script/conf/caches.py +44 -0
  80. mapproxy/script/conf/geopackage.py +136 -0
  81. mapproxy/script/conf/layers.py +54 -0
  82. mapproxy/script/conf/seeds.py +36 -0
  83. mapproxy/script/conf/sources.py +88 -0
  84. mapproxy/script/conf/utils.py +148 -0
  85. mapproxy/script/defrag.py +187 -0
  86. mapproxy/script/export.py +337 -0
  87. mapproxy/script/grids.py +198 -0
  88. mapproxy/script/scales.py +134 -0
  89. mapproxy/script/util.py +410 -0
  90. mapproxy/script/wms_capabilities.py +160 -0
  91. mapproxy/seed/__init__.py +0 -0
  92. mapproxy/seed/cachelock.py +127 -0
  93. mapproxy/seed/cleanup.py +191 -0
  94. mapproxy/seed/config.py +481 -0
  95. mapproxy/seed/script.py +391 -0
  96. mapproxy/seed/seeder.py +551 -0
  97. mapproxy/seed/spec.py +66 -0
  98. mapproxy/seed/util.py +266 -0
  99. mapproxy/service/__init__.py +14 -0
  100. mapproxy/service/base.py +45 -0
  101. mapproxy/service/demo.py +364 -0
  102. mapproxy/service/kml.py +333 -0
  103. mapproxy/service/ows.py +39 -0
  104. mapproxy/service/template_helper.py +55 -0
  105. mapproxy/service/templates/demo/capabilities_demo.html +18 -0
  106. mapproxy/service/templates/demo/demo.html +181 -0
  107. mapproxy/service/templates/demo/openlayers-demo.cfg +16 -0
  108. mapproxy/service/templates/demo/static/img/blank.gif +0 -0
  109. mapproxy/service/templates/demo/static/img/east-mini.png +0 -0
  110. mapproxy/service/templates/demo/static/img/north-mini.png +0 -0
  111. mapproxy/service/templates/demo/static/img/south-mini.png +0 -0
  112. mapproxy/service/templates/demo/static/img/west-mini.png +0 -0
  113. mapproxy/service/templates/demo/static/img/zoom-minus-mini.png +0 -0
  114. mapproxy/service/templates/demo/static/img/zoom-plus-mini.png +0 -0
  115. mapproxy/service/templates/demo/static/img/zoom-world-mini.png +0 -0
  116. mapproxy/service/templates/demo/static/logo.png +0 -0
  117. mapproxy/service/templates/demo/static/ol.css +345 -0
  118. mapproxy/service/templates/demo/static/ol.js +4 -0
  119. mapproxy/service/templates/demo/static/proj4.min.js +1 -0
  120. mapproxy/service/templates/demo/static/proj4defs.js +1 -0
  121. mapproxy/service/templates/demo/static/site.css +137 -0
  122. mapproxy/service/templates/demo/static/theme/default/framedCloud.css +0 -0
  123. mapproxy/service/templates/demo/static/theme/default/google.css +17 -0
  124. mapproxy/service/templates/demo/static/theme/default/ie6-style.css +10 -0
  125. mapproxy/service/templates/demo/static/theme/default/style.css +482 -0
  126. mapproxy/service/templates/demo/static.html +34 -0
  127. mapproxy/service/templates/demo/tms_demo.html +117 -0
  128. mapproxy/service/templates/demo/wms_demo.html +144 -0
  129. mapproxy/service/templates/demo/wmts_demo.html +118 -0
  130. mapproxy/service/templates/tms_capabilities.xml +13 -0
  131. mapproxy/service/templates/tms_exception.xml +4 -0
  132. mapproxy/service/templates/tms_root_resource.xml +7 -0
  133. mapproxy/service/templates/tms_tilemap_capabilities.xml +14 -0
  134. mapproxy/service/templates/wms100capabilities.xml +112 -0
  135. mapproxy/service/templates/wms100exception.xml +4 -0
  136. mapproxy/service/templates/wms110capabilities.xml +152 -0
  137. mapproxy/service/templates/wms110exception.xml +5 -0
  138. mapproxy/service/templates/wms111capabilities.xml +183 -0
  139. mapproxy/service/templates/wms111exception.xml +5 -0
  140. mapproxy/service/templates/wms130capabilities.xml +326 -0
  141. mapproxy/service/templates/wms130exception.xml +8 -0
  142. mapproxy/service/templates/wmts100capabilities.xml +155 -0
  143. mapproxy/service/templates/wmts100exception.xml +9 -0
  144. mapproxy/service/tile.py +540 -0
  145. mapproxy/service/wms.py +868 -0
  146. mapproxy/service/wmts.py +387 -0
  147. mapproxy/source/__init__.py +83 -0
  148. mapproxy/source/arcgis.py +39 -0
  149. mapproxy/source/error.py +40 -0
  150. mapproxy/source/mapnik.py +262 -0
  151. mapproxy/source/tile.py +97 -0
  152. mapproxy/source/wms.py +273 -0
  153. mapproxy/srs.py +734 -0
  154. mapproxy/template.py +54 -0
  155. mapproxy/test/__init__.py +0 -0
  156. mapproxy/test/conftest.py +8 -0
  157. mapproxy/test/helper.py +255 -0
  158. mapproxy/test/http.py +511 -0
  159. mapproxy/test/image.py +219 -0
  160. mapproxy/test/mocker.py +2291 -0
  161. mapproxy/test/schemas/inspire/common/1.0/common.xsd +1461 -0
  162. mapproxy/test/schemas/inspire/common/1.0/enums/enum_bul.xsd +108 -0
  163. mapproxy/test/schemas/inspire/common/1.0/enums/enum_cze.xsd +108 -0
  164. mapproxy/test/schemas/inspire/common/1.0/enums/enum_dan.xsd +108 -0
  165. mapproxy/test/schemas/inspire/common/1.0/enums/enum_dut.xsd +108 -0
  166. mapproxy/test/schemas/inspire/common/1.0/enums/enum_eng.xsd +155 -0
  167. mapproxy/test/schemas/inspire/common/1.0/enums/enum_est.xsd +108 -0
  168. mapproxy/test/schemas/inspire/common/1.0/enums/enum_fin.xsd +108 -0
  169. mapproxy/test/schemas/inspire/common/1.0/enums/enum_fre.xsd +108 -0
  170. mapproxy/test/schemas/inspire/common/1.0/enums/enum_ger.xsd +108 -0
  171. mapproxy/test/schemas/inspire/common/1.0/enums/enum_gle.xsd +109 -0
  172. mapproxy/test/schemas/inspire/common/1.0/enums/enum_gre.xsd +108 -0
  173. mapproxy/test/schemas/inspire/common/1.0/enums/enum_hun.xsd +108 -0
  174. mapproxy/test/schemas/inspire/common/1.0/enums/enum_ita.xsd +108 -0
  175. mapproxy/test/schemas/inspire/common/1.0/enums/enum_lav.xsd +108 -0
  176. mapproxy/test/schemas/inspire/common/1.0/enums/enum_lit.xsd +108 -0
  177. mapproxy/test/schemas/inspire/common/1.0/enums/enum_mlt.xsd +108 -0
  178. mapproxy/test/schemas/inspire/common/1.0/enums/enum_pol.xsd +108 -0
  179. mapproxy/test/schemas/inspire/common/1.0/enums/enum_por.xsd +108 -0
  180. mapproxy/test/schemas/inspire/common/1.0/enums/enum_rum.xsd +108 -0
  181. mapproxy/test/schemas/inspire/common/1.0/enums/enum_slo.xsd +108 -0
  182. mapproxy/test/schemas/inspire/common/1.0/enums/enum_slv.xsd +108 -0
  183. mapproxy/test/schemas/inspire/common/1.0/enums/enum_spa.xsd +108 -0
  184. mapproxy/test/schemas/inspire/common/1.0/enums/enum_swe.xsd +108 -0
  185. mapproxy/test/schemas/inspire/common/1.0/network.xsd +521 -0
  186. mapproxy/test/schemas/inspire/inspire_vs/1.0/inspire_vs.xsd +19 -0
  187. mapproxy/test/schemas/kml/2.2.0/ReadMe.txt +14 -0
  188. mapproxy/test/schemas/kml/2.2.0/atom-author-link.xsd +66 -0
  189. mapproxy/test/schemas/kml/2.2.0/ogckml22.xsd +1646 -0
  190. mapproxy/test/schemas/kml/2.2.0/xAL.xsd +1680 -0
  191. mapproxy/test/schemas/ows/1.1.0/ReadMe.txt +87 -0
  192. mapproxy/test/schemas/ows/1.1.0/ows19115subset.xsd +235 -0
  193. mapproxy/test/schemas/ows/1.1.0/owsAll.xsd +23 -0
  194. mapproxy/test/schemas/ows/1.1.0/owsCommon.xsd +157 -0
  195. mapproxy/test/schemas/ows/1.1.0/owsContents.xsd +86 -0
  196. mapproxy/test/schemas/ows/1.1.0/owsDataIdentification.xsd +127 -0
  197. mapproxy/test/schemas/ows/1.1.0/owsDomainType.xsd +279 -0
  198. mapproxy/test/schemas/ows/1.1.0/owsExceptionReport.xsd +76 -0
  199. mapproxy/test/schemas/ows/1.1.0/owsGetCapabilities.xsd +112 -0
  200. mapproxy/test/schemas/ows/1.1.0/owsGetResourceByID.xsd +51 -0
  201. mapproxy/test/schemas/ows/1.1.0/owsInputOutputData.xsd +59 -0
  202. mapproxy/test/schemas/ows/1.1.0/owsManifest.xsd +125 -0
  203. mapproxy/test/schemas/ows/1.1.0/owsOperationsMetadata.xsd +140 -0
  204. mapproxy/test/schemas/ows/1.1.0/owsServiceIdentification.xsd +60 -0
  205. mapproxy/test/schemas/ows/1.1.0/owsServiceProvider.xsd +47 -0
  206. mapproxy/test/schemas/sld/1.1.0/sld_capabilities.xsd +27 -0
  207. mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.dtd +353 -0
  208. mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.xml +188 -0
  209. mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.dtd +524 -0
  210. mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.xml +260 -0
  211. mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.dtd +273 -0
  212. mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.xml +303 -0
  213. mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.dtd +6 -0
  214. mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.xml +33 -0
  215. mapproxy/test/schemas/wms/1.1.1/OGC-exception.xsd +68 -0
  216. mapproxy/test/schemas/wms/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
  217. mapproxy/test/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd +274 -0
  218. mapproxy/test/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd +5 -0
  219. mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.dtd +276 -0
  220. mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.xml +303 -0
  221. mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.dtd +6 -0
  222. mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.xml +33 -0
  223. mapproxy/test/schemas/wms/1.3.0/ReadMe.txt +8 -0
  224. mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xml +277 -0
  225. mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xsd +611 -0
  226. mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xml +34 -0
  227. mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xsd +28 -0
  228. mapproxy/test/schemas/wmsc/1.1.1/OGC-exception.xsd +68 -0
  229. mapproxy/test/schemas/wmsc/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
  230. mapproxy/test/schemas/wmsc/1.1.1/WMS_MS_Capabilities.dtd +283 -0
  231. mapproxy/test/schemas/wmsc/1.1.1/WMS_exception_1_1_1.dtd +5 -0
  232. mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.dtd +276 -0
  233. mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.xml +303 -0
  234. mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.dtd +6 -0
  235. mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.xml +33 -0
  236. mapproxy/test/schemas/wmts/1.0/ReadMe.txt +32 -0
  237. mapproxy/test/schemas/wmts/1.0/wmts.xsd +28 -0
  238. mapproxy/test/schemas/wmts/1.0/wmtsAbstract.wsdl +151 -0
  239. mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_request.xsd +38 -0
  240. mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_response.xsd +564 -0
  241. mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_request.xsd +57 -0
  242. mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_response.xsd +72 -0
  243. mapproxy/test/schemas/wmts/1.0/wmtsGetTile_request.xsd +91 -0
  244. mapproxy/test/schemas/wmts/1.0/wmtsKVP.xsd +76 -0
  245. mapproxy/test/schemas/wmts/1.0/wmtsPayload_response.xsd +70 -0
  246. mapproxy/test/schemas/xlink/1.0.0/ReadMe.txt +6 -0
  247. mapproxy/test/schemas/xlink/1.0.0/xlinks.xsd +122 -0
  248. mapproxy/test/schemas/xml.xsd +287 -0
  249. mapproxy/test/system/__init__.py +98 -0
  250. mapproxy/test/system/fixture/arcgis.yaml +57 -0
  251. mapproxy/test/system/fixture/auth.yaml +70 -0
  252. mapproxy/test/system/fixture/cache.mbtiles +0 -0
  253. mapproxy/test/system/fixture/cache_azureblob.yaml +59 -0
  254. mapproxy/test/system/fixture/cache_band_merge.yaml +73 -0
  255. mapproxy/test/system/fixture/cache_bulk_meta_tiles.yaml +24 -0
  256. mapproxy/test/system/fixture/cache_coverage.yaml +84 -0
  257. mapproxy/test/system/fixture/cache_data/dop_cache_EPSG3857/00/000/000/000/000/000/000.png +0 -0
  258. mapproxy/test/system/fixture/cache_data/wms_cache_EPSG900913/01/000/000/000/000/000/001.jpeg +0 -0
  259. mapproxy/test/system/fixture/cache_data/wms_cache_transparent_EPSG900913/01/000/000/000/000/000/001.png +0 -0
  260. mapproxy/test/system/fixture/cache_geopackage.yaml +56 -0
  261. mapproxy/test/system/fixture/cache_grid_names.yaml +50 -0
  262. mapproxy/test/system/fixture/cache_mbtiles.yaml +28 -0
  263. mapproxy/test/system/fixture/cache_s3.yaml +58 -0
  264. mapproxy/test/system/fixture/cache_source.yaml +81 -0
  265. mapproxy/test/system/fixture/combined_sources.yaml +130 -0
  266. mapproxy/test/system/fixture/coverage.yaml +77 -0
  267. mapproxy/test/system/fixture/demo.yaml +135 -0
  268. mapproxy/test/system/fixture/dimension.yaml +59 -0
  269. mapproxy/test/system/fixture/disable_storage.yaml +25 -0
  270. mapproxy/test/system/fixture/empty_ogrdata.geojson +1 -0
  271. mapproxy/test/system/fixture/formats.yaml +72 -0
  272. mapproxy/test/system/fixture/inspire.yaml +101 -0
  273. mapproxy/test/system/fixture/inspire_full.yaml +124 -0
  274. mapproxy/test/system/fixture/kml_layer.yaml +66 -0
  275. mapproxy/test/system/fixture/layer.yaml +260 -0
  276. mapproxy/test/system/fixture/layergroups.yaml +57 -0
  277. mapproxy/test/system/fixture/layergroups_root.yaml +106 -0
  278. mapproxy/test/system/fixture/legendgraphic.yaml +93 -0
  279. mapproxy/test/system/fixture/mapnik_source.yaml +66 -0
  280. mapproxy/test/system/fixture/mapproxy_export.yaml +12 -0
  281. mapproxy/test/system/fixture/mapserver.yaml +23 -0
  282. mapproxy/test/system/fixture/minimal_cgi.py +16 -0
  283. mapproxy/test/system/fixture/mixed_mode.yaml +49 -0
  284. mapproxy/test/system/fixture/multi_cache_layers.yaml +111 -0
  285. mapproxy/test/system/fixture/multiapp1.yaml +20 -0
  286. mapproxy/test/system/fixture/multiapp2.yaml +19 -0
  287. mapproxy/test/system/fixture/renderd_client.yaml +55 -0
  288. mapproxy/test/system/fixture/scalehints.yaml +70 -0
  289. mapproxy/test/system/fixture/seed.yaml +94 -0
  290. mapproxy/test/system/fixture/seed_mapproxy.yaml +39 -0
  291. mapproxy/test/system/fixture/seed_old.yaml +12 -0
  292. mapproxy/test/system/fixture/seed_timeouts.yaml +12 -0
  293. mapproxy/test/system/fixture/seed_timeouts_mapproxy.yaml +27 -0
  294. mapproxy/test/system/fixture/seedonly.yaml +51 -0
  295. mapproxy/test/system/fixture/sld.yaml +35 -0
  296. mapproxy/test/system/fixture/source_errors.yaml +84 -0
  297. mapproxy/test/system/fixture/source_errors_raise.yaml +82 -0
  298. mapproxy/test/system/fixture/tileservice_origin.yaml +26 -0
  299. mapproxy/test/system/fixture/tileservice_refresh.yaml +59 -0
  300. mapproxy/test/system/fixture/tilesource_minmax_res.yaml +22 -0
  301. mapproxy/test/system/fixture/util-conf-base-grids.yaml +5 -0
  302. mapproxy/test/system/fixture/util-conf-overwrite.yaml +13 -0
  303. mapproxy/test/system/fixture/util-conf-wms-111-cap.xml +90 -0
  304. mapproxy/test/system/fixture/util_grids.yaml +29 -0
  305. mapproxy/test/system/fixture/util_wms_capabilities111.xml +130 -0
  306. mapproxy/test/system/fixture/util_wms_capabilities130.xml +100 -0
  307. mapproxy/test/system/fixture/util_wms_capabilities_service_exception.xml +5 -0
  308. mapproxy/test/system/fixture/watermark.yaml +50 -0
  309. mapproxy/test/system/fixture/wms_srs_extent.yaml +39 -0
  310. mapproxy/test/system/fixture/wms_versions.yaml +38 -0
  311. mapproxy/test/system/fixture/wmts.yaml +134 -0
  312. mapproxy/test/system/fixture/wmts_dimensions.yaml +57 -0
  313. mapproxy/test/system/fixture/xslt_featureinfo.yaml +54 -0
  314. mapproxy/test/system/fixture/xslt_featureinfo_input.yaml +51 -0
  315. mapproxy/test/system/test_arcgis.py +156 -0
  316. mapproxy/test/system/test_auth.py +1133 -0
  317. mapproxy/test/system/test_behind_proxy.py +75 -0
  318. mapproxy/test/system/test_bulk_meta_tiles.py +106 -0
  319. mapproxy/test/system/test_cache_azureblob.py +127 -0
  320. mapproxy/test/system/test_cache_band_merge.py +103 -0
  321. mapproxy/test/system/test_cache_coverage.py +168 -0
  322. mapproxy/test/system/test_cache_geopackage.py +144 -0
  323. mapproxy/test/system/test_cache_grid_names.py +89 -0
  324. mapproxy/test/system/test_cache_mbtiles.py +85 -0
  325. mapproxy/test/system/test_cache_s3.py +115 -0
  326. mapproxy/test/system/test_cache_source.py +146 -0
  327. mapproxy/test/system/test_combined_sources.py +335 -0
  328. mapproxy/test/system/test_coverage.py +140 -0
  329. mapproxy/test/system/test_decorate_img.py +214 -0
  330. mapproxy/test/system/test_demo.py +56 -0
  331. mapproxy/test/system/test_demo_with_extra_service.py +57 -0
  332. mapproxy/test/system/test_dimensions.py +279 -0
  333. mapproxy/test/system/test_disable_storage.py +42 -0
  334. mapproxy/test/system/test_formats.py +219 -0
  335. mapproxy/test/system/test_inspire_vs.py +173 -0
  336. mapproxy/test/system/test_kml.py +264 -0
  337. mapproxy/test/system/test_layergroups.py +160 -0
  338. mapproxy/test/system/test_legendgraphic.py +308 -0
  339. mapproxy/test/system/test_mapnik.py +162 -0
  340. mapproxy/test/system/test_mapserver.py +83 -0
  341. mapproxy/test/system/test_mixed_mode_format.py +201 -0
  342. mapproxy/test/system/test_multi_cache_layers.py +169 -0
  343. mapproxy/test/system/test_multiapp.py +92 -0
  344. mapproxy/test/system/test_refresh.py +206 -0
  345. mapproxy/test/system/test_renderd_client.py +304 -0
  346. mapproxy/test/system/test_response_headers.py +54 -0
  347. mapproxy/test/system/test_scalehints.py +140 -0
  348. mapproxy/test/system/test_seed.py +425 -0
  349. mapproxy/test/system/test_seed_only.py +93 -0
  350. mapproxy/test/system/test_sld.py +120 -0
  351. mapproxy/test/system/test_source_errors.py +377 -0
  352. mapproxy/test/system/test_tilesource_minmax_res.py +54 -0
  353. mapproxy/test/system/test_tms.py +277 -0
  354. mapproxy/test/system/test_tms_origin.py +46 -0
  355. mapproxy/test/system/test_util_conf.py +434 -0
  356. mapproxy/test/system/test_util_export.py +210 -0
  357. mapproxy/test/system/test_util_grids.py +88 -0
  358. mapproxy/test/system/test_util_wms_capabilities.py +182 -0
  359. mapproxy/test/system/test_watermark.py +91 -0
  360. mapproxy/test/system/test_wms.py +1616 -0
  361. mapproxy/test/system/test_wms_srs_extent.py +165 -0
  362. mapproxy/test/system/test_wms_version.py +85 -0
  363. mapproxy/test/system/test_wmsc.py +116 -0
  364. mapproxy/test/system/test_wmts.py +334 -0
  365. mapproxy/test/system/test_wmts_dimensions.py +206 -0
  366. mapproxy/test/system/test_wmts_restful.py +198 -0
  367. mapproxy/test/system/test_xslt_featureinfo.py +423 -0
  368. mapproxy/test/test_http_helper.py +217 -0
  369. mapproxy/test/unit/__init__.py +0 -0
  370. mapproxy/test/unit/epsg +2 -0
  371. mapproxy/test/unit/polygons/polygons.dbf +0 -0
  372. mapproxy/test/unit/polygons/polygons.shp +0 -0
  373. mapproxy/test/unit/polygons/polygons.shx +0 -0
  374. mapproxy/test/unit/test_async.py +242 -0
  375. mapproxy/test/unit/test_auth.py +430 -0
  376. mapproxy/test/unit/test_cache.py +1356 -0
  377. mapproxy/test/unit/test_cache_azureblob.py +97 -0
  378. mapproxy/test/unit/test_cache_compact.py +324 -0
  379. mapproxy/test/unit/test_cache_couchdb.py +118 -0
  380. mapproxy/test/unit/test_cache_geopackage.py +256 -0
  381. mapproxy/test/unit/test_cache_redis.py +123 -0
  382. mapproxy/test/unit/test_cache_riak.py +80 -0
  383. mapproxy/test/unit/test_cache_s3.py +93 -0
  384. mapproxy/test/unit/test_cache_tile.py +477 -0
  385. mapproxy/test/unit/test_client.py +488 -0
  386. mapproxy/test/unit/test_client_arcgis.py +74 -0
  387. mapproxy/test/unit/test_client_cgi.py +140 -0
  388. mapproxy/test/unit/test_collections.py +116 -0
  389. mapproxy/test/unit/test_concat_legends.py +37 -0
  390. mapproxy/test/unit/test_conf_loader.py +1267 -0
  391. mapproxy/test/unit/test_conf_validator.py +427 -0
  392. mapproxy/test/unit/test_config.py +118 -0
  393. mapproxy/test/unit/test_decorate_img.py +185 -0
  394. mapproxy/test/unit/test_exceptions.py +270 -0
  395. mapproxy/test/unit/test_featureinfo.py +313 -0
  396. mapproxy/test/unit/test_file_lock_load.py +49 -0
  397. mapproxy/test/unit/test_geom.py +512 -0
  398. mapproxy/test/unit/test_grid.py +1279 -0
  399. mapproxy/test/unit/test_image.py +1051 -0
  400. mapproxy/test/unit/test_image_mask.py +181 -0
  401. mapproxy/test/unit/test_image_messages.py +209 -0
  402. mapproxy/test/unit/test_image_options.py +160 -0
  403. mapproxy/test/unit/test_isodate.py +118 -0
  404. mapproxy/test/unit/test_multiapp.py +163 -0
  405. mapproxy/test/unit/test_ogr_reader.py +51 -0
  406. mapproxy/test/unit/test_request.py +745 -0
  407. mapproxy/test/unit/test_request_wmts.py +178 -0
  408. mapproxy/test/unit/test_response.py +78 -0
  409. mapproxy/test/unit/test_seed.py +365 -0
  410. mapproxy/test/unit/test_seed_cachelock.py +91 -0
  411. mapproxy/test/unit/test_srs.py +215 -0
  412. mapproxy/test/unit/test_tiled_source.py +122 -0
  413. mapproxy/test/unit/test_tilefilter.py +31 -0
  414. mapproxy/test/unit/test_times.py +25 -0
  415. mapproxy/test/unit/test_timeutils.py +50 -0
  416. mapproxy/test/unit/test_util_conf_utils.py +75 -0
  417. mapproxy/test/unit/test_utils.py +476 -0
  418. mapproxy/test/unit/test_wms_capabilities.py +44 -0
  419. mapproxy/test/unit/test_wms_layer.py +113 -0
  420. mapproxy/test/unit/test_yaml.py +68 -0
  421. mapproxy/tilefilter.py +61 -0
  422. mapproxy/util/__init__.py +0 -0
  423. mapproxy/util/async_.py +229 -0
  424. mapproxy/util/collections.py +134 -0
  425. mapproxy/util/coverage.py +337 -0
  426. mapproxy/util/ext/__init__.py +14 -0
  427. mapproxy/util/ext/dictspec/__init__.py +1 -0
  428. mapproxy/util/ext/dictspec/spec.py +131 -0
  429. mapproxy/util/ext/dictspec/test/__init__.py +0 -0
  430. mapproxy/util/ext/dictspec/test/test_validator.py +278 -0
  431. mapproxy/util/ext/dictspec/validator.py +194 -0
  432. mapproxy/util/ext/local.py +198 -0
  433. mapproxy/util/ext/lockfile.py +140 -0
  434. mapproxy/util/ext/odict.py +321 -0
  435. mapproxy/util/ext/serving.py +491 -0
  436. mapproxy/util/ext/tempita/__init__.py +1093 -0
  437. mapproxy/util/ext/tempita/_looper.py +163 -0
  438. mapproxy/util/ext/tempita/string_utils.py +24 -0
  439. mapproxy/util/ext/wmsparse/__init__.py +3 -0
  440. mapproxy/util/ext/wmsparse/duration.py +600 -0
  441. mapproxy/util/ext/wmsparse/parse.py +307 -0
  442. mapproxy/util/ext/wmsparse/test/__init__.py +0 -0
  443. mapproxy/util/ext/wmsparse/test/test_parse.py +111 -0
  444. mapproxy/util/ext/wmsparse/test/test_util.py +23 -0
  445. mapproxy/util/ext/wmsparse/test/wms-example-111.xml +90 -0
  446. mapproxy/util/ext/wmsparse/test/wms-example-130.xml +120 -0
  447. mapproxy/util/ext/wmsparse/test/wms-large-111.xml +2114 -0
  448. mapproxy/util/ext/wmsparse/test/wms_nasa_cap.xml +386 -0
  449. mapproxy/util/ext/wmsparse/util.py +189 -0
  450. mapproxy/util/fs.py +164 -0
  451. mapproxy/util/geom.py +307 -0
  452. mapproxy/util/lib.py +117 -0
  453. mapproxy/util/lock.py +171 -0
  454. mapproxy/util/ogr.py +247 -0
  455. mapproxy/util/py.py +75 -0
  456. mapproxy/util/times.py +78 -0
  457. mapproxy/util/yaml.py +58 -0
  458. mapproxy/version.py +33 -0
  459. mapproxy/wsgiapp.py +167 -0
@@ -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
@@ -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']