Coverage for pyguymer3/geo/_add_reefs.py: 3%
36 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-16 08:31 +0000
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-16 08:31 +0000
1#!/usr/bin/env python3
3# Define function ...
4def _add_reefs(
5 ax,
6 /,
7 *,
8 debug = __debug__,
9 fov = None,
10 linestyle = "solid",
11 linewidth = 0.5,
12 onlyValid = False,
13 repair = False,
14 resolution = "10m",
15):
16 """Add reefs to a Cartopy axis.
18 Parameters
19 ----------
20 axis : cartopy.mpl.geoaxes.GeoAxesSubplot
21 the axis to add the reefs to
22 debug : bool, optional
23 print debug messages
24 fov : None or shapely.geometry.polygon.Polygon, optional
25 clip the plotted shapes to the provided field-of-view to work around
26 occaisional MatPlotLib or Cartopy plotting errors when shapes much
27 larger than the field-of-view are plotted
28 linestyle : str, optional
29 the style of the exterior of the reefs
30 linewidth : float, optional
31 the width of the exterior of the reefs
32 onlyValid : bool, optional
33 only add valid Polygons (checks for validity can take a while, if being
34 being called often)
35 repair : bool, optional
36 attempt to repair invalid Polygons
37 resolution : str, optional
38 the resolution of the reefs
40 Notes
41 -----
42 This function uses `CSS4 named colours
43 <https://matplotlib.org/stable/gallery/color/named_colors.html>`_ .
45 Copyright 2017 Thomas Guymer [1]_
47 References
48 ----------
49 .. [1] PyGuymer3, https://github.com/Guymer/PyGuymer3
50 """
52 # Import standard modules ...
53 import pathlib
54 import urllib
56 # Import special modules ...
57 try:
58 import cartopy
59 cartopy.config.update(
60 {
61 "cache_dir" : pathlib.PosixPath("~/.local/share/cartopy_cache").expanduser(),
62 }
63 )
64 except:
65 raise Exception("\"cartopy\" is not installed; run \"pip install --user Cartopy\"") from None
66 try:
67 import matplotlib
68 matplotlib.rcParams.update(
69 {
70 "backend" : "Agg", # NOTE: See https://matplotlib.org/stable/gallery/user_interfaces/canvasagg.html
71 "figure.dpi" : 300,
72 "figure.figsize" : (9.6, 7.2), # NOTE: See https://github.com/Guymer/misc/blob/main/README.md#matplotlib-figure-sizes
73 "font.size" : 8,
74 }
75 )
76 except:
77 raise Exception("\"matplotlib\" is not installed; run \"pip install --user matplotlib\"") from None
79 # Import sub-functions ...
80 from .extract_polys import extract_polys
82 # **************************************************************************
84 # Create suitable colour ...
85 edgecolor = matplotlib.colors.to_rgba(matplotlib.colors.CSS4_COLORS["cornflowerblue"])
86 facecolor = matplotlib.colors.to_rgba(matplotlib.colors.CSS4_COLORS["aquamarine"])
87 if debug:
88 print(f"INFO: \"reefs\" is ({edgecolor[0]:.6f},{edgecolor[1]:.6f},{edgecolor[2]:.6f},{edgecolor[3]:.6f}) and ({facecolor[0]:.6f},{facecolor[1]:.6f},{facecolor[2]:.6f},{facecolor[3]:.6f}).")
90 # Find file containing the shapes ...
91 try:
92 sfile = cartopy.io.shapereader.natural_earth(
93 resolution = resolution,
94 category = "physical",
95 name = "reefs",
96 )
97 except urllib.error.HTTPError:
98 return
99 if debug:
100 print(f"INFO: \"reefs\" is \"{sfile}\".")
102 # Loop over records ...
103 for record in cartopy.io.shapereader.Reader(sfile).records():
104 # Skip bad records ...
105 if not hasattr(record, "geometry"):
106 continue
108 # Create a list of Polygons to plot (taking in to account if the user
109 # provided a field-of-view to clip them by) ...
110 polys = []
111 for poly in extract_polys(
112 record.geometry,
113 onlyValid = onlyValid,
114 repair = repair,
115 ):
116 if fov is None:
117 polys.append(poly)
118 continue
119 if poly.disjoint(fov):
120 continue
121 polys.append(poly.intersection(fov))
123 # Plot geometry ...
124 ax.add_geometries(
125 polys,
126 cartopy.crs.PlateCarree(),
127 edgecolor = edgecolor,
128 facecolor = facecolor,
129 linewidth = linewidth,
130 linestyle = linestyle,
131 )