-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #325 from koordinates/import-fix
Better type adaption / validation on OGR import.
- Loading branch information
Showing
3 changed files
with
78 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,88 @@ | ||
from osgeo import ogr | ||
from decimal import Decimal | ||
|
||
|
||
def adapt_value_noop(value): | ||
return value | ||
from .geometry import ogr_to_gpkg_geom | ||
|
||
|
||
def adapt_ogr_date(value): | ||
if value is None: | ||
return value | ||
# OGR uses this strange format: '2012/07/09' | ||
# We convert back to a normal ISO8601 format. | ||
return value.replace("/", "-") | ||
return str(value).replace("/", "-") | ||
|
||
|
||
def adapt_ogr_datetime(value): | ||
def adapt_ogr_timestamp(value): | ||
if value is None: | ||
return value | ||
# OGR uses this strange format: '2012/07/09 09:01:52+00' | ||
# We convert back to a normal ISO8601 format. | ||
return value.replace("/", "-").replace(" ", "T").replace("+00", "Z") | ||
return str(value).replace("/", "-").replace(" ", "T").replace("+00", "Z") | ||
|
||
|
||
def adapt_ogr_numeric(value): | ||
if value is None: | ||
return value | ||
return str(Decimal(value)) | ||
|
||
|
||
def adapt_ogr_geometry(value): | ||
if value is None: | ||
return value | ||
return ogr_to_gpkg_geom(value) | ||
|
||
|
||
def ensure_bool(value): | ||
if value is not None and not isinstance(value, bool): | ||
raise ValueError(f"Expected boolean but found {value!r}") | ||
return value | ||
|
||
|
||
def ensure_bytes(value): | ||
if value is not None and not isinstance(value, bytes): | ||
raise ValueError(f"Expected bytes but found {value!r}") | ||
return value | ||
|
||
|
||
def ensure_int(value): | ||
return int(value) if value is not None else None | ||
|
||
|
||
def ensure_float(value): | ||
return float(value) if value is not None else None | ||
|
||
|
||
def ensure_str(value): | ||
if value is not None and not isinstance(value, str): | ||
raise ValueError(f"Expected str but found {value!r}") | ||
return value | ||
|
||
|
||
def adapt_to_str(value): | ||
# These types aren't supported by OGR | ||
return str(value) if value is not None else None | ||
|
||
|
||
OGR_TYPE_ADAPTERS = { | ||
"boolean": ensure_bool, | ||
"blob": ensure_bytes, | ||
"date": adapt_ogr_date, | ||
"float": ensure_float, | ||
"geometry": adapt_ogr_geometry, | ||
"integer": ensure_int, | ||
"interval": adapt_to_str, | ||
"numeric": adapt_ogr_numeric, | ||
"text": ensure_str, | ||
"time": adapt_to_str, | ||
"timestamp": adapt_ogr_timestamp, | ||
} | ||
|
||
|
||
def get_type_value_adapter(ogr_type): | ||
def get_type_value_adapter(v2_type): | ||
""" | ||
Returns a function which will convert values of the given OGR type | ||
into a more-sensible value. | ||
Returns a function which will convert values to the given V2 type | ||
from the equivalent OGR type. | ||
For most types this is a noop. | ||
For most types this should be a no-op, but we try to be defensive and ensure that | ||
(for instance) floats stay floats and ints stay ints. | ||
""" | ||
if ogr_type == ogr.OFTDate: | ||
return adapt_ogr_date | ||
elif ogr_type == ogr.OFTDateTime: | ||
return adapt_ogr_datetime | ||
return adapt_value_noop | ||
return OGR_TYPE_ADAPTERS[v2_type] |