MapProxy 1.16.1__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 (458) hide show
  1. mapproxy/__init__.py +0 -0
  2. mapproxy/cache/__init__.py +36 -0
  3. mapproxy/cache/azureblob.py +145 -0
  4. mapproxy/cache/base.py +111 -0
  5. mapproxy/cache/compact.py +664 -0
  6. mapproxy/cache/couchdb.py +295 -0
  7. mapproxy/cache/dummy.py +34 -0
  8. mapproxy/cache/file.py +185 -0
  9. mapproxy/cache/geopackage.py +609 -0
  10. mapproxy/cache/legend.py +83 -0
  11. mapproxy/cache/mbtiles.py +392 -0
  12. mapproxy/cache/meta.py +78 -0
  13. mapproxy/cache/path.py +250 -0
  14. mapproxy/cache/redis.py +88 -0
  15. mapproxy/cache/renderd.py +95 -0
  16. mapproxy/cache/riak.py +202 -0
  17. mapproxy/cache/s3.py +177 -0
  18. mapproxy/cache/tile.py +699 -0
  19. mapproxy/client/__init__.py +0 -0
  20. mapproxy/client/arcgis.py +79 -0
  21. mapproxy/client/cgi.py +139 -0
  22. mapproxy/client/http.py +315 -0
  23. mapproxy/client/log.py +33 -0
  24. mapproxy/client/tile.py +150 -0
  25. mapproxy/client/wms.py +254 -0
  26. mapproxy/compat/__init__.py +46 -0
  27. mapproxy/compat/image.py +79 -0
  28. mapproxy/compat/itertools.py +29 -0
  29. mapproxy/compat/modules.py +13 -0
  30. mapproxy/config/__init__.py +22 -0
  31. mapproxy/config/config.py +201 -0
  32. mapproxy/config/coverage.py +107 -0
  33. mapproxy/config/defaults.py +98 -0
  34. mapproxy/config/loader.py +2286 -0
  35. mapproxy/config/spec.py +644 -0
  36. mapproxy/config/validator.py +239 -0
  37. mapproxy/config_template/__init__.py +0 -0
  38. mapproxy/config_template/base_config/config.wsgi +10 -0
  39. mapproxy/config_template/base_config/full_example.yaml +593 -0
  40. mapproxy/config_template/base_config/full_seed_example.yaml +79 -0
  41. mapproxy/config_template/base_config/log.ini +35 -0
  42. mapproxy/config_template/base_config/mapproxy.yaml +60 -0
  43. mapproxy/config_template/base_config/seed.yaml +27 -0
  44. mapproxy/exception.py +142 -0
  45. mapproxy/featureinfo.py +252 -0
  46. mapproxy/grid.py +1170 -0
  47. mapproxy/image/__init__.py +536 -0
  48. mapproxy/image/fonts/DejaVuSans.ttf +0 -0
  49. mapproxy/image/fonts/DejaVuSansMono.ttf +0 -0
  50. mapproxy/image/fonts/LICENSE +99 -0
  51. mapproxy/image/fonts/__init__.py +0 -0
  52. mapproxy/image/mask.py +75 -0
  53. mapproxy/image/merge.py +316 -0
  54. mapproxy/image/message.py +347 -0
  55. mapproxy/image/opts.py +182 -0
  56. mapproxy/image/tile.py +167 -0
  57. mapproxy/image/transform.py +350 -0
  58. mapproxy/layer.py +470 -0
  59. mapproxy/multiapp.py +231 -0
  60. mapproxy/proj.py +302 -0
  61. mapproxy/request/__init__.py +18 -0
  62. mapproxy/request/arcgis.py +259 -0
  63. mapproxy/request/base.py +476 -0
  64. mapproxy/request/tile.py +128 -0
  65. mapproxy/request/wms/__init__.py +793 -0
  66. mapproxy/request/wms/exception.py +99 -0
  67. mapproxy/request/wmts.py +436 -0
  68. mapproxy/response.py +237 -0
  69. mapproxy/script/__init__.py +0 -0
  70. mapproxy/script/conf/__init__.py +0 -0
  71. mapproxy/script/conf/app.py +195 -0
  72. mapproxy/script/conf/caches.py +45 -0
  73. mapproxy/script/conf/layers.py +54 -0
  74. mapproxy/script/conf/seeds.py +37 -0
  75. mapproxy/script/conf/sources.py +86 -0
  76. mapproxy/script/conf/utils.py +143 -0
  77. mapproxy/script/defrag.py +184 -0
  78. mapproxy/script/export.py +333 -0
  79. mapproxy/script/grids.py +188 -0
  80. mapproxy/script/scales.py +126 -0
  81. mapproxy/script/util.py +406 -0
  82. mapproxy/script/wms_capabilities.py +152 -0
  83. mapproxy/seed/__init__.py +0 -0
  84. mapproxy/seed/cachelock.py +121 -0
  85. mapproxy/seed/cleanup.py +187 -0
  86. mapproxy/seed/config.py +469 -0
  87. mapproxy/seed/script.py +388 -0
  88. mapproxy/seed/seeder.py +538 -0
  89. mapproxy/seed/spec.py +64 -0
  90. mapproxy/seed/util.py +254 -0
  91. mapproxy/service/__init__.py +14 -0
  92. mapproxy/service/base.py +46 -0
  93. mapproxy/service/demo.py +356 -0
  94. mapproxy/service/kml.py +331 -0
  95. mapproxy/service/ows.py +38 -0
  96. mapproxy/service/template_helper.py +53 -0
  97. mapproxy/service/templates/demo/capabilities_demo.html +16 -0
  98. mapproxy/service/templates/demo/demo.html +181 -0
  99. mapproxy/service/templates/demo/openlayers-demo.cfg +16 -0
  100. mapproxy/service/templates/demo/static/img/blank.gif +0 -0
  101. mapproxy/service/templates/demo/static/img/east-mini.png +0 -0
  102. mapproxy/service/templates/demo/static/img/north-mini.png +0 -0
  103. mapproxy/service/templates/demo/static/img/south-mini.png +0 -0
  104. mapproxy/service/templates/demo/static/img/west-mini.png +0 -0
  105. mapproxy/service/templates/demo/static/img/zoom-minus-mini.png +0 -0
  106. mapproxy/service/templates/demo/static/img/zoom-plus-mini.png +0 -0
  107. mapproxy/service/templates/demo/static/img/zoom-world-mini.png +0 -0
  108. mapproxy/service/templates/demo/static/logo.png +0 -0
  109. mapproxy/service/templates/demo/static/ol.css +345 -0
  110. mapproxy/service/templates/demo/static/ol.js +4 -0
  111. mapproxy/service/templates/demo/static/proj4.min.js +1 -0
  112. mapproxy/service/templates/demo/static/proj4defs.js +1 -0
  113. mapproxy/service/templates/demo/static/site.css +137 -0
  114. mapproxy/service/templates/demo/static/theme/default/framedCloud.css +0 -0
  115. mapproxy/service/templates/demo/static/theme/default/google.css +17 -0
  116. mapproxy/service/templates/demo/static/theme/default/ie6-style.css +10 -0
  117. mapproxy/service/templates/demo/static/theme/default/style.css +482 -0
  118. mapproxy/service/templates/demo/static.html +34 -0
  119. mapproxy/service/templates/demo/tms_demo.html +103 -0
  120. mapproxy/service/templates/demo/wms_demo.html +140 -0
  121. mapproxy/service/templates/demo/wmts_demo.html +110 -0
  122. mapproxy/service/templates/tms_capabilities.xml +13 -0
  123. mapproxy/service/templates/tms_exception.xml +4 -0
  124. mapproxy/service/templates/tms_root_resource.xml +7 -0
  125. mapproxy/service/templates/tms_tilemap_capabilities.xml +14 -0
  126. mapproxy/service/templates/wms100capabilities.xml +112 -0
  127. mapproxy/service/templates/wms100exception.xml +4 -0
  128. mapproxy/service/templates/wms110capabilities.xml +152 -0
  129. mapproxy/service/templates/wms110exception.xml +5 -0
  130. mapproxy/service/templates/wms111capabilities.xml +183 -0
  131. mapproxy/service/templates/wms111exception.xml +5 -0
  132. mapproxy/service/templates/wms130capabilities.xml +326 -0
  133. mapproxy/service/templates/wms130exception.xml +8 -0
  134. mapproxy/service/templates/wmts100capabilities.xml +155 -0
  135. mapproxy/service/templates/wmts100exception.xml +9 -0
  136. mapproxy/service/tile.py +536 -0
  137. mapproxy/service/wms.py +851 -0
  138. mapproxy/service/wmts.py +381 -0
  139. mapproxy/source/__init__.py +75 -0
  140. mapproxy/source/arcgis.py +39 -0
  141. mapproxy/source/error.py +39 -0
  142. mapproxy/source/mapnik.py +259 -0
  143. mapproxy/source/tile.py +96 -0
  144. mapproxy/source/wms.py +270 -0
  145. mapproxy/srs.py +726 -0
  146. mapproxy/template.py +54 -0
  147. mapproxy/test/__init__.py +0 -0
  148. mapproxy/test/conftest.py +7 -0
  149. mapproxy/test/helper.py +247 -0
  150. mapproxy/test/http.py +494 -0
  151. mapproxy/test/image.py +210 -0
  152. mapproxy/test/mocker.py +2268 -0
  153. mapproxy/test/schemas/inspire/common/1.0/common.xsd +1461 -0
  154. mapproxy/test/schemas/inspire/common/1.0/enums/enum_bul.xsd +108 -0
  155. mapproxy/test/schemas/inspire/common/1.0/enums/enum_cze.xsd +108 -0
  156. mapproxy/test/schemas/inspire/common/1.0/enums/enum_dan.xsd +108 -0
  157. mapproxy/test/schemas/inspire/common/1.0/enums/enum_dut.xsd +108 -0
  158. mapproxy/test/schemas/inspire/common/1.0/enums/enum_eng.xsd +155 -0
  159. mapproxy/test/schemas/inspire/common/1.0/enums/enum_est.xsd +108 -0
  160. mapproxy/test/schemas/inspire/common/1.0/enums/enum_fin.xsd +108 -0
  161. mapproxy/test/schemas/inspire/common/1.0/enums/enum_fre.xsd +108 -0
  162. mapproxy/test/schemas/inspire/common/1.0/enums/enum_ger.xsd +108 -0
  163. mapproxy/test/schemas/inspire/common/1.0/enums/enum_gle.xsd +109 -0
  164. mapproxy/test/schemas/inspire/common/1.0/enums/enum_gre.xsd +108 -0
  165. mapproxy/test/schemas/inspire/common/1.0/enums/enum_hun.xsd +108 -0
  166. mapproxy/test/schemas/inspire/common/1.0/enums/enum_ita.xsd +108 -0
  167. mapproxy/test/schemas/inspire/common/1.0/enums/enum_lav.xsd +108 -0
  168. mapproxy/test/schemas/inspire/common/1.0/enums/enum_lit.xsd +108 -0
  169. mapproxy/test/schemas/inspire/common/1.0/enums/enum_mlt.xsd +108 -0
  170. mapproxy/test/schemas/inspire/common/1.0/enums/enum_pol.xsd +108 -0
  171. mapproxy/test/schemas/inspire/common/1.0/enums/enum_por.xsd +108 -0
  172. mapproxy/test/schemas/inspire/common/1.0/enums/enum_rum.xsd +108 -0
  173. mapproxy/test/schemas/inspire/common/1.0/enums/enum_slo.xsd +108 -0
  174. mapproxy/test/schemas/inspire/common/1.0/enums/enum_slv.xsd +108 -0
  175. mapproxy/test/schemas/inspire/common/1.0/enums/enum_spa.xsd +108 -0
  176. mapproxy/test/schemas/inspire/common/1.0/enums/enum_swe.xsd +108 -0
  177. mapproxy/test/schemas/inspire/common/1.0/network.xsd +521 -0
  178. mapproxy/test/schemas/inspire/inspire_vs/1.0/inspire_vs.xsd +19 -0
  179. mapproxy/test/schemas/kml/2.2.0/ReadMe.txt +14 -0
  180. mapproxy/test/schemas/kml/2.2.0/atom-author-link.xsd +66 -0
  181. mapproxy/test/schemas/kml/2.2.0/ogckml22.xsd +1646 -0
  182. mapproxy/test/schemas/kml/2.2.0/xAL.xsd +1680 -0
  183. mapproxy/test/schemas/ows/1.1.0/ReadMe.txt +87 -0
  184. mapproxy/test/schemas/ows/1.1.0/ows19115subset.xsd +235 -0
  185. mapproxy/test/schemas/ows/1.1.0/owsAll.xsd +23 -0
  186. mapproxy/test/schemas/ows/1.1.0/owsCommon.xsd +157 -0
  187. mapproxy/test/schemas/ows/1.1.0/owsContents.xsd +86 -0
  188. mapproxy/test/schemas/ows/1.1.0/owsDataIdentification.xsd +127 -0
  189. mapproxy/test/schemas/ows/1.1.0/owsDomainType.xsd +279 -0
  190. mapproxy/test/schemas/ows/1.1.0/owsExceptionReport.xsd +76 -0
  191. mapproxy/test/schemas/ows/1.1.0/owsGetCapabilities.xsd +112 -0
  192. mapproxy/test/schemas/ows/1.1.0/owsGetResourceByID.xsd +51 -0
  193. mapproxy/test/schemas/ows/1.1.0/owsInputOutputData.xsd +59 -0
  194. mapproxy/test/schemas/ows/1.1.0/owsManifest.xsd +125 -0
  195. mapproxy/test/schemas/ows/1.1.0/owsOperationsMetadata.xsd +140 -0
  196. mapproxy/test/schemas/ows/1.1.0/owsServiceIdentification.xsd +60 -0
  197. mapproxy/test/schemas/ows/1.1.0/owsServiceProvider.xsd +47 -0
  198. mapproxy/test/schemas/sld/1.1.0/sld_capabilities.xsd +27 -0
  199. mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.dtd +353 -0
  200. mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.xml +188 -0
  201. mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.dtd +524 -0
  202. mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.xml +260 -0
  203. mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.dtd +273 -0
  204. mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.xml +303 -0
  205. mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.dtd +6 -0
  206. mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.xml +33 -0
  207. mapproxy/test/schemas/wms/1.1.1/OGC-exception.xsd +68 -0
  208. mapproxy/test/schemas/wms/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
  209. mapproxy/test/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd +274 -0
  210. mapproxy/test/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd +5 -0
  211. mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.dtd +276 -0
  212. mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.xml +303 -0
  213. mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.dtd +6 -0
  214. mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.xml +33 -0
  215. mapproxy/test/schemas/wms/1.3.0/ReadMe.txt +8 -0
  216. mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xml +277 -0
  217. mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xsd +611 -0
  218. mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xml +34 -0
  219. mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xsd +28 -0
  220. mapproxy/test/schemas/wmsc/1.1.1/OGC-exception.xsd +68 -0
  221. mapproxy/test/schemas/wmsc/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
  222. mapproxy/test/schemas/wmsc/1.1.1/WMS_MS_Capabilities.dtd +283 -0
  223. mapproxy/test/schemas/wmsc/1.1.1/WMS_exception_1_1_1.dtd +5 -0
  224. mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.dtd +276 -0
  225. mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.xml +303 -0
  226. mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.dtd +6 -0
  227. mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.xml +33 -0
  228. mapproxy/test/schemas/wmts/1.0/ReadMe.txt +32 -0
  229. mapproxy/test/schemas/wmts/1.0/wmts.xsd +28 -0
  230. mapproxy/test/schemas/wmts/1.0/wmtsAbstract.wsdl +151 -0
  231. mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_request.xsd +38 -0
  232. mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_response.xsd +564 -0
  233. mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_request.xsd +57 -0
  234. mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_response.xsd +72 -0
  235. mapproxy/test/schemas/wmts/1.0/wmtsGetTile_request.xsd +91 -0
  236. mapproxy/test/schemas/wmts/1.0/wmtsKVP.xsd +76 -0
  237. mapproxy/test/schemas/wmts/1.0/wmtsPayload_response.xsd +70 -0
  238. mapproxy/test/schemas/xlink/1.0.0/ReadMe.txt +6 -0
  239. mapproxy/test/schemas/xlink/1.0.0/xlinks.xsd +122 -0
  240. mapproxy/test/schemas/xml.xsd +287 -0
  241. mapproxy/test/system/__init__.py +98 -0
  242. mapproxy/test/system/fixture/arcgis.yaml +57 -0
  243. mapproxy/test/system/fixture/auth.yaml +70 -0
  244. mapproxy/test/system/fixture/cache.mbtiles +0 -0
  245. mapproxy/test/system/fixture/cache_azureblob.yaml +59 -0
  246. mapproxy/test/system/fixture/cache_band_merge.yaml +73 -0
  247. mapproxy/test/system/fixture/cache_bulk_meta_tiles.yaml +24 -0
  248. mapproxy/test/system/fixture/cache_data/dop_cache_EPSG3857/00/000/000/000/000/000/000.png +0 -0
  249. mapproxy/test/system/fixture/cache_data/wms_cache_EPSG900913/01/000/000/000/000/000/001.jpeg +0 -0
  250. mapproxy/test/system/fixture/cache_data/wms_cache_transparent_EPSG900913/01/000/000/000/000/000/001.png +0 -0
  251. mapproxy/test/system/fixture/cache_geopackage.yaml +56 -0
  252. mapproxy/test/system/fixture/cache_grid_names.yaml +50 -0
  253. mapproxy/test/system/fixture/cache_mbtiles.yaml +28 -0
  254. mapproxy/test/system/fixture/cache_s3.yaml +58 -0
  255. mapproxy/test/system/fixture/cache_source.yaml +81 -0
  256. mapproxy/test/system/fixture/combined_sources.yaml +130 -0
  257. mapproxy/test/system/fixture/coverage.yaml +77 -0
  258. mapproxy/test/system/fixture/demo.yaml +135 -0
  259. mapproxy/test/system/fixture/dimension.yaml +59 -0
  260. mapproxy/test/system/fixture/disable_storage.yaml +25 -0
  261. mapproxy/test/system/fixture/empty_ogrdata.geojson +1 -0
  262. mapproxy/test/system/fixture/formats.yaml +72 -0
  263. mapproxy/test/system/fixture/inspire.yaml +101 -0
  264. mapproxy/test/system/fixture/inspire_full.yaml +124 -0
  265. mapproxy/test/system/fixture/kml_layer.yaml +66 -0
  266. mapproxy/test/system/fixture/layer.yaml +260 -0
  267. mapproxy/test/system/fixture/layergroups.yaml +57 -0
  268. mapproxy/test/system/fixture/layergroups_root.yaml +106 -0
  269. mapproxy/test/system/fixture/legendgraphic.yaml +93 -0
  270. mapproxy/test/system/fixture/mapnik_source.yaml +66 -0
  271. mapproxy/test/system/fixture/mapproxy_export.yaml +12 -0
  272. mapproxy/test/system/fixture/mapserver.yaml +23 -0
  273. mapproxy/test/system/fixture/minimal_cgi.py +16 -0
  274. mapproxy/test/system/fixture/mixed_mode.yaml +49 -0
  275. mapproxy/test/system/fixture/multi_cache_layers.yaml +100 -0
  276. mapproxy/test/system/fixture/multiapp1.yaml +20 -0
  277. mapproxy/test/system/fixture/multiapp2.yaml +19 -0
  278. mapproxy/test/system/fixture/renderd_client.yaml +55 -0
  279. mapproxy/test/system/fixture/scalehints.yaml +70 -0
  280. mapproxy/test/system/fixture/seed.yaml +94 -0
  281. mapproxy/test/system/fixture/seed_mapproxy.yaml +39 -0
  282. mapproxy/test/system/fixture/seed_old.yaml +12 -0
  283. mapproxy/test/system/fixture/seed_timeouts.yaml +12 -0
  284. mapproxy/test/system/fixture/seed_timeouts_mapproxy.yaml +27 -0
  285. mapproxy/test/system/fixture/seedonly.yaml +51 -0
  286. mapproxy/test/system/fixture/sld.yaml +35 -0
  287. mapproxy/test/system/fixture/source_errors.yaml +84 -0
  288. mapproxy/test/system/fixture/source_errors_raise.yaml +82 -0
  289. mapproxy/test/system/fixture/tileservice_origin.yaml +26 -0
  290. mapproxy/test/system/fixture/tileservice_refresh.yaml +59 -0
  291. mapproxy/test/system/fixture/tilesource_minmax_res.yaml +22 -0
  292. mapproxy/test/system/fixture/util-conf-base-grids.yaml +5 -0
  293. mapproxy/test/system/fixture/util-conf-overwrite.yaml +13 -0
  294. mapproxy/test/system/fixture/util-conf-wms-111-cap.xml +90 -0
  295. mapproxy/test/system/fixture/util_grids.yaml +30 -0
  296. mapproxy/test/system/fixture/util_wms_capabilities111.xml +130 -0
  297. mapproxy/test/system/fixture/util_wms_capabilities130.xml +100 -0
  298. mapproxy/test/system/fixture/util_wms_capabilities_service_exception.xml +5 -0
  299. mapproxy/test/system/fixture/watermark.yaml +50 -0
  300. mapproxy/test/system/fixture/wms_srs_extent.yaml +39 -0
  301. mapproxy/test/system/fixture/wms_versions.yaml +38 -0
  302. mapproxy/test/system/fixture/wmts.yaml +134 -0
  303. mapproxy/test/system/fixture/wmts_dimensions.yaml +57 -0
  304. mapproxy/test/system/fixture/xslt_featureinfo.yaml +54 -0
  305. mapproxy/test/system/fixture/xslt_featureinfo_input.yaml +51 -0
  306. mapproxy/test/system/test_arcgis.py +156 -0
  307. mapproxy/test/system/test_auth.py +1134 -0
  308. mapproxy/test/system/test_behind_proxy.py +75 -0
  309. mapproxy/test/system/test_bulk_meta_tiles.py +106 -0
  310. mapproxy/test/system/test_cache_azureblob.py +127 -0
  311. mapproxy/test/system/test_cache_band_merge.py +103 -0
  312. mapproxy/test/system/test_cache_geopackage.py +144 -0
  313. mapproxy/test/system/test_cache_grid_names.py +89 -0
  314. mapproxy/test/system/test_cache_mbtiles.py +85 -0
  315. mapproxy/test/system/test_cache_s3.py +115 -0
  316. mapproxy/test/system/test_cache_source.py +146 -0
  317. mapproxy/test/system/test_combined_sources.py +335 -0
  318. mapproxy/test/system/test_coverage.py +140 -0
  319. mapproxy/test/system/test_decorate_img.py +214 -0
  320. mapproxy/test/system/test_demo.py +106 -0
  321. mapproxy/test/system/test_demo_with_extra_service.py +53 -0
  322. mapproxy/test/system/test_dimensions.py +278 -0
  323. mapproxy/test/system/test_disable_storage.py +42 -0
  324. mapproxy/test/system/test_formats.py +219 -0
  325. mapproxy/test/system/test_inspire_vs.py +173 -0
  326. mapproxy/test/system/test_kml.py +262 -0
  327. mapproxy/test/system/test_layergroups.py +160 -0
  328. mapproxy/test/system/test_legendgraphic.py +308 -0
  329. mapproxy/test/system/test_mapnik.py +161 -0
  330. mapproxy/test/system/test_mapserver.py +81 -0
  331. mapproxy/test/system/test_mixed_mode_format.py +195 -0
  332. mapproxy/test/system/test_multi_cache_layers.py +167 -0
  333. mapproxy/test/system/test_multiapp.py +92 -0
  334. mapproxy/test/system/test_refresh.py +207 -0
  335. mapproxy/test/system/test_renderd_client.py +304 -0
  336. mapproxy/test/system/test_response_headers.py +54 -0
  337. mapproxy/test/system/test_scalehints.py +140 -0
  338. mapproxy/test/system/test_seed.py +422 -0
  339. mapproxy/test/system/test_seed_only.py +93 -0
  340. mapproxy/test/system/test_sld.py +120 -0
  341. mapproxy/test/system/test_source_errors.py +377 -0
  342. mapproxy/test/system/test_tilesource_minmax_res.py +54 -0
  343. mapproxy/test/system/test_tms.py +276 -0
  344. mapproxy/test/system/test_tms_origin.py +46 -0
  345. mapproxy/test/system/test_util_conf.py +304 -0
  346. mapproxy/test/system/test_util_export.py +210 -0
  347. mapproxy/test/system/test_util_grids.py +88 -0
  348. mapproxy/test/system/test_util_wms_capabilities.py +182 -0
  349. mapproxy/test/system/test_watermark.py +91 -0
  350. mapproxy/test/system/test_wms.py +1611 -0
  351. mapproxy/test/system/test_wms_srs_extent.py +165 -0
  352. mapproxy/test/system/test_wms_version.py +85 -0
  353. mapproxy/test/system/test_wmsc.py +116 -0
  354. mapproxy/test/system/test_wmts.py +334 -0
  355. mapproxy/test/system/test_wmts_dimensions.py +206 -0
  356. mapproxy/test/system/test_wmts_restful.py +198 -0
  357. mapproxy/test/system/test_xslt_featureinfo.py +425 -0
  358. mapproxy/test/test_http_helper.py +219 -0
  359. mapproxy/test/unit/__init__.py +0 -0
  360. mapproxy/test/unit/epsg +2 -0
  361. mapproxy/test/unit/polygons/polygons.dbf +0 -0
  362. mapproxy/test/unit/polygons/polygons.shp +0 -0
  363. mapproxy/test/unit/polygons/polygons.shx +0 -0
  364. mapproxy/test/unit/test_async.py +245 -0
  365. mapproxy/test/unit/test_auth.py +419 -0
  366. mapproxy/test/unit/test_cache.py +1193 -0
  367. mapproxy/test/unit/test_cache_azureblob.py +94 -0
  368. mapproxy/test/unit/test_cache_compact.py +319 -0
  369. mapproxy/test/unit/test_cache_couchdb.py +114 -0
  370. mapproxy/test/unit/test_cache_geopackage.py +221 -0
  371. mapproxy/test/unit/test_cache_redis.py +67 -0
  372. mapproxy/test/unit/test_cache_riak.py +76 -0
  373. mapproxy/test/unit/test_cache_s3.py +84 -0
  374. mapproxy/test/unit/test_cache_tile.py +427 -0
  375. mapproxy/test/unit/test_client.py +479 -0
  376. mapproxy/test/unit/test_client_arcgis.py +73 -0
  377. mapproxy/test/unit/test_client_cgi.py +136 -0
  378. mapproxy/test/unit/test_collections.py +116 -0
  379. mapproxy/test/unit/test_concat_legends.py +37 -0
  380. mapproxy/test/unit/test_conf_loader.py +1061 -0
  381. mapproxy/test/unit/test_conf_validator.py +416 -0
  382. mapproxy/test/unit/test_config.py +117 -0
  383. mapproxy/test/unit/test_decorate_img.py +185 -0
  384. mapproxy/test/unit/test_exceptions.py +258 -0
  385. mapproxy/test/unit/test_featureinfo.py +291 -0
  386. mapproxy/test/unit/test_file_lock_load.py +49 -0
  387. mapproxy/test/unit/test_geom.py +503 -0
  388. mapproxy/test/unit/test_grid.py +1258 -0
  389. mapproxy/test/unit/test_image.py +1053 -0
  390. mapproxy/test/unit/test_image_mask.py +181 -0
  391. mapproxy/test/unit/test_image_messages.py +197 -0
  392. mapproxy/test/unit/test_image_options.py +160 -0
  393. mapproxy/test/unit/test_isodate.py +122 -0
  394. mapproxy/test/unit/test_multiapp.py +163 -0
  395. mapproxy/test/unit/test_ogr_reader.py +50 -0
  396. mapproxy/test/unit/test_request.py +745 -0
  397. mapproxy/test/unit/test_request_wmts.py +178 -0
  398. mapproxy/test/unit/test_response.py +79 -0
  399. mapproxy/test/unit/test_seed.py +365 -0
  400. mapproxy/test/unit/test_seed_cachelock.py +90 -0
  401. mapproxy/test/unit/test_srs.py +215 -0
  402. mapproxy/test/unit/test_tiled_source.py +122 -0
  403. mapproxy/test/unit/test_tilefilter.py +31 -0
  404. mapproxy/test/unit/test_times.py +25 -0
  405. mapproxy/test/unit/test_timeutils.py +50 -0
  406. mapproxy/test/unit/test_util_conf_utils.py +75 -0
  407. mapproxy/test/unit/test_utils.py +476 -0
  408. mapproxy/test/unit/test_wms_capabilities.py +44 -0
  409. mapproxy/test/unit/test_wms_layer.py +113 -0
  410. mapproxy/test/unit/test_yaml.py +69 -0
  411. mapproxy/tilefilter.py +59 -0
  412. mapproxy/util/__init__.py +0 -0
  413. mapproxy/util/async_.py +227 -0
  414. mapproxy/util/collections.py +132 -0
  415. mapproxy/util/coverage.py +329 -0
  416. mapproxy/util/escape.py +10 -0
  417. mapproxy/util/ext/__init__.py +14 -0
  418. mapproxy/util/ext/dictspec/__init__.py +1 -0
  419. mapproxy/util/ext/dictspec/spec.py +124 -0
  420. mapproxy/util/ext/dictspec/test/__init__.py +0 -0
  421. mapproxy/util/ext/dictspec/test/test_validator.py +274 -0
  422. mapproxy/util/ext/dictspec/validator.py +189 -0
  423. mapproxy/util/ext/local.py +196 -0
  424. mapproxy/util/ext/lockfile.py +138 -0
  425. mapproxy/util/ext/odict.py +330 -0
  426. mapproxy/util/ext/serving.py +508 -0
  427. mapproxy/util/ext/tempita/__init__.py +1174 -0
  428. mapproxy/util/ext/tempita/_looper.py +163 -0
  429. mapproxy/util/ext/tempita/compat3.py +46 -0
  430. mapproxy/util/ext/wmsparse/__init__.py +3 -0
  431. mapproxy/util/ext/wmsparse/duration.py +597 -0
  432. mapproxy/util/ext/wmsparse/parse.py +305 -0
  433. mapproxy/util/ext/wmsparse/test/__init__.py +0 -0
  434. mapproxy/util/ext/wmsparse/test/test_parse.py +162 -0
  435. mapproxy/util/ext/wmsparse/test/test_util.py +23 -0
  436. mapproxy/util/ext/wmsparse/test/wms-large-111.xml +2114 -0
  437. mapproxy/util/ext/wmsparse/test/wms-omniscale-111.xml +90 -0
  438. mapproxy/util/ext/wmsparse/test/wms-omniscale-130.xml +120 -0
  439. mapproxy/util/ext/wmsparse/test/wms_nasa_cap.xml +386 -0
  440. mapproxy/util/ext/wmsparse/util.py +187 -0
  441. mapproxy/util/fs.py +156 -0
  442. mapproxy/util/geom.py +295 -0
  443. mapproxy/util/lib.py +115 -0
  444. mapproxy/util/lock.py +163 -0
  445. mapproxy/util/ogr.py +231 -0
  446. mapproxy/util/py.py +81 -0
  447. mapproxy/util/times.py +75 -0
  448. mapproxy/util/yaml.py +56 -0
  449. mapproxy/version.py +31 -0
  450. mapproxy/wsgiapp.py +164 -0
  451. mapproxy-1.16.1.dist-info/METADATA +151 -0
  452. mapproxy-1.16.1.dist-info/RECORD +458 -0
  453. mapproxy-1.16.1.dist-info/WHEEL +5 -0
  454. mapproxy-1.16.1.dist-info/entry_points.txt +3 -0
  455. mapproxy-1.16.1.dist-info/licenses/AUTHORS.txt +33 -0
  456. mapproxy-1.16.1.dist-info/licenses/COPYING.txt +60 -0
  457. mapproxy-1.16.1.dist-info/licenses/LICENSE.txt +202 -0
  458. mapproxy-1.16.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,536 @@
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
+ Image and tile manipulation (transforming, merging, etc).
18
+ """
19
+ import io
20
+ from io import BytesIO
21
+
22
+
23
+ from mapproxy.compat.image import Image, ImageChops, ImageFileDirectory_v2, TiffTags
24
+ from mapproxy.image.opts import create_image, ImageFormat
25
+ from mapproxy.config import base_config
26
+ from mapproxy.srs import make_lin_transf, get_epsg_num
27
+ from mapproxy.compat import string_type
28
+
29
+ import logging
30
+ from functools import reduce
31
+ log = logging.getLogger('mapproxy.image')
32
+
33
+
34
+
35
+ magic_bytes = [
36
+ ('png', (b"\211PNG\r\n\032\n",)),
37
+ ('jpeg', (b"\xFF\xD8",)),
38
+ ('tiff', (b"MM\x00\x2a", b"II\x2a\x00",)),
39
+ ('gif', (b"GIF87a", b"GIF89a",)),
40
+ ]
41
+
42
+ def peek_image_format(buf):
43
+ buf.seek(0)
44
+ header = buf.read(10)
45
+ buf.seek(0)
46
+ for format, bytes in magic_bytes:
47
+ if header.startswith(bytes):
48
+ return format
49
+ return None
50
+
51
+ TIFF_MODELPIXELSCALETAG = 33550
52
+ TIFF_MODELTIEPOINTTAG = 33922
53
+ TIFF_GEOKEYDIRECTORYTAG = 34735
54
+
55
+ class GeoReference(object):
56
+ def __init__(self, bbox, srs):
57
+ self.bbox = bbox
58
+ self.srs = srs
59
+
60
+
61
+ def tiepoints(self):
62
+ return (
63
+ 0.0, 0.0, 0.0,
64
+ self.bbox[0], self.bbox[3], 0.0,
65
+ )
66
+
67
+ def pixelscale(self, img_size):
68
+ width = self.bbox[2] - self.bbox[0]
69
+ height = self.bbox[3] - self.bbox[1]
70
+ return (
71
+ float(width)/img_size[0], float(height)/img_size[1], 0.0,
72
+ )
73
+
74
+ def tiff_tags(self, img_size):
75
+ tags = ImageFileDirectory_v2()
76
+ tags[TIFF_MODELPIXELSCALETAG] = self.pixelscale(img_size)
77
+ tags.tagtype[TIFF_MODELPIXELSCALETAG] = TiffTags.DOUBLE
78
+ tags[TIFF_MODELTIEPOINTTAG] = self.tiepoints()
79
+ tags.tagtype[TIFF_MODELTIEPOINTTAG] = TiffTags.DOUBLE
80
+
81
+ model_type = 2 if self.srs.is_latlong else 1
82
+ tags[TIFF_GEOKEYDIRECTORYTAG] = (
83
+ 1, 1, 0, 4, # {KeyDirectoryVersion, KeyRevision, MinorRevision, NumberOfKeys}
84
+ 1024, 0, 1, model_type, # 1 projected, 2 geographic (lat/long)
85
+ 1025, 0, 1, 1, # 1 RasterIsArea, 2 RasterIsPoint
86
+ 3072, 0, 1, get_epsg_num(self.srs.srs_code),
87
+ )
88
+ tags.tagtype[TIFF_GEOKEYDIRECTORYTAG] = TiffTags.SHORT
89
+ return tags
90
+
91
+
92
+ class BaseImageSource(object):
93
+ """
94
+ Virtual parent class for ImageSource and BlankImageSource
95
+ """
96
+ def __init__(self):
97
+ raise Exception("Virtual class BaseImageSource, cannot be instanciated.")
98
+
99
+ def as_image(self):
100
+ raise Exception("Virtual class BaseImageSource, method as_image cannot be called.")
101
+
102
+ def as_buffer(self, image_opts=None, format=None, seekable=False):
103
+ raise Exception("Virtual class BaseImageSource, method as_buffer cannot be called.")
104
+
105
+ def close_buffers(self):
106
+ pass
107
+
108
+
109
+ class ImageSource(BaseImageSource):
110
+ """
111
+ This class wraps either a PIL image, a file-like object, or a file name.
112
+ You can access the result as an image (`as_image` ) or a file-like buffer
113
+ object (`as_buffer`).
114
+ """
115
+
116
+ def __init__(self, source, size=None, image_opts=None, cacheable=True, georef=None):
117
+ """
118
+ :param source: the image
119
+ :type source: PIL `Image`, image file object, or filename
120
+ :param format: the format of the ``source``
121
+ :param size: the size of the ``source`` in pixel
122
+ """
123
+ self._img = None
124
+ self._buf = None
125
+ self._fname = None
126
+ self.source = source
127
+ self.image_opts = image_opts
128
+ self._size = size
129
+ self.cacheable = cacheable
130
+ self.georef = georef
131
+ self.authorize_stale = False
132
+
133
+ @property
134
+ def source(self):
135
+ return self._img or self._buf or self._fname
136
+
137
+ @source.setter
138
+ def source(self, source):
139
+ self._img = None
140
+ self._buf = None
141
+ if isinstance(source, string_type):
142
+ self._fname = source
143
+ elif isinstance(source, Image.Image):
144
+ self._img = source
145
+ else:
146
+ self._buf = source
147
+
148
+ def close_buffers(self):
149
+ if self._buf:
150
+ try:
151
+ self._buf.close()
152
+ except IOError:
153
+ pass
154
+
155
+ @property
156
+ def filename(self):
157
+ return self._fname
158
+
159
+ def as_image(self):
160
+ """
161
+ Returns the image or the loaded image.
162
+
163
+ :rtype: PIL `Image`
164
+ """
165
+ if not self._img:
166
+ self._make_seekable_buf()
167
+ log.debug('file(%s) -> image', self._fname or self._buf)
168
+
169
+ try:
170
+ img = Image.open(self._buf)
171
+ except Exception:
172
+ self.close_buffers()
173
+ raise
174
+ self._img = img
175
+ if self.image_opts and self.image_opts.transparent and self._img.mode == 'P':
176
+ self._img = self._img.convert('RGBA')
177
+ return self._img
178
+
179
+ def _make_seekable_buf(self):
180
+ if not self._buf and self._fname:
181
+ self._buf = open(self._fname, 'rb')
182
+ else:
183
+ try:
184
+ self._buf.seek(0)
185
+ except (io.UnsupportedOperation, AttributeError):
186
+ # PIL needs file objects with seek
187
+ self._buf = BytesIO(self._buf.read())
188
+
189
+ def _make_readable_buf(self):
190
+ if not self._buf and self._fname:
191
+ self._buf = open(self._fname, 'rb')
192
+ elif not hasattr(self._buf, 'seek'):
193
+ if not isinstance(self._buf, ReadBufWrapper):
194
+ self._buf = ReadBufWrapper(self._buf)
195
+ else:
196
+ try:
197
+ self._buf.seek(0)
198
+ except (io.UnsupportedOperation, AttributeError):
199
+ # PIL needs file objects with seek
200
+ self._buf = BytesIO(self._buf.read())
201
+
202
+
203
+ def as_buffer(self, image_opts=None, format=None, seekable=False):
204
+ """
205
+ Returns the image as a file object.
206
+
207
+ :param format: The format to encode an image.
208
+ Existing files will not be re-encoded.
209
+ :rtype: file-like object
210
+ """
211
+ if format:
212
+ image_opts = (image_opts or self.image_opts).copy()
213
+ image_opts.format = ImageFormat(format)
214
+ if not self._buf and not self._fname:
215
+ if image_opts is None:
216
+ image_opts = self.image_opts
217
+ log.debug('image -> buf(%s)' % (image_opts.format,))
218
+ self._buf = img_to_buf(self._img, image_opts=image_opts, georef=self.georef)
219
+ else:
220
+ self._make_seekable_buf() if seekable else self._make_readable_buf()
221
+ if self.image_opts and image_opts and not self.image_opts.format and image_opts.format:
222
+ # need actual image_opts.format for next check
223
+ self.image_opts = self.image_opts.copy()
224
+ self.image_opts.format = peek_image_format(self._buf)
225
+ if self.image_opts and image_opts and self.image_opts.format != image_opts.format:
226
+ log.debug('converting image from %s -> %s' % (self.image_opts, image_opts))
227
+ self.source = self.as_image()
228
+ self._buf = None
229
+ self.image_opts = image_opts
230
+ # hide fname to prevent as_buffer from reading the file
231
+ fname = self._fname
232
+ self._fname = None
233
+ self.as_buffer(image_opts)
234
+ self._fname = fname
235
+ return self._buf
236
+
237
+ @property
238
+ def size(self):
239
+ if self._size is None:
240
+ self._size = self.as_image().size
241
+ return self._size
242
+
243
+ def SubImageSource(source, size, offset, image_opts, cacheable=True):
244
+ """
245
+ Create a new ImageSource with `size` and `image_opts` and
246
+ place `source` image at `offset`.
247
+ """
248
+ # force new image to contain alpha channel
249
+ new_image_opts = image_opts.copy()
250
+ new_image_opts.transparent = True
251
+ img = create_image(size, new_image_opts)
252
+
253
+ if not hasattr(source, 'as_image'):
254
+ source = ImageSource(source)
255
+ subimg = source.as_image()
256
+ img.paste(subimg, offset)
257
+ return ImageSource(img, size=size, image_opts=new_image_opts, cacheable=cacheable)
258
+
259
+ class BlankImageSource(BaseImageSource):
260
+ """
261
+ ImageSource for transparent or solid-color images.
262
+ Implements optimized as_buffer() method.
263
+ """
264
+ def __init__(self, size, image_opts, cacheable=False):
265
+ self.size = size
266
+ self.image_opts = image_opts
267
+ self._buf = None
268
+ self._img = None
269
+ self.cacheable = cacheable
270
+ self.authorize_stale = False
271
+
272
+ def as_image(self):
273
+ if not self._img:
274
+ self._img = create_image(self.size, self.image_opts)
275
+ return self._img
276
+
277
+ def as_buffer(self, image_opts=None, format=None, seekable=False):
278
+ if not self._buf:
279
+ image_opts = (image_opts or self.image_opts).copy()
280
+ if format:
281
+ image_opts.format = ImageFormat(format)
282
+ image_opts.colors = 0
283
+ self._buf = img_to_buf(self.as_image(), image_opts=image_opts)
284
+ return self._buf
285
+
286
+ def close_buffers(self):
287
+ pass
288
+
289
+ class ReadBufWrapper(object):
290
+ """
291
+ This class wraps everything with a ``read`` method and adds support
292
+ for ``seek``, etc. A call to everything but ``read`` will create a
293
+ StringIO object of the ``readbuf``.
294
+ """
295
+ def __init__(self, readbuf):
296
+ self.ok_to_seek = False
297
+ self.readbuf = readbuf
298
+ self.stringio = None
299
+
300
+ def read(self, *args, **kw):
301
+ if self.stringio:
302
+ return self.stringio.read(*args, **kw)
303
+ return self.readbuf.read(*args, **kw)
304
+
305
+ def __iter__(self):
306
+ if self.stringio:
307
+ return iter(self.stringio)
308
+ else:
309
+ return iter(self.readbuf)
310
+
311
+ def __getattr__(self, name):
312
+ if self.stringio is None:
313
+ if hasattr(self.readbuf, name):
314
+ return getattr(self.readbuf, name)
315
+ elif name == '__length_hint__':
316
+ raise AttributeError
317
+ self.ok_to_seek = True
318
+ self.stringio = BytesIO(self.readbuf.read())
319
+ return getattr(self.stringio, name)
320
+
321
+ def img_has_transparency(img):
322
+ if img.mode == 'P':
323
+ if img.info.get('transparency', False):
324
+ return True
325
+ # convert to RGBA and check alpha channel
326
+ img = img.convert('RGBA')
327
+ if img.mode == 'RGBA':
328
+ # any alpha except fully opaque
329
+ return any(img.histogram()[-256:-1])
330
+ return False
331
+
332
+ def img_to_buf(img, image_opts, georef=None):
333
+ defaults = {}
334
+ image_opts = image_opts.copy()
335
+
336
+ # convert I or L images to target mode
337
+ if image_opts.mode and img.mode[0] in ('I', 'L') and img.mode != image_opts.mode:
338
+ img = img.convert(image_opts.mode)
339
+
340
+ if (image_opts.colors is None and base_config().image.paletted
341
+ and image_opts.format.endswith('png')):
342
+ # force 255 colors for png with globals.image.paletted
343
+ image_opts.colors = 255
344
+
345
+ format = filter_format(image_opts.format.ext)
346
+ if format == 'mixed':
347
+ if img_has_transparency(img):
348
+ format = 'png'
349
+ image_opts.transparent = True
350
+ else:
351
+ format = 'jpeg'
352
+ image_opts.colors = None
353
+ image_opts.transparent = False
354
+
355
+ # quantize if colors is set, but not if we already have a paletted image
356
+ if image_opts.colors and not (img.mode == 'P' and len(img.getpalette()) == image_opts.colors*3):
357
+ quantizer = None
358
+ if 'quantizer' in image_opts.encoding_options:
359
+ quantizer = image_opts.encoding_options['quantizer']
360
+ if image_opts.transparent:
361
+ img = quantize(img, colors=image_opts.colors, alpha=True,
362
+ defaults=defaults, quantizer=quantizer)
363
+ else:
364
+ img = quantize(img, colors=image_opts.colors,
365
+ quantizer=quantizer)
366
+ if hasattr(Image, 'RLE'):
367
+ defaults['compress_type'] = Image.RLE
368
+
369
+ buf = BytesIO()
370
+ if format == 'jpeg':
371
+ img = img.convert('RGB')
372
+ if 'jpeg_quality' in image_opts.encoding_options:
373
+ defaults['quality'] = image_opts.encoding_options['jpeg_quality']
374
+ else:
375
+ defaults['quality'] = base_config().image.jpeg_quality
376
+
377
+ elif format == 'tiff':
378
+ if georef:
379
+ tags = georef.tiff_tags(img.size)
380
+ defaults['tiffinfo'] = tags
381
+ if 'tiff_compression' in image_opts.encoding_options:
382
+ defaults['compression'] = image_opts.encoding_options['tiff_compression']
383
+ if defaults['compression'] == 'jpeg':
384
+ if 'jpeg_quality' in image_opts.encoding_options:
385
+ defaults['quality'] = image_opts.encoding_options['jpeg_quality']
386
+
387
+ # unsupported transparency tuple can still be in non-RGB img.infos
388
+ # see: https://github.com/python-pillow/Pillow/pull/2633
389
+ if format == 'png' and img.mode != 'RGB' and 'transparency' in img.info and isinstance(img.info['transparency'], tuple):
390
+ del img.info['transparency']
391
+
392
+ img.save(buf, format, **defaults)
393
+ buf.seek(0)
394
+ return buf
395
+
396
+ def quantize(img, colors=256, alpha=False, defaults=None, quantizer=None):
397
+ if hasattr(Image, 'FASTOCTREE') and quantizer in (None, 'fastoctree'):
398
+ if not alpha:
399
+ img = img.convert('RGB')
400
+ try:
401
+ if img.mode == 'P':
402
+ # quantize with alpha does not work with P images
403
+ img = img.convert('RGBA')
404
+ img = img.quantize(colors, Image.FASTOCTREE)
405
+ except ValueError:
406
+ pass
407
+ else:
408
+ if alpha and img.mode == 'RGBA':
409
+ img.load() # split might fail if image is not loaded
410
+ alpha = img.split()[3]
411
+ img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=colors-1)
412
+ mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)
413
+ img.paste(255, mask)
414
+ if defaults is not None:
415
+ defaults['transparency'] = 255
416
+ else:
417
+ img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=colors)
418
+
419
+ return img
420
+
421
+
422
+ def filter_format(format):
423
+ if format.lower() == 'geotiff':
424
+ format = 'tiff'
425
+ if format.lower().startswith('png'):
426
+ format = 'png'
427
+ return format
428
+
429
+ image_filter = {
430
+ 'nearest': Image.NEAREST,
431
+ 'bilinear': Image.BILINEAR,
432
+ 'bicubic': Image.BICUBIC
433
+ }
434
+
435
+
436
+ def is_single_color_image(image):
437
+ """
438
+ Checks if the `image` contains only one color.
439
+ Returns ``False`` if it contains more than one color, else
440
+ the color-tuple of the single color.
441
+ """
442
+ result = image.getcolors(1)
443
+ # returns a list of (count, color), limit to one
444
+ if result is None:
445
+ return False
446
+
447
+ color = result[0][1]
448
+ if image.mode == 'P':
449
+ palette = image.getpalette()
450
+ return palette[color*3], palette[color*3+1], palette[color*3+2]
451
+
452
+ return result[0][1]
453
+
454
+ def make_transparent(img, color, tolerance=10):
455
+ """
456
+ Create alpha channel for the given image and make each pixel
457
+ in `color` full transparent.
458
+
459
+ Returns an RGBA ImageSoruce.
460
+
461
+ Modifies the image in-place, unless it needs to be converted
462
+ first (P->RGB).
463
+
464
+ :param color: RGB color tuple
465
+ :param tolerance: tolerance applied to each color value
466
+ """
467
+ result = _make_transparent(img.as_image(), color, tolerance)
468
+ image_opts = img.image_opts.copy()
469
+ image_opts.transparent = True
470
+ image_opts.mode = 'RGBA'
471
+ return ImageSource(result, size=result.size, image_opts=image_opts)
472
+
473
+ def _make_transparent(img, color, tolerance=10):
474
+ img.load()
475
+
476
+ if img.mode == 'P':
477
+ img = img.convert('RGBA')
478
+
479
+ channels = img.split()
480
+ mask_channels = []
481
+ for ch, c in zip(channels, color):
482
+ # create bit mask for each matched color
483
+ low_c, high_c = c-tolerance, c+tolerance
484
+ mask_channels.append(Image.eval(ch, lambda x: 255 if low_c <= x <= high_c else 0))
485
+
486
+ # multiply channel bit masks to get a single mask
487
+ alpha = reduce(ImageChops.multiply, mask_channels)
488
+ # invert to get alpha channel
489
+ alpha = ImageChops.invert(alpha)
490
+
491
+ if len(channels) == 4:
492
+ # multiply with existing alpha
493
+ alpha = ImageChops.multiply(alpha, channels[-1])
494
+
495
+ img.putalpha(alpha)
496
+ return img
497
+
498
+ def bbox_position_in_image(bbox, size, src_bbox):
499
+ """
500
+ Calculate the position of ``bbox`` in an image of ``size`` and ``src_bbox``.
501
+ Returns the sub-image size and the offset in pixel from top-left corner
502
+ and the sub-bbox.
503
+
504
+ >>> bbox_position_in_image((-180, -90, 180, 90), (600, 300), (-180, -90, 180, 90))
505
+ ((600, 300), (0, 0), (-180, -90, 180, 90))
506
+ >>> bbox_position_in_image((-200, -100, 200, 100), (600, 300), (-180, -90, 180, 90))
507
+ ((540, 270), (30, 15), (-180, -90, 180, 90))
508
+ >>> bbox_position_in_image((-200, -50, 200, 100), (600, 300), (-180, -90, 180, 90))
509
+ ((540, 280), (30, 20), (-180, -50, 180, 90))
510
+ >>> bbox_position_in_image((586400,196400,752800,362800), (256, 256), (586400,196400,752800,350000))
511
+ ((256, 237), (0, 19), (586400, 196400, 752800, 350000))
512
+ """
513
+ coord_to_px = make_lin_transf(bbox, (0, 0) + size)
514
+ offsets = [0, size[1], size[0], 0]
515
+ sub_bbox = list(bbox)
516
+ if src_bbox[0] > bbox[0]:
517
+ sub_bbox[0] = src_bbox[0]
518
+ x, y = coord_to_px((src_bbox[0], 0))
519
+ offsets[0] = int(x)
520
+ if src_bbox[1] > bbox[1]:
521
+ sub_bbox[1] = src_bbox[1]
522
+ x, y = coord_to_px((0, src_bbox[1]))
523
+ offsets[1] = int(y)
524
+
525
+ if src_bbox[2] < bbox[2]:
526
+ sub_bbox[2] = src_bbox[2]
527
+ x, y = coord_to_px((src_bbox[2], 0))
528
+ offsets[2] = int(x)
529
+
530
+ if src_bbox[3] < bbox[3]:
531
+ sub_bbox[3] = src_bbox[3]
532
+ x, y = coord_to_px((0, src_bbox[3]))
533
+ offsets[3] = int(y)
534
+
535
+ size = abs(offsets[2] - offsets[0]), abs(offsets[1] - offsets[3])
536
+ return size, (offsets[0], offsets[3]), tuple(sub_bbox)
Binary file
Binary file
@@ -0,0 +1,99 @@
1
+ Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
2
+ Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
3
+
4
+ Bitstream Vera Fonts Copyright
5
+ ------------------------------
6
+
7
+ Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
8
+ a trademark of Bitstream, Inc.
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of the fonts accompanying this license ("Fonts") and associated
12
+ documentation files (the "Font Software"), to reproduce and distribute the
13
+ Font Software, including without limitation the rights to use, copy, merge,
14
+ publish, distribute, and/or sell copies of the Font Software, and to permit
15
+ persons to whom the Font Software is furnished to do so, subject to the
16
+ following conditions:
17
+
18
+ The above copyright and trademark notices and this permission notice shall
19
+ be included in all copies of one or more of the Font Software typefaces.
20
+
21
+ The Font Software may be modified, altered, or added to, and in particular
22
+ the designs of glyphs or characters in the Fonts may be modified and
23
+ additional glyphs or characters may be added to the Fonts, only if the fonts
24
+ are renamed to names not containing either the words "Bitstream" or the word
25
+ "Vera".
26
+
27
+ This License becomes null and void to the extent applicable to Fonts or Font
28
+ Software that has been modified and is distributed under the "Bitstream
29
+ Vera" names.
30
+
31
+ The Font Software may be sold as part of a larger software package but no
32
+ copy of one or more of the Font Software typefaces may be sold by itself.
33
+
34
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
35
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
36
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
37
+ TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
38
+ FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
39
+ ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
40
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
41
+ THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
42
+ FONT SOFTWARE.
43
+
44
+ Except as contained in this notice, the names of Gnome, the Gnome
45
+ Foundation, and Bitstream Inc., shall not be used in advertising or
46
+ otherwise to promote the sale, use or other dealings in this Font Software
47
+ without prior written authorization from the Gnome Foundation or Bitstream
48
+ Inc., respectively. For further information, contact: fonts at gnome dot
49
+ org.
50
+
51
+ Arev Fonts Copyright
52
+ ------------------------------
53
+
54
+ Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
55
+
56
+ Permission is hereby granted, free of charge, to any person obtaining
57
+ a copy of the fonts accompanying this license ("Fonts") and
58
+ associated documentation files (the "Font Software"), to reproduce
59
+ and distribute the modifications to the Bitstream Vera Font Software,
60
+ including without limitation the rights to use, copy, merge, publish,
61
+ distribute, and/or sell copies of the Font Software, and to permit
62
+ persons to whom the Font Software is furnished to do so, subject to
63
+ the following conditions:
64
+
65
+ The above copyright and trademark notices and this permission notice
66
+ shall be included in all copies of one or more of the Font Software
67
+ typefaces.
68
+
69
+ The Font Software may be modified, altered, or added to, and in
70
+ particular the designs of glyphs or characters in the Fonts may be
71
+ modified and additional glyphs or characters may be added to the
72
+ Fonts, only if the fonts are renamed to names not containing either
73
+ the words "Tavmjong Bah" or the word "Arev".
74
+
75
+ This License becomes null and void to the extent applicable to Fonts
76
+ or Font Software that has been modified and is distributed under the
77
+ "Tavmjong Bah Arev" names.
78
+
79
+ The Font Software may be sold as part of a larger software package but
80
+ no copy of one or more of the Font Software typefaces may be sold by
81
+ itself.
82
+
83
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
84
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
85
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
86
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
87
+ TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
88
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
89
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
90
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
91
+ OTHER DEALINGS IN THE FONT SOFTWARE.
92
+
93
+ Except as contained in this notice, the name of Tavmjong Bah shall not
94
+ be used in advertising or otherwise to promote the sale, use or other
95
+ dealings in this Font Software without prior written authorization
96
+ from Tavmjong Bah. For further information, contact: tavmjong @ free
97
+ . fr.
98
+
99
+ $Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $
File without changes