From 5a72d0866b1776f8e1006e0b8f20fc4a643527d3 Mon Sep 17 00:00:00 2001 From: Felicio Cassalho <1620665785113305@mil> Date: Tue, 3 Sep 2024 11:05:29 -0400 Subject: [PATCH 1/4] util functions for triangulating RiverMapper_00 --- ocsmesh/utils.py | 138 ++++++++++++++++++++++++++++++++++++++++- tests/api/utils.py | 7 +++ tests/data/rm_poly.cpg | 1 + tests/data/rm_poly.dbf | Bin 0 -> 306 bytes tests/data/rm_poly.prj | 1 + tests/data/rm_poly.qmd | 27 ++++++++ tests/data/rm_poly.shp | Bin 0 -> 4324 bytes tests/data/rm_poly.shx | Bin 0 -> 260 bytes 8 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 tests/data/rm_poly.cpg create mode 100644 tests/data/rm_poly.dbf create mode 100644 tests/data/rm_poly.prj create mode 100644 tests/data/rm_poly.qmd create mode 100644 tests/data/rm_poly.shp create mode 100644 tests/data/rm_poly.shx diff --git a/ocsmesh/utils.py b/ocsmesh/utils.py index a85e100..e1f1f8c 100644 --- a/ocsmesh/utils.py +++ b/ocsmesh/utils.py @@ -21,11 +21,12 @@ RectBivariateSpline, griddata) from scipy import sparse, constants from scipy.spatial import cKDTree +from shapely import difference from shapely.geometry import ( # type: ignore[import] Polygon, MultiPolygon, box, GeometryCollection, Point, MultiPoint, LineString, LinearRing) -from shapely.ops import polygonize, linemerge, unary_union +from shapely.ops import polygonize, linemerge, unary_union, triangulate import geopandas as gpd import pandas as pd import utm @@ -3579,3 +3580,138 @@ def batched(iterable, n): iterator = iter(iterable) while batch := tuple(islice(iterator, n)): yield batch + + +def delaunay_within(gdf): + ''' + Creates the initial delaunay triangules for + a gpd composed of polygons (only). + Selects those delaunay triangules that fall within domain. + + Parameters + ---------- + gdf : gpd of polygons + + Returns + ------- + gdf : gpd of triangulated polygons + + Notes + ----- + + ''' + + tt=[] + for polygon in gdf['geometry']: + try: + tri = [triangle for triangle in \ + triangulate(polygon) if triangle.within(polygon)] + tt.append(MultiPolygon(tri)) + except: + pass + shape_tri = gpd.GeoDataFrame(geometry=gpd.GeoSeries(tt)).set_crs(crs=4326) + shape_tri = shape_tri[~shape_tri.is_empty].dropna() + return shape_tri + + +def triangulate_shp(gdf): + ''' + Fills out the gaps left by the delaunay_within + + Parameters + ---------- + gdf : gpd of polygons + + Returns + ------- + gdf : gpd of triangulated polygons + + Notes + ----- + + ''' + + shape_tri = [delaunay_within(gdf)] + shape_diff = gpd.GeoDataFrame(geometry = + gpd.GeoSeries( + gdf.difference(shape_tri[0]))) + shape_diff = shape_diff[~shape_diff.is_empty].dropna()#.explode() + shape_diff_len = len(shape_diff) + while shape_diff_len>0: + print(shape_diff_len) + shape_diff_tri = delaunay_within(shape_diff) + shape_tri.append(shape_diff_tri) + shape_diff = gpd.GeoDataFrame(geometry= + gpd.GeoSeries(difference( + shape_diff.union_all(), + shape_diff_tri.union_all() + ))) + shape_diff = shape_diff[~shape_diff.is_empty].dropna().explode() + if len(shape_diff) == shape_diff_len: + break + shape_diff_len = len(shape_diff) + + shape_final = gpd.GeoDataFrame(pd.concat( + shape_tri, ignore_index=True)).explode() + shape_final = shape_final[shape_final.geometry.type == 'Polygon'] + shape_final.reset_index(drop=True, inplace=True) + + return shape_final + + +def shptri_to_msht(triangulated_shp): + ''' + Converts a triangulated shapefile to msh_t + + Parameters + ---------- + triangulated_shp : triangulated gpd + + Returns + ------- + jigsaw_msh_t + + Notes + ----- + + ''' + + coords = [] + verts = [] + for t in enumerate(triangulated_shp['geometry']): + if len(np.array(t[-1].boundary.xy).T) == 4: + coords.append(np.array(t[-1].boundary.xy).T[:-1]) + verts.append(np.array([0,1,2])+3*t[0]) + + msht = msht_from_numpy(coordinates = np.vstack(coords), + triangles = verts, + ) + cleanup_duplicates(msht) + cleanup_isolates(msht) + put_id_tags(msht) + + return msht + + +def triangulate_rivermapper_poly(rm_poly): + ''' + Creates triangulated mesh using the RiverMapperoutputs + + Parameters + ---------- + rm_poly : .shp (gpd) file with the RiverMapper outputs + + Returns + ------- + jigsaw_msh_t + River Mesh + + Notes + ----- + + ''' + + rm_poly = triangulate_shp(rm_poly) + rm_mesh = shptri_to_msht(rm_poly) + + return rm_mesh diff --git a/tests/api/utils.py b/tests/api/utils.py index 3211a7f..b6be88d 100644 --- a/tests/api/utils.py +++ b/tests/api/utils.py @@ -116,6 +116,13 @@ def test_clean_concv(self): class RiverMapper(unittest.TestCase): + def test_triangulate_rivermapper_poly(self): + p = Path(__file__).parents[1] / "data" / "rm_poly.shp" + rm_poly = gpd.read_file(p) + trias = utils.triangulate_rivermapper_poly(rm_poly) + + self.assertEqual(len(trias.tria3), 56) + def test_quadrangulate_rivermapper_arcs(self): p = Path(__file__).parents[1] / "data" / "diag_arcs_clipped.shp" arcs_shp = gpd.read_file(p) diff --git a/tests/data/rm_poly.cpg b/tests/data/rm_poly.cpg new file mode 100644 index 0000000..3ad133c --- /dev/null +++ b/tests/data/rm_poly.cpg @@ -0,0 +1 @@ +UTF-8 \ No newline at end of file diff --git a/tests/data/rm_poly.dbf b/tests/data/rm_poly.dbf new file mode 100644 index 0000000000000000000000000000000000000000..b321fae1de72d015b6de65c033f6683f5f24f25b GIT binary patch literal 306 zcmZXNF$#b%3`Gl_MBSX6Jc6}Ns-qx+izo8%Dq8!%49UwM-nU0#8)M9Ds%!se-If&Y yH@)YufnhJEBp$7gfqe!eR~2YXeasr literal 0 HcmV?d00001 diff --git a/tests/data/rm_poly.prj b/tests/data/rm_poly.prj new file mode 100644 index 0000000..f45cbad --- /dev/null +++ b/tests/data/rm_poly.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] \ No newline at end of file diff --git a/tests/data/rm_poly.qmd b/tests/data/rm_poly.qmd new file mode 100644 index 0000000..6d7a10d --- /dev/null +++ b/tests/data/rm_poly.qmd @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + +proj=longlat +datum=WGS84 +no_defs + 0 + 0 + + + + + false + + + + diff --git a/tests/data/rm_poly.shp b/tests/data/rm_poly.shp new file mode 100644 index 0000000000000000000000000000000000000000..e83defedad489ccf197e4ba02eeaff77d90e882b GIT binary patch literal 4324 zcmZ`-2~bsK6b3;b^4JoPO$>)X77fJ04DiQ=#6$-|i;xg)aRD(99~!uTlVLbh@d*NGnc+O&5jpVzF9TQD&%Q;EdI@m&-Z{M6-nlV|7=uY`7euahL&jU*y z1%>d#fi=j>zeD6rYE-rFIz?V9T&{_i<$ zE4S9>AA2qK+`L`p1hoh*vVM?%#Nuo?j~3(T9$Cj>0e9*<~2v}Il3xwHzQL)RhVfLR7k;2`x_b!dOA+fHh4_cNJe_)?G(s;gx?5l;}rOEj6t1a0TWOKb7KlRkfF+tug0{U>j z{@O{=aLir6f5&jp`S4O#u_DR9u92QYH{yx95nbBzYHY3cOe7BIKL?I?J9m2P*9nt`@(vw% zj{azh^jWgI%wOOf5J#HSbZP4cTrg|+Udn#wI(RIfL%>GP_@Iw#$#N7n^ zLsnLcG|Dad8+#&`O8)SH5ARoC{czADwvYOmp9^0PUdZ#1t(#M2Sud=Qu=f|-PuxxE z`p>-LGXxwYf6Ob+m(L$QpVXhd?j+||(yd;z2GX-N^M1daSDHf!TWiVYdO1Gk5ati= zm`m`ld--hh>LgE*?i2Rl63we2-MT!G1T(s{^|mvi^s^U!tys7q;=LH|; z5AO?LHLUwN&z;szX`8!N{(S{3z8-T3{lM+`^j5bW_xy!^#!sR9XFg?R$ec_GO>B%cSGXO_3-r%Y|E}2RQL_`19+oe;D-+QiTiVOY5N5= z&1)DOl>Nf_^7;oB`oqa|!PEnko0(UR7F?nJ@Q$6R$s*e;)-bV=Y_6B%^ZJJ_JV&3D z=3Y4WcDkqVOv|ggO#K4gh$pS1=sGNm?$3#Rb+yC+@3`=SZOzNb#Tz`b{O<$af1F>(g&oVD)OrnlSEBDwzs)WYq zd`Br^J&3zxmqYmgcH~XhrumdVo?o7Sj^AZnm}W?NpdWYi1N^3Wb)!a;e&hvtLOf}; zf?j;vqd%Yl9F=dM?b)yS!thdMS7tdc|iO>()pU< literal 0 HcmV?d00001 diff --git a/tests/data/rm_poly.shx b/tests/data/rm_poly.shx new file mode 100644 index 0000000000000000000000000000000000000000..fc194cfe19995e1a54266fb0d0005a4cefea04f8 GIT binary patch literal 260 zcmZQzQ0HR64w_ytGcfRjwI*v$6}ljP%H+BCjoH=5dQ<>00sueAPApvAB4{&1f+rLn2LaO36OpT z;WK+dDIg70&*}u>vo3 Date: Tue, 3 Sep 2024 11:10:35 -0400 Subject: [PATCH 2/4] Update utils.py --- ocsmesh/utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ocsmesh/utils.py b/ocsmesh/utils.py index e1f1f8c..e1e1b41 100644 --- a/ocsmesh/utils.py +++ b/ocsmesh/utils.py @@ -3638,7 +3638,6 @@ def triangulate_shp(gdf): shape_diff = shape_diff[~shape_diff.is_empty].dropna()#.explode() shape_diff_len = len(shape_diff) while shape_diff_len>0: - print(shape_diff_len) shape_diff_tri = delaunay_within(shape_diff) shape_tri.append(shape_diff_tri) shape_diff = gpd.GeoDataFrame(geometry= From 62cc7549ca9c6e565195880c883614fd46ca30da Mon Sep 17 00:00:00 2001 From: Felicio Cassalho <61760479+felicio93@users.noreply.github.com> Date: Tue, 3 Sep 2024 11:20:15 -0400 Subject: [PATCH 3/4] Update functional_test.yml changed: actions/upload-artifact@v2 to: actions/upload-artifact@v4 --- .github/workflows/functional_test.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/functional_test.yml b/.github/workflows/functional_test.yml index 36a001b..79a63a0 100644 --- a/.github/workflows/functional_test.yml +++ b/.github/workflows/functional_test.yml @@ -59,7 +59,7 @@ jobs: - name: 'Upload conda environment' if: runner.os != 'Windows' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: conda-environment-${{ matrix.python-version }} path: environment_py${{ matrix.python-version }}.yml @@ -68,7 +68,7 @@ jobs: - name: 'Upload test dem' if: runner.os != 'Windows' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: test-dem-${{ matrix.python-version }} path: /tmp/test_dem.tif @@ -81,7 +81,7 @@ jobs: - name: 'Upload Geom build results' if: runner.os != 'Windows' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: geom-build-results-${{ matrix.python-version }} path: test_shape @@ -94,7 +94,7 @@ jobs: - name: 'Upload Hfun build results' if: runner.os != 'Windows' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: hfun-build-results-${{ matrix.python-version }} path: test.2dm @@ -107,7 +107,7 @@ jobs: - name: 'Upload remesh results' if: runner.os != 'Windows' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: remesh-bydem-results-${{ matrix.python-version }} path: remeshed.2dm From e223d567130a67de519e959eaa0f4e146b0b8a4d Mon Sep 17 00:00:00 2001 From: Felicio Cassalho <61760479+felicio93@users.noreply.github.com> Date: Tue, 3 Sep 2024 11:23:05 -0400 Subject: [PATCH 4/4] Update functional_test_2.yml changed: actions/upload-artifact@v2 to: actions/upload-artifact@v4 --- .github/workflows/functional_test_2.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/functional_test_2.yml b/.github/workflows/functional_test_2.yml index 1f9dd49..2a9b5ea 100644 --- a/.github/workflows/functional_test_2.yml +++ b/.github/workflows/functional_test_2.yml @@ -60,7 +60,7 @@ jobs: - name: 'Upload test dem' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: test-dem-${{ matrix.python-version }} path: /tmp/test_dem.tif @@ -71,7 +71,7 @@ jobs: run: source tests/cli/build_geom.sh - name: 'Upload Geom build results' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: geom-build-results-${{ matrix.python-version }} path: test_shape @@ -82,7 +82,7 @@ jobs: run: source tests/cli/build_hfun.sh - name: 'Upload Hfun build results' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: hfun-build-results-${{ matrix.python-version }} path: test.2dm @@ -93,7 +93,7 @@ jobs: run: source tests/cli/remesh_by_dem.sh - name: 'Upload remesh results' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: remesh-bydem-results-${{ matrix.python-version }} path: remeshed.2dm