[docs]classGeometryError(Exception):"""Class reflecting errors when creating JuPedSim geometry objects."""def__init__(self,message)->None:"""Create GeometryError with the given message. Args: message: Error message """self.message=message
def_geometry_from_wkt(wkt_input:str)->Geometry:geometry_collection=Nonetry:wkt_type=shapely.from_wkt(wkt_input)exceptExceptionasexc:raiseGeometryError(f"Could not create geometry objects from the given WKT: "f"{wkt_input}. See following error message:\n{exc}")fromexcifisinstance(wkt_type,shapely.GeometryCollection):geometry_collection=wkt_typeelse:try:geometry_collection=shapely.GeometryCollection([wkt_type])exceptExceptionasexc:raiseGeometryError(f"Could not create a geometry collection from the given WKT: "f"{wkt_input}. See following error message:\n{exc}")fromexcpolygons=_polygons_from_geometry_collection(geometry_collection)returnGeometry(_internal_build_geometry(polygons))def_geometry_from_shapely(geometry_input:(shapely.Polygon|shapely.MultiPolygon|shapely.GeometryCollection|shapely.MultiPoint),)->Geometry:polygons=_polygons_from_geometry_collection(shapely.GeometryCollection([geometry_input]))returnGeometry(_internal_build_geometry(polygons))def_geometry_from_coordinates(coordinates:List[Tuple],*,excluded_areas:Optional[List[Tuple]]=None)->Geometry:polygon=shapely.Polygon(coordinates,holes=excluded_areas)returnGeometry(_internal_build_geometry([polygon]))def_polygons_from_geometry_collection(geometry_collection:shapely.GeometryCollection,)->List[shapely.Polygon]:def_polygons_from_multi_polygon(multi_polygon:shapely.MultiPolygon,)->List[shapely.Polygon]:result=[]forpolygoninmulti_polygon.geoms:result+=_polygons_from_polygon(polygon)returnresultdef_polygons_from_linear_ring(linear_ring:shapely.LinearRing,)->List[shapely.Polygon]:return_polygons_from_polygon(shapely.Polygon(linear_ring))def_polygons_from_polygon(polygon:shapely.Polygon,)->List[shapely.Polygon]:return[polygon]polygons=[]forgeoingeometry_collection.geoms:ifshapely.get_type_id(geo)==shapely.GeometryType.GEOMETRYCOLLECTION:polygons+=_polygons_from_geometry_collection(geo)elifshapely.get_type_id(geo)==shapely.GeometryType.MULTIPOLYGON:polygons+=_polygons_from_multi_polygon(geo)elifshapely.get_type_id(geo)==shapely.GeometryType.LINEARRING:polygons+=_polygons_from_linear_ring(geo)elifshapely.get_type_id(geo)==shapely.GeometryType.POLYGON:polygons+=_polygons_from_polygon(geo)else:raiseGeometryError(f"Unexpected geometry type found in GeometryCollection: "f"{geo.geom_type}. Only Polygon types are allowed.")returnpolygonsdef_internal_build_geometry(polygons:List[shapely.Polygon],)->py_jps.Geometry:geo_builder=py_jps.GeometryBuilder()forpolygoninpolygons:geo_builder.add_accessible_area(polygon.exterior.coords[:-1])forholeinpolygon.interiors:geo_builder.exclude_from_accessible_area(hole.coords[:-1])returngeo_builder.build()
[docs]defbuild_geometry(geometry:(list[tuple[float,float]]|shapely.GeometryCollection|shapely.Polygon|shapely.MultiPolygon|shapely.MultiPoint|str),**kwargs:Any,)->Geometry:"""Create a :class:`~jupedsim.geometry.Geometry` from different input representations. .. note :: The geometric data supplied need to form a single "simple" polygon with holes. In case the input contains multiple polygons this must hold true for the union of all polygons. Arguments: geometry: Data to create the geometry out of. Data may be supplied as: * list of 2d points describing the outer boundary, holes may be added with use of `excluded_areas` kw-argument * :class:`~shapely.GeometryCollection` consisting only out of :class:`Polygons <shapely.Polygon>`, :class:`MultiPolygons <shapely.MultiPolygon>` and :class:`MultiPoints <shapely.MultiPoint>` * :class:`~shapely.MultiPolygon` * :class:`~shapely.Polygon` * :class:`~shapely.MultiPoint` forming a "simple" polygon when points are interpreted as linear ring without repetition of the start/end point. * str with a valid Well Known Text. In this format the same WKT types as mentioned for the shapely types are supported: GEOMETRYCOLLETION, MULTIPOLYGON, POLYGON, MULTIPOINT. The same restrictions as mentioned for the shapely types apply. Keyword Arguments: excluded_areas: describes exclusions from the walkable area. Only use this argument if `geometry` was provided as list[tuple[float, float]]. """ifisinstance(geometry,str):return_geometry_from_wkt(geometry)elif(isinstance(geometry,shapely.GeometryCollection)orisinstance(geometry,shapely.Polygon)orisinstance(geometry,shapely.MultiPolygon)orisinstance(geometry,shapely.MultiPoint)):return_geometry_from_shapely(geometry)else:return_geometry_from_coordinates(geometry,excluded_areas=kwargs.get("excluded_areas"))