-
Notifications
You must be signed in to change notification settings - Fork 202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add shim module and support for GDAL 3 #804
Changes from 1 commit
08e1e01
48d51e1
4b4c368
a010a3e
ac9c97f
aee61f8
3386560
58454a0
84e829a
4a6dfcd
062c465
0e30757
bc037e2
20ecc7b
c45aa28
e34fbd8
7371b7d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,8 @@ cdef OGRFieldSubType get_field_subtype(void *fielddefn) | |
cdef void set_field_subtype(void *fielddefn, OGRFieldSubType subtype) | ||
cdef bint check_capability_create_layer(void *cogr_ds) | ||
cdef void *get_linear_geometry(void *geom) | ||
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function is copied from rasterio. It isn't called in fiona yet, but it will be in a future version as we change our modules to be more like those in rasterio. Therefore, I'm going to leave it in. |
||
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs) | ||
|
||
from fiona._shim cimport OGR_F_GetFieldAsInteger as OGR_F_GetFieldAsInteger64 | ||
from fiona._shim cimport OGR_F_SetFieldInteger as OGR_F_SetFieldInteger64 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
include "ogrext3.pxd" | ||
|
||
cdef bint is_field_null(void *feature, int n) | ||
cdef void set_field_null(void *feature, int n) | ||
cdef void gdal_flush_cache(void *cogr_ds) | ||
cdef void* gdal_open_vector(const char *path_c, int mode, drivers, options) except NULL | ||
cdef void* gdal_create(void* cogr_driver, const char *path_c, options) except NULL | ||
cdef OGRErr gdal_start_transaction(void *cogr_ds, int force) | ||
cdef OGRErr gdal_commit_transaction(void *cogr_ds) | ||
cdef OGRErr gdal_rollback_transaction(void *cogr_ds) | ||
cdef OGRFieldSubType get_field_subtype(void *fielddefn) | ||
cdef void set_field_subtype(void *fielddefn, OGRFieldSubType subtype) | ||
cdef bint check_capability_create_layer(void *cogr_ds) | ||
cdef void *get_linear_geometry(void *geom) | ||
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs) | ||
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
"""Shims on top of ogrext for GDAL versions >= 2.2""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. >= 3.0 |
||
|
||
cdef extern from "ogr_api.h": | ||
|
||
int OGR_F_IsFieldNull(void *feature, int n) | ||
|
||
|
||
cdef extern from "ogr_srs_api.h" nogil: | ||
|
||
ctypedef enum OSRAxisMappingStrategy: | ||
OAMS_TRADITIONAL_GIS_ORDER | ||
|
||
const char* OSRGetName(OGRSpatialReferenceH hSRS) | ||
void OSRSetAxisMappingStrategy(OGRSpatialReferenceH hSRS, OSRAxisMappingStrategy) | ||
|
||
|
||
from fiona.ogrext2 cimport * | ||
from fiona._err cimport exc_wrap_pointer | ||
from fiona._err import cpl_errs, CPLE_BaseError, FionaNullPointerError | ||
from fiona.errors import DriverError | ||
|
||
import logging | ||
|
||
|
||
log = logging.getLogger(__name__) | ||
|
||
|
||
cdef bint is_field_null(void *feature, int n): | ||
if OGR_F_IsFieldNull(feature, n): | ||
return True | ||
elif not OGR_F_IsFieldSet(feature, n): | ||
return True | ||
else: | ||
return False | ||
|
||
|
||
cdef void set_field_null(void *feature, int n): | ||
OGR_F_SetFieldNull(feature, n) | ||
|
||
|
||
cdef void gdal_flush_cache(void *cogr_ds): | ||
with cpl_errs: | ||
GDALFlushCache(cogr_ds) | ||
|
||
|
||
cdef void* gdal_open_vector(char* path_c, int mode, drivers, options) except NULL: | ||
cdef void* cogr_ds = NULL | ||
cdef char **drvs = NULL | ||
cdef void* drv = NULL | ||
cdef char **open_opts = NULL | ||
|
||
flags = GDAL_OF_VECTOR | GDAL_OF_VERBOSE_ERROR | ||
if mode == 1: | ||
flags |= GDAL_OF_UPDATE | ||
else: | ||
flags |= GDAL_OF_READONLY | ||
|
||
if drivers: | ||
for name in drivers: | ||
name_b = name.encode() | ||
name_c = name_b | ||
drv = GDALGetDriverByName(name_c) | ||
if drv != NULL: | ||
drvs = CSLAddString(drvs, name_c) | ||
|
||
for k, v in options.items(): | ||
|
||
if v is None: | ||
continue | ||
|
||
k = k.upper().encode('utf-8') | ||
if isinstance(v, bool): | ||
v = ('ON' if v else 'OFF').encode('utf-8') | ||
else: | ||
v = str(v).encode('utf-8') | ||
log.debug("Set option %r: %r", k, v) | ||
open_opts = CSLAddNameValue(open_opts, <const char *>k, <const char *>v) | ||
|
||
open_opts = CSLAddNameValue(open_opts, "VALIDATE_OPEN_OPTIONS", "NO") | ||
|
||
try: | ||
cogr_ds = exc_wrap_pointer( | ||
GDALOpenEx(path_c, flags, <const char *const *>drvs, open_opts, NULL) | ||
) | ||
return cogr_ds | ||
except FionaNullPointerError: | ||
raise DriverError("Failed to open dataset (mode={}): {}".format(mode, path_c.decode("utf-8"))) | ||
except CPLE_BaseError as exc: | ||
raise DriverError(str(exc)) | ||
finally: | ||
CSLDestroy(drvs) | ||
CSLDestroy(open_opts) | ||
|
||
|
||
cdef void* gdal_create(void* cogr_driver, const char *path_c, options) except NULL: | ||
cdef char **creation_opts = NULL | ||
cdef void *cogr_ds = NULL | ||
|
||
for k, v in options.items(): | ||
k = k.upper().encode('utf-8') | ||
if isinstance(v, bool): | ||
v = ('ON' if v else 'OFF').encode('utf-8') | ||
else: | ||
v = str(v).encode('utf-8') | ||
log.debug("Set option %r: %r", k, v) | ||
creation_opts = CSLAddNameValue(creation_opts, <const char *>k, <const char *>v) | ||
|
||
try: | ||
return exc_wrap_pointer(GDALCreate(cogr_driver, path_c, 0, 0, 0, GDT_Unknown, creation_opts)) | ||
except FionaNullPointerError: | ||
raise DriverError("Failed to create dataset: {}".format(path_c.decode("utf-8"))) | ||
except CPLE_BaseError as exc: | ||
raise DriverError(str(exc)) | ||
finally: | ||
CSLDestroy(creation_opts) | ||
|
||
|
||
cdef OGRErr gdal_start_transaction(void* cogr_ds, int force): | ||
return GDALDatasetStartTransaction(cogr_ds, force) | ||
|
||
|
||
cdef OGRErr gdal_commit_transaction(void* cogr_ds): | ||
return GDALDatasetCommitTransaction(cogr_ds) | ||
|
||
|
||
cdef OGRErr gdal_rollback_transaction(void* cogr_ds): | ||
return GDALDatasetRollbackTransaction(cogr_ds) | ||
|
||
|
||
cdef OGRFieldSubType get_field_subtype(void *fielddefn): | ||
return OGR_Fld_GetSubType(fielddefn) | ||
|
||
|
||
cdef void set_field_subtype(void *fielddefn, OGRFieldSubType subtype): | ||
OGR_Fld_SetSubType(fielddefn, subtype) | ||
|
||
|
||
cdef bint check_capability_create_layer(void *cogr_ds): | ||
return GDALDatasetTestCapability(cogr_ds, ODsCCreateLayer) | ||
|
||
|
||
cdef void *get_linear_geometry(void *geom): | ||
return OGR_G_GetLinearGeometry(geom, 0.0, NULL) | ||
|
||
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs): | ||
return OSRGetName(hSrs) | ||
|
||
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs): | ||
OSRSetAxisMappingStrategy(hSrs, OAMS_TRADITIONAL_GIS_ORDER) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this OSRFixup call should be still used in GDAL < 3.0. Supporting both version scenarios is probably complicated, however.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you see any harm in having osr_set_traditional_axis_mapping_strategy call OSRFixup for GDAL versions 1 and 2 @hobu ? That's one way to bring it back in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No harm, but that's not quite where you want it. You want it right after any ImportFromWkt-type calls happen where the input might be ESRI content.