pycoast 1.1.0__py3-none-any.whl → 1.8.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.
- pycoast/__init__.py +30 -9
- pycoast/conftest.py +14 -0
- pycoast/cw_agg.py +761 -485
- pycoast/cw_base.py +1575 -785
- pycoast/cw_pil.py +581 -379
- pycoast/tests/__init__.py +1 -0
- pycoast/tests/brazil_shapefiles.png +0 -0
- pycoast/tests/brazil_shapefiles_agg.png +0 -0
- pycoast/tests/coasts_and_grid.ini +13 -0
- pycoast/tests/coasts_and_grid_agg.ini +17 -0
- pycoast/tests/contours_europe.png +0 -0
- pycoast/tests/contours_europe_agg.png +0 -0
- pycoast/tests/contours_europe_alpha.png +0 -0
- pycoast/tests/contours_geos.png +0 -0
- pycoast/tests/contours_geos_agg.png +0 -0
- pycoast/tests/dateline_boundary_cross.png +0 -0
- pycoast/tests/dateline_cross.png +0 -0
- pycoast/tests/eastern_shapes_agg.png +0 -0
- pycoast/tests/eastern_shapes_pil.png +0 -0
- pycoast/tests/grid_europe.png +0 -0
- pycoast/tests/grid_europe_agg.png +0 -0
- pycoast/tests/grid_europe_agg_txt.png +0 -0
- pycoast/tests/grid_from_dict_agg.png +0 -0
- pycoast/tests/grid_from_dict_pil.png +0 -0
- pycoast/tests/grid_geos.png +0 -0
- pycoast/tests/grid_geos_agg.png +0 -0
- pycoast/tests/grid_germ.png +0 -0
- pycoast/tests/grid_nh.png +0 -0
- pycoast/tests/grid_nh_agg.png +0 -0
- pycoast/tests/grid_nh_cfg_agg.png +0 -0
- pycoast/tests/lonlat_boundary_cross.png +0 -0
- pycoast/tests/nh_cities_agg.ini +26 -0
- pycoast/tests/nh_cities_agg.png +0 -0
- pycoast/tests/nh_cities_from_dict_agg.png +0 -0
- pycoast/tests/nh_cities_from_dict_pil.png +0 -0
- pycoast/tests/nh_cities_pil.ini +20 -0
- pycoast/tests/nh_cities_pil.png +0 -0
- pycoast/tests/nh_one_shapefile.ini +11 -0
- pycoast/tests/nh_points_agg.ini +24 -0
- pycoast/tests/nh_points_agg.png +0 -0
- pycoast/tests/nh_points_cfg_pil.png +0 -0
- pycoast/tests/nh_points_pil.ini +19 -0
- pycoast/tests/nh_points_pil.png +0 -0
- pycoast/tests/nh_polygons.png +0 -0
- pycoast/tests/nh_polygons_agg.png +0 -0
- pycoast/tests/no_h_scratch_agg.png +0 -0
- pycoast/tests/no_h_scratch_pil.png +0 -0
- pycoast/tests/no_v_scratch_agg.png +0 -0
- pycoast/tests/no_v_scratch_pil.png +0 -0
- pycoast/tests/one_shapefile_from_cfg_agg.png +0 -0
- pycoast/tests/one_shapefile_from_cfg_pil.png +0 -0
- pycoast/tests/test_data/DejaVuSerif.ttf +0 -0
- pycoast/tests/test_data/gshhs/CITIES/cities.txt +20 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L1.dbf +0 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L1.prj +1 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L1.shp +0 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L1.shx +0 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L2.dbf +0 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L2.prj +1 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L2.shp +0 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L2.shx +0 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L3.dbf +0 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L3.prj +1 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L3.shp +0 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L3.shx +0 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L4.dbf +0 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L4.prj +1 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L4.shp +0 -0
- pycoast/tests/test_data/gshhs/GSHHS_shp/l/GSHHS_l_L4.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L1.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L1.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L1.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L1.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L2.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L2.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L2.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L2.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L3.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L3.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L3.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_border_c_L3.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L01.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L01.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L01.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L01.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L02.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L02.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L02.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L02.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L03.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L03.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L03.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L03.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L04.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L04.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L04.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L04.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L05.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L05.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L05.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L05.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L06.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L06.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L06.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L06.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L07.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L07.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L07.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L07.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L08.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L08.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L08.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L08.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L09.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L09.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L09.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L09.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L1.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L1.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L1.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L10.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L10.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L10.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L10.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L11.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L11.prj +1 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L11.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L11.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L2.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L2.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L2.shx +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L3.dbf +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L3.shp +0 -0
- pycoast/tests/test_data/gshhs/WDBII_shp/c/WDBII_river_c_L3.shx +0 -0
- pycoast/tests/test_data/shapes/Metareas.dbf +0 -0
- pycoast/tests/test_data/shapes/Metareas.mxd +0 -0
- pycoast/tests/test_data/shapes/Metareas.prj +1 -0
- pycoast/tests/test_data/shapes/Metareas.sbn +0 -0
- pycoast/tests/test_data/shapes/Metareas.sbx +0 -0
- pycoast/tests/test_data/shapes/Metareas.shp +0 -0
- pycoast/tests/test_data/shapes/Metareas.shx +0 -0
- pycoast/tests/test_data/shapes/README +3 -0
- pycoast/tests/test_data/shapes/divisao_politica/BRASIL.dbf +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/BRASIL.shp +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/BRASIL.shx +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/BR_Capitais.dbf +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/BR_Capitais.shp +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/BR_Capitais.shx +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/BR_Contorno.dbf +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/BR_Contorno.shp +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/BR_Contorno.shx +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/BR_Regioes.dbf +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/BR_Regioes.shp +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/BR_Regioes.shx +0 -0
- pycoast/tests/test_data/shapes/divisao_politica/divisao_politica.txt +40 -0
- pycoast/tests/test_data/shapes/divisao_politica/leia.txt +9 -0
- pycoast/tests/test_data/shapes/metarea5.gsf +0 -0
- pycoast/tests/test_data/shapes/metarea5.tbl +21 -0
- pycoast/tests/test_data/shapes/metarea5.tbl.info +25 -0
- pycoast/tests/test_data/test_config.ini +12 -0
- pycoast/tests/test_pycoast.py +1913 -434
- pycoast/tests/two_shapefiles_agg.png +0 -0
- pycoast/tests/two_shapefiles_pil.png +0 -0
- pycoast/tests/western_shapes_agg.png +0 -0
- pycoast/tests/western_shapes_pil.png +0 -0
- pycoast/version.py +19 -17
- pycoast-1.8.0.dist-info/METADATA +107 -0
- pycoast-1.8.0.dist-info/RECORD +171 -0
- {pycoast-1.1.0.dist-info → pycoast-1.8.0.dist-info}/WHEEL +1 -1
- pycoast-1.8.0.dist-info/licenses/LICENSE.txt +201 -0
- pycoast-1.1.0.dist-info/DESCRIPTION.rst +0 -3
- pycoast-1.1.0.dist-info/METADATA +0 -24
- pycoast-1.1.0.dist-info/RECORD +0 -13
- pycoast-1.1.0.dist-info/metadata.json +0 -1
- {pycoast-1.1.0.dist-info → pycoast-1.8.0.dist-info}/top_level.txt +0 -0
pycoast/cw_agg.py
CHANGED
|
@@ -1,31 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# pycoast, Writing of coastlines, borders and rivers to images in Python
|
|
4
|
-
#
|
|
5
|
-
# Copyright (C) 2011-2015
|
|
6
|
-
# Esben S. Nielsen
|
|
7
|
-
# Hróbjartur Þorsteinsson
|
|
8
|
-
# Stefano Cerino
|
|
9
|
-
# Katja Hungershofer
|
|
10
|
-
# Panu Lahtinen
|
|
11
|
-
#
|
|
12
|
-
# This program is free software: you can redistribute it and/or modify
|
|
13
|
-
# it under the terms of the GNU General Public License as published by
|
|
14
|
-
# the Free Software Foundation, either version 3 of the License, or
|
|
15
|
-
# (at your option) any later version.
|
|
16
|
-
#
|
|
17
|
-
# This program is distributed in the hope that it will be useful,
|
|
18
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20
|
-
# GNU General Public License for more details.
|
|
21
|
-
#
|
|
22
|
-
# You should have received a copy of the GNU General Public License
|
|
23
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
1
|
+
"""ContourWriter based on the aggdraw library."""
|
|
24
2
|
|
|
25
|
-
from PIL import Image
|
|
26
3
|
import logging
|
|
27
4
|
|
|
28
5
|
import aggdraw
|
|
6
|
+
from PIL import Image
|
|
29
7
|
|
|
30
8
|
from pycoast.cw_base import ContourWriterBase
|
|
31
9
|
|
|
@@ -33,65 +11,73 @@ logger = logging.getLogger(__name__)
|
|
|
33
11
|
|
|
34
12
|
|
|
35
13
|
class ContourWriterAGG(ContourWriterBase):
|
|
36
|
-
|
|
37
|
-
"""Adds countours from GSHHS and WDBII to images
|
|
38
|
-
using the AGG engine for high quality images.
|
|
14
|
+
"""Adds countours from GSHHS and WDBII to images using the AGG engine for high quality images.
|
|
39
15
|
|
|
40
16
|
:Parameters:
|
|
41
|
-
|
|
42
|
-
|
|
17
|
+
db_root_path : str
|
|
18
|
+
Path to root dir of GSHHS and WDBII shapefiles
|
|
19
|
+
|
|
43
20
|
"""
|
|
21
|
+
|
|
44
22
|
_draw_module = "AGG"
|
|
45
23
|
# This is a flag to make _add_grid aware of which text draw routine
|
|
46
24
|
# from PIL or from aggdraw should be used
|
|
47
25
|
# (unfortunately they are not fully compatible)
|
|
48
26
|
|
|
49
27
|
def _get_canvas(self, image):
|
|
50
|
-
"""
|
|
51
|
-
"""
|
|
28
|
+
"""Return AGG image object."""
|
|
52
29
|
return aggdraw.Draw(image)
|
|
53
30
|
|
|
54
31
|
def _engine_text_draw(self, draw, x_pos, y_pos, txt, font, **kwargs):
|
|
55
32
|
draw.text((x_pos, y_pos), txt, font)
|
|
56
33
|
|
|
57
34
|
def _draw_polygon(self, draw, coordinates, **kwargs):
|
|
58
|
-
"""Draw polygon
|
|
59
|
-
"""
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
fill_opacity = 0
|
|
65
|
-
else:
|
|
66
|
-
fill_opacity = kwargs['fill_opacity']
|
|
67
|
-
brush = aggdraw.Brush(kwargs['fill'], fill_opacity)
|
|
35
|
+
"""Draw polygon."""
|
|
36
|
+
pen = aggdraw.Pen(kwargs["outline"], kwargs["width"], kwargs["outline_opacity"])
|
|
37
|
+
|
|
38
|
+
fill_opacity = kwargs.get("fill_opacity", 255) if kwargs["fill"] else 0
|
|
39
|
+
|
|
40
|
+
brush = aggdraw.Brush(kwargs["fill"], fill_opacity)
|
|
68
41
|
draw.polygon(coordinates, pen, brush)
|
|
69
42
|
|
|
70
43
|
def _draw_rectangle(self, draw, coordinates, **kwargs):
|
|
71
|
-
"""Draw rectangle
|
|
72
|
-
"""
|
|
73
|
-
|
|
44
|
+
"""Draw rectangle."""
|
|
45
|
+
pen = aggdraw.Pen(kwargs["outline"], kwargs["width"], kwargs["outline_opacity"])
|
|
46
|
+
|
|
47
|
+
fill_opacity = kwargs.get("fill_opacity", 255) if kwargs["fill"] else 0
|
|
48
|
+
|
|
49
|
+
brush = aggdraw.Brush(kwargs["fill"], fill_opacity)
|
|
74
50
|
|
|
75
|
-
fill_opacity = kwargs.get('fill_opacity', 255)
|
|
76
|
-
brush = aggdraw.Brush(kwargs['fill'], fill_opacity)
|
|
77
51
|
draw.rectangle(coordinates, pen, brush)
|
|
78
52
|
|
|
79
53
|
def _draw_ellipse(self, draw, coordinates, **kwargs):
|
|
80
|
-
"""Draw ellipse
|
|
81
|
-
"""
|
|
82
|
-
pen = aggdraw.Pen(kwargs['outline'])
|
|
54
|
+
"""Draw ellipse."""
|
|
55
|
+
pen = aggdraw.Pen(kwargs["outline"], kwargs["width"], kwargs["outline_opacity"])
|
|
83
56
|
|
|
84
|
-
fill_opacity = kwargs.get(
|
|
85
|
-
brush = aggdraw.Brush(kwargs['fill'], fill_opacity)
|
|
86
|
-
draw.ellipse(coordinates, brush, pen)
|
|
57
|
+
fill_opacity = kwargs.get("fill_opacity", 255) if kwargs["fill"] else 0
|
|
87
58
|
|
|
88
|
-
|
|
89
|
-
box_outline, box_opacity):
|
|
90
|
-
"""Add text box in xy
|
|
91
|
-
"""
|
|
59
|
+
brush = aggdraw.Brush(kwargs["fill"], fill_opacity)
|
|
92
60
|
|
|
61
|
+
draw.ellipse(coordinates, brush, pen)
|
|
62
|
+
|
|
63
|
+
def _draw_text_box(
|
|
64
|
+
self,
|
|
65
|
+
draw,
|
|
66
|
+
text_position,
|
|
67
|
+
text,
|
|
68
|
+
font,
|
|
69
|
+
outline,
|
|
70
|
+
box_outline,
|
|
71
|
+
box_opacity,
|
|
72
|
+
**kwargs,
|
|
73
|
+
):
|
|
74
|
+
"""Add a text box at position (x,y)."""
|
|
93
75
|
if box_outline is not None:
|
|
94
|
-
|
|
76
|
+
if hasattr(draw, "textsize"):
|
|
77
|
+
text_size = draw.textsize(text, font)
|
|
78
|
+
else:
|
|
79
|
+
left, top, right, bottom = draw.textbbox(text_position, text, font)
|
|
80
|
+
text_size = right - left, top - bottom
|
|
95
81
|
margin = 2
|
|
96
82
|
xUL = text_position[0] - margin
|
|
97
83
|
yUL = text_position[1]
|
|
@@ -99,499 +85,789 @@ class ContourWriterAGG(ContourWriterBase):
|
|
|
99
85
|
yLR = yUL + text_size[1]
|
|
100
86
|
box_size = (xUL, yUL, xLR, yLR)
|
|
101
87
|
|
|
88
|
+
width = kwargs.get("box_linewidth", 1)
|
|
89
|
+
fill = kwargs.get("box_fill", None)
|
|
90
|
+
|
|
102
91
|
self._draw_rectangle(
|
|
103
|
-
draw,
|
|
104
|
-
|
|
92
|
+
draw,
|
|
93
|
+
box_size,
|
|
94
|
+
outline=box_outline,
|
|
95
|
+
width=width,
|
|
96
|
+
outline_opacity=box_opacity,
|
|
97
|
+
fill=fill,
|
|
98
|
+
fill_opacity=box_opacity,
|
|
99
|
+
)
|
|
105
100
|
|
|
106
101
|
self._draw_text(draw, text_position, text, font, align="no")
|
|
107
102
|
|
|
108
103
|
def _draw_line(self, draw, coordinates, **kwargs):
|
|
109
|
-
"""Draw line
|
|
110
|
-
"""
|
|
111
|
-
pen = aggdraw.Pen(kwargs['outline'],
|
|
112
|
-
kwargs['width'],
|
|
113
|
-
kwargs['outline_opacity'])
|
|
104
|
+
"""Draw line."""
|
|
105
|
+
pen = aggdraw.Pen(kwargs["outline"], kwargs["width"], kwargs["outline_opacity"])
|
|
114
106
|
draw.line(coordinates, pen)
|
|
115
107
|
|
|
116
|
-
def
|
|
117
|
-
"""
|
|
118
|
-
|
|
108
|
+
def _draw_asterisk(self, draw, pt_size, coordinate, **kwargs):
|
|
109
|
+
"""Draw a asterisk sign '*' at the given coordinate."""
|
|
110
|
+
half_ptsize = int(round(pt_size / 2.0))
|
|
111
|
+
x, y = coordinate
|
|
112
|
+
|
|
113
|
+
outline = kwargs.get("outline", "white")
|
|
114
|
+
width = kwargs.get("width", 1.0)
|
|
115
|
+
outline_opacity = kwargs.get("outline_opacity", 255)
|
|
116
|
+
|
|
117
|
+
# draw '|'
|
|
118
|
+
x_bm, y_bm = (x, y - half_ptsize) # bottom middle point
|
|
119
|
+
x_tm, y_tm = (x, y + half_ptsize) # top middle point
|
|
120
|
+
self._draw_line(
|
|
121
|
+
draw,
|
|
122
|
+
[x_bm, y_bm, x_tm, y_tm],
|
|
123
|
+
outline=outline,
|
|
124
|
+
width=width,
|
|
125
|
+
outline_opacity=outline_opacity,
|
|
126
|
+
)
|
|
127
|
+
# draw '-'
|
|
128
|
+
x_lm, y_lm = (x - half_ptsize, y) # left middle point
|
|
129
|
+
x_rm, y_rm = (x + half_ptsize, y) # right middle point
|
|
130
|
+
self._draw_line(
|
|
131
|
+
draw,
|
|
132
|
+
[x_lm, y_lm, x_rm, y_rm],
|
|
133
|
+
outline=outline,
|
|
134
|
+
width=width,
|
|
135
|
+
outline_opacity=outline_opacity,
|
|
136
|
+
)
|
|
137
|
+
# draw '/'
|
|
138
|
+
x_bl, y_bl = (x - half_ptsize, y - half_ptsize) # bottom left point
|
|
139
|
+
x_tr, y_tr = (x + half_ptsize, y + half_ptsize) # top right point
|
|
140
|
+
self._draw_line(
|
|
141
|
+
draw,
|
|
142
|
+
[x_bl, y_bl, x_tr, y_tr],
|
|
143
|
+
outline=outline,
|
|
144
|
+
width=width,
|
|
145
|
+
outline_opacity=outline_opacity,
|
|
146
|
+
)
|
|
147
|
+
# draw '\'
|
|
148
|
+
x_tl, y_tl = (x - half_ptsize, y + half_ptsize) # top left point
|
|
149
|
+
x_br, y_br = (x + half_ptsize, y - half_ptsize) # bottom right point
|
|
150
|
+
self._draw_line(
|
|
151
|
+
draw,
|
|
152
|
+
[x_tl, y_tl, x_br, y_br],
|
|
153
|
+
outline=outline,
|
|
154
|
+
width=width,
|
|
155
|
+
outline_opacity=outline_opacity,
|
|
156
|
+
)
|
|
119
157
|
|
|
158
|
+
def _finalize(self, draw):
|
|
159
|
+
"""Flush the AGG image object."""
|
|
120
160
|
draw.flush()
|
|
121
161
|
|
|
122
|
-
def add_shapefile_shapes(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
162
|
+
def add_shapefile_shapes(
|
|
163
|
+
self,
|
|
164
|
+
image,
|
|
165
|
+
area_def,
|
|
166
|
+
filename,
|
|
167
|
+
feature_type=None,
|
|
168
|
+
fill=None,
|
|
169
|
+
fill_opacity=255,
|
|
170
|
+
outline="white",
|
|
171
|
+
width=1,
|
|
172
|
+
outline_opacity=255,
|
|
173
|
+
x_offset=0,
|
|
174
|
+
y_offset=0,
|
|
175
|
+
):
|
|
127
176
|
"""Add shape file shapes from an ESRI shapefile.
|
|
177
|
+
|
|
128
178
|
Note: Currently only supports lon-lat formatted coordinates.
|
|
129
179
|
|
|
130
180
|
:Parameters:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
181
|
+
image : object
|
|
182
|
+
PIL image object
|
|
183
|
+
area_def : list [proj4_string, area_extent]
|
|
184
|
+
| proj4_string : str
|
|
185
|
+
| Projection of area as Proj.4 string
|
|
186
|
+
| area_extent : list
|
|
187
|
+
| Area extent as a list (LL_x, LL_y, UR_x, UR_y)
|
|
188
|
+
filename : str
|
|
189
|
+
Path to ESRI shape file
|
|
190
|
+
feature_type : 'polygon' or 'line',
|
|
191
|
+
only to override the shape type defined in shapefile, optional
|
|
192
|
+
fill : str or (R, G, B), optional
|
|
193
|
+
Polygon fill color
|
|
194
|
+
fill_opacity : int, optional {0; 255}
|
|
195
|
+
Opacity of polygon fill
|
|
196
|
+
outline : str or (R, G, B), optional
|
|
197
|
+
line color
|
|
198
|
+
width : float, optional
|
|
199
|
+
line width
|
|
200
|
+
outline_opacity : int, optional {0; 255}
|
|
201
|
+
Opacity of lines
|
|
202
|
+
x_offset : float, optional
|
|
203
|
+
Pixel offset in x direction
|
|
204
|
+
y_offset : float, optional
|
|
205
|
+
Pixel offset in y direction
|
|
206
|
+
|
|
156
207
|
"""
|
|
157
|
-
self._add_shapefile_shapes(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
208
|
+
self._add_shapefile_shapes(
|
|
209
|
+
image=image,
|
|
210
|
+
area_def=area_def,
|
|
211
|
+
filename=filename,
|
|
212
|
+
feature_type=feature_type,
|
|
213
|
+
x_offset=x_offset,
|
|
214
|
+
y_offset=y_offset,
|
|
215
|
+
fill=fill,
|
|
216
|
+
fill_opacity=fill_opacity,
|
|
217
|
+
outline=outline,
|
|
218
|
+
width=width,
|
|
219
|
+
outline_opacity=outline_opacity,
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
def add_shapefile_shape(
|
|
223
|
+
self,
|
|
224
|
+
image,
|
|
225
|
+
area_def,
|
|
226
|
+
filename,
|
|
227
|
+
shape_id,
|
|
228
|
+
feature_type=None,
|
|
229
|
+
fill=None,
|
|
230
|
+
fill_opacity=255,
|
|
231
|
+
outline="white",
|
|
232
|
+
width=1,
|
|
233
|
+
outline_opacity=255,
|
|
234
|
+
x_offset=0,
|
|
235
|
+
y_offset=0,
|
|
236
|
+
):
|
|
170
237
|
"""Add a single shape file shape from an ESRI shapefile.
|
|
238
|
+
|
|
171
239
|
Note: To add all shapes in file use the 'add_shape_file_shapes' routine
|
|
240
|
+
|
|
172
241
|
Note: Currently only supports lon-lat formatted coordinates.
|
|
173
242
|
|
|
174
243
|
:Parameters:
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
244
|
+
image : object
|
|
245
|
+
PIL image object
|
|
246
|
+
area_def : list [proj4_string, area_extent]
|
|
247
|
+
| proj4_string : str
|
|
248
|
+
| Projection of area as Proj.4 string
|
|
249
|
+
| area_extent : list
|
|
250
|
+
| Area extent as a list (LL_x, LL_y, UR_x, UR_y)
|
|
251
|
+
filename : str
|
|
252
|
+
Path to ESRI shape file
|
|
253
|
+
shape_id : int
|
|
254
|
+
integer id of shape in shape file {0; ... }
|
|
255
|
+
feature_type : 'polygon' or 'line',
|
|
256
|
+
only to override the shape type defined in shapefile, optional
|
|
257
|
+
fill : str or (R, G, B), optional
|
|
258
|
+
Polygon fill color
|
|
259
|
+
fill_opacity : int, optional {0; 255}
|
|
260
|
+
Opacity of polygon fill
|
|
261
|
+
outline : str or (R, G, B), optional
|
|
262
|
+
line color
|
|
263
|
+
width : float, optional
|
|
264
|
+
line width
|
|
265
|
+
outline_opacity : int, optional {0; 255}
|
|
266
|
+
Opacity of lines
|
|
267
|
+
x_offset : float, optional
|
|
268
|
+
Pixel offset in x direction
|
|
269
|
+
y_offset : float, optional
|
|
270
|
+
Pixel offset in y direction
|
|
271
|
+
|
|
202
272
|
"""
|
|
203
|
-
self._add_shapefile_shape(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
273
|
+
self._add_shapefile_shape(
|
|
274
|
+
image=image,
|
|
275
|
+
area_def=area_def,
|
|
276
|
+
filename=filename,
|
|
277
|
+
shape_id=shape_id,
|
|
278
|
+
feature_type=feature_type,
|
|
279
|
+
x_offset=x_offset,
|
|
280
|
+
y_offset=y_offset,
|
|
281
|
+
fill=fill,
|
|
282
|
+
fill_opacity=fill_opacity,
|
|
283
|
+
outline=outline,
|
|
284
|
+
width=width,
|
|
285
|
+
outline_opacity=outline_opacity,
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
def add_line(
|
|
289
|
+
self,
|
|
290
|
+
image,
|
|
291
|
+
area_def,
|
|
292
|
+
lonlats,
|
|
293
|
+
fill=None,
|
|
294
|
+
fill_opacity=255,
|
|
295
|
+
outline="white",
|
|
296
|
+
width=1,
|
|
297
|
+
outline_opacity=255,
|
|
298
|
+
x_offset=0,
|
|
299
|
+
y_offset=0,
|
|
300
|
+
):
|
|
215
301
|
"""Add a user defined poly-line from a list of (lon,lat) coordinates.
|
|
216
302
|
|
|
217
303
|
:Parameters:
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
304
|
+
image : object
|
|
305
|
+
PIL image object
|
|
306
|
+
area_def : list [proj4_string, area_extent]
|
|
307
|
+
| proj4_string : str
|
|
308
|
+
| Projection of area as Proj.4 string
|
|
309
|
+
| area_extent : list
|
|
310
|
+
| Area extent as a list (LL_x, LL_y, UR_x, UR_y)
|
|
311
|
+
lonlats : list of lon lat pairs
|
|
312
|
+
e.g. [(10,20),(20,30),...,(20,20)]
|
|
313
|
+
outline : str or (R, G, B), optional
|
|
314
|
+
line color
|
|
315
|
+
width : float, optional
|
|
316
|
+
line width
|
|
317
|
+
outline_opacity : int, optional {0; 255}
|
|
318
|
+
Opacity of lines
|
|
319
|
+
x_offset : float, optional
|
|
320
|
+
Pixel offset in x direction
|
|
321
|
+
y_offset : float, optional
|
|
322
|
+
Pixel offset in y direction
|
|
323
|
+
|
|
237
324
|
"""
|
|
238
|
-
self._add_line(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
325
|
+
self._add_line(
|
|
326
|
+
image,
|
|
327
|
+
area_def,
|
|
328
|
+
lonlats,
|
|
329
|
+
x_offset=x_offset,
|
|
330
|
+
y_offset=y_offset,
|
|
331
|
+
fill=fill,
|
|
332
|
+
fill_opacity=fill_opacity,
|
|
333
|
+
outline=outline,
|
|
334
|
+
width=width,
|
|
335
|
+
outline_opacity=outline_opacity,
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
def add_polygon(
|
|
339
|
+
self,
|
|
340
|
+
image,
|
|
341
|
+
area_def,
|
|
342
|
+
lonlats,
|
|
343
|
+
fill=None,
|
|
344
|
+
fill_opacity=255,
|
|
345
|
+
outline="white",
|
|
346
|
+
width=1,
|
|
347
|
+
outline_opacity=255,
|
|
348
|
+
x_offset=0,
|
|
349
|
+
y_offset=0,
|
|
350
|
+
):
|
|
246
351
|
"""Add a user defined polygon from a list of (lon,lat) coordinates.
|
|
247
352
|
|
|
248
353
|
:Parameters:
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
354
|
+
image : object
|
|
355
|
+
PIL image object
|
|
356
|
+
area_def : list [proj4_string, area_extent]
|
|
357
|
+
| proj4_string : str
|
|
358
|
+
| Projection of area as Proj.4 string
|
|
359
|
+
| area_extent : list
|
|
360
|
+
| Area extent as a list (LL_x, LL_y, UR_x, UR_y)
|
|
361
|
+
lonlats : list of lon lat pairs
|
|
362
|
+
e.g. [(10,20),(20,30),...,(20,20)]
|
|
363
|
+
fill : str or (R, G, B), optional
|
|
364
|
+
Polygon fill color
|
|
365
|
+
fill_opacity : int, optional {0; 255}
|
|
366
|
+
Opacity of polygon fill
|
|
367
|
+
outline : str or (R, G, B), optional
|
|
368
|
+
line color
|
|
369
|
+
width : float, optional
|
|
370
|
+
line width
|
|
371
|
+
outline_opacity : int, optional {0; 255}
|
|
372
|
+
Opacity of lines
|
|
373
|
+
x_offset : float, optional
|
|
374
|
+
Pixel offset in x direction
|
|
375
|
+
y_offset : float, optional
|
|
376
|
+
Pixel offset in y direction
|
|
377
|
+
|
|
272
378
|
"""
|
|
273
|
-
self._add_polygon(
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
379
|
+
self._add_polygon(
|
|
380
|
+
image,
|
|
381
|
+
area_def,
|
|
382
|
+
lonlats,
|
|
383
|
+
x_offset=x_offset,
|
|
384
|
+
y_offset=y_offset,
|
|
385
|
+
fill=fill,
|
|
386
|
+
fill_opacity=fill_opacity,
|
|
387
|
+
outline=outline,
|
|
388
|
+
width=width,
|
|
389
|
+
outline_opacity=outline_opacity,
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
def add_grid(
|
|
393
|
+
self,
|
|
394
|
+
image,
|
|
395
|
+
area_def,
|
|
396
|
+
Dlonlat,
|
|
397
|
+
dlonlat,
|
|
398
|
+
font=None,
|
|
399
|
+
write_text=True,
|
|
400
|
+
fill=None,
|
|
401
|
+
fill_opacity=255,
|
|
402
|
+
outline="white",
|
|
403
|
+
width=1.0,
|
|
404
|
+
outline_opacity=255,
|
|
405
|
+
minor_outline="white",
|
|
406
|
+
minor_width=0.5,
|
|
407
|
+
minor_outline_opacity=255,
|
|
408
|
+
minor_is_tick=True,
|
|
409
|
+
lon_placement="tb",
|
|
410
|
+
lat_placement="lr",
|
|
411
|
+
):
|
|
412
|
+
"""Add a lon-lat grid to a PIL image object.
|
|
285
413
|
|
|
286
414
|
:Parameters:
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
415
|
+
image : object
|
|
416
|
+
PIL image object
|
|
417
|
+
proj4_string : str
|
|
418
|
+
Projection of area as Proj.4 string
|
|
419
|
+
Dlonlat: (float, float)
|
|
420
|
+
Major grid line separation
|
|
421
|
+
dlonlat: (float, float)
|
|
422
|
+
Minor grid line separation
|
|
423
|
+
font: Aggdraw Font object, optional
|
|
424
|
+
Font for major line markings
|
|
425
|
+
write_text : boolean, optional
|
|
426
|
+
Determine if line markings are enabled
|
|
427
|
+
fill_opacity : int, optional {0; 255}
|
|
428
|
+
Opacity of text
|
|
429
|
+
outline : str or (R, G, B), optional
|
|
430
|
+
Major line color
|
|
431
|
+
width : float, optional
|
|
432
|
+
Major line width
|
|
433
|
+
outline_opacity : int, optional {0; 255}
|
|
434
|
+
Opacity of major lines
|
|
435
|
+
minor_outline : str or (R, G, B), optional
|
|
436
|
+
Minor line/tick color
|
|
437
|
+
minor_width : float, optional
|
|
438
|
+
Minor line width
|
|
439
|
+
minor_outline_opacity : int, optional {0; 255}
|
|
440
|
+
Opacity of minor lines/ticks
|
|
441
|
+
minor_is_tick : boolean, optional
|
|
442
|
+
Use tick minor line style (True) or full minor line style (False)
|
|
443
|
+
|
|
315
444
|
"""
|
|
316
445
|
Dlon, Dlat = Dlonlat
|
|
317
446
|
dlon, dlat = dlonlat
|
|
318
|
-
self._add_grid(
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
447
|
+
self._add_grid(
|
|
448
|
+
image,
|
|
449
|
+
area_def,
|
|
450
|
+
Dlon,
|
|
451
|
+
Dlat,
|
|
452
|
+
dlon,
|
|
453
|
+
dlat,
|
|
454
|
+
font=font,
|
|
455
|
+
write_text=write_text,
|
|
456
|
+
fill=fill,
|
|
457
|
+
fill_opacity=fill_opacity,
|
|
458
|
+
outline=outline,
|
|
459
|
+
width=width,
|
|
460
|
+
outline_opacity=outline_opacity,
|
|
461
|
+
minor_outline=minor_outline,
|
|
462
|
+
minor_width=minor_width,
|
|
463
|
+
minor_outline_opacity=minor_outline_opacity,
|
|
464
|
+
minor_is_tick=minor_is_tick,
|
|
465
|
+
lon_placement=lon_placement,
|
|
466
|
+
lat_placement=lat_placement,
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
def add_grid_to_file(
|
|
470
|
+
self,
|
|
471
|
+
filename,
|
|
472
|
+
area_def,
|
|
473
|
+
Dlonlat,
|
|
474
|
+
dlonlat,
|
|
475
|
+
font=None,
|
|
476
|
+
write_text=True,
|
|
477
|
+
fill=None,
|
|
478
|
+
fill_opacity=255,
|
|
479
|
+
outline="white",
|
|
480
|
+
width=1,
|
|
481
|
+
outline_opacity=255,
|
|
482
|
+
minor_outline="white",
|
|
483
|
+
minor_width=0.5,
|
|
484
|
+
minor_outline_opacity=255,
|
|
485
|
+
minor_is_tick=True,
|
|
486
|
+
lon_placement="tb",
|
|
487
|
+
lat_placement="lr",
|
|
488
|
+
):
|
|
489
|
+
"""Add a lon-lat grid to an image. The resulting image is in 'RGBA' mode.
|
|
336
490
|
|
|
337
491
|
:Parameters:
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
"""
|
|
492
|
+
image : object
|
|
493
|
+
PIL image object
|
|
494
|
+
proj4_string : str
|
|
495
|
+
Projection of area as Proj.4 string
|
|
496
|
+
Dlonlat: (float, float)
|
|
497
|
+
Major grid line separation
|
|
498
|
+
dlonlat: (float, float)
|
|
499
|
+
Minor grid line separation
|
|
500
|
+
font: Aggdraw Font object, optional
|
|
501
|
+
Font for major line markings
|
|
502
|
+
write_text : boolean, optional
|
|
503
|
+
Determine if line markings are enabled
|
|
504
|
+
fill_opacity : int, optional {0; 255}
|
|
505
|
+
Opacity of text
|
|
506
|
+
outline : str or (R, G, B), optional
|
|
507
|
+
Major line color
|
|
508
|
+
width : float, optional
|
|
509
|
+
Major line width
|
|
510
|
+
outline_opacity : int, optional {0; 255}
|
|
511
|
+
Opacity of major lines
|
|
512
|
+
minor_outline : str or (R, G, B), optional
|
|
513
|
+
Minor line/tick color
|
|
514
|
+
minor_width : float, optional
|
|
515
|
+
Minor line width
|
|
516
|
+
minor_outline_opacity : int, optional {0; 255}
|
|
517
|
+
Opacity of minor lines/ticks
|
|
518
|
+
minor_is_tick : boolean, optional
|
|
519
|
+
Use tick minor line style (True) or full minor line style (False)
|
|
367
520
|
|
|
521
|
+
"""
|
|
368
522
|
image = Image.open(filename)
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
523
|
+
image = image.convert("RGBA")
|
|
524
|
+
self.add_grid(
|
|
525
|
+
image,
|
|
526
|
+
area_def,
|
|
527
|
+
Dlonlat,
|
|
528
|
+
dlonlat,
|
|
529
|
+
font=font,
|
|
530
|
+
write_text=write_text,
|
|
531
|
+
fill=fill,
|
|
532
|
+
fill_opacity=fill_opacity,
|
|
533
|
+
outline=outline,
|
|
534
|
+
width=width,
|
|
535
|
+
outline_opacity=outline_opacity,
|
|
536
|
+
minor_outline=minor_outline,
|
|
537
|
+
minor_width=minor_width,
|
|
538
|
+
minor_outline_opacity=minor_outline_opacity,
|
|
539
|
+
minor_is_tick=minor_is_tick,
|
|
540
|
+
lon_placement=lon_placement,
|
|
541
|
+
lat_placement=lat_placement,
|
|
542
|
+
)
|
|
379
543
|
image.save(filename)
|
|
380
544
|
|
|
381
|
-
def add_coastlines(
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
545
|
+
def add_coastlines(
|
|
546
|
+
self,
|
|
547
|
+
image,
|
|
548
|
+
area_def,
|
|
549
|
+
resolution="c",
|
|
550
|
+
level=1,
|
|
551
|
+
fill=None,
|
|
552
|
+
fill_opacity=255,
|
|
553
|
+
outline="white",
|
|
554
|
+
width=1,
|
|
555
|
+
outline_opacity=255,
|
|
556
|
+
x_offset=0,
|
|
557
|
+
y_offset=0,
|
|
558
|
+
):
|
|
559
|
+
"""Add coastlines to a PIL image object.
|
|
385
560
|
|
|
386
561
|
:Parameters:
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
"""
|
|
412
|
-
|
|
413
|
-
self._add_feature(image, area_def, 'polygon', 'GSHHS',
|
|
414
|
-
resolution=resolution, level=level,
|
|
415
|
-
fill=fill, fill_opacity=fill_opacity,
|
|
416
|
-
outline=outline, width=width,
|
|
417
|
-
outline_opacity=outline_opacity, x_offset=x_offset,
|
|
418
|
-
y_offset=y_offset)
|
|
562
|
+
image : object
|
|
563
|
+
PIL image object
|
|
564
|
+
proj4_string : str
|
|
565
|
+
Projection of area as Proj.4 string
|
|
566
|
+
area_extent : list
|
|
567
|
+
Area extent as a list (LL_x, LL_y, UR_x, UR_y)
|
|
568
|
+
resolution : str, optional {'c', 'l', 'i', 'h', 'f'}
|
|
569
|
+
Dataset resolution to use
|
|
570
|
+
level : int, optional {1, 2, 3, 4}
|
|
571
|
+
Detail level of dataset
|
|
572
|
+
fill : str or (R, G, B), optional
|
|
573
|
+
Land color
|
|
574
|
+
fill_opacity : int, optional {0; 255}
|
|
575
|
+
Opacity of land color
|
|
576
|
+
outline : str or (R, G, B), optional
|
|
577
|
+
Coastline color
|
|
578
|
+
width : float, optional
|
|
579
|
+
Width of coastline
|
|
580
|
+
outline_opacity : int, optional {0; 255}
|
|
581
|
+
Opacity of coastline color
|
|
582
|
+
x_offset : float, optional
|
|
583
|
+
Pixel offset in x direction
|
|
584
|
+
y_offset : float, optional
|
|
585
|
+
Pixel offset in y direction
|
|
419
586
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
587
|
+
"""
|
|
588
|
+
self._add_feature(
|
|
589
|
+
image,
|
|
590
|
+
area_def,
|
|
591
|
+
"polygon",
|
|
592
|
+
"GSHHS",
|
|
593
|
+
resolution=resolution,
|
|
594
|
+
level=level,
|
|
595
|
+
fill=fill,
|
|
596
|
+
fill_opacity=fill_opacity,
|
|
597
|
+
outline=outline,
|
|
598
|
+
width=width,
|
|
599
|
+
outline_opacity=outline_opacity,
|
|
600
|
+
x_offset=x_offset,
|
|
601
|
+
y_offset=y_offset,
|
|
602
|
+
)
|
|
603
|
+
|
|
604
|
+
def add_coastlines_to_file(
|
|
605
|
+
self,
|
|
606
|
+
filename,
|
|
607
|
+
area_def,
|
|
608
|
+
resolution="c",
|
|
609
|
+
level=1,
|
|
610
|
+
fill=None,
|
|
611
|
+
fill_opacity=255,
|
|
612
|
+
outline="white",
|
|
613
|
+
width=1,
|
|
614
|
+
outline_opacity=255,
|
|
615
|
+
x_offset=0,
|
|
616
|
+
y_offset=0,
|
|
617
|
+
):
|
|
618
|
+
"""Add coastlines to an image file. The resulting image is in 'RGBA' mode.
|
|
425
619
|
|
|
426
620
|
:Parameters:
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
"""
|
|
621
|
+
filename : str
|
|
622
|
+
Image file
|
|
623
|
+
proj4_string : str
|
|
624
|
+
Projection of area as Proj.4 string
|
|
625
|
+
area_extent : list
|
|
626
|
+
Area extent as a list (LL_x, LL_y, UR_x, UR_y)
|
|
627
|
+
resolution : str, optional {'c', 'l', 'i', 'h', 'f'}
|
|
628
|
+
Dataset resolution to use
|
|
629
|
+
level : int, optional {1, 2, 3, 4}
|
|
630
|
+
Detail level of dataset
|
|
631
|
+
fill : str or (R, G, B), optional
|
|
632
|
+
Land color
|
|
633
|
+
fill_opacity : int, optional {0; 255}
|
|
634
|
+
Opacity of land color
|
|
635
|
+
outline : str or (R, G, B), optional
|
|
636
|
+
Coastline color
|
|
637
|
+
width : float, optional
|
|
638
|
+
Width of coastline
|
|
639
|
+
outline_opacity : int, optional {0; 255}
|
|
640
|
+
Opacity of coastline color
|
|
641
|
+
x_offset : float, optional
|
|
642
|
+
Pixel offset in x direction
|
|
643
|
+
y_offset : float, optional
|
|
644
|
+
Pixel offset in y direction
|
|
452
645
|
|
|
646
|
+
"""
|
|
453
647
|
image = Image.open(filename)
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
648
|
+
image = image.convert("RGBA")
|
|
649
|
+
self.add_coastlines(
|
|
650
|
+
image,
|
|
651
|
+
area_def,
|
|
652
|
+
resolution=resolution,
|
|
653
|
+
level=level,
|
|
654
|
+
fill=fill,
|
|
655
|
+
fill_opacity=fill_opacity,
|
|
656
|
+
outline=outline,
|
|
657
|
+
width=width,
|
|
658
|
+
outline_opacity=outline_opacity,
|
|
659
|
+
x_offset=x_offset,
|
|
660
|
+
y_offset=y_offset,
|
|
661
|
+
)
|
|
459
662
|
image.save(filename)
|
|
460
663
|
|
|
461
|
-
def add_borders(
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
664
|
+
def add_borders(
|
|
665
|
+
self,
|
|
666
|
+
image,
|
|
667
|
+
area_def,
|
|
668
|
+
resolution="c",
|
|
669
|
+
level=1,
|
|
670
|
+
outline="white",
|
|
671
|
+
width=1,
|
|
672
|
+
outline_opacity=255,
|
|
673
|
+
x_offset=0,
|
|
674
|
+
y_offset=0,
|
|
675
|
+
):
|
|
676
|
+
"""Add borders to a PIL image object.
|
|
465
677
|
|
|
466
678
|
:Parameters:
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
"""
|
|
679
|
+
image : object
|
|
680
|
+
PIL image object
|
|
681
|
+
proj4_string : str
|
|
682
|
+
Projection of area as Proj.4 string
|
|
683
|
+
area_extent : list
|
|
684
|
+
Area extent as a list (LL_x, LL_y, UR_x, UR_y)
|
|
685
|
+
resolution : str, optional {'c', 'l', 'i', 'h', 'f'}
|
|
686
|
+
Dataset resolution to use
|
|
687
|
+
level : int, optional {1, 2, 3}
|
|
688
|
+
Detail level of dataset
|
|
689
|
+
outline : str or (R, G, B), optional
|
|
690
|
+
Border color
|
|
691
|
+
width : float, optional
|
|
692
|
+
Width of coastline
|
|
693
|
+
outline_opacity : int, optional {0; 255}
|
|
694
|
+
Opacity of coastline color
|
|
695
|
+
x_offset : float, optional
|
|
696
|
+
Pixel offset in x direction
|
|
697
|
+
y_offset : float, optional
|
|
698
|
+
Pixel offset in y direction
|
|
488
699
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
700
|
+
"""
|
|
701
|
+
self._add_feature(
|
|
702
|
+
image,
|
|
703
|
+
area_def,
|
|
704
|
+
"line",
|
|
705
|
+
"WDBII",
|
|
706
|
+
tag="border",
|
|
707
|
+
resolution=resolution,
|
|
708
|
+
level=level,
|
|
709
|
+
outline=outline,
|
|
710
|
+
width=width,
|
|
711
|
+
outline_opacity=outline_opacity,
|
|
712
|
+
x_offset=x_offset,
|
|
713
|
+
y_offset=y_offset,
|
|
714
|
+
)
|
|
715
|
+
|
|
716
|
+
def add_borders_to_file(
|
|
717
|
+
self,
|
|
718
|
+
filename,
|
|
719
|
+
area_def,
|
|
720
|
+
resolution="c",
|
|
721
|
+
level=1,
|
|
722
|
+
outline="white",
|
|
723
|
+
width=1,
|
|
724
|
+
outline_opacity=255,
|
|
725
|
+
x_offset=0,
|
|
726
|
+
y_offset=0,
|
|
727
|
+
):
|
|
728
|
+
"""Add borders to an image file. The resulting image is in 'RGBA' mode.
|
|
498
729
|
|
|
499
730
|
:Parameters:
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
731
|
+
image : object
|
|
732
|
+
Image file
|
|
733
|
+
proj4_string : str
|
|
734
|
+
Projection of area as Proj.4 string
|
|
735
|
+
area_extent : list
|
|
736
|
+
Area extent as a list (LL_x, LL_y, UR_x, UR_y)
|
|
737
|
+
resolution : str, optional {'c', 'l', 'i', 'h', 'f'}
|
|
738
|
+
Dataset resolution to use
|
|
739
|
+
level : int, optional {1, 2, 3}
|
|
740
|
+
Detail level of dataset
|
|
741
|
+
outline : str or (R, G, B), optional
|
|
742
|
+
Border color
|
|
743
|
+
width : float, optional
|
|
744
|
+
Width of coastline
|
|
745
|
+
outline_opacity : int, optional {0; 255}
|
|
746
|
+
Opacity of coastline color
|
|
747
|
+
x_offset : float, optional
|
|
748
|
+
Pixel offset in x direction
|
|
749
|
+
y_offset : float, optional
|
|
750
|
+
Pixel offset in y direction
|
|
751
|
+
|
|
520
752
|
"""
|
|
521
753
|
image = Image.open(filename)
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
754
|
+
image = image.convert("RGBA")
|
|
755
|
+
self.add_borders(
|
|
756
|
+
image,
|
|
757
|
+
area_def,
|
|
758
|
+
resolution=resolution,
|
|
759
|
+
level=level,
|
|
760
|
+
outline=outline,
|
|
761
|
+
width=width,
|
|
762
|
+
outline_opacity=outline_opacity,
|
|
763
|
+
x_offset=x_offset,
|
|
764
|
+
y_offset=y_offset,
|
|
765
|
+
)
|
|
526
766
|
image.save(filename)
|
|
527
767
|
|
|
528
|
-
def add_rivers(
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
768
|
+
def add_rivers(
|
|
769
|
+
self,
|
|
770
|
+
image,
|
|
771
|
+
area_def,
|
|
772
|
+
resolution="c",
|
|
773
|
+
level=1,
|
|
774
|
+
outline="white",
|
|
775
|
+
width=1,
|
|
776
|
+
outline_opacity=255,
|
|
777
|
+
x_offset=0,
|
|
778
|
+
y_offset=0,
|
|
779
|
+
):
|
|
780
|
+
"""Add rivers to a PIL image object.
|
|
532
781
|
|
|
533
782
|
:Parameters:
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
"""
|
|
555
|
-
|
|
556
|
-
self._add_feature(image, area_def, 'line', 'WDBII', tag='river',
|
|
557
|
-
zero_pad=True, resolution=resolution, level=level,
|
|
558
|
-
outline=outline, width=width,
|
|
559
|
-
outline_opacity=outline_opacity, x_offset=x_offset,
|
|
560
|
-
y_offset=y_offset)
|
|
783
|
+
image : object
|
|
784
|
+
PIL image object
|
|
785
|
+
proj4_string : str
|
|
786
|
+
Projection of area as Proj.4 string
|
|
787
|
+
area_extent : list
|
|
788
|
+
Area extent as a list (LL_x, LL_y, UR_x, UR_y)
|
|
789
|
+
resolution : str, optional {'c', 'l', 'i', 'h', 'f'}
|
|
790
|
+
Dataset resolution to use
|
|
791
|
+
level : int, optional {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
|
|
792
|
+
Detail level of dataset
|
|
793
|
+
outline : str or (R, G, B), optional
|
|
794
|
+
River color
|
|
795
|
+
width : float, optional
|
|
796
|
+
Width of coastline
|
|
797
|
+
outline_opacity : int, optional {0; 255}
|
|
798
|
+
Opacity of coastline color
|
|
799
|
+
x_offset : float, optional
|
|
800
|
+
Pixel offset in x direction
|
|
801
|
+
y_offset : float, optional
|
|
802
|
+
Pixel offset in y direction
|
|
561
803
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
804
|
+
"""
|
|
805
|
+
self._add_feature(
|
|
806
|
+
image,
|
|
807
|
+
area_def,
|
|
808
|
+
"line",
|
|
809
|
+
"WDBII",
|
|
810
|
+
tag="river",
|
|
811
|
+
zero_pad=True,
|
|
812
|
+
resolution=resolution,
|
|
813
|
+
level=level,
|
|
814
|
+
outline=outline,
|
|
815
|
+
width=width,
|
|
816
|
+
outline_opacity=outline_opacity,
|
|
817
|
+
x_offset=x_offset,
|
|
818
|
+
y_offset=y_offset,
|
|
819
|
+
)
|
|
820
|
+
|
|
821
|
+
def add_rivers_to_file(
|
|
822
|
+
self,
|
|
823
|
+
filename,
|
|
824
|
+
area_def,
|
|
825
|
+
resolution="c",
|
|
826
|
+
level=1,
|
|
827
|
+
outline="white",
|
|
828
|
+
width=1,
|
|
829
|
+
outline_opacity=255,
|
|
830
|
+
x_offset=0,
|
|
831
|
+
y_offset=0,
|
|
832
|
+
):
|
|
833
|
+
"""Add rivers to an image file. The resulting image is in 'RGBA' mode.
|
|
566
834
|
|
|
567
835
|
:Parameters:
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
"""
|
|
836
|
+
image : object
|
|
837
|
+
Image file
|
|
838
|
+
proj4_string : str
|
|
839
|
+
Projection of area as Proj.4 string
|
|
840
|
+
area_extent : list
|
|
841
|
+
Area extent as a list (LL_x, LL_y, UR_x, UR_y)
|
|
842
|
+
resolution : str, optional {'c', 'l', 'i', 'h', 'f'}
|
|
843
|
+
Dataset resolution to use
|
|
844
|
+
level : int, optional {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
|
|
845
|
+
Detail level of dataset
|
|
846
|
+
outline : str or (R, G, B), optional
|
|
847
|
+
River color
|
|
848
|
+
width : float, optional
|
|
849
|
+
Width of coastline
|
|
850
|
+
outline_opacity : int, optional {0; 255}
|
|
851
|
+
Opacity of coastline color
|
|
852
|
+
x_offset : float, optional
|
|
853
|
+
Pixel offset in x direction
|
|
854
|
+
y_offset : float, optional
|
|
855
|
+
Pixel offset in y direction
|
|
589
856
|
|
|
857
|
+
"""
|
|
590
858
|
image = Image.open(filename)
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
859
|
+
image = image.convert("RGBA")
|
|
860
|
+
self.add_rivers(
|
|
861
|
+
image,
|
|
862
|
+
area_def,
|
|
863
|
+
resolution=resolution,
|
|
864
|
+
level=level,
|
|
865
|
+
outline=outline,
|
|
866
|
+
width=width,
|
|
867
|
+
outline_opacity=outline_opacity,
|
|
868
|
+
x_offset=x_offset,
|
|
869
|
+
y_offset=y_offset,
|
|
870
|
+
)
|
|
595
871
|
image.save(filename)
|
|
596
872
|
|
|
597
873
|
def _get_font(self, outline, font_file, font_size):
|