import warnings from pyogrio._ogr cimport * from pyogrio._err cimport * from pyogrio._err import CPLE_BaseError, NullPointerError from pyogrio.errors import DataLayerError, GeometryError # Mapping of OGR integer geometry types to GeoJSON type names. GEOMETRY_TYPES = { wkbUnknown: 'Unknown', wkbPoint: 'Point', wkbLineString: 'LineString', wkbPolygon: 'Polygon', wkbMultiPoint: 'MultiPoint', wkbMultiLineString: 'MultiLineString', wkbMultiPolygon: 'MultiPolygon', wkbGeometryCollection: 'GeometryCollection', wkbNone: None, wkbLinearRing: 'LinearRing', # WARNING: Measured types are not supported in GEOS and downstream uses # these are stripped automatically to their corresponding 2D / 3D types wkbPointM: 'PointM', wkbLineStringM: 'Measured LineString', wkbPolygonM: 'Measured Polygon', wkbMultiPointM: 'Measured MultiPoint', wkbMultiLineStringM: 'Measured MultiLineString', wkbMultiPolygonM: 'Measured MultiPolygon', wkbGeometryCollectionM: 'Measured GeometryCollection', wkbPointZM: 'Measured 3D Point', wkbLineStringZM: 'Measured 3D LineString', wkbPolygonZM: 'Measured 3D Polygon', wkbMultiPointZM: 'Measured 3D MultiPoint', wkbMultiLineStringZM: 'Measured 3D MultiLineString', wkbMultiPolygonZM: 'Measured 3D MultiPolygon', wkbGeometryCollectionZM: 'Measured 3D GeometryCollection', wkbPoint25D: 'Point Z', wkbLineString25D: 'LineString Z', wkbPolygon25D: 'Polygon Z', wkbMultiPoint25D: 'MultiPoint Z', wkbMultiLineString25D: 'MultiLineString Z', wkbMultiPolygon25D: 'MultiPolygon Z', wkbGeometryCollection25D: 'GeometryCollection Z', } GEOMETRY_TYPE_CODES = {v:k for k, v in GEOMETRY_TYPES.items()} # add additional aliases from 2.5D format GEOMETRY_TYPE_CODES.update({ '2.5D Point': wkbPoint25D, '2.5D LineString': wkbLineString25D, '2.5D Polygon': wkbPolygon25D, '2.5D MultiPoint': wkbMultiPoint25D, '2.5D MultiLineString': wkbMultiLineString25D, '2.5D MultiPolygon': wkbMultiPolygon25D, '2.5D GeometryCollection': wkbGeometryCollection25D }) # 2.5D also represented using negative numbers not enumerated above GEOMETRY_TYPES.update({ -2147483647: 'Point Z', -2147483646: 'LineString Z', -2147483645: 'Polygon Z', -2147483644: 'MultiPoint Z', -2147483643: 'MultiLineString Z', -2147483642: 'MultiPolygon Z', -2147483641: 'GeometryCollection Z', }) cdef str get_geometry_type(void *ogr_layer): """Get geometry type for layer. Parameters ---------- ogr_layer : pointer to open OGR layer Returns ------- str geometry type """ cdef void *cogr_featuredef = NULL cdef OGRwkbGeometryType ogr_type try: ogr_featuredef = exc_wrap_pointer(OGR_L_GetLayerDefn(ogr_layer)) except NullPointerError: raise DataLayerError("Could not get layer definition") except CPLE_BaseError as exc: raise DataLayerError(str(exc)) ogr_type = OGR_FD_GetGeomType(ogr_featuredef) if ogr_type not in GEOMETRY_TYPES: raise GeometryError(f"Geometry type is not supported: {ogr_type}") if OGR_GT_HasM(ogr_type): original_type = GEOMETRY_TYPES[ogr_type] # Downgrade the type to 2D / 3D ogr_type = OGR_GT_SetModifier(ogr_type, OGR_GT_HasZ(ogr_type), 0) # TODO: review; this might be annoying... warnings.warn( "Measured (M) geometry types are not supported. " f"Original type '{original_type}' " f"is converted to '{GEOMETRY_TYPES[ogr_type]}'") return GEOMETRY_TYPES[ogr_type] cdef OGRwkbGeometryType get_geometry_type_code(str geometry_type) except *: """Get geometry type code for string geometry type. Parameters ---------- geometry_type : str Returns ------- int geometry type code """ if geometry_type not in GEOMETRY_TYPE_CODES: raise GeometryError(f"Geometry type is not supported: {geometry_type}") return GEOMETRY_TYPE_CODES[geometry_type]