mirror of
https://github.com/rasterio/rasterio.git
synced 2025-12-08 17:36:12 +00:00
REF: Replace usage of _osr_from_crs with CRS.from_user_input (#2488)
This commit is contained in:
parent
3b325cec04
commit
d0ba302486
@ -32,7 +32,6 @@ cdef class DatasetBase:
|
|||||||
|
|
||||||
|
|
||||||
cdef const char *get_driver_name(GDALDriverH driver)
|
cdef const char *get_driver_name(GDALDriverH driver)
|
||||||
cdef OGRSpatialReferenceH _osr_from_crs(object crs) except NULL
|
|
||||||
cdef _safe_osr_release(OGRSpatialReferenceH srs)
|
|
||||||
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs)
|
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs)
|
||||||
cdef GDALDatasetH open_dataset(object filename, int mode, object allowed_drivers, object open_options, object siblings) except NULL
|
cdef GDALDatasetH open_dataset(object filename, int mode, object allowed_drivers, object open_options, object siblings) except NULL
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import os
|
|||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from libc.string cimport strncmp
|
from libc.string cimport strncmp
|
||||||
|
from rasterio.crs cimport CRS
|
||||||
|
|
||||||
from rasterio._err import (
|
from rasterio._err import (
|
||||||
GDALError, CPLE_BaseError, CPLE_IllegalArgError, CPLE_OpenFailedError,
|
GDALError, CPLE_BaseError, CPLE_IllegalArgError, CPLE_OpenFailedError,
|
||||||
@ -1454,16 +1455,14 @@ def _transform(src_crs, dst_crs, xs, ys, zs):
|
|||||||
cdef double *x = NULL
|
cdef double *x = NULL
|
||||||
cdef double *y = NULL
|
cdef double *y = NULL
|
||||||
cdef double *z = NULL
|
cdef double *z = NULL
|
||||||
cdef OGRSpatialReferenceH src = NULL
|
|
||||||
cdef OGRSpatialReferenceH dst = NULL
|
|
||||||
cdef OGRCoordinateTransformationH transform = NULL
|
cdef OGRCoordinateTransformationH transform = NULL
|
||||||
cdef int i
|
cdef int i
|
||||||
|
|
||||||
assert len(xs) == len(ys)
|
assert len(xs) == len(ys)
|
||||||
assert zs is None or len(xs) == len(zs)
|
assert zs is None or len(xs) == len(zs)
|
||||||
|
|
||||||
src = _osr_from_crs(src_crs)
|
cdef CRS src = CRS.from_user_input(src_crs)
|
||||||
dst = _osr_from_crs(dst_crs)
|
cdef CRS dst = CRS.from_user_input(dst_crs)
|
||||||
|
|
||||||
n = len(xs)
|
n = len(xs)
|
||||||
x = <double *>CPLMalloc(n*sizeof(double))
|
x = <double *>CPLMalloc(n*sizeof(double))
|
||||||
@ -1478,7 +1477,7 @@ def _transform(src_crs, dst_crs, xs, ys, zs):
|
|||||||
z[i] = zs[i]
|
z[i] = zs[i]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
transform = OCTNewCoordinateTransformation(src, dst)
|
transform = OCTNewCoordinateTransformation(src._osr, dst._osr)
|
||||||
transform = exc_wrap_pointer(transform)
|
transform = exc_wrap_pointer(transform)
|
||||||
# OCTTransform() returns TRUE/FALSE contrary to most GDAL API functions
|
# OCTTransform() returns TRUE/FALSE contrary to most GDAL API functions
|
||||||
exc_wrap_int(OCTTransform(transform, n, x, y, z) == 0)
|
exc_wrap_int(OCTTransform(transform, n, x, y, z) == 0)
|
||||||
@ -1500,47 +1499,6 @@ def _transform(src_crs, dst_crs, xs, ys, zs):
|
|||||||
CPLFree(y)
|
CPLFree(y)
|
||||||
CPLFree(z)
|
CPLFree(z)
|
||||||
OCTDestroyCoordinateTransformation(transform)
|
OCTDestroyCoordinateTransformation(transform)
|
||||||
_safe_osr_release(src)
|
|
||||||
_safe_osr_release(dst)
|
|
||||||
|
|
||||||
|
|
||||||
cdef OGRSpatialReferenceH _osr_from_crs(object crs) except NULL:
|
|
||||||
"""Returns a reference to memory that must be deallocated
|
|
||||||
by the caller."""
|
|
||||||
crs = CRS.from_user_input(crs)
|
|
||||||
|
|
||||||
# EPSG is a special case.
|
|
||||||
init = crs.get('init')
|
|
||||||
if init:
|
|
||||||
auth, val = init.strip().split(':')
|
|
||||||
|
|
||||||
if not val or auth.upper() != 'EPSG':
|
|
||||||
raise CRSError("Invalid CRS: {!r}".format(crs))
|
|
||||||
proj = 'EPSG:{}'.format(val).encode('utf-8')
|
|
||||||
else:
|
|
||||||
proj = crs.to_string().encode('utf-8')
|
|
||||||
log.debug("PROJ.4 to be imported: %r", proj)
|
|
||||||
|
|
||||||
cdef OGRSpatialReferenceH osr = OSRNewSpatialReference(NULL)
|
|
||||||
try:
|
|
||||||
retval = exc_wrap_int(OSRSetFromUserInput(osr, <const char *>proj))
|
|
||||||
if retval:
|
|
||||||
_safe_osr_release(osr)
|
|
||||||
raise CRSError("Invalid CRS: {!r}".format(crs))
|
|
||||||
except CPLE_BaseError as exc:
|
|
||||||
_safe_osr_release(osr)
|
|
||||||
raise CRSError(str(exc))
|
|
||||||
else:
|
|
||||||
osr_set_traditional_axis_mapping_strategy(osr)
|
|
||||||
return osr
|
|
||||||
|
|
||||||
|
|
||||||
cdef _safe_osr_release(OGRSpatialReferenceH srs):
|
|
||||||
"""Wrapper to handle OSR release when NULL."""
|
|
||||||
|
|
||||||
if srs != NULL:
|
|
||||||
OSRRelease(srs)
|
|
||||||
srs = NULL
|
|
||||||
|
|
||||||
|
|
||||||
def _can_create_osr(crs):
|
def _can_create_osr(crs):
|
||||||
@ -1558,26 +1516,14 @@ def _can_create_osr(crs):
|
|||||||
True if source coordinate reference appears valid.
|
True if source coordinate reference appears valid.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cdef char *wkt = NULL
|
|
||||||
cdef OGRSpatialReferenceH osr = NULL
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Note: _osr_from_crs() has "except NULL" in its signature.
|
wkt = CRS.from_user_input(crs).to_wkt()
|
||||||
# It raises, it does not return NULL.
|
|
||||||
osr = _osr_from_crs(crs)
|
|
||||||
OSRExportToWkt(osr, &wkt)
|
|
||||||
|
|
||||||
# If input was empty, WKT can be too; otherwise the conversion
|
# If input was empty, WKT can be too; otherwise the conversion
|
||||||
# didn't work properly and indicates an error.
|
# didn't work properly and indicates an error.
|
||||||
return wkt != NULL and bool(crs) == (wkt[0] != 0)
|
return bool(wkt)
|
||||||
|
|
||||||
except CRSError:
|
except CRSError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
finally:
|
|
||||||
_safe_osr_release(osr)
|
|
||||||
CPLFree(wkt)
|
|
||||||
|
|
||||||
|
|
||||||
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs):
|
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs):
|
||||||
OSRSetAxisMappingStrategy(hSrs, OAMS_TRADITIONAL_GIS_ORDER)
|
OSRSetAxisMappingStrategy(hSrs, OAMS_TRADITIONAL_GIS_ORDER)
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import os.path
|
|||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from rasterio._base cimport _safe_osr_release
|
|
||||||
from rasterio._err import CPLE_BaseError
|
from rasterio._err import CPLE_BaseError
|
||||||
from rasterio._err cimport exc_wrap_ogrerr, exc_wrap_int
|
from rasterio._err cimport exc_wrap_ogrerr, exc_wrap_int
|
||||||
from rasterio._filepath cimport install_filepath_plugin, uninstall_filepath_plugin
|
from rasterio._filepath cimport install_filepath_plugin, uninstall_filepath_plugin
|
||||||
@ -312,7 +311,8 @@ class PROJDataFinder:
|
|||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
finally:
|
finally:
|
||||||
_safe_osr_release(osr)
|
if osr != NULL:
|
||||||
|
OSRRelease(osr)
|
||||||
|
|
||||||
|
|
||||||
def search(self, prefix=None):
|
def search(self, prefix=None):
|
||||||
|
|||||||
@ -38,8 +38,7 @@ from libc.stdio cimport FILE
|
|||||||
from rasterio.enums import Resampling
|
from rasterio.enums import Resampling
|
||||||
from rasterio.env import GDALVersion
|
from rasterio.env import GDALVersion
|
||||||
from rasterio.errors import ResamplingAlgorithmError, DatasetIOShapeError
|
from rasterio.errors import ResamplingAlgorithmError, DatasetIOShapeError
|
||||||
from rasterio._base cimport (
|
from rasterio._base cimport get_driver_name, DatasetBase
|
||||||
_osr_from_crs, _safe_osr_release, get_driver_name, DatasetBase)
|
|
||||||
from rasterio._err cimport exc_wrap_int, exc_wrap_pointer, exc_wrap_vsilfile
|
from rasterio._err cimport exc_wrap_int, exc_wrap_pointer, exc_wrap_vsilfile
|
||||||
|
|
||||||
cimport numpy as np
|
cimport numpy as np
|
||||||
@ -2001,15 +2000,15 @@ cdef class DatasetWriterBase(DatasetReaderBase):
|
|||||||
gcplist[i].dfGCPZ = obj.z or 0.0
|
gcplist[i].dfGCPZ = obj.z or 0.0
|
||||||
|
|
||||||
# Try to use the primary crs if possible.
|
# Try to use the primary crs if possible.
|
||||||
if not crs:
|
if crs is None:
|
||||||
crs = self.crs
|
crs = self.crs
|
||||||
|
else:
|
||||||
osr = _osr_from_crs(crs)
|
crs = CRS.from_user_input(crs)
|
||||||
OSRExportToWkt(osr, <char**>&srcwkt)
|
srcwkt_b = crs.to_wkt().encode('utf-8')
|
||||||
|
srcwkt = srcwkt_b
|
||||||
GDALSetGCPs(self.handle(), len(gcps), gcplist, srcwkt)
|
GDALSetGCPs(self.handle(), len(gcps), gcplist, srcwkt)
|
||||||
finally:
|
finally:
|
||||||
CPLFree(gcplist)
|
CPLFree(gcplist)
|
||||||
CPLFree(srcwkt)
|
|
||||||
|
|
||||||
# Invalidate cached value.
|
# Invalidate cached value.
|
||||||
self._gcps = None
|
self._gcps = None
|
||||||
|
|||||||
@ -35,12 +35,12 @@ cimport cython
|
|||||||
cimport numpy as np
|
cimport numpy as np
|
||||||
from libc.math cimport HUGE_VAL
|
from libc.math cimport HUGE_VAL
|
||||||
|
|
||||||
from rasterio._base cimport _osr_from_crs, get_driver_name, _safe_osr_release
|
from rasterio._base cimport get_driver_name
|
||||||
from rasterio._err cimport exc_wrap, exc_wrap_pointer, exc_wrap_int
|
from rasterio._err cimport exc_wrap, exc_wrap_pointer, exc_wrap_int
|
||||||
from rasterio._io cimport (
|
from rasterio._io cimport (
|
||||||
DatasetReaderBase, MemoryDataset, in_dtype_range, io_auto)
|
DatasetReaderBase, MemoryDataset, in_dtype_range, io_auto)
|
||||||
from rasterio._features cimport GeomBuilder, OGRGeomBuilder
|
from rasterio._features cimport GeomBuilder, OGRGeomBuilder
|
||||||
|
from rasterio.crs cimport CRS
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -92,19 +92,13 @@ def _transform_geom(
|
|||||||
int precision):
|
int precision):
|
||||||
"""Return a transformed geometry."""
|
"""Return a transformed geometry."""
|
||||||
cdef char **options = NULL
|
cdef char **options = NULL
|
||||||
cdef OGRSpatialReferenceH src = NULL
|
|
||||||
cdef OGRSpatialReferenceH dst = NULL
|
|
||||||
cdef OGRCoordinateTransformationH transform = NULL
|
cdef OGRCoordinateTransformationH transform = NULL
|
||||||
cdef OGRGeometryFactory *factory = NULL
|
cdef OGRGeometryFactory *factory = NULL
|
||||||
|
|
||||||
src = _osr_from_crs(src_crs)
|
cdef CRS src = CRS.from_user_input(src_crs)
|
||||||
dst = _osr_from_crs(dst_crs)
|
cdef CRS dst = CRS.from_user_input(dst_crs)
|
||||||
|
|
||||||
try:
|
transform = exc_wrap_pointer(OCTNewCoordinateTransformation(src._osr, dst._osr))
|
||||||
transform = exc_wrap_pointer(OCTNewCoordinateTransformation(src, dst))
|
|
||||||
finally:
|
|
||||||
_safe_osr_release(src)
|
|
||||||
_safe_osr_release(dst)
|
|
||||||
|
|
||||||
# GDAL cuts on the antimeridian by default and using different
|
# GDAL cuts on the antimeridian by default and using different
|
||||||
# logic in versions >= 2.2.
|
# logic in versions >= 2.2.
|
||||||
@ -632,7 +626,6 @@ def _calculate_default_transform(
|
|||||||
cdef int nlines = 0
|
cdef int nlines = 0
|
||||||
cdef double extent[4]
|
cdef double extent[4]
|
||||||
cdef double geotransform[6]
|
cdef double geotransform[6]
|
||||||
cdef OGRSpatialReferenceH osr = NULL
|
|
||||||
cdef char *wkt = NULL
|
cdef char *wkt = NULL
|
||||||
cdef GDALDatasetH hds = NULL
|
cdef GDALDatasetH hds = NULL
|
||||||
cdef char **imgProjOptions = NULL
|
cdef char **imgProjOptions = NULL
|
||||||
@ -650,19 +643,11 @@ def _calculate_default_transform(
|
|||||||
else:
|
else:
|
||||||
transform = None
|
transform = None
|
||||||
|
|
||||||
try:
|
dst_crs = CRS.from_user_input(dst_crs)
|
||||||
osr = _osr_from_crs(dst_crs)
|
wkt_b = dst_crs.to_wkt().encode('utf-8')
|
||||||
exc_wrap_int(OSRExportToWkt(osr, &wkt))
|
wkt = wkt_b
|
||||||
except CPLE_BaseError as exc:
|
if src_crs is not None:
|
||||||
raise CRSError("Could not convert to WKT. {}".format(str(exc)))
|
src_crs = CRS.from_user_input(src_crs)
|
||||||
finally:
|
|
||||||
_safe_osr_release(osr)
|
|
||||||
|
|
||||||
if isinstance(src_crs, str):
|
|
||||||
src_crs = CRS.from_string(src_crs)
|
|
||||||
elif isinstance(src_crs, dict):
|
|
||||||
src_crs = CRS(**src_crs)
|
|
||||||
|
|
||||||
# The transformer at the heart of this function requires a dataset.
|
# The transformer at the heart of this function requires a dataset.
|
||||||
# We use an in-memory VRT dataset.
|
# We use an in-memory VRT dataset.
|
||||||
vrt_doc = _suggested_proxy_vrt_doc(
|
vrt_doc = _suggested_proxy_vrt_doc(
|
||||||
@ -671,14 +656,12 @@ def _calculate_default_transform(
|
|||||||
transform=transform,
|
transform=transform,
|
||||||
crs=src_crs,
|
crs=src_crs,
|
||||||
gcps=gcps
|
gcps=gcps
|
||||||
).decode('ascii')
|
).decode('utf-8')
|
||||||
hds = open_dataset(vrt_doc, 0x00 | 0x02 | 0x04, ['VRT'], {}, None)
|
hds = open_dataset(vrt_doc, 0x00 | 0x02 | 0x04, ['VRT'], {}, None)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
imgProjOptions = CSLSetNameValue(imgProjOptions, "GCPS_OK", "TRUE")
|
imgProjOptions = CSLSetNameValue(imgProjOptions, "GCPS_OK", "TRUE")
|
||||||
imgProjOptions = CSLSetNameValue(imgProjOptions, "MAX_GCP_ORDER", "0")
|
imgProjOptions = CSLSetNameValue(imgProjOptions, "MAX_GCP_ORDER", "0")
|
||||||
imgProjOptions = CSLSetNameValue(imgProjOptions, "DST_SRS", wkt)
|
imgProjOptions = CSLSetNameValue(imgProjOptions, "DST_SRS", wkt)
|
||||||
|
|
||||||
for key, val in kwargs.items():
|
for key, val in kwargs.items():
|
||||||
key = key.upper().encode('utf-8')
|
key = key.upper().encode('utf-8')
|
||||||
|
|
||||||
@ -728,8 +711,6 @@ def _calculate_default_transform(
|
|||||||
raise CRSError(err.errmsg)
|
raise CRSError(err.errmsg)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
if wkt != NULL:
|
|
||||||
CPLFree(wkt)
|
|
||||||
if hTransformArg != NULL:
|
if hTransformArg != NULL:
|
||||||
GDALDestroyGenImgProjTransformer(hTransformArg)
|
GDALDestroyGenImgProjTransformer(hTransformArg)
|
||||||
if hds != NULL:
|
if hds != NULL:
|
||||||
@ -963,23 +944,13 @@ cdef class WarpedVRTReaderBase(DatasetReaderBase):
|
|||||||
self.dst_crs = CRS.from_user_input(crs) if crs is not None else self.src_crs
|
self.dst_crs = CRS.from_user_input(crs) if crs is not None else self.src_crs
|
||||||
|
|
||||||
# Convert CRSes to C WKT strings.
|
# Convert CRSes to C WKT strings.
|
||||||
try:
|
if self.src_crs is not None:
|
||||||
if not self.src_crs:
|
src_crs_wkt_b = self.src_crs.to_wkt().encode("utf-8")
|
||||||
src_crs_wkt = NULL
|
src_crs_wkt = src_crs_wkt_b
|
||||||
else:
|
|
||||||
osr = _osr_from_crs(self.src_crs)
|
|
||||||
OSRExportToWkt(osr, &src_crs_wkt)
|
|
||||||
finally:
|
|
||||||
if osr != NULL:
|
|
||||||
OSRRelease(osr)
|
|
||||||
osr = NULL
|
|
||||||
|
|
||||||
if self.dst_crs is not None:
|
if self.dst_crs is not None:
|
||||||
try:
|
dst_crs_wkt_b = self.dst_crs.to_wkt().encode("utf-8")
|
||||||
osr = _osr_from_crs(self.dst_crs)
|
dst_crs_wkt = dst_crs_wkt_b
|
||||||
OSRExportToWkt(osr, &dst_crs_wkt)
|
|
||||||
finally:
|
|
||||||
_safe_osr_release(osr)
|
|
||||||
|
|
||||||
log.debug("Exported CRS to WKT.")
|
log.debug("Exported CRS to WKT.")
|
||||||
|
|
||||||
@ -1057,8 +1028,6 @@ cdef class WarpedVRTReaderBase(DatasetReaderBase):
|
|||||||
<const char **>c_warp_extras,
|
<const char **>c_warp_extras,
|
||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
CPLFree(dst_crs_wkt)
|
|
||||||
CPLFree(src_crs_wkt)
|
|
||||||
CSLDestroy(c_warp_extras)
|
CSLDestroy(c_warp_extras)
|
||||||
if psWOptions != NULL:
|
if psWOptions != NULL:
|
||||||
GDALDestroyWarpOptions(psWOptions)
|
GDALDestroyWarpOptions(psWOptions)
|
||||||
@ -1112,8 +1081,6 @@ cdef class WarpedVRTReaderBase(DatasetReaderBase):
|
|||||||
# If we get here it's because the tests above are buggy.
|
# If we get here it's because the tests above are buggy.
|
||||||
# We raise a Python exception to indicate that.
|
# We raise a Python exception to indicate that.
|
||||||
else:
|
else:
|
||||||
CPLFree(dst_crs_wkt)
|
|
||||||
CPLFree(src_crs_wkt)
|
|
||||||
CSLDestroy(c_warp_extras)
|
CSLDestroy(c_warp_extras)
|
||||||
if psWOptions != NULL:
|
if psWOptions != NULL:
|
||||||
GDALDestroyWarpOptions(psWOptions)
|
GDALDestroyWarpOptions(psWOptions)
|
||||||
@ -1152,8 +1119,6 @@ cdef class WarpedVRTReaderBase(DatasetReaderBase):
|
|||||||
GDALSetProjection(hds_warped, dst_crs_wkt)
|
GDALSetProjection(hds_warped, dst_crs_wkt)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
CPLFree(dst_crs_wkt)
|
|
||||||
CPLFree(src_crs_wkt)
|
|
||||||
CSLDestroy(c_warp_extras)
|
CSLDestroy(c_warp_extras)
|
||||||
if psWOptions != NULL:
|
if psWOptions != NULL:
|
||||||
GDALDestroyWarpOptions(psWOptions)
|
GDALDestroyWarpOptions(psWOptions)
|
||||||
@ -1469,28 +1434,21 @@ cdef double antimeridian_max(data):
|
|||||||
@cython.boundscheck(False)
|
@cython.boundscheck(False)
|
||||||
@cython.wraparound(False)
|
@cython.wraparound(False)
|
||||||
def _transform_bounds(
|
def _transform_bounds(
|
||||||
src_crs,
|
CRS src_crs,
|
||||||
dst_crs,
|
CRS dst_crs,
|
||||||
double left,
|
double left,
|
||||||
double bottom,
|
double bottom,
|
||||||
double right,
|
double right,
|
||||||
double top,
|
double top,
|
||||||
int densify_pts,
|
int densify_pts,
|
||||||
):
|
):
|
||||||
src_crs = CRS.from_user_input(src_crs)
|
|
||||||
dst_crs = CRS.from_user_input(dst_crs)
|
|
||||||
|
|
||||||
IF (CTE_GDAL_MAJOR_VERSION, CTE_GDAL_MINOR_VERSION) >= (3, 4):
|
IF (CTE_GDAL_MAJOR_VERSION, CTE_GDAL_MINOR_VERSION) >= (3, 4):
|
||||||
cdef double out_left = np.inf
|
cdef double out_left = np.inf
|
||||||
cdef double out_bottom = np.inf
|
cdef double out_bottom = np.inf
|
||||||
cdef double out_right = np.inf
|
cdef double out_right = np.inf
|
||||||
cdef double out_top = np.inf
|
cdef double out_top = np.inf
|
||||||
cdef OGRSpatialReferenceH src = NULL
|
|
||||||
cdef OGRSpatialReferenceH dst = NULL
|
|
||||||
cdef OGRCoordinateTransformationH transform = NULL
|
cdef OGRCoordinateTransformationH transform = NULL
|
||||||
src = _osr_from_crs(src_crs)
|
transform = OCTNewCoordinateTransformation(src_crs._osr, dst_crs._osr)
|
||||||
dst = _osr_from_crs(dst_crs)
|
|
||||||
transform = OCTNewCoordinateTransformation(src, dst)
|
|
||||||
transform = exc_wrap_pointer(transform)
|
transform = exc_wrap_pointer(transform)
|
||||||
|
|
||||||
# OCTTransformBounds() returns TRUE/FALSE contrary to most GDAL API functions
|
# OCTTransformBounds() returns TRUE/FALSE contrary to most GDAL API functions
|
||||||
@ -1506,9 +1464,6 @@ def _transform_bounds(
|
|||||||
exc_wrap_int(status == 0)
|
exc_wrap_int(status == 0)
|
||||||
finally:
|
finally:
|
||||||
OCTDestroyCoordinateTransformation(transform)
|
OCTDestroyCoordinateTransformation(transform)
|
||||||
_safe_osr_release(src)
|
|
||||||
_safe_osr_release(dst)
|
|
||||||
|
|
||||||
return out_left, out_bottom, out_right, out_top
|
return out_left, out_bottom, out_right, out_top
|
||||||
|
|
||||||
ELSE:
|
ELSE:
|
||||||
|
|||||||
@ -32,8 +32,7 @@ from rasterio._err import CPLE_BaseError, CPLE_NotSupportedError
|
|||||||
from rasterio.errors import CRSError
|
from rasterio.errors import CRSError
|
||||||
from rasterio.enums import WktVersion
|
from rasterio.enums import WktVersion
|
||||||
|
|
||||||
from rasterio._base cimport _osr_from_crs as osr_from_crs
|
from rasterio._base cimport osr_set_traditional_axis_mapping_strategy
|
||||||
from rasterio._base cimport _safe_osr_release, osr_set_traditional_axis_mapping_strategy
|
|
||||||
from rasterio._err cimport exc_wrap_ogrerr, exc_wrap_int, exc_wrap_pointer
|
from rasterio._err cimport exc_wrap_ogrerr, exc_wrap_int, exc_wrap_pointer
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +48,14 @@ _RE_PROJ_PARAM = re.compile(r"""
|
|||||||
""", re.X)
|
""", re.X)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cdef _safe_osr_release(OGRSpatialReferenceH srs):
|
||||||
|
"""Wrapper to handle OSR release when NULL."""
|
||||||
|
if srs != NULL:
|
||||||
|
OSRRelease(srs)
|
||||||
|
srs = NULL
|
||||||
|
|
||||||
|
|
||||||
cdef class CRS:
|
cdef class CRS:
|
||||||
"""A geographic or projected coordinate reference system.
|
"""A geographic or projected coordinate reference system.
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ with rasterio._loading.add_gdal_dll_directories():
|
|||||||
import rasterio
|
import rasterio
|
||||||
|
|
||||||
from rasterio._base import _transform
|
from rasterio._base import _transform
|
||||||
|
from rasterio.crs import CRS
|
||||||
from rasterio.enums import Resampling
|
from rasterio.enums import Resampling
|
||||||
from rasterio.env import ensure_env, require_gdal_version
|
from rasterio.env import ensure_env, require_gdal_version
|
||||||
from rasterio.errors import TransformError, RPCError
|
from rasterio.errors import TransformError, RPCError
|
||||||
@ -145,6 +146,8 @@ def transform_bounds(
|
|||||||
left, bottom, right, top: float
|
left, bottom, right, top: float
|
||||||
Outermost coordinates in target coordinate reference system.
|
Outermost coordinates in target coordinate reference system.
|
||||||
"""
|
"""
|
||||||
|
src_crs = CRS.from_user_input(src_crs)
|
||||||
|
dst_crs = CRS.from_user_input(dst_crs)
|
||||||
return _transform_bounds(
|
return _transform_bounds(
|
||||||
src_crs,
|
src_crs,
|
||||||
dst_crs,
|
dst_crs,
|
||||||
|
|||||||
@ -285,8 +285,8 @@ def test_transform_bounds__esri_wkt():
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"density,expected",
|
"density,expected",
|
||||||
[
|
[
|
||||||
(0, (-1684649.41338, -350356.81377, 1684649.41338, 2234551.18559)),
|
(0, (-1688721.99764, -350040.36880, 1688799.61159, 2236495.86829)),
|
||||||
(100, (-1684649.41338, -555777.79210, 1684649.41338, 2234551.18559)),
|
(100, (-1688721.99764, -555239.84875, 1688799.61159, 2236495.86829)),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_transform_bounds_densify(density, expected):
|
def test_transform_bounds_densify(density, expected):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user