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
mapproxy/util/fs.py ADDED
@@ -0,0 +1,164 @@
1
+ # This file is part of the MapProxy project.
2
+ # Copyright (C) 2010-2013 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
+ File system related utility functions.
18
+ """
19
+ from __future__ import absolute_import
20
+ import time
21
+ import os
22
+ import sys
23
+ import random
24
+ import errno
25
+ import shutil
26
+
27
+
28
+ def swap_dir(src_dir, dst_dir, keep_old=False, backup_ext='.tmp'):
29
+ """
30
+ Rename `src_dir` to `dst_dir`. The `dst_dir` is first renamed to
31
+ `dst_dir` + `backup_ext` to keep the interruption short.
32
+ Then the `src_dir` is renamed. If `keep_old` is False, the old content
33
+ of `dst_dir` will be removed.
34
+ """
35
+ tmp_dir = dst_dir + backup_ext
36
+ if os.path.exists(dst_dir):
37
+ os.rename(dst_dir, tmp_dir)
38
+
39
+ _force_rename_dir(src_dir, dst_dir)
40
+
41
+ if os.path.exists(tmp_dir) and not keep_old:
42
+ shutil.rmtree(tmp_dir)
43
+
44
+
45
+ def _force_rename_dir(src_dir, dst_dir):
46
+ """
47
+ Rename `src_dir` to `dst_dir`. If `dst_dir` exists, it will be removed.
48
+ """
49
+ # someone might recreate the directory between rmtree and rename,
50
+ # so we try to remove it until we can rename our new directory
51
+ rename_tries = 0
52
+ while rename_tries < 10:
53
+ try:
54
+ os.rename(src_dir, dst_dir)
55
+ except OSError as ex:
56
+ if ex.errno == errno.ENOTEMPTY or ex.errno == errno.EEXIST:
57
+ if rename_tries > 0:
58
+ time.sleep(2**rename_tries / 100.0) # from 10ms to 5s
59
+ rename_tries += 1
60
+ shutil.rmtree(dst_dir)
61
+ else:
62
+ raise
63
+ else:
64
+ break # on success
65
+
66
+
67
+ def cleanup_directory(directory, before_timestamp, remove_empty_dirs=True,
68
+ file_handler=None):
69
+ if file_handler is None:
70
+ if before_timestamp == 0 and remove_empty_dirs is True and os.path.exists(directory):
71
+ shutil.rmtree(directory, ignore_errors=True)
72
+ return
73
+
74
+ file_handler = os.remove
75
+
76
+ if os.path.exists(directory):
77
+ for dirpath, dirnames, filenames in os.walk(directory, topdown=False):
78
+ if not filenames:
79
+ if (remove_empty_dirs and not os.listdir(dirpath)
80
+ and dirpath != directory):
81
+ os.rmdir(dirpath)
82
+ continue
83
+ for filename in filenames:
84
+ filename = os.path.join(dirpath, filename)
85
+ try:
86
+ if before_timestamp == 0:
87
+ file_handler(filename)
88
+ if os.lstat(filename).st_mtime < before_timestamp:
89
+ file_handler(filename)
90
+ except OSError as ex:
91
+ if ex.errno != errno.ENOENT:
92
+ raise
93
+
94
+ if remove_empty_dirs:
95
+ remove_dir_if_emtpy(dirpath)
96
+
97
+ if remove_empty_dirs:
98
+ remove_dir_if_emtpy(directory)
99
+
100
+
101
+ def remove_dir_if_emtpy(directory):
102
+ try:
103
+ os.rmdir(directory)
104
+ except OSError as ex:
105
+ if ex.errno != errno.ENOENT and ex.errno != errno.ENOTEMPTY:
106
+ raise
107
+
108
+
109
+ def ensure_directory(file_name):
110
+ """
111
+ Create directory if it does not exist, else do nothing.
112
+ """
113
+ dir_name = os.path.dirname(file_name)
114
+ if not os.path.exists(dir_name):
115
+ try:
116
+ os.makedirs(dir_name)
117
+ except OSError as e:
118
+ if e.errno != errno.EEXIST:
119
+ raise e
120
+
121
+
122
+ def write_atomic(filename, data):
123
+ """
124
+ write_atomic writes `data` to a random file in filename's directory
125
+ first and renames that file to the target filename afterwards.
126
+ Rename is atomic on all POSIX platforms.
127
+
128
+ Falls back to normal write on Windows.
129
+ """
130
+ if not sys.platform.startswith('win'):
131
+ # write to random filename to prevent concurrent writes in cases
132
+ # where file locking does not work (network fs)
133
+ path_tmp = filename + '.tmp-' + str(random.randint(0, 99999999))
134
+ try:
135
+ fd = os.open(path_tmp, os.O_EXCL | os.O_CREAT | os.O_WRONLY, 0o664)
136
+ with os.fdopen(fd, 'wb') as f:
137
+ f.write(data)
138
+ os.rename(path_tmp, filename)
139
+ except OSError as ex:
140
+ try:
141
+ os.unlink(path_tmp)
142
+ except OSError:
143
+ pass
144
+ raise ex
145
+ else:
146
+ fd = os.open(filename, os.O_CREAT | os.O_WRONLY, 0o664)
147
+ with os.fdopen(fd, 'wb') as f:
148
+ f.write(data)
149
+
150
+
151
+ def find_exec(executable):
152
+ """
153
+ Search executable in PATH environment. Return path if found, None if not.
154
+ """
155
+ path = os.environ.get('PATH')
156
+ if not path:
157
+ return
158
+ for p in path.split(os.path.pathsep):
159
+ p = os.path.join(p, executable)
160
+ if os.path.exists(p):
161
+ return p
162
+ p += '.exe'
163
+ if os.path.exists(p):
164
+ return p
mapproxy/util/geom.py ADDED
@@ -0,0 +1,307 @@
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
+ import os
19
+ import json
20
+ import codecs
21
+ from functools import partial
22
+ from contextlib import closing
23
+
24
+ from mapproxy.grid import tile_grid
25
+
26
+ import logging
27
+ log_config = logging.getLogger('mapproxy.config.coverage')
28
+
29
+ try:
30
+ import shapely.wkt
31
+ import shapely.geometry
32
+ import shapely.ops
33
+ import shapely.prepared
34
+ from shapely.errors import ShapelyError
35
+ geom_support = True
36
+ except ImportError:
37
+ geom_support = False
38
+
39
+
40
+ class GeometryError(Exception):
41
+ pass
42
+
43
+
44
+ class EmptyGeometryError(Exception):
45
+ pass
46
+
47
+
48
+ class CoverageReadError(Exception):
49
+ pass
50
+
51
+
52
+ def require_geom_support():
53
+ if not geom_support:
54
+ raise ImportError('Shapely required for geometry support')
55
+
56
+
57
+ def load_datasource(datasource, where=None):
58
+ """
59
+ Loads polygons from WKT text files or OGR datasources.
60
+
61
+ Returns a list of Shapely Polygons.
62
+ """
63
+ # check if it is a wkt or geojson file
64
+ if os.path.exists(os.path.abspath(datasource)):
65
+ with open(os.path.abspath(datasource), 'rb') as fp:
66
+ data = fp.read(50)
67
+ if data.lower().lstrip().startswith((b'polygon', b'multipolygon')):
68
+ return load_polygons(datasource)
69
+ # only load geojson directly if we don't have a filter
70
+ if where is None and data and data.startswith(b'{'):
71
+ return load_geojson(datasource)
72
+ # otherwise pass to OGR
73
+ return load_ogr_datasource(datasource, where=where)
74
+
75
+
76
+ def load_ogr_datasource(datasource, where=None):
77
+ """
78
+ Loads polygons from any OGR datasource.
79
+
80
+ Returns a list of Shapely Polygons.
81
+ """
82
+ from mapproxy.util.ogr import OGRShapeReader, OGRShapeReaderError
83
+
84
+ polygons = []
85
+ try:
86
+ with closing(OGRShapeReader(datasource)) as reader:
87
+ for wkt in reader.wkts(where):
88
+ if not isinstance(wkt, str):
89
+ wkt = wkt.decode()
90
+ try:
91
+ geom = shapely.wkt.loads(wkt)
92
+ except ShapelyError as ex:
93
+ raise GeometryError(ex)
94
+ if geom.geom_type == 'Polygon':
95
+ polygons.append(geom)
96
+ elif geom.geom_type == 'MultiPolygon':
97
+ for p in geom.geoms:
98
+ polygons.append(p)
99
+ else:
100
+ log_config.warning('skipping %s geometry from %s: not a Polygon/MultiPolygon',
101
+ geom.geom_type, datasource)
102
+ except OGRShapeReaderError as ex:
103
+ raise CoverageReadError(ex)
104
+
105
+ return polygons
106
+
107
+
108
+ def load_polygons(geom_files):
109
+ """
110
+ Loads WKT polygons from one or more text files.
111
+
112
+ Returns a list of Shapely Polygons.
113
+ """
114
+ polygons = []
115
+ if isinstance(geom_files, str):
116
+ geom_files = [geom_files]
117
+
118
+ for geom_file in geom_files:
119
+ # open with utf-8-sig encoding to get rid of UTF8 BOM from MS Notepad
120
+ with codecs.open(geom_file, encoding='utf-8-sig') as f:
121
+ polygons.extend(load_polygon_lines(f, source=geom_files))
122
+
123
+ return polygons
124
+
125
+
126
+ def load_geojson(datasource):
127
+ with open(datasource) as f:
128
+ geojson = json.load(f)
129
+ t = geojson.get('type')
130
+ if not t:
131
+ raise CoverageReadError("not a GeoJSON")
132
+ geometries = []
133
+ if t == 'FeatureCollection':
134
+ for f in geojson.get('features'):
135
+ geom = f.get('geometry')
136
+ if geom:
137
+ geometries.append(geom)
138
+ elif t == 'Feature':
139
+ if 'geometry' in geojson:
140
+ geometries.append(geojson['geometry'])
141
+ elif t in ('Polygon', 'MultiPolygon'):
142
+ geometries.append(geojson)
143
+ else:
144
+ log_config.warning('skipping feature of type %s from %s: not a Polygon/MultiPolygon',
145
+ t, datasource)
146
+
147
+ polygons = []
148
+ for geom in geometries:
149
+ geom = shapely.geometry.shape(geom)
150
+ if geom.geom_type == 'Polygon':
151
+ polygons.append(geom)
152
+ elif geom.geom_type == 'MultiPolygon':
153
+ for p in geom.geoms:
154
+ polygons.append(p)
155
+ else:
156
+ log_config.warning('ignoring non-polygon geometry (%s) from %s',
157
+ geom.geom_type, datasource)
158
+
159
+ return polygons
160
+
161
+
162
+ def load_polygon_lines(line_iter, source='<string>'):
163
+ polygons = []
164
+ for line in line_iter:
165
+ if not line.strip():
166
+ continue
167
+ geom = shapely.wkt.loads(line)
168
+ if geom.geom_type == 'Polygon':
169
+ polygons.append(geom)
170
+ elif geom.geom_type == 'MultiPolygon':
171
+ for p in geom.geoms:
172
+ polygons.append(p)
173
+ else:
174
+ log_config.warning('ignoring non-polygon geometry (%s) from %s',
175
+ geom.geom_type, source)
176
+
177
+ return polygons
178
+
179
+
180
+ def build_multipolygon(polygons, simplify=False):
181
+ if not polygons:
182
+ raise EmptyGeometryError('no polygons')
183
+
184
+ if len(polygons) == 1:
185
+ geom = polygons[0]
186
+ if simplify:
187
+ geom = simplify_geom(geom)
188
+ return geom.bounds, geom
189
+
190
+ if simplify:
191
+ polygons = [simplify_geom(g) for g in polygons]
192
+
193
+ # eliminate any self-overlaps
194
+ mp = shapely.ops.unary_union(polygons)
195
+
196
+ return mp.bounds, mp
197
+
198
+
199
+ def simplify_geom(geom):
200
+ bounds = geom.bounds
201
+ if not bounds:
202
+ raise EmptyGeometryError('Empty geometry given')
203
+ w, h = bounds[2] - bounds[0], bounds[3] - bounds[1]
204
+ tolerance = min((w/1e6, h/1e6))
205
+ geom = geom.simplify(tolerance, preserve_topology=True)
206
+ if not geom.is_valid:
207
+ geom = geom.buffer(0)
208
+ return geom
209
+
210
+
211
+ def bbox_polygon(bbox):
212
+ """
213
+ Create Polygon that covers the given bbox.
214
+ """
215
+ return shapely.geometry.Polygon((
216
+ (bbox[0], bbox[1]),
217
+ (bbox[2], bbox[1]),
218
+ (bbox[2], bbox[3]),
219
+ (bbox[0], bbox[3]),
220
+ ))
221
+
222
+
223
+ def transform_geometry(from_srs, to_srs, geometry):
224
+ transf = partial(transform_xy, from_srs, to_srs)
225
+
226
+ if geometry.geom_type == 'Polygon':
227
+ result = transform_polygon(transf, geometry)
228
+ elif geometry.geom_type == 'MultiPolygon':
229
+ result = transform_multipolygon(transf, geometry)
230
+ else:
231
+ raise ValueError('cannot transform %s' % geometry.geom_type)
232
+
233
+ if not result.is_valid:
234
+ result = result.buffer(0)
235
+ return result
236
+
237
+
238
+ def transform_polygon(transf, polygon):
239
+ ext = transf(polygon.exterior.xy)
240
+ ints = [transf(ring.xy) for ring in polygon.interiors]
241
+ return shapely.geometry.Polygon(ext, ints)
242
+
243
+
244
+ def transform_multipolygon(transf, multipolygon):
245
+ transformed_polygons = []
246
+ for polygon in multipolygon.geoms:
247
+ transformed_polygons.append(transform_polygon(transf, polygon))
248
+ return shapely.geometry.MultiPolygon(transformed_polygons)
249
+
250
+
251
+ def transform_xy(from_srs, to_srs, xy):
252
+ return list(from_srs.transform_to(to_srs, list(zip(*xy))))
253
+
254
+
255
+ def flatten_to_polygons(geometry):
256
+ """
257
+ Return a list of all polygons of this (multi)`geometry`.
258
+ """
259
+ if geometry.geom_type == 'Polygon':
260
+ return [geometry]
261
+
262
+ if geometry.geom_type == 'MultiPolygon':
263
+ return list(geometry.geoms)
264
+
265
+ if hasattr(geometry, 'geoms'):
266
+ # GeometryCollection or MultiLineString? return list of all polygons
267
+ geoms = []
268
+ for part in geometry.geoms:
269
+ if part.type == 'Polygon':
270
+ geoms.append(part)
271
+
272
+ if geoms:
273
+ return geoms
274
+
275
+ return []
276
+
277
+
278
+ def load_expire_tiles(expire_dir, grid=None):
279
+ if grid is None:
280
+ grid = tile_grid(3857, origin='nw')
281
+ tiles = set()
282
+
283
+ def parse(filename):
284
+ with open(filename) as f:
285
+ try:
286
+ for line in f:
287
+ if not line:
288
+ continue
289
+ tile = tuple(map(int, line.split('/')))
290
+ tiles.add(tile)
291
+ except Exception:
292
+ log_config.warning('found error in %s, skipping rest of file', filename)
293
+
294
+ if os.path.isdir(expire_dir):
295
+ for root, dirs, files in os.walk(expire_dir):
296
+ for name in files:
297
+ filename = os.path.join(root, name)
298
+ parse(filename)
299
+ else:
300
+ parse(expire_dir)
301
+
302
+ boxes = []
303
+ for tile in tiles:
304
+ z, x, y = tile
305
+ boxes.append(shapely.geometry.box(*grid.tile_bbox((x, y, z))))
306
+
307
+ return boxes
mapproxy/util/lib.py ADDED
@@ -0,0 +1,117 @@
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
+ ctypes utilities.
18
+ """
19
+ from __future__ import print_function
20
+
21
+ import sys
22
+ import os
23
+
24
+ from ctypes import CDLL
25
+ from ctypes.util import find_library as _find_library
26
+
27
+
28
+ default_locations = dict(
29
+ darwin=dict(
30
+ paths=['/opt/local/lib'],
31
+ exts=['.dylib'],
32
+ ),
33
+ win32=dict(
34
+ paths=[os.path.dirname(os.__file__) + '/../../../DLLs'],
35
+ exts=['.dll']
36
+ ),
37
+ other=dict(
38
+ paths=[], # MAPPROXY_LIB_PATH will add paths here
39
+ exts=['.so']
40
+ ),
41
+ )
42
+
43
+ additional_lib_path = os.environ.get('MAPPROXY_LIB_PATH')
44
+ if additional_lib_path:
45
+ additional_lib_path = additional_lib_path.split(os.pathsep)
46
+ additional_lib_path.reverse()
47
+ for locs in default_locations.values():
48
+ for path in additional_lib_path:
49
+ locs['paths'].insert(0, path)
50
+
51
+
52
+ def load_library(lib_names, locations_conf=default_locations):
53
+ """
54
+ Load the `lib_name` library with ctypes.
55
+ If ctypes.util.find_library does not find the library,
56
+ different path and filename extensions will be tried.
57
+
58
+ Retruns the loaded library or None.
59
+ """
60
+ if isinstance(lib_names, str):
61
+ lib_names = [lib_names]
62
+
63
+ for lib_name in lib_names:
64
+ lib = load_library_(lib_name, locations_conf)
65
+ if lib is not None:
66
+ return lib
67
+
68
+
69
+ def load_library_(lib_name, locations_conf=default_locations):
70
+ lib_path = find_library(lib_name)
71
+
72
+ if lib_path:
73
+ return CDLL(lib_path)
74
+
75
+ if sys.platform in locations_conf:
76
+ paths = locations_conf[sys.platform]['paths']
77
+ exts = locations_conf[sys.platform]['exts']
78
+ lib_path = find_library(lib_name, paths, exts)
79
+ else:
80
+ paths = locations_conf['other']['paths']
81
+ exts = locations_conf['other']['exts']
82
+ lib_path = find_library(lib_name, paths, exts)
83
+
84
+ if lib_path:
85
+ return CDLL(lib_path)
86
+
87
+
88
+ def find_library(lib_name, paths=None, exts=None):
89
+ """
90
+ Search for library in all permutations of `paths` and `exts`.
91
+ If nothing is found None is returned.
92
+ """
93
+ if not paths or not exts:
94
+ lib = None
95
+ try:
96
+ lib = _find_library(lib_name)
97
+ except FileNotFoundError:
98
+ pass
99
+ if lib is None and lib_name.startswith('lib'):
100
+ try:
101
+ lib = _find_library(lib_name[3:])
102
+ except FileNotFoundError:
103
+ pass
104
+ return lib
105
+
106
+ for lib_name in [lib_name] + ([lib_name[3:]] if lib_name.startswith('lib') else []):
107
+ for path in paths:
108
+ for ext in exts:
109
+ lib_path = os.path.join(path, lib_name + ext)
110
+ if os.path.exists(lib_path):
111
+ return lib_path
112
+
113
+ return None
114
+
115
+
116
+ if __name__ == '__main__':
117
+ print(load_library(sys.argv[1]))