This is an automated email from the ASF dual-hosted git repository.
jiayu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sedona.git
The following commit(s) were added to refs/heads/master by this push:
new 4364d413f2 [SEDONA-674] Update the sedona-raster python module to
support GDAL 3.10 (#1682)
4364d413f2 is described below
commit 4364d413f2a798698d19c5c3379b7f0336d70806
Author: Kristin Cowalcijk <[email protected]>
AuthorDate: Sat Nov 16 02:53:55 2024 +0800
[SEDONA-674] Update the sedona-raster python module to support GDAL 3.10
(#1682)
---
python/sedona/raster/sedona_raster.py | 77 +++++++++++++++++++++++------------
1 file changed, 52 insertions(+), 25 deletions(-)
diff --git a/python/sedona/raster/sedona_raster.py
b/python/sedona/raster/sedona_raster.py
index f47d208f42..ccb90de001 100644
--- a/python/sedona/raster/sedona_raster.py
+++ b/python/sedona/raster/sedona_raster.py
@@ -16,7 +16,8 @@
# under the License.
from abc import ABC, abstractmethod
-from typing import Dict, List, Optional
+from typing import List, Optional
+import json
from xml.etree.ElementTree import Element, SubElement, tostring
import numpy as np
@@ -34,8 +35,24 @@ except:
from rasterio.path import parse_path # type: ignore
from .awt_raster import AWTRaster
-from .data_buffer import DataBuffer
-from .meta import AffineTransform, PixelAnchor, SampleDimension
+from .meta import AffineTransform, SampleDimension
+
+
+GDAL_VERSION = rasterio.env.GDALVersion.runtime()
+
+
+def _has_env_with_gdal_mem_enabled():
+ if rasterio.env.hasenv():
+ if GDAL_VERSION.at_least(rasterio.env.GDALVersion(3, 10)):
+ # For GDAL >= 3.10, GDAL_MEM_ENABLE_OPEN must be enabled to load
+ # MEM:: dataset. Please refer to
+ # https://gdal.org/en/latest/drivers/raster/mem.html for details.
+ options = rasterio.env.getenv()
+ return options.get("GDAL_MEM_ENABLE_OPEN") == "YES"
+ else:
+ return True
+ else:
+ return False
def _rasterio_open(fp, driver=None):
@@ -44,12 +61,20 @@ def _rasterio_open(fp, driver=None):
introduced by GDAL env initialization.
"""
- if rasterio.env.hasenv():
+ if _has_env_with_gdal_mem_enabled():
# There is already an env, so we can get rid of the overhead of
# GDAL env initialization in rasterio.open().
return DatasetReader(parse_path(fp), driver=driver)
else:
- return rasterio.open(fp, mode="r", driver=driver)
+ with rasterio.env.Env(GDAL_MEM_ENABLE_OPEN="YES"):
+ return rasterio.open(fp, mode="r", driver=driver)
+
+
+def _rasterio_open_memfile(memfile: MemoryFile, driver=None):
+ if not _has_env_with_gdal_mem_enabled():
+ with rasterio.env.Env(GDAL_MEM_ENABLE_OPEN="YES"):
+ return memfile.open(driver=driver)
+ return memfile.open(driver=driver)
def _generate_vrt_xml(
@@ -266,31 +291,33 @@ class InDbSedonaRaster(SedonaRaster):
f"{self._affine_trans.ip_x}/{self._affine_trans.scale_x}/{self._affine_trans.skew_x}/"
+
f"{self._affine_trans.ip_y}/{self._affine_trans.skew_y}/{self._affine_trans.scale_y}"
)
- # FIXME: GDAL 3.6 shipped with rasterio does not support
- # SPATIALREFERENCE parameter, so we have to workaround this issue in a
- # hacky way. If newer versions of rasterio bundle GDAL 3.7 then this
- # won't be a problem. See https://gdal.org/drivers/raster/mem.html
desc = (
f"MEM:::DATAPOINTER={data_pointer},PIXELS={self._width},LINES={self._height},BANDS={num_bands},"
+ f"DATATYPE={data_type},GEOTRANSFORM={geotransform}"
)
- # construct a VRT to wrap this MEM dataset, with SRS set up properly
- vrt_xml = _generate_vrt_xml(
- desc,
- data_type,
- self._width,
- self._height,
- geotransform.replace("/", ","),
- self._crs_wkt,
- 0,
- 0,
- list(range(num_bands)),
- )
-
- # dataset = _rasterio_open(desc, driver="MEM")
- self.rasterio_memfile = MemoryFile(vrt_xml, ext=".vrt")
- dataset = self.rasterio_memfile.open(driver="VRT")
+ # If we are using GDAL >= 3.7, we can use the SPATIALREFERENCE
+ # parameter; otherwise we have to wrap the MEM dataset with an VRT to
+ # set up the SRS.
+ if GDAL_VERSION.at_least(rasterio.env.GDALVersion(3, 7)):
+ escaped_srs = json.dumps(self._crs_wkt.replace("\n", ""))
+ desc += f",SPATIALREFERENCE={escaped_srs}"
+ dataset = _rasterio_open(desc, driver="MEM")
+ else:
+ # construct a VRT to wrap this MEM dataset, with SRS set up
properly
+ vrt_xml = _generate_vrt_xml(
+ desc,
+ data_type,
+ self._width,
+ self._height,
+ geotransform.replace("/", ","),
+ self._crs_wkt,
+ 0,
+ 0,
+ list(range(num_bands)),
+ )
+ self.rasterio_memfile = MemoryFile(vrt_xml, ext=".vrt")
+ dataset = _rasterio_open_memfile(self.rasterio_memfile,
driver="VRT")
# XXX: dataset does not copy the data held by data_array, so we set
# data_array as a property of dataset to make sure that the lifetime of