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,387 @@
1
+ # This file is part of the MapProxy project.
2
+ # Copyright (C) 2011 Omniscale <http://omniscale.de>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ """
17
+ WMS service handler
18
+ """
19
+ from __future__ import print_function
20
+
21
+ from functools import partial
22
+
23
+ from mapproxy.request.wmts import (
24
+ wmts_request, make_wmts_rest_request_parser,
25
+ URLTemplateConverter,
26
+ FeatureInfoURLTemplateConverter,
27
+ )
28
+ from mapproxy.layer import InfoQuery
29
+ from mapproxy.featureinfo import combine_docs
30
+ from mapproxy.service.base import Server
31
+ from mapproxy.response import Response
32
+ from mapproxy.exception import RequestError
33
+ from mapproxy.util.coverage import load_limited_to
34
+ from mapproxy.util.ext.odict import odict
35
+
36
+ from mapproxy.template import template_loader, bunch
37
+ import logging
38
+
39
+ env = {'bunch': bunch}
40
+ get_template = template_loader(__package__, 'templates', namespace=env)
41
+ log = logging.getLogger(__name__)
42
+
43
+
44
+ class WMTSServer(Server):
45
+ service = 'wmts'
46
+
47
+ def __init__(self, layers, md, request_parser=None, max_tile_age=None, info_formats={}):
48
+ Server.__init__(self)
49
+ self.request_parser = request_parser or wmts_request
50
+ self.md = md
51
+ self.max_tile_age = max_tile_age
52
+ self.layers, self.matrix_sets = self._matrix_sets(layers)
53
+ self.capabilities_class = Capabilities
54
+ self.fi_transformers = None
55
+ self.info_formats = info_formats
56
+
57
+ def _matrix_sets(self, layers):
58
+ sets = {}
59
+ layers_grids = odict()
60
+ for layer in layers.values():
61
+ grid = layer.grid
62
+ if not grid.supports_access_with_origin('nw'):
63
+ log.warning("skipping layer '%s' for WMTS, grid '%s' of cache '%s' is not compatible with WMTS",
64
+ layer.name, grid.name, layer.md['cache_name'])
65
+ continue
66
+ if grid.name not in sets:
67
+ try:
68
+ sets[grid.name] = TileMatrixSet(grid)
69
+ except AssertionError:
70
+ continue # TODO
71
+ layers_grids.setdefault(layer.name, odict())[grid.name] = layer
72
+ wmts_layers = odict()
73
+ for layer_name, layers in layers_grids.items():
74
+ wmts_layers[layer_name] = WMTSTileLayer(layers)
75
+ return wmts_layers, sets.values()
76
+
77
+ def capabilities(self, request):
78
+ service = self._service_md(request)
79
+ layers = self.authorized_tile_layers(request.http.environ)
80
+
81
+ result = self.capabilities_class(service, layers, self.matrix_sets,
82
+ info_formats=self.info_formats).render(request)
83
+ return Response(result, mimetype='application/xml')
84
+
85
+ def tile(self, request):
86
+ self.check_request(request)
87
+
88
+ tile_layer = self.layers[request.layer][request.tilematrixset]
89
+ if not request.format:
90
+ request.format = tile_layer.format
91
+
92
+ self.check_request_dimensions(tile_layer, request)
93
+
94
+ limited_to = self.authorize_tile_layer(tile_layer, request)
95
+
96
+ def decorate_img(image):
97
+ query_extent = tile_layer.grid.srs.srs_code, tile_layer.tile_bbox(request)
98
+ return self.decorate_img(image, 'wmts', [tile_layer.name], request.http.environ, query_extent)
99
+
100
+ tile = tile_layer.render(request, coverage=limited_to, decorate_img=decorate_img)
101
+
102
+ # set the content_type to tile.format and not to request.format ( to support mixed_mode)
103
+ resp = Response(tile.as_buffer(), content_type='image/' + tile.format)
104
+ resp.cache_headers(tile.timestamp, etag_data=(tile.timestamp, tile.size),
105
+ max_age=self.max_tile_age)
106
+ resp.make_conditional(request.http)
107
+ return resp
108
+
109
+ def featureinfo(self, request):
110
+ infos = []
111
+ self.check_request(request, self.info_formats)
112
+
113
+ tile_layer = self.layers[request.layer][request.tilematrixset]
114
+ if not request.format:
115
+ request.format = tile_layer.format
116
+
117
+ feature_count = None
118
+ # WMTS REST style request do not have request params
119
+ if hasattr(request, 'params'):
120
+ feature_count = request.params.get('feature_count', None)
121
+
122
+ bbox = tile_layer.grid.tile_bbox(request.tile)
123
+ query = InfoQuery(bbox, tile_layer.grid.tile_size, tile_layer.grid.srs, request.pos,
124
+ request.infoformat, feature_count=feature_count)
125
+ self.check_request_dimensions(tile_layer, request)
126
+ coverage = self.authorize_tile_layer(tile_layer, request, featureinfo=True)
127
+
128
+ if not tile_layer.info_sources:
129
+ raise RequestError('layer %s not queryable' % str(request.layer),
130
+ code='OperationNotSupported', request=request)
131
+
132
+ if coverage and not coverage.contains(query.coord, query.srs):
133
+ infos = []
134
+ else:
135
+ for source in tile_layer.info_sources:
136
+ info = source.get_info(query)
137
+ if info is None:
138
+ continue
139
+ infos.append(info)
140
+
141
+ mimetype = request.infoformat
142
+
143
+ if not infos:
144
+ return Response('', mimetype=mimetype)
145
+
146
+ resp, _ = combine_docs(infos)
147
+
148
+ return Response(resp, mimetype=mimetype)
149
+
150
+ def authorize_tile_layer(self, tile_layer, request, featureinfo=False):
151
+ if 'mapproxy.authorize' not in request.http.environ:
152
+ return
153
+
154
+ query_extent = tile_layer.grid.srs.srs_code, tile_layer.tile_bbox(request)
155
+
156
+ service = 'wmts'
157
+ key = 'tile'
158
+ if featureinfo:
159
+ service += '.featureinfo'
160
+ key = 'featureinfo'
161
+
162
+ result = request.http.environ['mapproxy.authorize'](service, [tile_layer.name],
163
+ query_extent=query_extent, environ=request.http.environ)
164
+ if result['authorized'] == 'unauthenticated':
165
+ raise RequestError('unauthorized', status=401)
166
+ if result['authorized'] == 'full':
167
+ return
168
+ if result['authorized'] == 'partial':
169
+ if result['layers'].get(tile_layer.name, {}).get(key, False) is True:
170
+ limited_to = result['layers'][tile_layer.name].get('limited_to')
171
+ if not limited_to:
172
+ limited_to = result.get('limited_to')
173
+ if limited_to:
174
+ return load_limited_to(limited_to)
175
+ else:
176
+ return None
177
+ raise RequestError('forbidden', status=403)
178
+
179
+ def authorized_tile_layers(self, env):
180
+ if 'mapproxy.authorize' in env:
181
+ result = env['mapproxy.authorize']('wmts', [x for x in self.layers],
182
+ query_extent=None, environ=env)
183
+ if result['authorized'] == 'unauthenticated':
184
+ raise RequestError('unauthorized', status=401)
185
+ if result['authorized'] == 'full':
186
+ return self.layers.values()
187
+ if result['authorized'] == 'none':
188
+ raise RequestError('forbidden', status=403)
189
+ allowed_layers = []
190
+ for layer in self.layers.values():
191
+ if result['layers'].get(layer.name, {}).get('tile', False):
192
+ allowed_layers.append(layer)
193
+ return allowed_layers
194
+ else:
195
+ return self.layers.values()
196
+
197
+ def check_request(self, request, info_formats=None):
198
+ request.make_request()
199
+ if request.layer not in self.layers:
200
+ raise RequestError('unknown layer: ' + str(request.layer),
201
+ code='InvalidParameterValue', request=request)
202
+ if request.tilematrixset not in self.layers[request.layer]:
203
+ raise RequestError('unknown tilematrixset: ' + str(request.tilematrixset),
204
+ code='InvalidParameterValue', request=request)
205
+
206
+ if info_formats is not None:
207
+ if '/' in request.infoformat: # mimetype
208
+ if request.infoformat not in self.info_formats.values():
209
+ raise RequestError('unknown infoformat: ' + str(request.infoformat),
210
+ code='InvalidParameterValue', request=request)
211
+ else: # RESTful suffix
212
+ if request.infoformat not in self.info_formats:
213
+ raise RequestError('unknown infoformat: ' + str(request.infoformat),
214
+ code='InvalidParameterValue', request=request)
215
+ # set mimetype as infoformat
216
+ request.infoformat = self.info_formats[request.infoformat]
217
+
218
+ def check_request_dimensions(self, tile_layer, request):
219
+ # allow arbitrary dimensions in KVP service
220
+ # actual used values are checked later in TileLayer
221
+ pass
222
+
223
+ def _service_md(self, tile_request):
224
+ md = dict(self.md)
225
+ md['url'] = tile_request.url
226
+ return md
227
+
228
+
229
+ class WMTSRestServer(WMTSServer):
230
+ """
231
+ OGC WMTS 1.0.0 RESTful Server
232
+ """
233
+ service = None
234
+ names = ('wmts',)
235
+ request_methods = ('tile', 'capabilities')
236
+ default_template = '/{Layer}/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.{Format}'
237
+ default_info_template = '/{Layer}/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}/{I}/{J}.{InfoFormat}'
238
+
239
+ def __init__(self, layers, md, max_tile_age=None, template=None, fi_template=None, info_formats={}):
240
+ WMTSServer.__init__(self, layers, md)
241
+ self.max_tile_age = max_tile_age
242
+ self.template = template or self.default_template
243
+ self.fi_template = fi_template or self.default_info_template
244
+ self.info_formats = info_formats
245
+ self.url_converter = URLTemplateConverter(self.template)
246
+ self.fi_url_converter = FeatureInfoURLTemplateConverter(self.fi_template)
247
+ self.request_parser = make_wmts_rest_request_parser(self.url_converter, self.fi_url_converter)
248
+ self.capabilities_class = partial(
249
+ RestfulCapabilities, url_converter=self.url_converter, fi_url_converter=self.fi_url_converter)
250
+
251
+ def check_request_dimensions(self, tile_layer, request):
252
+ # check that unknown dimension for this layer are set to default
253
+ if request.dimensions:
254
+ for dimension, value in request.dimensions.items():
255
+ dimension = dimension.lower()
256
+ if dimension not in tile_layer.dimensions and value != 'default':
257
+ raise RequestError('unknown dimension: ' + str(dimension),
258
+ code='InvalidParameterValue', request=request)
259
+
260
+
261
+ class Capabilities(object):
262
+ """
263
+ Renders WMS capabilities documents.
264
+ """
265
+
266
+ def __init__(self, server_md, layers, matrix_sets, info_formats={}):
267
+ self.service = server_md
268
+ self.layers = layers
269
+ self.info_formats = info_formats
270
+ self.matrix_sets = matrix_sets
271
+
272
+ def render(self, _map_request):
273
+ return self._render_template(_map_request.capabilities_template)
274
+
275
+ def template_context(self):
276
+ return dict(service=bunch(default='', **self.service),
277
+ restful=False,
278
+ layers=self.layers,
279
+ info_formats=self.info_formats,
280
+ tile_matrix_sets=self.matrix_sets)
281
+
282
+ def _render_template(self, template):
283
+ template = get_template(template)
284
+ doc = template.substitute(**self.template_context())
285
+ # strip blank lines
286
+ doc = '\n'.join(x for x in doc.split('\n') if x.rstrip())
287
+ return doc
288
+
289
+
290
+ class RestfulCapabilities(Capabilities):
291
+ def __init__(self, server_md, layers, matrix_sets, url_converter, fi_url_converter, info_formats={}):
292
+ Capabilities.__init__(self, server_md, layers, matrix_sets, info_formats=info_formats)
293
+ self.url_converter = url_converter
294
+ self.fi_url_converter = fi_url_converter
295
+
296
+ def template_context(self):
297
+ return dict(service=bunch(default='', **self.service),
298
+ restful=True,
299
+ layers=self.layers,
300
+ info_formats=self.info_formats,
301
+ tile_matrix_sets=self.matrix_sets,
302
+ resource_template=self.url_converter.template,
303
+ fi_resource_template=self.fi_url_converter.template,
304
+ # dimension_key maps lowercase dimensions to the actual
305
+ # casing from the restful template
306
+ dimension_keys=dict((k.lower(), k) for k in self.url_converter.dimensions),
307
+ format_resource_template=format_resource_template,
308
+ format_info_resource_template=format_info_resource_template,
309
+ )
310
+
311
+
312
+ def format_resource_template(layer, template, service):
313
+ if '{Format}' in template:
314
+ template = template.replace('{Format}', layer.format)
315
+
316
+ if '{Layer}' in template:
317
+ template = template.replace('{Layer}', layer.name)
318
+
319
+ return service.url + template
320
+
321
+
322
+ def format_info_resource_template(layer, template, info_format, service):
323
+ if '{InfoFormat}' in template:
324
+ template = template.replace('{InfoFormat}', info_format)
325
+
326
+ if '{Layer}' in template:
327
+ template = template.replace('{Layer}', layer.name)
328
+
329
+ return service.url + template
330
+
331
+
332
+ class WMTSTileLayer(object):
333
+ """
334
+ Wrap multiple TileLayers for the same cache but with different grids.
335
+ """
336
+
337
+ def __init__(self, layers):
338
+ self.grids = [lyr.grid for lyr in layers.values()]
339
+ self.layers = layers
340
+ self._layer = layers[layers.keys()[0]]
341
+
342
+ def __getattr__(self, name):
343
+ return getattr(self._layer, name)
344
+
345
+ def __contains__(self, gridname):
346
+ return gridname in self.layers
347
+
348
+ def __getitem__(self, gridname):
349
+ return self.layers[gridname]
350
+
351
+
352
+ # calculated from well-known scale set GoogleCRS84Quad
353
+ METERS_PER_DEEGREE = 111319.4907932736
354
+
355
+
356
+ def meter_per_unit(srs):
357
+ if srs.is_latlong:
358
+ return METERS_PER_DEEGREE
359
+ return 1
360
+
361
+
362
+ class TileMatrixSet(object):
363
+ def __init__(self, grid):
364
+ self.grid = grid
365
+ self.name = grid.name
366
+ self.srs_name = grid.srs.srs_code
367
+ self.tile_matrices = list(self._tile_matrices())
368
+
369
+ def __iter__(self):
370
+ return iter(self.tile_matrices)
371
+
372
+ def _tile_matrices(self):
373
+ for level, res in self.grid.resolutions.iteritems():
374
+ origin = self.grid.origin_tile(level, 'ul')
375
+ bbox = self.grid.tile_bbox(origin)
376
+ topleft = bbox[0], bbox[3]
377
+ if self.grid.srs.is_axis_order_ne:
378
+ topleft = bbox[3], bbox[0]
379
+ grid_size = self.grid.grid_sizes[level]
380
+ scale_denom = res / (0.28 / 1000) * meter_per_unit(self.grid.srs)
381
+ yield bunch(
382
+ identifier=level,
383
+ topleft=topleft,
384
+ grid_size=grid_size,
385
+ scale_denom=scale_denom,
386
+ tile_size=self.grid.tile_size,
387
+ )
@@ -0,0 +1,83 @@
1
+ # This file is part of the MapProxy project.
2
+ # Copyright (C) 2010 Omniscale <http://omniscale.de>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ """
17
+ Map/information sources for layers or tile cache.
18
+ """
19
+
20
+ from mapproxy.layer import (
21
+ MapLayer, MapExtent, DefaultMapExtent, MapError, MapBBOXError, BlankImage, InfoLayer
22
+ )
23
+ from mapproxy.image.message import message_image
24
+ from mapproxy.image.opts import ImageOptions
25
+ from mapproxy.srs import SRS
26
+
27
+
28
+ class SourceError(MapError):
29
+ pass
30
+
31
+
32
+ class SourceBBOXError(SourceError, MapBBOXError):
33
+ pass
34
+
35
+
36
+ class InvalidSourceQuery(SourceError):
37
+ pass
38
+
39
+
40
+ class InfoSource(InfoLayer):
41
+ def get_info(self, query):
42
+ raise NotImplementedError
43
+
44
+
45
+ class LegendSource(object):
46
+ def get_legend(self, query):
47
+ raise NotImplementedError
48
+
49
+
50
+ class DebugSource(MapLayer):
51
+ def __init__(self):
52
+ MapLayer.__init__(self)
53
+ self.extent = DefaultMapExtent()
54
+ self.res_range = None
55
+
56
+ def get_map(self, query):
57
+ bbox = query.bbox
58
+ w = bbox[2] - bbox[0]
59
+ h = bbox[3] - bbox[1]
60
+ res_x = w/query.size[0]
61
+ res_y = h/query.size[1]
62
+ debug_info = "bbox: %r\nres: %.8f(%.8f)" % (bbox, res_x, res_y)
63
+ return message_image(debug_info, size=query.size,
64
+ image_opts=ImageOptions(transparent=True))
65
+
66
+
67
+ class DummySource(MapLayer):
68
+ supports_meta_tiles = True
69
+
70
+ """
71
+ Source that always returns a blank image.
72
+
73
+ Used internally for 'offline' sources (e.g. seed_only).
74
+ """
75
+
76
+ def __init__(self, coverage=None):
77
+ MapLayer.__init__(self)
78
+ self.image_opts.transparent = True
79
+ self.extent = MapExtent((-180, -90, 180, 90), SRS(4326))
80
+ self.extent = MapExtent(coverage.bbox, coverage.srs) if coverage else DefaultMapExtent()
81
+
82
+ def get_map(self, query):
83
+ raise BlankImage()
@@ -0,0 +1,39 @@
1
+ # This file is part of the MapProxy project.
2
+ # Copyright (C) 2010 Omniscale <http://omniscale.de>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from mapproxy.source.wms import WMSSource, WMSInfoSource
17
+
18
+ import logging
19
+ log = logging.getLogger('mapproxy.source.arcgis')
20
+
21
+
22
+ class ArcGISSource(WMSSource):
23
+ def __init__(self, client, image_opts=None, coverage=None,
24
+ res_range=None, supported_srs=None, supported_formats=None,
25
+ error_handler=None):
26
+ WMSSource.__init__(self, client, image_opts=image_opts,
27
+ coverage=coverage, res_range=res_range,
28
+ supported_srs=supported_srs,
29
+ supported_formats=supported_formats,
30
+ error_handler=error_handler)
31
+
32
+
33
+ class ArcGISInfoSource(WMSInfoSource):
34
+ def __init__(self, client):
35
+ self.client = client
36
+
37
+ def get_info(self, query):
38
+ doc = self.client.get_info(query)
39
+ return doc
@@ -0,0 +1,40 @@
1
+ # This file is part of the MapProxy project.
2
+ # Copyright (C) 2012 Omniscale <http://omniscale.de>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from mapproxy.image.opts import ImageOptions
17
+ from mapproxy.image import BlankImageSource
18
+
19
+
20
+ class HTTPSourceErrorHandler(object):
21
+ def __init__(self):
22
+ self.response_error_codes = {}
23
+
24
+ def add_handler(self, http_code, color, cacheable=False, authorize_stale=False):
25
+ self.response_error_codes[http_code] = (color, cacheable, authorize_stale)
26
+
27
+ def handle(self, status_code, query):
28
+ color = cacheable = None
29
+ if status_code in self.response_error_codes:
30
+ color, cacheable, authorize_stale = self.response_error_codes[status_code]
31
+ elif 'other' in self.response_error_codes:
32
+ color, cacheable, authorize_stale = self.response_error_codes['other']
33
+ else:
34
+ return None
35
+
36
+ transparent = len(color) == 4
37
+ image_opts = ImageOptions(bgcolor=color, transparent=transparent)
38
+ img_source = BlankImageSource(query.size, image_opts, cacheable=cacheable)
39
+ img_source.authorize_stale = authorize_stale
40
+ return img_source