pycoast 1.6.1__tar.gz → 1.7.1__tar.gz
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.
- pycoast-1.7.1/AUTHORS.md +20 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/MANIFEST.in +1 -2
- pycoast-1.7.1/PKG-INFO +81 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/Makefile +1 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/installation.rst +1 -1
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/__init__.py +1 -0
- pycoast-1.7.1/pycoast/conftest.py +14 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/cw_agg.py +5 -1
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/cw_base.py +93 -69
- pycoast-1.7.1/pycoast/tests/coasts_and_grid.ini +13 -0
- pycoast-1.7.1/pycoast/tests/coasts_and_grid_agg.ini +17 -0
- pycoast-1.7.1/pycoast/tests/eastern_shapes_agg.png +0 -0
- pycoast-1.7.1/pycoast/tests/eastern_shapes_pil.png +0 -0
- pycoast-1.7.1/pycoast/tests/grid_europe_agg_txt.png +0 -0
- pycoast-1.7.1/pycoast/tests/grid_from_dict_agg.png +0 -0
- pycoast-1.7.1/pycoast/tests/grid_from_dict_pil.png +0 -0
- pycoast-1.7.1/pycoast/tests/grid_germ.png +0 -0
- pycoast-1.7.1/pycoast/tests/grid_nh_agg.png +0 -0
- pycoast-1.7.1/pycoast/tests/grid_nh_cfg_agg.png +0 -0
- pycoast-1.7.1/pycoast/tests/lonlat_boundary_cross.png +0 -0
- pycoast-1.7.1/pycoast/tests/nh_cities_agg.ini +26 -0
- pycoast-1.7.1/pycoast/tests/nh_cities_pil.ini +20 -0
- pycoast-1.7.1/pycoast/tests/nh_one_shapefile.ini +11 -0
- pycoast-1.7.1/pycoast/tests/nh_points_agg.ini +24 -0
- pycoast-1.7.1/pycoast/tests/nh_points_pil.ini +19 -0
- pycoast-1.7.1/pycoast/tests/no_h_scratch_agg.png +0 -0
- pycoast-1.7.1/pycoast/tests/no_h_scratch_pil.png +0 -0
- pycoast-1.7.1/pycoast/tests/no_v_scratch_agg.png +0 -0
- pycoast-1.7.1/pycoast/tests/no_v_scratch_pil.png +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/DejaVuSerif.ttf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/CITIES/cities.txt +20 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L1.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L1.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L1.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L1.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L2.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L2.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L2.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L2.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L3.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L3.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L3.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L3.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L4.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L4.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L4.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L4.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L1.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L1.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L1.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L1.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L2.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L2.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L2.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L2.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L3.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L3.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L3.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L3.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L01.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L01.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L01.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L01.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L02.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L02.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L02.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L02.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L03.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L03.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L03.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L03.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L04.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L04.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L04.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L04.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L05.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L05.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L05.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L05.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L06.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L06.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L06.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L06.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L07.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L07.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L07.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L07.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L08.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L08.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L08.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L08.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L09.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L09.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L09.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L09.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L1.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L1.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L1.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L10.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L10.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L10.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L10.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L11.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L11.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L11.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L11.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L2.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L2.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L2.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L3.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L3.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L3.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/Metareas.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/Metareas.mxd +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/Metareas.prj +1 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/Metareas.sbn +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/Metareas.sbx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/Metareas.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/Metareas.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/README +3 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BRASIL.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BRASIL.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BRASIL.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BR_Capitais.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BR_Capitais.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BR_Capitais.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BR_Contorno.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BR_Contorno.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BR_Contorno.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BR_Regioes.dbf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BR_Regioes.shp +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/BR_Regioes.shx +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/divisao_politica.txt +40 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/divisao_politica/leia.txt +9 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/metarea5.gsf +0 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/metarea5.tbl +21 -0
- pycoast-1.7.1/pycoast/tests/test_data/shapes/metarea5.tbl.info +25 -0
- pycoast-1.7.1/pycoast/tests/test_data/test_config.ini +12 -0
- pycoast-1.7.1/pycoast/tests/test_pycoast.py +2124 -0
- pycoast-1.7.1/pycoast/tests/western_shapes_agg.png +0 -0
- pycoast-1.7.1/pycoast/tests/western_shapes_pil.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/version.py +4 -4
- pycoast-1.7.1/pycoast.egg-info/PKG-INFO +81 -0
- pycoast-1.7.1/pycoast.egg-info/SOURCES.txt +207 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast.egg-info/requires.txt +7 -5
- {pycoast-1.6.1 → pycoast-1.7.1}/pyproject.toml +6 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/setup.cfg +1 -1
- {pycoast-1.6.1 → pycoast-1.7.1}/setup.py +6 -4
- {pycoast-1.6.1 → pycoast-1.7.1}/versioneer.py +173 -108
- pycoast-1.6.1/PKG-INFO +0 -65
- pycoast-1.6.1/pycoast/tests/eastern_shapes_agg.png +0 -0
- pycoast-1.6.1/pycoast/tests/eastern_shapes_pil.png +0 -0
- pycoast-1.6.1/pycoast/tests/grid_europe_agg_txt.png +0 -0
- pycoast-1.6.1/pycoast/tests/grid_from_dict_agg.png +0 -0
- pycoast-1.6.1/pycoast/tests/grid_from_dict_pil.png +0 -0
- pycoast-1.6.1/pycoast/tests/grid_germ.png +0 -0
- pycoast-1.6.1/pycoast/tests/grid_nh_agg.png +0 -0
- pycoast-1.6.1/pycoast/tests/grid_nh_cfg_agg.png +0 -0
- pycoast-1.6.1/pycoast/tests/no_h_scratch_agg.png +0 -0
- pycoast-1.6.1/pycoast/tests/no_h_scratch_pil.png +0 -0
- pycoast-1.6.1/pycoast/tests/no_v_scratch_agg.png +0 -0
- pycoast-1.6.1/pycoast/tests/no_v_scratch_pil.png +0 -0
- pycoast-1.6.1/pycoast/tests/test_pycoast.py +0 -2154
- pycoast-1.6.1/pycoast/tests/utils.py +0 -42
- pycoast-1.6.1/pycoast/tests/western_shapes_agg.png +0 -0
- pycoast-1.6.1/pycoast/tests/western_shapes_pil.png +0 -0
- pycoast-1.6.1/pycoast.egg-info/PKG-INFO +0 -65
- pycoast-1.6.1/pycoast.egg-info/SOURCES.txt +0 -89
- {pycoast-1.6.1 → pycoast-1.7.1}/LICENSE.txt +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/README +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/api/.gitkeep +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/conf.py +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/config.rst +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/graticule.rst +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/high_quality_contours.rst +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/BMNG_clouds_201109181715_areaT2.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/brazil_shapefiles_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/euro_coast.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/euro_coast_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/euro_coast_grid_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/euro_grid.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/euro_grid_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/geos_coast.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/geos_coast_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/grid_geos_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/nh_grid_coarse_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/nh_points_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/nh_polygons_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/images/nh_polygons_lines_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/index.rst +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/points.rst +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/polygons_and_lines.rst +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/shapefiles.rst +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/test.rst +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/docs/source/usage.rst +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/cw_pil.py +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/__init__.py +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/brazil_shapefiles.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/brazil_shapefiles_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/contours_europe.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/contours_europe_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/contours_europe_alpha.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/contours_geos.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/contours_geos_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/dateline_boundary_cross.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/dateline_cross.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/grid_europe.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/grid_europe_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/grid_geos.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/grid_geos_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/grid_nh.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/nh_cities_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/nh_cities_from_dict_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/nh_cities_from_dict_pil.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/nh_cities_pil.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/nh_points_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/nh_points_cfg_pil.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/nh_points_pil.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/nh_polygons.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/nh_polygons_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/one_shapefile_from_cfg_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/one_shapefile_from_cfg_pil.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/two_shapefiles_agg.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast/tests/two_shapefiles_pil.png +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast.egg-info/dependency_links.txt +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast.egg-info/not-zip-safe +0 -0
- {pycoast-1.6.1 → pycoast-1.7.1}/pycoast.egg-info/top_level.txt +0 -0
pycoast-1.7.1/AUTHORS.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Project Contributors
|
|
2
|
+
|
|
3
|
+
The following people have made contributions to this project:
|
|
4
|
+
|
|
5
|
+
<!--- Use your GitHub account or any other personal reference URL --->
|
|
6
|
+
<!--- See https://gist.github.com/djhoese/52220272ec73b12eb8f4a29709be110d for auto-generating parts of this list --->
|
|
7
|
+
|
|
8
|
+
- Stefano Cerino
|
|
9
|
+
- [Andrew Brooks (howff)](https://github.com/howff)
|
|
10
|
+
- [Adam Dybbroe (adybbroe)](https://github.com/adybbroe)
|
|
11
|
+
- [David Hoese (djhoese)](https://github.com/djhoese)
|
|
12
|
+
- [Katja Hungershofer (khunger)](https://github.com/khunger)
|
|
13
|
+
- [Mikhail Itkin (mitkin)](https://github.com/mitkin)
|
|
14
|
+
- [Panu Lahtinen (pnuu)](https://github.com/pnuu)
|
|
15
|
+
- [Ernst Lobsiger (lobsiger)](https://github.com/lobsiger)
|
|
16
|
+
- [Esben S. Nielsen (storpipfugl)](https://github.com/storpipfugl)
|
|
17
|
+
- [Martin Raspaud (mraspaud)](https://github.com/mraspaud)
|
|
18
|
+
- [Hrobjartur Thorsteinsson (thorsteinssonh)](https://github.com/thorsteinssonh)
|
|
19
|
+
- [Antonio Valentino (avalentino)](https://github.com/avalentino)
|
|
20
|
+
- [Yufei Zhu (yufeizhu600)](https://github.com/yufeizhu600)
|
pycoast-1.7.1/PKG-INFO
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pycoast
|
|
3
|
+
Version: 1.7.1
|
|
4
|
+
Summary: Writing of coastlines, borders and rivers to images in Python
|
|
5
|
+
Author: Esben S. Nielsen
|
|
6
|
+
Author-email: esn@dmi.dk
|
|
7
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
8
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
9
|
+
Classifier: Programming Language :: Python
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering
|
|
13
|
+
Requires-Python: >3.9
|
|
14
|
+
License-File: LICENSE.txt
|
|
15
|
+
License-File: AUTHORS.md
|
|
16
|
+
Requires-Dist: aggdraw
|
|
17
|
+
Requires-Dist: pyshp
|
|
18
|
+
Requires-Dist: numpy
|
|
19
|
+
Requires-Dist: pyproj
|
|
20
|
+
Requires-Dist: pillow
|
|
21
|
+
Provides-Extra: docs
|
|
22
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
23
|
+
Requires-Dist: pyresample; extra == "docs"
|
|
24
|
+
Requires-Dist: pytest; extra == "docs"
|
|
25
|
+
Requires-Dist: pytest-lazy-fixtures; extra == "docs"
|
|
26
|
+
Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
|
27
|
+
Requires-Dist: sphinxcontrib-apidoc; extra == "docs"
|
|
28
|
+
Provides-Extra: tests
|
|
29
|
+
Requires-Dist: pyresample; extra == "tests"
|
|
30
|
+
Requires-Dist: pytest; extra == "tests"
|
|
31
|
+
Requires-Dist: pytest-cov; extra == "tests"
|
|
32
|
+
Requires-Dist: coverage; extra == "tests"
|
|
33
|
+
Requires-Dist: coveralls; extra == "tests"
|
|
34
|
+
Requires-Dist: pytest-lazy-fixtures; extra == "tests"
|
|
35
|
+
|
|
36
|
+
PyCoast
|
|
37
|
+
=======
|
|
38
|
+
|
|
39
|
+
.. image:: https://github.com/pytroll/pycoast/workflows/CI/badge.svg?branch=main
|
|
40
|
+
:target: https://github.com/pytroll/pycoast/actions?query=workflow%3A%22CI%22
|
|
41
|
+
|
|
42
|
+
.. image:: https://coveralls.io/repos/github/pytroll/pycoast/badge.svg?branch=main
|
|
43
|
+
:target: https://coveralls.io/github/pytroll/pycoast?branch=main
|
|
44
|
+
|
|
45
|
+
.. image:: https://img.shields.io/pypi/v/pycoast.svg
|
|
46
|
+
:target: https://pypi.python.org/pypi/pycoast
|
|
47
|
+
|
|
48
|
+
.. image:: https://results.pre-commit.ci/badge/github/pytroll/pycoast/main.svg
|
|
49
|
+
:target: https://results.pre-commit.ci/latest/github/pytroll/pycoast/main
|
|
50
|
+
:alt: pre-commit.ci status
|
|
51
|
+
|
|
52
|
+
Python package for adding coastlines, borders, rivers, lakes, cities, and other
|
|
53
|
+
overlays to raster images.
|
|
54
|
+
|
|
55
|
+
Installation
|
|
56
|
+
------------
|
|
57
|
+
|
|
58
|
+
PyCoast can be installed from PyPI using pip::
|
|
59
|
+
|
|
60
|
+
pip install pycoast
|
|
61
|
+
|
|
62
|
+
Or with conda using the conda-forge channel::
|
|
63
|
+
|
|
64
|
+
conda install -c conda-forge pycoast
|
|
65
|
+
|
|
66
|
+
Example
|
|
67
|
+
-------
|
|
68
|
+
|
|
69
|
+
::
|
|
70
|
+
|
|
71
|
+
>>> from PIL import Image
|
|
72
|
+
>>> from pycoast import ContourWriterAGG
|
|
73
|
+
>>> img = Image.open('BMNG_clouds_201109181715_areaT2.png')
|
|
74
|
+
>>> proj4_string = '+proj=stere +lon_0=8.00 +lat_0=50.00 +lat_ts=50.00 +ellps=WGS84'
|
|
75
|
+
>>> area_extent = (-3363403.31,-2291879.85,2630596.69,2203620.1)
|
|
76
|
+
>>> area_def = (proj4_string, area_extent)
|
|
77
|
+
>>> cw = ContourWriterAGG('/home/esn/data/gshhs')
|
|
78
|
+
>>> cw.add_coastlines(img, area_def, resolution='l', level=4)
|
|
79
|
+
>>> cw.add_rivers(img, area_def, level=5, outline='blue')
|
|
80
|
+
>>> cw.add_borders(img, area_def, outline=(255, 0, 0))
|
|
81
|
+
>>> img.show()
|
|
@@ -34,7 +34,7 @@ rivers, and lakes, shapefiles from the
|
|
|
34
34
|
installed. Download the zipped GSHHS and WDBII shapefiles. At the time of
|
|
35
35
|
writing the current zip file can be found at:
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
https://www.soest.hawaii.edu/pwessel/gshhg/gshhg-shp-2.3.7.zip
|
|
38
38
|
|
|
39
39
|
Unzip the files to a data directory (hereafter *DB_DATA_ROOT*).
|
|
40
40
|
The absolute path/name of this directory is called *db_root_path*
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""The conftest file."""
|
|
2
|
+
|
|
3
|
+
from pytest import hookimpl
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@hookimpl(tryfirst=True, hookwrapper=True)
|
|
7
|
+
def pytest_runtest_makereport(item, call):
|
|
8
|
+
"""Add test status in the report for fixtures to use."""
|
|
9
|
+
# execute all other hooks to obtain the report object
|
|
10
|
+
outcome = yield
|
|
11
|
+
rep = outcome.get_result()
|
|
12
|
+
# store test results for each phase of a call, which can
|
|
13
|
+
# be "setup", "call", "teardown"
|
|
14
|
+
setattr(item, "rep_" + rep.when, rep)
|
|
@@ -91,7 +91,11 @@ class ContourWriterAGG(ContourWriterBase):
|
|
|
91
91
|
):
|
|
92
92
|
"""Add a text box at position (x,y)."""
|
|
93
93
|
if box_outline is not None:
|
|
94
|
-
|
|
94
|
+
if hasattr(draw, "textsize"):
|
|
95
|
+
text_size = draw.textsize(text, font)
|
|
96
|
+
else:
|
|
97
|
+
left, top, right, bottom = draw.textbbox(text_position, text, font)
|
|
98
|
+
text_size = right - left, top - bottom
|
|
95
99
|
margin = 2
|
|
96
100
|
xUL = text_position[0] - margin
|
|
97
101
|
yUL = text_position[1]
|
|
@@ -26,12 +26,13 @@ import json
|
|
|
26
26
|
import logging
|
|
27
27
|
import math
|
|
28
28
|
import os
|
|
29
|
+
from pathlib import Path
|
|
29
30
|
from typing import Generator
|
|
30
31
|
|
|
31
32
|
import numpy as np
|
|
32
|
-
import pyproj
|
|
33
33
|
import shapefile
|
|
34
34
|
from PIL import Image
|
|
35
|
+
from pyproj import CRS, Proj
|
|
35
36
|
|
|
36
37
|
try:
|
|
37
38
|
from pyresample import AreaDefinition
|
|
@@ -45,16 +46,11 @@ def get_resolution_from_area(area_def):
|
|
|
45
46
|
"""Get the best resolution for an area definition."""
|
|
46
47
|
x_size = area_def.width
|
|
47
48
|
y_size = area_def.height
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
x_ll, y_ll = prj(area_def.area_extent[0], area_def.area_extent[1])
|
|
51
|
-
x_ur, y_ur = prj(area_def.area_extent[2], area_def.area_extent[3])
|
|
52
|
-
x_resolution = (x_ur - x_ll) / x_size
|
|
53
|
-
y_resolution = (y_ur - y_ll) / y_size
|
|
54
|
-
else:
|
|
55
|
-
x_resolution = (area_def.area_extent[2] - area_def.area_extent[0]) / x_size
|
|
56
|
-
y_resolution = (area_def.area_extent[3] - area_def.area_extent[1]) / y_size
|
|
49
|
+
x_resolution = abs(area_def.area_extent[2] - area_def.area_extent[0]) / x_size
|
|
50
|
+
y_resolution = abs(area_def.area_extent[3] - area_def.area_extent[1]) / y_size
|
|
57
51
|
res = min(x_resolution, y_resolution)
|
|
52
|
+
if "degree" in area_def.crs.axis_info[0].unit_name:
|
|
53
|
+
res = _estimate_metered_resolution_from_degrees(area_def.crs, res)
|
|
58
54
|
|
|
59
55
|
if res > 25000:
|
|
60
56
|
return "c"
|
|
@@ -68,6 +64,12 @@ def get_resolution_from_area(area_def):
|
|
|
68
64
|
return "f"
|
|
69
65
|
|
|
70
66
|
|
|
67
|
+
def _estimate_metered_resolution_from_degrees(crs: CRS, resolution_degrees: float) -> float:
|
|
68
|
+
major_radius = crs.datum.ellipsoid.semi_major_metre
|
|
69
|
+
# estimate by taking the arc length using the radius
|
|
70
|
+
return major_radius * math.radians(resolution_degrees)
|
|
71
|
+
|
|
72
|
+
|
|
71
73
|
class _CoordConverter:
|
|
72
74
|
"""Convert coordinates from one space to in-bound image pixel column and row.
|
|
73
75
|
|
|
@@ -91,7 +93,8 @@ class _CoordConverter:
|
|
|
91
93
|
raise ValueError(f"'coord_ref' must be one of {pretty_coord_refs}.")
|
|
92
94
|
self._convert_method = convert_methods[coord_ref]
|
|
93
95
|
|
|
94
|
-
|
|
96
|
+
@staticmethod
|
|
97
|
+
def _check_area_def(area_def):
|
|
95
98
|
if AreaDefinition is None:
|
|
96
99
|
raise ImportError(
|
|
97
100
|
"Missing required 'pyresample' module, please "
|
|
@@ -130,16 +133,6 @@ def hash_dict(dict_to_hash: dict) -> str:
|
|
|
130
133
|
return dhash.hexdigest()
|
|
131
134
|
|
|
132
135
|
|
|
133
|
-
class Proj(pyproj.Proj):
|
|
134
|
-
"""Wrapper around pyproj to add in 'is_latlong'."""
|
|
135
|
-
|
|
136
|
-
def is_latlong(self):
|
|
137
|
-
if hasattr(self, "crs"):
|
|
138
|
-
return self.crs.is_geographic
|
|
139
|
-
# pyproj<2.0
|
|
140
|
-
return super(Proj, self).is_latlong()
|
|
141
|
-
|
|
142
|
-
|
|
143
136
|
class ContourWriterBase(object):
|
|
144
137
|
"""Base class for contourwriters. Do not instantiate.
|
|
145
138
|
|
|
@@ -167,7 +160,16 @@ class ContourWriterBase(object):
|
|
|
167
160
|
|
|
168
161
|
def _draw_text(self, draw, position, txt, font, align="cc", **kwargs):
|
|
169
162
|
"""Draw text with agg module."""
|
|
170
|
-
|
|
163
|
+
if hasattr(draw, "textsize"):
|
|
164
|
+
txt_width, txt_height = draw.textsize(txt, font)
|
|
165
|
+
else:
|
|
166
|
+
left, top, right, bottom = draw.textbbox(position, txt, font)
|
|
167
|
+
# bbox is based on "left ascender" anchor for horizontal text
|
|
168
|
+
# but does not include the ascender to top distance.
|
|
169
|
+
# In order to include that additional distance we take height from
|
|
170
|
+
# anchor (`position`) to the bottom of the text. See:
|
|
171
|
+
# https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html#text-anchors
|
|
172
|
+
txt_width, txt_height = right - left, bottom - position[1]
|
|
171
173
|
x_pos, y_pos = position
|
|
172
174
|
ax, ay = align.lower()
|
|
173
175
|
if ax == "r":
|
|
@@ -178,7 +180,7 @@ class ContourWriterBase(object):
|
|
|
178
180
|
if ay == "b":
|
|
179
181
|
y_pos = y_pos - txt_height
|
|
180
182
|
elif ay == "c":
|
|
181
|
-
y_pos = y_pos -
|
|
183
|
+
y_pos = y_pos - txt_height / 2
|
|
182
184
|
|
|
183
185
|
self._engine_text_draw(draw, x_pos, y_pos, txt, font, **kwargs)
|
|
184
186
|
|
|
@@ -500,16 +502,21 @@ class ContourWriterBase(object):
|
|
|
500
502
|
return overlays
|
|
501
503
|
|
|
502
504
|
def add_overlay_from_dict(self, overlays, area_def, cache_epoch=None, background=None):
|
|
503
|
-
"""Create and return a transparent image adding all the overlays contained in the
|
|
505
|
+
"""Create and return a transparent image adding all the overlays contained in the ``overlays`` dict.
|
|
504
506
|
|
|
505
507
|
Optionally caches overlay results for faster rendering of images with
|
|
506
508
|
the same provided AreaDefinition and parameters. Cached results are
|
|
507
|
-
identified by hashing the AreaDefinition and the overlays dictionary.
|
|
509
|
+
identified by hashing the AreaDefinition and the ``overlays`` dictionary.
|
|
510
|
+
|
|
511
|
+
Note that if ``background`` is provided and caching is not used, the
|
|
512
|
+
result will be the final result of applying the overlays onto the
|
|
513
|
+
background. This is due to an optimization step avoiding creating a
|
|
514
|
+
separate overlay image in memory when it isn't needed.
|
|
508
515
|
|
|
509
516
|
.. warning::
|
|
510
517
|
|
|
511
518
|
Font objects are ignored in parameter hashing as they can't be easily hashed.
|
|
512
|
-
Therefore font changes will not trigger a new rendering for the cache.
|
|
519
|
+
Therefore, font changes will not trigger a new rendering for the cache.
|
|
513
520
|
|
|
514
521
|
:Parameters:
|
|
515
522
|
overlays : dict
|
|
@@ -524,24 +531,33 @@ class ContourWriterBase(object):
|
|
|
524
531
|
provided dictionary (see below).
|
|
525
532
|
background: pillow image instance
|
|
526
533
|
The image on which to write the overlays on. If it's None (default),
|
|
527
|
-
a new image is created, otherwise the
|
|
534
|
+
a new image is created, otherwise the provided background is
|
|
528
535
|
used and changed *in place*.
|
|
529
536
|
|
|
537
|
+
The keys in ``overlays`` that will be taken into account are:
|
|
538
|
+
cache, coasts, rivers, borders, shapefiles, grid, cities, points
|
|
530
539
|
|
|
531
|
-
|
|
532
|
-
|
|
540
|
+
For all of them except ``cache``, the items are the same as the
|
|
541
|
+
corresponding functions in pycoast, so refer to the docstrings of
|
|
542
|
+
these functions (add_coastlines, add_rivers, add_borders,
|
|
543
|
+
add_shapefile_shapes, add_grid, add_cities, add_points).
|
|
544
|
+
For cache, two parameters are configurable:
|
|
533
545
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
546
|
+
- `file`:
|
|
547
|
+
specify the directory and the prefix
|
|
548
|
+
of the file to save the caches decoration to (for example
|
|
549
|
+
/var/run/black_coasts_red_borders)
|
|
550
|
+
- `regenerate`:
|
|
551
|
+
True or False (default) to force the overwriting
|
|
552
|
+
of an already cached file.
|
|
539
553
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
554
|
+
:Returns: PIL.Image.Image
|
|
555
|
+
|
|
556
|
+
Resulting overlays as an Image object. If caching was used then
|
|
557
|
+
the Image wraps an open file and should be closed by the caller.
|
|
558
|
+
If caching was not used or the cached image was recreated then
|
|
559
|
+
this is an in-memory Image object. Regardless, it can be closed
|
|
560
|
+
by calling the ``.close()`` method of the Image.
|
|
545
561
|
|
|
546
562
|
"""
|
|
547
563
|
overlay_helper = _OverlaysFromDict(self, overlays, area_def, cache_epoch, background)
|
|
@@ -550,12 +566,22 @@ class ContourWriterBase(object):
|
|
|
550
566
|
def add_overlay_from_config(self, config_file, area_def, background=None):
|
|
551
567
|
"""Create and return a transparent image adding all the overlays contained in a configuration file.
|
|
552
568
|
|
|
569
|
+
See :meth:`add_overlay_from_dict` for more information.
|
|
570
|
+
|
|
553
571
|
:Parameters:
|
|
554
572
|
config_file : str
|
|
555
573
|
Configuration file name
|
|
556
574
|
area_def : object
|
|
557
575
|
Area Definition of the creating image
|
|
558
576
|
|
|
577
|
+
:Returns: PIL.Image.Image
|
|
578
|
+
|
|
579
|
+
Resulting overlays as an Image object. If caching was used then
|
|
580
|
+
the Image wraps an open file and should be closed by the caller.
|
|
581
|
+
If caching was not used or the cached image was recreated then
|
|
582
|
+
this is an in-memory Image object. Regardless, it can be closed
|
|
583
|
+
by calling the ``.close()`` method of the Image.
|
|
584
|
+
|
|
559
585
|
"""
|
|
560
586
|
overlays = self._config_to_dict(config_file)
|
|
561
587
|
return self.add_overlay_from_dict(overlays, area_def, os.path.getmtime(config_file), background)
|
|
@@ -699,8 +725,7 @@ class ContourWriterBase(object):
|
|
|
699
725
|
# cities.red is a reduced version of the files avalable at http://download.geonames.org
|
|
700
726
|
# Fields: 0=name (UTF-8), 1=asciiname, 2=longitude [°E], 3=latitude [°N], 4=countrycode
|
|
701
727
|
cities_filename = os.path.join(db_root_path, os.path.join("CITIES", "cities.txt"))
|
|
702
|
-
|
|
703
|
-
for city_name, lon, lat in cities_parser.iter_cities_names_lon_lat(cities_list):
|
|
728
|
+
for city_name, lon, lat in iter_cities_names_lon_lat(cities_filename, cities_list):
|
|
704
729
|
try:
|
|
705
730
|
x, y = area_def.get_array_indices_from_lonlat(lon, lat)
|
|
706
731
|
except ValueError:
|
|
@@ -1053,16 +1078,10 @@ def _get_bounding_box_lonlat_sides(area_extent, x_size, y_size, prj):
|
|
|
1053
1078
|
x_range = np.linspace(x_ll, x_ur, num=x_size)
|
|
1054
1079
|
y_range = np.linspace(y_ll, y_ur, num=y_size)
|
|
1055
1080
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
lons_s4, lats_s4 = x_range, y_ll * np.ones(x_range.size)
|
|
1061
|
-
else:
|
|
1062
|
-
lons_s1, lats_s1 = prj(np.ones(y_range.size) * x_ll, y_range, inverse=True)
|
|
1063
|
-
lons_s2, lats_s2 = prj(x_range, np.ones(x_range.size) * y_ur, inverse=True)
|
|
1064
|
-
lons_s3, lats_s3 = prj(np.ones(y_range.size) * x_ur, y_range, inverse=True)
|
|
1065
|
-
lons_s4, lats_s4 = prj(x_range, np.ones(x_range.size) * y_ll, inverse=True)
|
|
1081
|
+
lons_s1, lats_s1 = prj(np.ones(y_range.size) * x_ll, y_range, inverse=True)
|
|
1082
|
+
lons_s2, lats_s2 = prj(x_range, np.ones(x_range.size) * y_ur, inverse=True)
|
|
1083
|
+
lons_s3, lats_s3 = prj(np.ones(y_range.size) * x_ur, y_range, inverse=True)
|
|
1084
|
+
lons_s4, lats_s4 = prj(x_range, np.ones(x_range.size) * y_ll, inverse=True)
|
|
1066
1085
|
return (lons_s1, lons_s2, lons_s3, lons_s4), (lats_s1, lats_s2, lats_s3, lats_s4)
|
|
1067
1086
|
|
|
1068
1087
|
|
|
@@ -1087,12 +1106,7 @@ def _get_pixel_index(shape, area_extent, x_size, y_size, prj, x_offset=0, y_offs
|
|
|
1087
1106
|
shape_data = np.array(shape.points if hasattr(shape, "points") else shape)
|
|
1088
1107
|
lons = shape_data[:, 0]
|
|
1089
1108
|
lats = shape_data[:, 1]
|
|
1090
|
-
|
|
1091
|
-
if prj.is_latlong():
|
|
1092
|
-
x_ll, y_ll = prj(area_extent[0], area_extent[1])
|
|
1093
|
-
x_ur, y_ur = prj(area_extent[2], area_extent[3])
|
|
1094
|
-
else:
|
|
1095
|
-
x_ll, y_ll, x_ur, y_ur = area_extent
|
|
1109
|
+
x_ll, y_ll, x_ur, y_ur = area_extent
|
|
1096
1110
|
|
|
1097
1111
|
x, y = prj(lons, lats)
|
|
1098
1112
|
|
|
@@ -1137,14 +1151,12 @@ def _get_pixel_index(shape, area_extent, x_size, y_size, prj, x_offset=0, y_offs
|
|
|
1137
1151
|
return index_arrays, is_reduced
|
|
1138
1152
|
|
|
1139
1153
|
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
def iter_cities_names_lon_lat(self, cities_list: list[str]) -> Generator[tuple[str, float, float], None, None]:
|
|
1147
|
-
for city_row in self._cities_file:
|
|
1154
|
+
def iter_cities_names_lon_lat(
|
|
1155
|
+
cities_filename: str | Path, cities_list: list[str]
|
|
1156
|
+
) -> Generator[tuple[str, float, float], None, None]:
|
|
1157
|
+
"""Iterate over citiesN.txt files from GeoNames.org."""
|
|
1158
|
+
with open(cities_filename, mode="r", encoding="utf-8") as cities_file:
|
|
1159
|
+
for city_row in cities_file:
|
|
1148
1160
|
city_info = city_row.split("\t")
|
|
1149
1161
|
if not city_info or not (city_info[1] in cities_list or city_info[2] in cities_list):
|
|
1150
1162
|
continue
|
|
@@ -1199,7 +1211,7 @@ class _OverlaysFromDict:
|
|
|
1199
1211
|
foreground = Image.open(cache_file)
|
|
1200
1212
|
logger.info("Using image in cache %s", cache_file)
|
|
1201
1213
|
if background is not None:
|
|
1202
|
-
background
|
|
1214
|
+
_apply_cached_foreground_on_background(background, foreground)
|
|
1203
1215
|
return foreground
|
|
1204
1216
|
logger.info("Regenerating cache file.")
|
|
1205
1217
|
except OSError:
|
|
@@ -1212,7 +1224,7 @@ class _OverlaysFromDict:
|
|
|
1212
1224
|
except IOError as e:
|
|
1213
1225
|
logger.error("Can't save cache: %s", str(e))
|
|
1214
1226
|
if self._background is not None:
|
|
1215
|
-
self._background
|
|
1227
|
+
_apply_cached_foreground_on_background(self._background, self._foreground)
|
|
1216
1228
|
|
|
1217
1229
|
def _generate_cache_filename(self, cache_prefix, area_def, overlays_dict):
|
|
1218
1230
|
area_hash = hash(area_def)
|
|
@@ -1443,6 +1455,18 @@ class _OverlaysFromDict:
|
|
|
1443
1455
|
)
|
|
1444
1456
|
|
|
1445
1457
|
|
|
1458
|
+
def _apply_cached_foreground_on_background(background, foreground):
|
|
1459
|
+
premult_foreground = foreground.convert("RGBa")
|
|
1460
|
+
if background.mode == "RGBA":
|
|
1461
|
+
# Cached foreground and background are both RGBA, no extra conversions needed
|
|
1462
|
+
background.paste(premult_foreground, mask=premult_foreground)
|
|
1463
|
+
return
|
|
1464
|
+
background_rgba = background.convert("RGBA")
|
|
1465
|
+
background_rgba.paste(premult_foreground, mask=premult_foreground)
|
|
1466
|
+
# overwrite background image in place
|
|
1467
|
+
background.paste(background_rgba)
|
|
1468
|
+
|
|
1469
|
+
|
|
1446
1470
|
class _GridDrawer:
|
|
1447
1471
|
"""Helper for drawing graticule/grid lines."""
|
|
1448
1472
|
|
|
@@ -1514,7 +1538,7 @@ class _GridDrawer:
|
|
|
1514
1538
|
min_lons[min_lons > 180] = min_lons[min_lons > 180] - 360
|
|
1515
1539
|
|
|
1516
1540
|
# Get min_lons not in maj_lons
|
|
1517
|
-
min_lons = np.
|
|
1541
|
+
min_lons = np.setdiff1d(min_lons, maj_lons)
|
|
1518
1542
|
|
|
1519
1543
|
# lats along major lon lines
|
|
1520
1544
|
lin_lats = np.arange(
|
|
@@ -1535,7 +1559,7 @@ class _GridDrawer:
|
|
|
1535
1559
|
min_lats = np.arange(round_lat_min + increase_min_lat, lat_max - shorten_max_lat, dlat)
|
|
1536
1560
|
|
|
1537
1561
|
# Get min_lats not in maj_lats
|
|
1538
|
-
min_lats = np.
|
|
1562
|
+
min_lats = np.setdiff1d(min_lats, maj_lats)
|
|
1539
1563
|
|
|
1540
1564
|
# lons along major lat lines (extended slightly to avoid missing the end)
|
|
1541
1565
|
lin_lons = np.linspace(lon_min, lon_max + Dlon / 5.0, max(self._x_size, self._y_size) // 5)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[coasts]
|
|
2
|
+
level = 4
|
|
3
|
+
resolution = l
|
|
4
|
+
outline = white
|
|
5
|
+
|
|
6
|
+
[grid]
|
|
7
|
+
write_text = True
|
|
8
|
+
lon_major = 10.0
|
|
9
|
+
lat_major = 10.0
|
|
10
|
+
lon_minor = 2.0
|
|
11
|
+
lat_minor = 2.0
|
|
12
|
+
minor_outline = blue
|
|
13
|
+
outline = blue
|
|
14
|
+
lon_placement = tblr
|
|
15
|
+
lat_placement = ''
|
|
16
|
+
font = 'test_data/DejaVuSerif.ttf'
|
|
17
|
+
font_size = 10
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[coasts]
|
|
2
|
+
level = 4
|
|
3
|
+
resolution = l
|
|
4
|
+
outline = black
|
|
5
|
+
|
|
6
|
+
[borders]
|
|
7
|
+
level = 1
|
|
8
|
+
outline = black
|
|
9
|
+
width = 3
|
|
10
|
+
resolution = c
|
|
11
|
+
|
|
12
|
+
[cities]
|
|
13
|
+
# Backward compatibility: Allows for *ONE* type of cities
|
|
14
|
+
cities_list = Zurich, Oslo, Reykjavik, Fairbanks, Toronto
|
|
15
|
+
font = test_data/DejaVuSerif.ttf
|
|
16
|
+
font_size = 20
|
|
17
|
+
symbol = square
|
|
18
|
+
ptsize = 16
|
|
19
|
+
outline = black
|
|
20
|
+
width = 1
|
|
21
|
+
fill = blue
|
|
22
|
+
fill_opacity = 128
|
|
23
|
+
box_outline = blue
|
|
24
|
+
box_linewidth = 0.5
|
|
25
|
+
box_fill = yellow
|
|
26
|
+
box_opacity = 200
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[coasts]
|
|
2
|
+
level = 4
|
|
3
|
+
resolution = l
|
|
4
|
+
outline = black
|
|
5
|
+
|
|
6
|
+
[borders]
|
|
7
|
+
level = 1
|
|
8
|
+
outline = black
|
|
9
|
+
resolution = c
|
|
10
|
+
|
|
11
|
+
[cities]
|
|
12
|
+
# Backward compatibility: Allows for *ONE* type of cities
|
|
13
|
+
cities_list = Zurich, Oslo, Reykjavik, Fairbanks, Toronto
|
|
14
|
+
font = test_data/DejaVuSerif.ttf
|
|
15
|
+
font_size = 20
|
|
16
|
+
symbol = square
|
|
17
|
+
ptsize = 16
|
|
18
|
+
outline = black
|
|
19
|
+
fill = blue
|
|
20
|
+
box_outline = blue
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[coasts]
|
|
2
|
+
level = 4
|
|
3
|
+
resolution = l
|
|
4
|
+
outline = black
|
|
5
|
+
|
|
6
|
+
[borders]
|
|
7
|
+
level = 1
|
|
8
|
+
outline = black
|
|
9
|
+
width = 3
|
|
10
|
+
resolution = c
|
|
11
|
+
|
|
12
|
+
[points]
|
|
13
|
+
points_list = ((2.3522, 48.8566), 'Paris'), ((0.1278, 51.5074), 'London')
|
|
14
|
+
font = 'test_data/DejaVuSerif.ttf'
|
|
15
|
+
symbol = circle
|
|
16
|
+
ptsize = 16
|
|
17
|
+
outline = black
|
|
18
|
+
width = 3
|
|
19
|
+
fill = red
|
|
20
|
+
fill_opacity = 128
|
|
21
|
+
box_outline = blue
|
|
22
|
+
box_linewidth = 0.5
|
|
23
|
+
box_fill = yellow
|
|
24
|
+
box_opacity = 200
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[coasts]
|
|
2
|
+
level = 4
|
|
3
|
+
resolution = l
|
|
4
|
+
outline = black
|
|
5
|
+
|
|
6
|
+
[borders]
|
|
7
|
+
level = 1
|
|
8
|
+
outline = black
|
|
9
|
+
width = 3
|
|
10
|
+
resolution = c
|
|
11
|
+
|
|
12
|
+
[points]
|
|
13
|
+
points_list = ((13.4050, 52.5200), 'Berlin'), ((12.4964, 41.9028), 'Rome')
|
|
14
|
+
font = 'test_data/DejaVuSerif.ttf'
|
|
15
|
+
symbol = square
|
|
16
|
+
ptsize = 6
|
|
17
|
+
outline = red
|
|
18
|
+
fill = yellow
|
|
19
|
+
box_outline = black
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|