129 lines
4.0 KiB
Cython
129 lines
4.0 KiB
Cython
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] |