Skip to content

Commit

Permalink
Use default contourpy algortihm
Browse files Browse the repository at this point in the history
Instead of legacy mpl2014, which is not supported anymore. Seems this
solves some issues and remove the need for clipPath step.
  • Loading branch information
agrenott committed Mar 5, 2023
1 parent 045c6cc commit 8fc9edd
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 72 deletions.
69 changes: 1 addition & 68 deletions phyghtmap/hgt.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,62 +290,6 @@ def _cutBeginning(self, p):
else:
return self._cutBeginning(p[1:])

def clipPath(self, path: List[numpy.typing.ArrayLike]):
"""clips a path with self.polygon and returns a list of
clipped paths. This method also removes consecutive identical nodes.
This method also does a potentially needed transformation of the projection.
"""
# do the transform if necessary
if self.transform != None:
path = numpy.array(self.transform(path))
if numpy.where(path != path, 1, 0).sum() != 0:
pathContainsNans = True
else:
pathContainsNans = False
if not pathContainsNans:
tmpList = []
for ind, p in enumerate(path):
if ind != 0:
op = path[ind - 1]
if numpy.all(p == op):
continue
tmpList.append(p)
if len(tmpList) < 2:
tmpList = []
return [
numpy.array(tmpList),
]
# path contains nans (from a polygon or void area or both)
pathList = []
tmpList = []
for ind, p in enumerate(path):
if ind != 0:
op = path[ind - 1]
if numpy.all(p == op):
# skip the rest if there are two consecutive identical nodes
continue
x, y = p
if not False in [x == x, y == y]:
# (x, y) inside polygon. We know this because x or y would else be
# nan since data outside the polygon is masked and filled with nans
# and the resulting nodes' coordinates are (nan, nan).
tmpList.append((x, y))
elif len(tmpList) > 0:
# (x, y) outside polygon, non-empty tmpList
if len(tmpList) > 1:
# if tmpList has only one node, this is not a meaningful path and we
# don't want to evaluate it then
pathList.append(numpy.array(tmpList))
tmpList = []
else:
# (x, y) outside polygon, previous (x, y) dto.
continue
else:
if len(tmpList) > 1:
# only append this last piece if it has more than one node
pathList.append(numpy.array(tmpList))
return pathList

def splitList(self, l):
"""splits a path to contain not more than self.maxNodesPerWay nodes.
Expand Down Expand Up @@ -465,17 +409,8 @@ def trace(self, elevation, **kwargs):
# Keep only the first element of the tuple, ignoring matplot line code
rawPaths: List[numpy.typing.ArrayLike] = self.Cntr.create_contour(elevation)[0]
numOfPaths, numOfNodes = 0, 0
intermediatePaths = []
# matplotlib 2.0.0 or higher should actually handle masks correctly.
# However, for some reason not yet investigated further, masked values
# are handled anyways. The otherwise applicable code would have been
# intermediatePaths = rawPaths
# As a workaround, we stick to the old behaviour which handles masked
# values explicitly in the generated contour data
for path in rawPaths:
intermediatePaths.extend(self.clipPath(path))
resultPaths = []
for path in intermediatePaths:
for path in rawPaths:
path = self.simplifyPath(path)
splitPaths, numOfNodesAdd, numOfPathsAdd = self.splitList(path)
resultPaths.extend(splitPaths)
Expand Down Expand Up @@ -971,8 +906,6 @@ def getContLimit(ele: int, step: int) -> int:
x,
y,
z,
# TODO: try using newer "serial" algorithm
name="mpl2014",
corner_mask=corner_mask,
chunk_size=nchunk,
line_type=contourpy.LineType.SeparateCode,
Expand Down
Binary file modified tests/data/toulon_ref.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 8 additions & 4 deletions tests/test_hgt.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from phyghtmap import hgt

TEST_DATA_PATH = os.path.join(os.path.dirname(os.path.relpath(__file__)), "data")
HGT_SIZE: int = 1201


@pytest.fixture
Expand All @@ -29,8 +30,8 @@ def test_contourLines(toulon_tiles: List[hgt.hgtTile]) -> None:
assert contour_data
# Get the countours for 20m elevation
contour_list_20 = contour_data.trace(20)[0]
assert len(contour_list_20) == 102
assert len(contour_list_20[0]) == 6618
assert len(contour_list_20) == 145
assert len(contour_list_20[0]) == 5

# Get the countours for 1920m elevation
contour_list_1920 = contour_data.trace(1920)[0]
Expand All @@ -40,13 +41,13 @@ def test_contourLines(toulon_tiles: List[hgt.hgtTile]) -> None:
contour_list_1920[0],
numpy.array(
[
[6.63732143, 43.89583333],
[6.6375, 43.89591954],
[6.63833333, 43.89583333],
[6.63777778, 43.895],
[6.6375, 43.8948913],
[6.63714286, 43.895],
[6.63732143, 43.89583333],
[6.6375, 43.89591954],
]
),
)
Expand All @@ -59,7 +60,10 @@ def test_draw_contours_Toulon(toulon_tiles: List[hgt.hgtTile]) -> plt.Figure:
To compare output, run `pytest --mpl`
"""
elevations, contour_data = toulon_tiles[0].contourLines()
fig = plt.figure()
dpi = 100
# Add some space for axises, while trying to get graph space close to original data size
out_size = HGT_SIZE + 300
fig = plt.figure(figsize=(out_size / dpi, out_size / dpi), dpi=dpi)
for elev in range(0, 500, 100):
for contour in contour_data.trace(elev)[0]:
x, y = zip(*contour)
Expand Down

0 comments on commit 8fc9edd

Please sign in to comment.