Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cvfdutil): polygon area and centroid calculations now use shapely #2165

Merged
merged 5 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion autotest/test_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
from flopy.modflow import Modflow, ModflowDis
from flopy.utils import import_optional_dependency
from flopy.utils.crs import get_authority_crs
from flopy.utils.cvfdutil import gridlist_to_disv_gridprops, to_cvfd
from flopy.utils.cvfdutil import (
area_of_polygon,
centroid_of_polygon,
gridlist_to_disv_gridprops,
to_cvfd,
)
from flopy.utils.triangle import Triangle
from flopy.utils.voronoi import VoronoiGrid

Expand Down Expand Up @@ -946,6 +951,28 @@ def test_tocvfd3():
assert i == j, f"{i} not equal {j}"


@requires_pkg("shapely")
def test_area_centroid_polygon():
pts = [
(685053.450097303, 6295544.549730939),
(685055.8377391606, 6295545.167682521),
(685057.3028430222, 6295542.712221102),
(685055.3500302795, 6295540.907246565),
(685053.2040466429, 6295542.313082705),
(685053.450097303, 6295544.549730939),
]
xc, yc = centroid_of_polygon(pts)
result = np.array([xc, yc])
answer = np.array((685055.1035824707, 6295543.12059913))
assert np.allclose(
result, answer
), "cvfdutil centroid of polygon incorrect"
x, y = list(zip(*pts))
result = area_of_polygon(x, y)
answer = 11.228131838368032
assert np.allclose(result, answer), "cvfdutil area of polygon incorrect"


def test_unstructured_grid_shell():
# constructor with no arguments. incomplete shell should exist
g = UnstructuredGrid()
Expand Down
40 changes: 12 additions & 28 deletions flopy/utils/cvfdutil.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,22 @@
import numpy as np

from .utl_import import import_optional_dependency


def area_of_polygon(x, y):
"""Calculates the signed area of an arbitrary polygon given its vertices
https://stackoverflow.com/a/4682656/ (Joe Kington)
http://softsurfer.com/Archive/algorithm_0101/algorithm_0101.htm#2D%20Polygons
"""
area = 0.0
for i in range(-1, len(x) - 1):
area += x[i] * (y[i + 1] - y[i - 1])
return area / 2.0
shapely = import_optional_dependency("shapely")
from shapely.geometry import Polygon

pgon = Polygon(zip(x, y))
return pgon.area


def centroid_of_polygon(points):
"""
https://stackoverflow.com/a/14115494/ (mgamba)
"""
import itertools as IT

area = area_of_polygon(*zip(*points))
result_x = 0
result_y = 0
N = len(points)
points = IT.cycle(points)
x1, y1 = next(points)
for i in range(N):
x0, y0 = x1, y1
x1, y1 = next(points)
cross = (x0 * y1) - (x1 * y0)
result_x += (x0 + x1) * cross
result_y += (y0 + y1) * cross
result_x /= area * 6.0
result_y /= area * 6.0
return (result_x, result_y)
shapely = import_optional_dependency("shapely")
from shapely.geometry import Polygon

pgon = Polygon(points)
return pgon.centroid.x, pgon.centroid.y


class Point:
Expand Down
Loading