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,512 @@
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 tempfile
20
+ import shutil
21
+
22
+ import pytest
23
+ import shapely
24
+ import shapely.prepared
25
+ from shapely.errors import ShapelyError
26
+
27
+ from mapproxy.srs import SRS, bbox_equals
28
+ from mapproxy.util.geom import (
29
+ load_polygons,
30
+ load_datasource,
31
+ load_geojson,
32
+ load_expire_tiles,
33
+ transform_geometry,
34
+ geom_support,
35
+ bbox_polygon,
36
+ build_multipolygon,
37
+ )
38
+ from mapproxy.util.coverage import (
39
+ coverage,
40
+ MultiCoverage,
41
+ union_coverage,
42
+ diff_coverage,
43
+ intersection_coverage,
44
+ )
45
+ from mapproxy.layer import MapExtent, DefaultMapExtent
46
+ from mapproxy.test.helper import TempFile
47
+ from mapproxy.util.coverage import BBOXCoverage
48
+
49
+ pytestmark = pytest.mark.skipif(not geom_support,
50
+ reason="requires Shapely")
51
+
52
+
53
+ VALID_POLYGON1 = b"""POLYGON ((953296.704552185838111 7265916.626927595585585,
54
+ 944916.907243740395643 7266183.505430161952972,
55
+ 943803.712335807620548 7266450.200959664769471,
56
+ 935361.798751499853097 7269866.750814219936728,
57
+ 934743.530299633974209 7270560.353549793362617,
58
+ 934743.530299633974209 7271628.176921582780778,
59
+ 935794.720251194899902 7274619.979839355684817,
60
+ 936567.834114754223265 7275849.767033117823303,
61
+ 937959.439069160842337 7277078.402297221124172,
62
+ 940062.041611264110543 7278254.31110474281013,
63
+ 941948.350382756092586 7278948.856433514505625,
64
+ 950513.717282353783958 7279590.533784243278205,
65
+ 951905.099597778869793 7279323.193848768249154,
66
+ 953976.97796042333357 7278628.807455806992948,
67
+ 955337.636096389498562 7277987.20964437816292,
68
+ 955646.770322322496213 7277612.74426197167486,
69
+ 955894.122230865177698 7277238.489366835914552,
70
+ 956759.965230255154893 7273070.375410236418247,
71
+ 956790.912048695725389 7272483.464432151056826,
72
+ 954255.388006897410378 7266929.622660100460052,
73
+ 953760.684189812047407 7266129.1298723295331,
74
+ 953296.704552185838111 7265916.626927595585585))""".replace(b'\n', b' ')
75
+
76
+ VALID_POLYGON2 = b"""POLYGON ((929919.722805089084432 7252212.673410807736218,
77
+ 929393.960850072442554 7252372.056830812245607,
78
+ 928651.905124444281682 7252957.449742536991835,
79
+ 927507.763398071052507 7254289.325379111804068,
80
+ 923735.145855087204836 7261007.430086207576096,
81
+ 923394.953491222811863 7261914.35770049970597,
82
+ 923333.171173832495697 7262554.628265766426921,
83
+ 923580.523082375293598 7263621.350993251428008,
84
+ 924786.558445629663765 7266503.041579172946513,
85
+ 925281.262262714910321 7267303.380754604935646,
86
+ 928713.687441834714264 7270453.271698194555938,
87
+ 929486.801305394037627 7271041.567251891829073,
88
+ 929950.558304038597271 7271201.337567078880966,
89
+ 930414.426622174330987 7270987.157654598355293,
90
+ 935083.722663498250768 7255089.941797585226595,
91
+ 931527.621530107106082 7252531.635323006659746,
92
+ 931125.535529361688532 7252317.969672014936805,
93
+ 929919.722805089084432 7252212.673410807736218))""".replace(b'\n', b' ')
94
+
95
+ INTERSECTING_POLYGONS = """POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))
96
+ POLYGON ((5 0, 15 0, 15 10, 5 10, 5 0))
97
+ """
98
+
99
+
100
+ class TestPolygonLoading(object):
101
+ def test_loading_polygon(self):
102
+ with TempFile() as fname:
103
+ with open(fname, 'wb') as f:
104
+ f.write(VALID_POLYGON1)
105
+ polygon = load_polygons(fname)
106
+ bbox, polygon = build_multipolygon(polygon, simplify=True)
107
+ assert polygon.is_valid
108
+ assert polygon.geom_type == 'Polygon'
109
+
110
+ def test_loading_multipolygon(self):
111
+ with TempFile() as fname:
112
+ with open(fname, 'wb') as f:
113
+ f.write(VALID_POLYGON1)
114
+ f.write(b'\n')
115
+ f.write(VALID_POLYGON2)
116
+ polygon = load_polygons(fname)
117
+ bbox, polygon = build_multipolygon(polygon, simplify=True)
118
+ assert polygon.is_valid
119
+ assert polygon.geom_type == 'MultiPolygon'
120
+
121
+ def test_loading_broken(self):
122
+ with TempFile() as fname:
123
+ with open(fname, 'wb') as f:
124
+ f.write(b"POLYGON((")
125
+ with pytest.raises(ShapelyError):
126
+ load_polygons(fname)
127
+
128
+ def test_loading_skip_non_polygon(self):
129
+ with TempFile() as fname:
130
+ with open(fname, 'wb') as f:
131
+ f.write(b"POINT(0 0)\n")
132
+ f.write(VALID_POLYGON1)
133
+ polygon = load_polygons(fname)
134
+ bbox, polygon = build_multipolygon(polygon, simplify=True)
135
+ assert polygon.is_valid
136
+ assert polygon.geom_type == 'Polygon'
137
+
138
+ def test_loading_intersecting_polygons(self):
139
+ # check that the self intersection is eliminated
140
+ # otherwise the geometry will be invalid
141
+ with TempFile() as fname:
142
+ with open(fname, 'w') as f:
143
+ f.write(INTERSECTING_POLYGONS)
144
+ polygon = load_polygons(fname)
145
+ bbox, polygon = build_multipolygon(polygon, simplify=True)
146
+ assert polygon.is_valid
147
+ assert polygon.geom_type == 'Polygon'
148
+ assert polygon.equals(shapely.geometry.Polygon([(0, 0), (15, 0), (15, 10), (0, 10)]))
149
+
150
+
151
+ class TestGeoJSONLoading(object):
152
+ @pytest.mark.parametrize('geojson,geometry', [
153
+ ['''{"type": "Polygon", "coordinates": [[[0, 0], [10, 0], [10, 10], [0, 0]]]}''',
154
+ shapely.geometry.Polygon([[0, 0], [10, 0], [10, 10], [0, 0]]), ],
155
+ ['''{"type": "MultiPolygon", "coordinates":
156
+ [[[[0, 0], [10, 0], [10, 10], [0, 0]]], [[[20, 0], [30, 0], [20, 10], [20, 0]]]]}''',
157
+ shapely.geometry.Polygon([[0, 0], [10, 0], [10, 10], [0, 0]]).union(
158
+ shapely.geometry.Polygon([[20, 0], [30, 0], [20, 10], [20, 0]])), ],
159
+ ['''{"type": "Feature", "geometry": {"type": "Polygon", "coordinates":
160
+ [[[0, 0], [10, 0], [10, 10], [0, 0]]]}}''',
161
+ shapely.geometry.Polygon([[0, 0], [10, 0], [10, 10], [0, 0]]), ],
162
+ ['''{"type": "FeatureCollection", "features": [{"type": "Feature", "geometry":
163
+ {"type": "Polygon", "coordinates": [[[0, 0], [10, 0], [10, 10], [0, 0]]]}}]}''',
164
+ shapely.geometry.Polygon([[0, 0], [10, 0], [10, 10], [0, 0]]), ],
165
+ ])
166
+ def test_geojson(self, geojson, geometry):
167
+ with TempFile() as fname:
168
+ with open(fname, 'w') as f:
169
+ f.write(geojson)
170
+ polygon = load_geojson(fname)
171
+ bbox, polygon = build_multipolygon(polygon, simplify=True)
172
+ assert polygon.is_valid
173
+ assert polygon.geom_type in ('Polygon', 'MultiPolygon'), polygon.geom_type
174
+ assert polygon.equals(geometry)
175
+
176
+
177
+ class TestTransform(object):
178
+ def test_polygon_transf(self):
179
+ p1 = shapely.geometry.Polygon([(0, 0), (10, 0), (10, 10), (0, 10)])
180
+
181
+ p2 = transform_geometry(SRS(4326), SRS(900913), p1)
182
+ assert p2.contains(shapely.geometry.Point((1000000, 1000000)))
183
+ p3 = transform_geometry(SRS(900913), SRS(4326), p2)
184
+
185
+ assert p3.symmetric_difference(p1).area < 0.00001
186
+
187
+ def test_multipolygon_transf(self):
188
+ p1 = shapely.geometry.Polygon([(0, 0), (10, 0), (10, 10), (0, 10)])
189
+ p2 = shapely.geometry.Polygon([(20, 20), (30, 20), (30, 30), (20, 30)])
190
+ mp1 = shapely.geometry.MultiPolygon([p1, p2])
191
+
192
+ mp2 = transform_geometry(SRS(4326), SRS(900913), mp1)
193
+ assert mp2.contains(shapely.geometry.Point((1000000, 1000000)))
194
+ assert not mp2.contains(shapely.geometry.Point((2000000, 2000000)))
195
+ assert mp2.contains(shapely.geometry.Point((3000000, 3000000)))
196
+
197
+ mp3 = transform_geometry(SRS(900913), SRS(4326), mp2)
198
+
199
+ assert mp3.symmetric_difference(mp1).area < 0.00001
200
+
201
+ def test_invalid_transf(self):
202
+ p = shapely.geometry.Point((0, 0))
203
+ with pytest.raises(ValueError):
204
+ transform_geometry(SRS(4326), SRS(900913), p)
205
+
206
+
207
+ class TestBBOXPolygon(object):
208
+ def test_bbox_polygon(self):
209
+ p = bbox_polygon([5, 53, 6, 54])
210
+ assert p.geom_type == 'Polygon'
211
+
212
+
213
+ class TestGeomCoverage(object):
214
+ def setup_method(self):
215
+ # box from 10 10 to 80 80 with small spike/corner to -10 60 (upper left)
216
+ self.geom = shapely.wkt.loads(
217
+ "POLYGON((10 10, 10 50, -10 60, 10 80, 80 80, 80 10, 10 10))")
218
+ self.coverage = coverage(self.geom, SRS(4326))
219
+
220
+ def test_bbox(self):
221
+ assert bbox_equals(self.coverage.bbox, [-10, 10, 80, 80], 0.0001)
222
+
223
+ def test_geom(self):
224
+ assert self.coverage.geom.geom_type == 'Polygon'
225
+
226
+ def test_contains(self):
227
+ assert self.coverage.contains((15, 15, 20, 20), SRS(4326))
228
+ assert self.coverage.contains((15, 15, 80, 20), SRS(4326))
229
+ assert not self.coverage.contains((9, 10, 20, 20), SRS(4326))
230
+
231
+ def test_intersects(self):
232
+ assert self.coverage.intersects((15, 15, 20, 20), SRS(4326))
233
+ assert self.coverage.intersects((15, 15, 80, 20), SRS(4326))
234
+ assert self.coverage.intersects((9, 10, 20, 20), SRS(4326))
235
+ assert self.coverage.intersects((-30, 10, -8, 70), SRS(4326))
236
+ assert not self.coverage.intersects((-30, 10, -11, 70), SRS(4326))
237
+
238
+ assert not self.coverage.intersects((0, 0, 1000, 1000), SRS(900913))
239
+ assert self.coverage.intersects((0, 0, 1500000, 1500000), SRS(900913))
240
+
241
+ def test_prepared(self):
242
+ assert hasattr(self.coverage, '_prepared_max')
243
+ self.coverage._prepared_max = 100
244
+ for i in range(110):
245
+ assert self.coverage.intersects((-30, 10, -8, 70), SRS(4326))
246
+
247
+ def test_eq(self):
248
+ g1 = shapely.wkt.loads("POLYGON((10 10, 10 50, -10 60, 10 80, 80 80, 80 10, 10 10))")
249
+ g2 = shapely.wkt.loads("POLYGON((10 10, 10 50, -10 60, 10 80, 80 80, 80 10, 10 10))")
250
+ assert coverage(g1, SRS(4326)) == coverage(g2, SRS(4326))
251
+ assert coverage(g1, SRS(4326)) != coverage(g2, SRS(31467))
252
+ g3 = shapely.wkt.loads("POLYGON((10.0 10, 10 50.0, -10 60, 10 80, 80 80, 80 10, 10 10))")
253
+ assert coverage(g1, SRS(4326)) == coverage(g3, SRS(4326))
254
+ g4 = shapely.wkt.loads("POLYGON((10 10, 10.1 50, -10 60, 10 80, 80 80, 80 10, 10 10))")
255
+ assert coverage(g1, SRS(4326)) != coverage(g4, SRS(4326))
256
+
257
+
258
+ class TestBBOXCoverage(object):
259
+ def setup_method(self):
260
+ self.coverage = coverage([-10, 10, 80, 80], SRS(4326))
261
+
262
+ def test_bbox(self):
263
+ assert bbox_equals(self.coverage.bbox, [-10, 10, 80, 80], 0.0001)
264
+
265
+ def test_geom(self):
266
+ assert self.coverage.geom is None
267
+
268
+ def test_contains(self):
269
+ assert self.coverage.contains((15, 15, 20, 20), SRS(4326))
270
+ assert self.coverage.contains((15, 15, 79, 20), SRS(4326))
271
+ assert self.coverage.contains((9, 10, 20, 20), SRS(4326))
272
+ assert not self.coverage.contains((9, 9.99999999, 20, 20), SRS(4326))
273
+
274
+ def test_intersects(self):
275
+ assert self.coverage.intersects((15, 15, 20, 20), SRS(4326))
276
+ assert self.coverage.intersects((15, 15, 80, 20), SRS(4326))
277
+ assert self.coverage.intersects((9, 10, 20, 20), SRS(4326))
278
+ assert self.coverage.intersects((-30, 10, -8, 70), SRS(4326))
279
+ assert not self.coverage.intersects((-30, 10, -11, 70), SRS(4326))
280
+
281
+ assert not self.coverage.intersects((0, 0, 1000, 1000), SRS(900913))
282
+ assert self.coverage.intersects((0, 0, 1500000, 1500000), SRS(900913))
283
+
284
+ def test_intersection(self):
285
+ assert (self.coverage.intersection((15, 15, 20, 20), SRS(4326)) ==
286
+ BBOXCoverage((15, 15, 20, 20), SRS(4326)))
287
+ assert (self.coverage.intersection((15, 15, 80, 20), SRS(4326)) ==
288
+ BBOXCoverage((15, 15, 80, 20), SRS(4326)))
289
+ assert (self.coverage.intersection((9, 10, 20, 20), SRS(4326)) ==
290
+ BBOXCoverage((9, 10, 20, 20), SRS(4326)))
291
+ assert (self.coverage.intersection((-30, 10, -8, 70), SRS(4326)) ==
292
+ BBOXCoverage((-10, 10, -8, 70), SRS(4326)))
293
+ assert (self.coverage.intersection((-30, 10, -11, 70), SRS(4326)) is None)
294
+ assert (self.coverage.intersection((0, 0, 1000, 1000), SRS(900913)) is None)
295
+ assert bbox_equals(
296
+ self.coverage.intersection((0, 0, 1500000, 1500000), SRS(900913)).bbox,
297
+ (0.0, 10, 13.47472926179282, 13.352207626707813)
298
+ )
299
+
300
+ def test_eq(self):
301
+ assert coverage([-10, 10, 80, 80], SRS(4326)) == coverage([-10, 10, 80, 80], SRS(4326))
302
+ assert coverage([-10, 10, 80, 80], SRS(4326)) == coverage([-10, 10.0, 80.0, 80], SRS(4326))
303
+ assert coverage([-10, 10, 80, 80], SRS(4326)) != coverage([-10.1, 10.0, 80.0, 80], SRS(4326))
304
+ assert coverage([-10, 10, 80, 80], SRS(4326)) != coverage([-10, 10.0, 80.0, 80], SRS(31467))
305
+
306
+
307
+ class TestUnionCoverage(object):
308
+ def setup_method(self):
309
+ self.coverage = union_coverage([
310
+ coverage([0, 0, 10, 10], SRS(4326)),
311
+ coverage(shapely.wkt.loads("POLYGON((10 0, 20 0, 20 10, 10 10, 10 0))"), SRS(4326)),
312
+ coverage(shapely.wkt.loads(
313
+ "POLYGON((-1000000 0, 0 0, 0 1000000, -1000000 1000000, -1000000 0))"), SRS(3857)),
314
+ ])
315
+
316
+ def test_bbox(self):
317
+ assert bbox_equals(self.coverage.bbox, [-8.98315284, 0.0, 20.0, 10.0], 0.0001), self.coverage.bbox
318
+
319
+ def test_contains(self):
320
+ assert self.coverage.contains((0, 0, 5, 5), SRS(4326))
321
+ assert self.coverage.contains((-50000, 0, -20000, 20000), SRS(3857))
322
+ assert not self.coverage.contains((-50000, -100, -20000, 20000), SRS(3857))
323
+
324
+ def test_intersects(self):
325
+ assert self.coverage.intersects((0, 0, 5, 5), SRS(4326))
326
+ assert self.coverage.intersects((5, 0, 25, 5), SRS(4326))
327
+ assert self.coverage.intersects((-50000, 0, -20000, 20000), SRS(3857))
328
+ assert self.coverage.intersects((-50000, -100, -20000, 20000), SRS(3857))
329
+
330
+
331
+ class TestDiffCoverage(object):
332
+ def setup_method(self):
333
+ g1 = coverage(shapely.wkt.loads("POLYGON((-10 0, 20 0, 20 10, -10 10, -10 0))"), SRS(4326))
334
+ g2 = coverage([0, 2, 8, 8], SRS(4326))
335
+ g3 = coverage(shapely.wkt.loads(
336
+ "POLYGON((-1000000 500000, 0 500000, 0 1000000, -1000000 1000000, -1000000 500000))"), SRS(3857))
337
+ self.coverage = diff_coverage([g1, g2, g3])
338
+
339
+ def test_bbox(self):
340
+ assert bbox_equals(self.coverage.bbox, [-10, 0.0, 20.0, 10.0], 0.0001), self.coverage.bbox
341
+
342
+ def test_contains(self):
343
+ assert self.coverage.contains((0, 0, 1, 1), SRS(4326))
344
+ assert self.coverage.contains((-1100000, 510000, -1050000, 600000), SRS(3857))
345
+ assert not self.coverage.contains((-1100000, 510000, -990000, 600000), SRS(3857)) # touches # g3
346
+ assert not self.coverage.contains((4, 4, 5, 5), SRS(4326)) # in g2
347
+
348
+ def test_intersects(self):
349
+ assert self.coverage.intersects((0, 0, 1, 1), SRS(4326))
350
+ assert self.coverage.intersects((-1100000, 510000, -1050000, 600000), SRS(3857))
351
+ assert self.coverage.intersects((-1100000, 510000, -990000, 600000), SRS(3857)) # touches # g3
352
+ assert not self.coverage.intersects((4, 4, 5, 5), SRS(4326)) # in g2
353
+
354
+
355
+ class TestIntersectionCoverage(object):
356
+ def setup_method(self):
357
+ g1 = coverage(shapely.wkt.loads("POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))"), SRS(4326))
358
+ g2 = coverage([5, 5, 15, 15], SRS(4326))
359
+ self.coverage = intersection_coverage([g1, g2])
360
+
361
+ def test_bbox(self):
362
+ assert bbox_equals(self.coverage.bbox, [5.0, 5.0, 10.0, 10.0], 0.0001), self.coverage.bbox
363
+
364
+ def test_contains(self):
365
+ assert not self.coverage.contains((0, 0, 1, 1), SRS(4326))
366
+ assert self.coverage.contains((6, 6, 7, 7), SRS(4326))
367
+
368
+ def test_intersects(self):
369
+ assert self.coverage.intersection((3, 6, 7, 7), SRS(4326))
370
+ assert self.coverage.intersection((6, 6, 7, 7), SRS(4326))
371
+ assert not self.coverage.intersects((0, 0, 1, 1), SRS(4326))
372
+
373
+
374
+ class TestMultiCoverage(object):
375
+ def setup_method(self):
376
+ # box from 10 10 to 80 80 with small spike/corner to -10 60 (upper left)
377
+ self.geom = shapely.wkt.loads(
378
+ "POLYGON((10 10, 10 50, -10 60, 10 80, 80 80, 80 10, 10 10))")
379
+ self.coverage1 = coverage(self.geom, SRS(4326))
380
+ self.coverage2 = coverage([100, 0, 120, 20], SRS(4326))
381
+ self.coverage = MultiCoverage([self.coverage1, self.coverage2])
382
+
383
+ def test_bbox(self):
384
+ assert bbox_equals(self.coverage.bbox, [-10, 0, 120, 80], 0.0001)
385
+
386
+ def test_contains(self):
387
+ assert self.coverage.contains((15, 15, 20, 20), SRS(4326))
388
+ assert self.coverage.contains((15, 15, 79, 20), SRS(4326))
389
+ assert not self.coverage.contains((9, 10, 20, 20), SRS(4326))
390
+ assert self.coverage.contains((110, 5, 115, 15), SRS(4326))
391
+
392
+ def test_intersects(self):
393
+ assert self.coverage.intersects((15, 15, 20, 20), SRS(4326))
394
+ assert self.coverage.intersects((15, 15, 80, 20), SRS(4326))
395
+ assert self.coverage.intersects((9, 10, 20, 20), SRS(4326))
396
+ assert self.coverage.intersects((-30, 10, -8, 70), SRS(4326))
397
+ assert not self.coverage.intersects((-30, 10, -11, 70), SRS(4326))
398
+
399
+ assert not self.coverage.intersects((0, 0, 1000, 1000), SRS(900913))
400
+ assert self.coverage.intersects((0, 0, 1500000, 1500000), SRS(900913))
401
+
402
+ assert self.coverage.intersects((110, 5, 115, 15), SRS(4326))
403
+ assert self.coverage.intersects((90, 5, 105, 15), SRS(4326))
404
+
405
+ def test_eq(self):
406
+ g1 = shapely.wkt.loads("POLYGON((10 10, 10 50, -10 60, 10 80, 80 80, 80 10, 10 10))")
407
+ g2 = shapely.wkt.loads("POLYGON((10 10, 10 50, -10 60, 10 80, 80 80, 80 10, 10 10))")
408
+ assert MultiCoverage([coverage(g1, SRS(4326))]) == MultiCoverage([coverage(g2, SRS(4326))])
409
+ assert MultiCoverage([coverage(g1, SRS(4326))]) != MultiCoverage([coverage(g2, SRS(31467))])
410
+ c = coverage([-10, 10, 80, 80], SRS(4326))
411
+ assert MultiCoverage([c, coverage(g1, SRS(4326))]) != MultiCoverage([c, coverage(g2, SRS(31467))])
412
+
413
+
414
+ class TestMapExtent(object):
415
+ def setup_method(self):
416
+ self.extent = MapExtent([-10, 10, 80, 80], SRS(4326))
417
+
418
+ def test_bbox(self):
419
+ assert bbox_equals(self.extent.bbox, [-10, 10, 80, 80], 0.0001)
420
+
421
+ def test_contains(self):
422
+ assert self.extent.contains(MapExtent((15, 15, 20, 20), SRS(4326)))
423
+ assert self.extent.contains(MapExtent((15, 15, 79, 20), SRS(4326)))
424
+ assert self.extent.contains(MapExtent((9, 10, 20, 20), SRS(4326)))
425
+ assert not self.extent.contains(MapExtent((9, 9.99999999, 20, 20), SRS(4326)))
426
+
427
+ def test_intersects(self):
428
+ assert self.extent.intersects(MapExtent((15, 15, 20, 20), SRS(4326)))
429
+ assert self.extent.intersects(MapExtent((15, 15, 80, 20), SRS(4326)))
430
+ assert self.extent.intersects(MapExtent((9, 10, 20, 20), SRS(4326)))
431
+ assert self.extent.intersects(MapExtent((-30, 10, -8, 70), SRS(4326)))
432
+ assert not self.extent.intersects(MapExtent((-30, 10, -11, 70), SRS(4326)))
433
+
434
+ assert not self.extent.intersects(MapExtent((0, 0, 1000, 1000), SRS(900913)))
435
+ assert self.extent.intersects(MapExtent((0, 0, 1500000, 1500000), SRS(900913)))
436
+
437
+ def test_eq(self):
438
+ assert MapExtent([-10, 10, 80, 80], SRS(4326)) == MapExtent([-10, 10, 80, 80], SRS(4326))
439
+ assert MapExtent([-10, 10, 80, 80], SRS(4326)) == MapExtent([-10, 10.0, 80.0, 80], SRS(4326))
440
+ assert MapExtent([-10, 10, 80, 80], SRS(4326)) != MapExtent([-10.1, 10.0, 80.0, 80], SRS(4326))
441
+ assert MapExtent([-10, 10, 80, 80], SRS(4326)) != MapExtent([-10, 10.0, 80.0, 80], SRS(31467))
442
+
443
+ def test_intersection(self):
444
+ assert (DefaultMapExtent().intersection(MapExtent((0, 0, 10, 10), SRS(4326)))
445
+ == MapExtent((0, 0, 10, 10), SRS(4326)))
446
+
447
+ assert (MapExtent((0, 0, 10, 10), SRS(4326)).intersection(MapExtent((20, 20, 30, 30), SRS(4326)))
448
+ is None)
449
+
450
+ sub = MapExtent((0, 0, 10, 10), SRS(4326)).intersection(MapExtent((-1000, -1000, 100000, 100000), SRS(3857)))
451
+ bbox = SRS(3857).transform_bbox_to(SRS(4326), (0, 0, 100000, 100000), 0)
452
+ assert bbox_equals(bbox, sub.bbox)
453
+
454
+
455
+ class TestLoadDatasource(object):
456
+ def test_shp(self):
457
+ polygon_file = os.path.join(os.path.dirname(__file__), 'polygons', 'polygons.shp')
458
+ geoms = load_datasource(polygon_file)
459
+ assert len(geoms) == 3
460
+
461
+ def test_wkt(self):
462
+ with TempFile() as fname:
463
+ with open(fname, 'wb') as f:
464
+ f.write(VALID_POLYGON1)
465
+ f.write(b"\n")
466
+ f.write(VALID_POLYGON1)
467
+
468
+ geoms = load_datasource(fname)
469
+ assert len(geoms) == 2
470
+
471
+ def test_geojson(self):
472
+ with TempFile() as fname:
473
+ with open(fname, 'wb') as f:
474
+ f.write(b'''{"type": "FeatureCollection", "features": [
475
+ {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [
476
+ [[0, 0], [10, 0], [10, 10], [0, 0]]
477
+ ]}},
478
+ {"type": "Feature", "geometry": {"type": "MultiPolygon", "coordinates": [
479
+ [[[0, 0], [10, 0], [10, 10], [0, 0]]],
480
+ [[[0, 0], [10, 0], [10, 10], [0, 0]]],
481
+ [[[0, 0], [10, 0], [10, 10], [0, 0]]]
482
+ ]}},
483
+ {"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}}
484
+ ]}''')
485
+
486
+ geoms = load_datasource(fname)
487
+ assert len(geoms) == 4
488
+
489
+ def test_expire_tiles_dir(self):
490
+ dirname = tempfile.mkdtemp()
491
+ try:
492
+ fname = os.path.join(dirname, 'tiles')
493
+ with open(fname, 'wb') as f:
494
+ f.write(b"4/2/5\n")
495
+ f.write(b"4/2/6\n")
496
+ f.write(b"4/4/3\n")
497
+
498
+ geoms = load_expire_tiles(dirname)
499
+ assert len(geoms) == 3
500
+ finally:
501
+ shutil.rmtree(dirname)
502
+
503
+ def test_expire_tiles_file(self):
504
+ with TempFile() as fname:
505
+ with open(fname, 'wb') as f:
506
+ f.write(b"4/2/5\n")
507
+ f.write(b"4/2/6\n")
508
+ f.write(b"error\n")
509
+ f.write(b"4/2/1\n") # rest of file is ignored
510
+
511
+ geoms = load_expire_tiles(fname)
512
+ assert len(geoms) == 2