Skip to content

Commit

Permalink
Change _CRS class to make WKT canonical (#1597)
Browse files Browse the repository at this point in the history
* Refactor of _CRS class to make WKT canonical

* Finish work on making WKT canonical

Many test assertions needed update

* Accept {'init': 'EPSG:xxxx'}

Also removed commented code

* Restore previous rio-info behavior when there's an EPSG code

* Remove unneeded import

* Use from_proj4 in from_epsg

* Rewrite of _CRS to keep an OGRSpatialReferenceH (#1602)

* Rewrite of _CRS to keep an OGRSpatialReferenceH

Rewrite of CRS to use _CRS by composition, not inheritance

New OGRErr handling function exc_wrap_ogrerr

* Remove commented code

* Add back in the error stack check for ImportFromProj

Also fix up docstrings
  • Loading branch information
sgillies authored Jan 22, 2019
1 parent 96b4074 commit f934c34
Show file tree
Hide file tree
Showing 24 changed files with 756 additions and 437 deletions.
2 changes: 2 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Changes
Next
----

- The _CRS class has been refactored so that a WKT representation, rather than PROJ4 representation, is the canonical form.

- On entering a dataset context (DatasetBase.__enter__) a new anonymous GDAL
environment is created if needed and is entered. This makes `with
rasterio.open(...) as dataset:` roughly equivalent to `with
Expand Down
54 changes: 9 additions & 45 deletions rasterio/_base.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -262,56 +262,19 @@ cdef class DatasetBase(object):

def _handle_crswkt(self, wkt):
"""Return the GDAL dataset's stored CRS"""
cdef OGRSpatialReferenceH osr = NULL
cdef const char *auth_key = NULL
cdef const char *auth_val = NULL

if not wkt:
log.debug("No projection detected.")
return None

wkt_b = wkt.encode('utf-8')
cdef const char *wkt_c = wkt_b

try:

osr = exc_wrap_pointer(OSRNewSpatialReference(wkt_c))
log.debug("Got coordinate system")

retval = OSRAutoIdentifyEPSG(osr)

if retval > 0:
log.debug("Failed to auto identify EPSG: %d", retval)

else:
log.debug("Auto identified EPSG: %d", retval)

try:
auth_key = OSRGetAuthorityName(osr, NULL)
auth_val = OSRGetAuthorityCode(osr, NULL)

except CPLE_NotSupportedError as exc:
log.debug("{}".format(exc))

if auth_key != NULL and auth_val != NULL:
return CRS({'init': u'{}:{}'.format(auth_key.lower(), auth_val)})

# No dialect morphing, if the dataset was created using software
# "speaking" the Esri dialect, we will read Esri WKT.
if wkt:
return CRS.from_wkt(wkt)

except CPLE_BaseError as exc:
raise CRSError("{}".format(exc))

finally:
_safe_osr_release(osr)
else:
return CRS()

def read_crs(self):
"""Return the GDAL dataset's stored CRS"""
cdef const char *wkt_b = NULL

wkt_b = GDALGetProjectionRef(self._hds)
if wkt_b == NULL:
raise ValueError("Unexpected NULL spatial reference")
cdef const char *wkt_b = GDALGetProjectionRef(self.handle())
wkt = wkt_b
if wkt == NULL:
raise ValueError("Unexpected NULL spatial reference")
return self._handle_crswkt(wkt)

def read_transform(self):
Expand Down Expand Up @@ -1328,6 +1291,7 @@ cdef OGRSpatialReferenceH _osr_from_crs(object crs) except NULL:
if retval:
_safe_osr_release(osr)
raise CRSError("Invalid CRS: {!r}".format(crs))
exc_wrap_int(OSRMorphFromESRI(osr))
except CPLE_BaseError as exc:
_safe_osr_release(osr)
raise CRSError(str(exc))
Expand Down
8 changes: 8 additions & 0 deletions rasterio/_crs.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# _CRS class definition

include "gdal.pxi"


cdef class _CRS:

cdef OGRSpatialReferenceH _osr
Loading

0 comments on commit f934c34

Please sign in to comment.