Skip to content

Commit

Permalink
Merge pull request #2225 from rcomer/contourf-paths
Browse files Browse the repository at this point in the history
FIX: contourf nested contours
  • Loading branch information
greglucas authored Aug 4, 2023
2 parents 3ff2b13 + 33530b3 commit 94ffd38
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
15 changes: 10 additions & 5 deletions lib/cartopy/mpl/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,20 @@ def path_to_geos(path, force_ccw=False):
geom = sgeom.LineString(path_verts)

# If geom is a Polygon and is contained within the last geom in
# collection, add it to its list of internal polygons, otherwise
# simply append it as a new external geom.
# collection, it usually needs to be an interior to that geom (e.g. a
# lake within a land mass). Sometimes there is a further geom within
# this interior (e.g. an island in a lake, or some instances of
# contours). This needs to be a new external geom in the collection.
if geom.is_empty:
pass
elif (len(collection) > 0 and
isinstance(collection[-1][0], sgeom.Polygon) and
isinstance(geom, sgeom.Polygon) and
collection[-1][0].contains(geom.exterior)):
collection[-1][1].append(geom.exterior)
if any(internal.contains(geom) for internal in collection[-1][1]):
collection.append((geom, []))
else:
collection[-1][1].append(geom)
elif isinstance(geom, sgeom.Point):
other_result_geoms.append(geom)
else:
Expand All @@ -188,8 +193,8 @@ def path_to_geos(path, force_ccw=False):
geom_collection = []
for external_geom, internal_polys in collection:
if internal_polys:
# XXX worry about islands within lakes
geom = sgeom.Polygon(external_geom.exterior, internal_polys)
exteriors = [geom.exterior for geom in internal_polys]
geom = sgeom.Polygon(external_geom.exterior, exteriors)
else:
geom = external_geom

Expand Down
16 changes: 16 additions & 0 deletions lib/cartopy/tests/mpl/test_patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,19 @@ def test_polygon_with_interior_and_singularity(self):
geoms = cpatch.path_to_geos(p)
assert [type(geom) for geom in geoms] == [sgeom.Polygon, sgeom.Point]
assert len(geoms[0].interiors) == 1

def test_nested_polygons(self):
# A geometry with three nested squares.
vertices = [[0, 0], [0, 10], [10, 10], [10, 0], [0, 0],
[2, 2], [2, 8], [8, 8], [8, 2], [2, 2],
[4, 4], [4, 6], [6, 6], [6, 4], [4, 4]]
codes = [1, 2, 2, 2, 79, 1, 2, 2, 2, 79, 1, 2, 2, 2, 79]
p = Path(vertices, codes=codes)
geoms = cpatch.path_to_geos(p)

# The first square makes the first geometry with the second square as
# its interior. The third square is its own geometry with no interior.
assert len(geoms) == 2
assert all(type(geom) == sgeom.Polygon for geom in geoms)
assert len(geoms[0].interiors) == 1
assert len(geoms[1].interiors) == 0

0 comments on commit 94ffd38

Please sign in to comment.