Skip to content

Commit ae23de3

Browse files
remove dependency on shapefile package. Use fiona and shapely instead.
1 parent 4e1de05 commit ae23de3

1 file changed

Lines changed: 54 additions & 36 deletions

File tree

schimpy/mesh_volume_tvd.py

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -607,37 +607,47 @@ def _write_perimeter_shapefile(
607607
"""
608608
Write 2D polyline Shapefile (.shp + .shx + .dbf, and .prj if EPSG given) for perimeter edges.
609609
"""
610-
try:
611-
import shapefile # pyshp
612-
except Exception:
613-
raise SystemExit(
614-
"Writing shapefile requires pyshp. Install with: pip install pyshp"
615-
)
610+
616611
xs, ys = mesh.nodes[:, 0], mesh.nodes[:, 1]
617612
node_depth = mesh.nodes[:, 2].astype(float)
618613
edge_mean_d = _edge_mean_depth(mesh, node_depth)
619614
if not path.lower().endswith(".shp"):
620615
path += ".shp"
621-
w = shapefile.Writer(path, shapeType=shapefile.POLYLINE)
622-
w.field("edge_id", "N", 10, 0)
623-
w.field("n1", "N", 10, 0)
624-
w.field("n2", "N", 10, 0)
625-
w.field("label", "C", 16)
626-
w.field("depth_mean", "F", 18, 6)
627-
for eidx, lab in labels.items():
628-
n1, n2 = int(mesh.edges[eidx, 0]), int(mesh.edges[eidx, 1])
629-
w.line([[(float(xs[n1]), float(ys[n1])), (float(xs[n2]), float(ys[n2]))]])
630-
w.record(int(eidx), n1, n2, str(lab), float(edge_mean_d[eidx]))
631-
w.close()
616+
schema = {
617+
"geometry": "LineString",
618+
"properties": {
619+
"edge_id": "int",
620+
"n1": "int",
621+
"n2": "int",
622+
"label": "str",
623+
"depth_mean": "float",
624+
},
625+
}
632626
if epsg is not None:
633627
try:
634628
from pyproj import CRS
635629

636630
wkt = CRS.from_epsg(int(epsg)).to_wkt()
637631
except Exception:
638632
wkt = ""
639-
with open(path[:-4] + ".prj", "w") as prj:
640-
prj.write(wkt)
633+
with fiona.open(path, "w", driver="ESRI Shapefile", schema=schema, crs=wkt) as shp:
634+
for eidx, lab in labels.items():
635+
n1, n2 = int(mesh.edges[eidx, 0]), int(mesh.edges[eidx, 1])
636+
geom = LineString(
637+
[[(float(xs[n1]), float(ys[n1])), (float(xs[n2]), float(ys[n2]))]]
638+
)
639+
shp.write(
640+
{
641+
"geometry": mapping(geom),
642+
"properties": {
643+
"edge_id": int(eidx),
644+
"n1": n1,
645+
"n2": n2,
646+
"label": str(lab),
647+
"depth_mean": float(edge_mean_d[eidx]),
648+
},
649+
}
650+
)
641651

642652

643653
# ------------------------ Merging + Visualization -----------------------------
@@ -755,31 +765,40 @@ def _merged_polylines_and_node_rows(mesh, labels_all: Dict[int, str]):
755765

756766

757767
def _write_merged_shapefile(polylines, path: str, epsg: int = None):
758-
try:
759-
import shapefile # pyshp
760-
except Exception:
761-
raise SystemExit(
762-
"Writing shapefile requires pyshp. Install with: pip install pyshp"
763-
)
764768
if not path.lower().endswith(".shp"):
765769
path += ".shp"
766-
w = shapefile.Writer(path, shapeType=shapefile.POLYLINE)
767-
w.field("poly_id", "N", 10, 0)
768-
w.field("label", "C", 16)
769-
for p in polylines:
770-
w.line([[(float(x), float(y)) for (x, y) in p["coords"]]])
771-
w.record(int(p["poly_id"]), str(p["label"]))
772-
w.close()
773-
# .prj
770+
771+
schema = {
772+
"geometry": "LineString",
773+
"properties": {
774+
"edge_id": "int",
775+
"n1": "int",
776+
"n2": "int",
777+
"label": "str",
778+
"depth_mean": "float",
779+
},
780+
}
774781
if epsg is not None:
775782
try:
776783
from pyproj import CRS
777784

778785
wkt = CRS.from_epsg(int(epsg)).to_wkt()
779786
except Exception:
780787
wkt = ""
781-
with open(path[:-4] + ".prj", "w") as prj:
782-
prj.write(wkt)
788+
with fiona.open(path, "w", driver="ESRI Shapefile", schema=schema, crs=wkt) as shp:
789+
w.field("poly_id", "N", 10, 0)
790+
w.field("label", "C", 16)
791+
for p in polylines:
792+
geom = LineString([[(float(x), float(y)) for (x, y) in p["coords"]]])
793+
shp.write(
794+
{
795+
"geometry": mapping(geom),
796+
"properties": {
797+
"poly_id": int(p["poly_id"]),
798+
"label": str(p["label"]),
799+
},
800+
}
801+
)
783802

784803

785804
def _write_nodes_csv(node_rows, path: str, epsg: int = None):
@@ -816,7 +835,6 @@ def _plot_profiles(
816835
window: int = 5,
817836
):
818837

819-
820838
rows_by_node = {int(r["node"]): r for r in node_rows}
821839
for p in polylines:
822840
pid = int(p["poly_id"])

0 commit comments

Comments
 (0)