Files
pygeoapi/pygeoapi/provider/speckle_utils/converter_utils.py
T
KatKatKateryna e2c123529d refactor
2024-08-20 23:25:26 +01:00

145 lines
5.0 KiB
Python

from typing import Dict, List
def assign_geometry(feature: Dict, f_base) -> ( List[List[List[float]]], List[List[None| List[int]]] ):
"""Assign geom type and convert object coords into flat lists of coordinates and schema."""
from specklepy.objects.geometry import Point, Line, Polyline, Curve, Mesh, Brep
from specklepy.objects.GIS.geometry import GisPolygonGeometry
from specklepy.objects.GIS.GisFeature import GisFeature
geometry = feature["geometry"]
coords = []
coord_counts = []
if isinstance(f_base, Point):
geometry["type"] = "MultiPoint"
coord_counts.append(None)
coords.append([f_base.x, f_base.y])
coord_counts.append([1])
elif isinstance(f_base, Mesh) or isinstance(f_base, Brep):
geometry["type"] = "MultiPolygon"
coord_counts.append(None) # as an indicator of a MultiPolygon
faces = []
vertices = []
if isinstance(f_base, Mesh):
faces = f_base.faces
vertices = f_base.vertices
elif isinstance(f_base, Brep):
if f_base.displayValue is None or (
isinstance(f_base.displayValue, list)
and len(f_base.displayValue) == 0
):
geometry = {}
return
elif isinstance(f_base.displayValue, list):
faces = f_base.displayValue[0].faces
vertices = f_base.displayValue[0].vertices
else:
faces = f_base.displayValue.faces
vertices = f_base.displayValue.vertices
count: int = 0
for i, pt_count in enumerate(faces):
if i != count:
continue
# old encoding
if pt_count == 0:
pt_count = 3
elif pt_count == 1:
pt_count = 4
coord_counts.append([pt_count])
for vertex_index in faces[count + 1 : count + 1 + pt_count]:
x = vertices[vertex_index * 3]
y = vertices[vertex_index * 3 + 1]
coords.append([x, y])
count += pt_count + 1
elif f_base.speckle_type.endswith(".GisFeature") and len(f_base["geometry"]) > 0: # isinstance(f_base, GisFeature) and len(f_base.geometry) > 0:
# GisFeature doesn't deserialize properly, need to check for speckle_type
if isinstance(f_base.geometry[0], Point):
geometry["type"] = "MultiPoint"
coord_counts.append(None)
for geom in f_base.geometry:
coords.append([geom.x, geom.y])
coord_counts.append([1])
elif isinstance(f_base.geometry[0], Polyline):
geometry["type"] = "MultiLineString"
coord_counts.append(None)
for geom in f_base.geometry:
coord_counts.append([])
local_poly_count = 0
for pt in geom.as_points():
coords.append([pt.x, pt.y])
local_poly_count += 1
if len(coords)>2 and geom.closed is True and coords[0] != coords[-1]:
coords.append(coords[0])
local_poly_count += 1
coord_counts[-1].append(local_poly_count)
elif isinstance(f_base.geometry[0], GisPolygonGeometry):
geometry["type"] = "MultiPolygon"
coord_counts.append(None)
for polygon in f_base.geometry:
coord_counts.append([])
boundary_count = 0
for pt in polygon.boundary.as_points():
coords.append([pt.x, pt.y])
boundary_count += 1
coord_counts[-1].append(boundary_count)
for void in polygon.voids:
void_count = 0
for pt_void in void.as_points():
coords.append([pt_void.x, pt_void.y])
void_count += 1
coord_counts[-1].append(void_count)
elif isinstance(f_base, Line):
geometry["type"] = "LineString"
start = [f_base.start.x, f_base.start.y]
end = [f_base.end.x, f_base.end.y]
coords.extend([start, end])
coord_counts.append([2])
elif isinstance(f_base, Polyline):
geometry["type"] = "LineString"
for pt in f_base.as_points():
coords.append([pt.x, pt.y])
if len(coords)>2 and f_base.closed is True and coords[0] != coords[-1]:
coords.append(coords[0])
coord_counts.append([len(coords)])
elif isinstance(f_base, Curve):
geometry["type"] = "LineString"
for pt in f_base.displayValue.as_points():
coords.append([pt.x, pt.y])
if len(coords)>2 and f_base.displayValue.closed is True and coords[0] != coords[-1]:
coords.append(coords[0])
coord_counts.append([len(coords)])
else:
geometry = {}
# print(f"Unsupported geometry type: {f_base.speckle_type}")
return coords, coord_counts