pyogrio 0.9.0__cp310-cp310-manylinux_2_28_aarch64.whl → 0.10.0__cp310-cp310-manylinux_2_28_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyogrio might be problematic. Click here for more details.
- pyogrio/__init__.py +20 -13
- pyogrio/_compat.py +7 -1
- pyogrio/_env.py +4 -6
- pyogrio/_err.cpython-310-aarch64-linux-gnu.so +0 -0
- pyogrio/_geometry.cpython-310-aarch64-linux-gnu.so +0 -0
- pyogrio/_io.cpython-310-aarch64-linux-gnu.so +0 -0
- pyogrio/_ogr.cpython-310-aarch64-linux-gnu.so +0 -0
- pyogrio/_version.py +3 -3
- pyogrio/_vsi.cpython-310-aarch64-linux-gnu.so +0 -0
- pyogrio/core.py +86 -20
- pyogrio/errors.py +9 -16
- pyogrio/gdal_data/GDAL-targets-release.cmake +3 -3
- pyogrio/gdal_data/GDAL-targets.cmake +1 -1
- pyogrio/gdal_data/GDALConfig.cmake +0 -1
- pyogrio/gdal_data/GDALConfigVersion.cmake +3 -3
- pyogrio/gdal_data/MM_m_idofic.csv +321 -0
- pyogrio/gdal_data/gdaltileindex.xsd +269 -0
- pyogrio/gdal_data/gdalvrt.xsd +130 -22
- pyogrio/gdal_data/ogrinfo_output.schema.json +23 -0
- pyogrio/gdal_data/ogrvrt.xsd +3 -0
- pyogrio/gdal_data/pci_datum.txt +222 -155
- pyogrio/gdal_data/pci_ellips.txt +90 -38
- pyogrio/gdal_data/vcpkg.spdx.json +26 -26
- pyogrio/gdal_data/vcpkg_abi_info.txt +25 -25
- pyogrio/geopandas.py +32 -24
- pyogrio/proj_data/proj-config-version.cmake +2 -2
- pyogrio/proj_data/proj-targets.cmake +1 -1
- pyogrio/proj_data/proj.db +0 -0
- pyogrio/proj_data/proj4-targets.cmake +1 -1
- pyogrio/proj_data/projjson.schema.json +1 -1
- pyogrio/proj_data/vcpkg.spdx.json +20 -20
- pyogrio/proj_data/vcpkg_abi_info.txt +13 -13
- pyogrio/raw.py +46 -30
- pyogrio/tests/conftest.py +206 -12
- pyogrio/tests/fixtures/README.md +32 -13
- pyogrio/tests/fixtures/curve.gpkg +0 -0
- pyogrio/tests/fixtures/{test_multisurface.gpkg → curvepolygon.gpkg} +0 -0
- pyogrio/tests/fixtures/line_zm.gpkg +0 -0
- pyogrio/tests/fixtures/multisurface.gpkg +0 -0
- pyogrio/tests/test_arrow.py +178 -24
- pyogrio/tests/test_core.py +162 -72
- pyogrio/tests/test_geopandas_io.py +239 -99
- pyogrio/tests/test_path.py +29 -17
- pyogrio/tests/test_raw_io.py +165 -54
- pyogrio/tests/test_util.py +56 -0
- pyogrio/util.py +54 -30
- {pyogrio-0.9.0.dist-info → pyogrio-0.10.0.dist-info}/LICENSE +1 -1
- {pyogrio-0.9.0.dist-info → pyogrio-0.10.0.dist-info}/METADATA +37 -8
- {pyogrio-0.9.0.dist-info → pyogrio-0.10.0.dist-info}/RECORD +198 -214
- {pyogrio-0.9.0.dist-info → pyogrio-0.10.0.dist-info}/WHEEL +1 -1
- pyogrio.libs/{libgdal-6ff0914e.so.34.3.8.5 → libgdal-b0847c7b.so.35.3.9.1} +0 -0
- pyogrio/_err.pxd +0 -4
- pyogrio/_err.pyx +0 -250
- pyogrio/_geometry.pxd +0 -4
- pyogrio/_geometry.pyx +0 -129
- pyogrio/_io.pxd +0 -0
- pyogrio/_io.pyx +0 -2742
- pyogrio/_ogr.pxd +0 -444
- pyogrio/_ogr.pyx +0 -346
- pyogrio/_vsi.pxd +0 -4
- pyogrio/_vsi.pyx +0 -140
- pyogrio/arrow_bridge.h +0 -115
- pyogrio/gdal_data/bag_template.xml +0 -201
- pyogrio/gdal_data/gmlasconf.xml +0 -169
- pyogrio/gdal_data/gmlasconf.xsd +0 -1066
- pyogrio/gdal_data/netcdf_config.xsd +0 -143
- pyogrio/gdal_data/template_tiles.mapml +0 -28
- pyogrio/tests/fixtures/poly_not_enough_points.shp.zip +0 -0
- pyogrio/tests/fixtures/test_datetime.geojson +0 -7
- pyogrio/tests/fixtures/test_datetime_tz.geojson +0 -8
- pyogrio/tests/fixtures/test_fgdb.gdb.zip +0 -0
- pyogrio/tests/fixtures/test_nested.geojson +0 -18
- pyogrio/tests/fixtures/test_ogr_types_list.geojson +0 -12
- {pyogrio-0.9.0.dist-info → pyogrio-0.10.0.dist-info}/top_level.txt +0 -0
pyogrio/_ogr.pyx
DELETED
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
from uuid import uuid4
|
|
4
|
-
import warnings
|
|
5
|
-
|
|
6
|
-
from pyogrio._err cimport exc_wrap_int, exc_wrap_ogrerr, exc_wrap_pointer
|
|
7
|
-
from pyogrio._err import CPLE_BaseError, NullPointerError
|
|
8
|
-
from pyogrio.errors import DataSourceError
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
cdef get_string(const char *c_str, str encoding="UTF-8"):
|
|
12
|
-
"""Get Python string from a char *
|
|
13
|
-
|
|
14
|
-
IMPORTANT: the char * must still be freed by the caller.
|
|
15
|
-
|
|
16
|
-
Parameters
|
|
17
|
-
----------
|
|
18
|
-
c_str : char *
|
|
19
|
-
encoding : str, optional (default: UTF-8)
|
|
20
|
-
|
|
21
|
-
Returns
|
|
22
|
-
-------
|
|
23
|
-
Python string
|
|
24
|
-
"""
|
|
25
|
-
cdef bytes py_str
|
|
26
|
-
|
|
27
|
-
py_str = c_str
|
|
28
|
-
return py_str.decode(encoding)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def get_gdal_version():
|
|
32
|
-
"""Convert GDAL version number into tuple of (major, minor, revision)"""
|
|
33
|
-
version = int(GDALVersionInfo("VERSION_NUM"))
|
|
34
|
-
major = version // 1000000
|
|
35
|
-
minor = (version - (major * 1000000)) // 10000
|
|
36
|
-
revision = (version - (major * 1000000) - (minor * 10000)) // 100
|
|
37
|
-
return (major, minor, revision)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def get_gdal_version_string():
|
|
41
|
-
cdef const char* version = GDALVersionInfo("RELEASE_NAME")
|
|
42
|
-
return get_string(version)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
IF CTE_GDAL_VERSION >= (3, 4, 0):
|
|
46
|
-
|
|
47
|
-
cdef extern from "ogr_api.h":
|
|
48
|
-
bint OGRGetGEOSVersion(int *pnMajor, int *pnMinor, int *pnPatch)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def get_gdal_geos_version():
|
|
52
|
-
cdef int major, minor, revision
|
|
53
|
-
|
|
54
|
-
IF CTE_GDAL_VERSION >= (3, 4, 0):
|
|
55
|
-
if not OGRGetGEOSVersion(&major, &minor, &revision):
|
|
56
|
-
return None
|
|
57
|
-
return (major, minor, revision)
|
|
58
|
-
ELSE:
|
|
59
|
-
return None
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def set_gdal_config_options(dict options):
|
|
63
|
-
for name, value in options.items():
|
|
64
|
-
name_b = name.encode('utf-8')
|
|
65
|
-
name_c = name_b
|
|
66
|
-
|
|
67
|
-
# None is a special case; this is used to clear the previous value
|
|
68
|
-
if value is None:
|
|
69
|
-
CPLSetConfigOption(<const char*>name_c, NULL)
|
|
70
|
-
continue
|
|
71
|
-
|
|
72
|
-
# normalize bool to ON/OFF
|
|
73
|
-
if isinstance(value, bool):
|
|
74
|
-
value_b = b'ON' if value else b'OFF'
|
|
75
|
-
else:
|
|
76
|
-
value_b = str(value).encode('utf-8')
|
|
77
|
-
|
|
78
|
-
value_c = value_b
|
|
79
|
-
CPLSetConfigOption(<const char*>name_c, <const char*>value_c)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def get_gdal_config_option(str name):
|
|
83
|
-
name_b = name.encode('utf-8')
|
|
84
|
-
name_c = name_b
|
|
85
|
-
value = CPLGetConfigOption(<const char*>name_c, NULL)
|
|
86
|
-
|
|
87
|
-
if not value:
|
|
88
|
-
return None
|
|
89
|
-
|
|
90
|
-
if value.isdigit():
|
|
91
|
-
return int(value)
|
|
92
|
-
|
|
93
|
-
if value == b'ON':
|
|
94
|
-
return True
|
|
95
|
-
if value == b'OFF':
|
|
96
|
-
return False
|
|
97
|
-
|
|
98
|
-
str_value = get_string(value)
|
|
99
|
-
|
|
100
|
-
return str_value
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def ogr_driver_supports_write(driver):
|
|
104
|
-
# check metadata for driver to see if it supports write
|
|
105
|
-
if _get_driver_metadata_item(driver, "DCAP_CREATE") == 'YES':
|
|
106
|
-
return True
|
|
107
|
-
|
|
108
|
-
return False
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def ogr_driver_supports_vsi(driver):
|
|
112
|
-
# check metadata for driver to see if it supports write
|
|
113
|
-
if _get_driver_metadata_item(driver, "DCAP_VIRTUALIO") == 'YES':
|
|
114
|
-
return True
|
|
115
|
-
|
|
116
|
-
return False
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
def ogr_list_drivers():
|
|
120
|
-
cdef OGRSFDriverH driver = NULL
|
|
121
|
-
cdef int i
|
|
122
|
-
cdef char *name_c
|
|
123
|
-
|
|
124
|
-
drivers = dict()
|
|
125
|
-
for i in range(OGRGetDriverCount()):
|
|
126
|
-
driver = OGRGetDriver(i)
|
|
127
|
-
name_c = <char *>OGR_Dr_GetName(driver)
|
|
128
|
-
|
|
129
|
-
name = get_string(name_c)
|
|
130
|
-
|
|
131
|
-
if ogr_driver_supports_write(name):
|
|
132
|
-
drivers[name] = "rw"
|
|
133
|
-
|
|
134
|
-
else:
|
|
135
|
-
drivers[name] = "r"
|
|
136
|
-
|
|
137
|
-
return drivers
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
cdef void set_proj_search_path(str path):
|
|
141
|
-
"""Set PROJ library data file search path for use in GDAL."""
|
|
142
|
-
cdef char **paths = NULL
|
|
143
|
-
cdef const char *path_c = NULL
|
|
144
|
-
path_b = path.encode("utf-8")
|
|
145
|
-
path_c = path_b
|
|
146
|
-
paths = CSLAddString(paths, path_c)
|
|
147
|
-
OSRSetPROJSearchPaths(<const char *const *>paths)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
def has_gdal_data():
|
|
151
|
-
"""Verify that GDAL library data files are correctly found.
|
|
152
|
-
|
|
153
|
-
Adapted from Fiona (_env.pyx).
|
|
154
|
-
"""
|
|
155
|
-
|
|
156
|
-
if CPLFindFile("gdal", "header.dxf") != NULL:
|
|
157
|
-
return True
|
|
158
|
-
|
|
159
|
-
return False
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def get_gdal_data_path():
|
|
163
|
-
"""
|
|
164
|
-
Get the path to the directory GDAL uses to read data files.
|
|
165
|
-
"""
|
|
166
|
-
cdef const char *path_c = CPLFindFile("gdal", "header.dxf")
|
|
167
|
-
if path_c != NULL:
|
|
168
|
-
return get_string(path_c).rstrip("header.dxf")
|
|
169
|
-
return None
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
def has_proj_data():
|
|
173
|
-
"""Verify that PROJ library data files are correctly found.
|
|
174
|
-
|
|
175
|
-
Returns
|
|
176
|
-
-------
|
|
177
|
-
bool
|
|
178
|
-
True if a test spatial reference object could be created, which verifies
|
|
179
|
-
that data files are correctly loaded.
|
|
180
|
-
|
|
181
|
-
Adapted from Fiona (_env.pyx).
|
|
182
|
-
"""
|
|
183
|
-
cdef OGRSpatialReferenceH srs = OSRNewSpatialReference(NULL)
|
|
184
|
-
|
|
185
|
-
try:
|
|
186
|
-
exc_wrap_ogrerr(exc_wrap_int(OSRImportFromEPSG(srs, 4326)))
|
|
187
|
-
except CPLE_BaseError:
|
|
188
|
-
return False
|
|
189
|
-
else:
|
|
190
|
-
return True
|
|
191
|
-
finally:
|
|
192
|
-
if srs != NULL:
|
|
193
|
-
OSRRelease(srs)
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
def init_gdal_data():
|
|
197
|
-
"""Set GDAL data search directories in the following precedence:
|
|
198
|
-
- wheel copy of gdal_data
|
|
199
|
-
- default detection by GDAL, including GDAL_DATA (detected automatically by GDAL)
|
|
200
|
-
- other well-known paths under sys.prefix
|
|
201
|
-
|
|
202
|
-
Adapted from Fiona (env.py, _env.pyx).
|
|
203
|
-
"""
|
|
204
|
-
|
|
205
|
-
# wheels are packaged to include GDAL data files at pyogrio/gdal_data
|
|
206
|
-
wheel_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "gdal_data"))
|
|
207
|
-
if os.path.exists(wheel_path):
|
|
208
|
-
set_gdal_config_options({"GDAL_DATA": wheel_path})
|
|
209
|
-
if not has_gdal_data():
|
|
210
|
-
raise ValueError("Could not correctly detect GDAL data files installed by pyogrio wheel")
|
|
211
|
-
return
|
|
212
|
-
|
|
213
|
-
# GDAL correctly found data files from GDAL_DATA or compiled-in paths
|
|
214
|
-
if has_gdal_data():
|
|
215
|
-
return
|
|
216
|
-
|
|
217
|
-
wk_path = os.path.join(sys.prefix, 'share', 'gdal')
|
|
218
|
-
if os.path.exists(wk_path):
|
|
219
|
-
set_gdal_config_options({"GDAL_DATA": wk_path})
|
|
220
|
-
if not has_gdal_data():
|
|
221
|
-
raise ValueError(f"Found GDAL data directory at {wk_path} but it does not appear to correctly contain GDAL data files")
|
|
222
|
-
return
|
|
223
|
-
|
|
224
|
-
warnings.warn("Could not detect GDAL data files. Set GDAL_DATA environment variable to the correct path.", RuntimeWarning)
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
def init_proj_data():
|
|
228
|
-
"""Set Proj search directories in the following precedence:
|
|
229
|
-
- wheel copy of proj_data
|
|
230
|
-
- default detection by PROJ, including PROJ_LIB (detected automatically by PROJ)
|
|
231
|
-
- search other well-known paths under sys.prefix
|
|
232
|
-
|
|
233
|
-
Adapted from Fiona (env.py, _env.pyx).
|
|
234
|
-
"""
|
|
235
|
-
|
|
236
|
-
# wheels are packaged to include PROJ data files at pyogrio/proj_data
|
|
237
|
-
wheel_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "proj_data"))
|
|
238
|
-
if os.path.exists(wheel_path):
|
|
239
|
-
set_proj_search_path(wheel_path)
|
|
240
|
-
# verify that this now resolves
|
|
241
|
-
if not has_proj_data():
|
|
242
|
-
raise ValueError("Could not correctly detect PROJ data files installed by pyogrio wheel")
|
|
243
|
-
return
|
|
244
|
-
|
|
245
|
-
# PROJ correctly found data files from PROJ_LIB or compiled-in paths
|
|
246
|
-
if has_proj_data():
|
|
247
|
-
return
|
|
248
|
-
|
|
249
|
-
wk_path = os.path.join(sys.prefix, 'share', 'proj')
|
|
250
|
-
if os.path.exists(wk_path):
|
|
251
|
-
set_proj_search_path(wk_path)
|
|
252
|
-
# verify that this now resolves
|
|
253
|
-
if not has_proj_data():
|
|
254
|
-
raise ValueError(f"Found PROJ data directory at {wk_path} but it does not appear to correctly contain PROJ data files")
|
|
255
|
-
return
|
|
256
|
-
|
|
257
|
-
warnings.warn("Could not detect PROJ data files. Set PROJ_LIB environment variable to the correct path.", RuntimeWarning)
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
def _register_drivers():
|
|
261
|
-
# Register all drivers
|
|
262
|
-
GDALAllRegister()
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
def _get_driver_metadata_item(driver, metadata_item):
|
|
266
|
-
"""
|
|
267
|
-
Query driver metadata items.
|
|
268
|
-
|
|
269
|
-
Parameters
|
|
270
|
-
----------
|
|
271
|
-
driver : str
|
|
272
|
-
Driver to query
|
|
273
|
-
metadata_item : str
|
|
274
|
-
Metadata item to query
|
|
275
|
-
|
|
276
|
-
Returns
|
|
277
|
-
-------
|
|
278
|
-
str or None
|
|
279
|
-
Metadata item
|
|
280
|
-
"""
|
|
281
|
-
cdef const char* metadata_c = NULL
|
|
282
|
-
cdef void *cogr_driver = NULL
|
|
283
|
-
|
|
284
|
-
try:
|
|
285
|
-
cogr_driver = exc_wrap_pointer(GDALGetDriverByName(driver.encode('UTF-8')))
|
|
286
|
-
except NullPointerError:
|
|
287
|
-
raise DataSourceError(
|
|
288
|
-
f"Could not obtain driver: {driver} (check that it was installed "
|
|
289
|
-
"correctly into GDAL)"
|
|
290
|
-
)
|
|
291
|
-
except CPLE_BaseError as exc:
|
|
292
|
-
raise DataSourceError(str(exc))
|
|
293
|
-
|
|
294
|
-
metadata_c = GDALGetMetadataItem(cogr_driver, metadata_item.encode('UTF-8'), NULL)
|
|
295
|
-
|
|
296
|
-
metadata = None
|
|
297
|
-
if metadata_c != NULL:
|
|
298
|
-
metadata = metadata_c
|
|
299
|
-
metadata = metadata.decode('UTF-8')
|
|
300
|
-
if len(metadata) == 0:
|
|
301
|
-
metadata = None
|
|
302
|
-
|
|
303
|
-
return metadata
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
def _get_drivers_for_path(path):
|
|
307
|
-
cdef OGRSFDriverH driver = NULL
|
|
308
|
-
cdef int i
|
|
309
|
-
cdef char *name_c
|
|
310
|
-
|
|
311
|
-
path = str(path).lower()
|
|
312
|
-
|
|
313
|
-
parts = os.path.splitext(path)
|
|
314
|
-
if len(parts) == 2 and len(parts[1]) > 1:
|
|
315
|
-
ext = parts[1][1:]
|
|
316
|
-
else:
|
|
317
|
-
ext = None
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
# allow specific drivers to have a .zip extension to match GDAL behavior
|
|
321
|
-
if ext == 'zip':
|
|
322
|
-
if path.endswith('.shp.zip'):
|
|
323
|
-
ext = 'shp.zip'
|
|
324
|
-
elif path.endswith('.gpkg.zip'):
|
|
325
|
-
ext = 'gpkg.zip'
|
|
326
|
-
|
|
327
|
-
drivers = []
|
|
328
|
-
for i in range(OGRGetDriverCount()):
|
|
329
|
-
driver = OGRGetDriver(i)
|
|
330
|
-
name_c = <char *>OGR_Dr_GetName(driver)
|
|
331
|
-
name = get_string(name_c)
|
|
332
|
-
|
|
333
|
-
if not ogr_driver_supports_write(name):
|
|
334
|
-
continue
|
|
335
|
-
|
|
336
|
-
# extensions is a space-delimited list of supported extensions
|
|
337
|
-
# for driver
|
|
338
|
-
extensions = _get_driver_metadata_item(name, "DMD_EXTENSIONS")
|
|
339
|
-
if ext is not None and extensions is not None and ext in extensions.lower().split(' '):
|
|
340
|
-
drivers.append(name)
|
|
341
|
-
else:
|
|
342
|
-
prefix = _get_driver_metadata_item(name, "DMD_CONNECTION_PREFIX")
|
|
343
|
-
if prefix is not None and path.startswith(prefix.lower()):
|
|
344
|
-
drivers.append(name)
|
|
345
|
-
|
|
346
|
-
return drivers
|
pyogrio/_vsi.pxd
DELETED
pyogrio/_vsi.pyx
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
from io import BytesIO
|
|
2
|
-
from uuid import uuid4
|
|
3
|
-
|
|
4
|
-
from libc.stdlib cimport malloc, free
|
|
5
|
-
from libc.string cimport memcpy
|
|
6
|
-
|
|
7
|
-
from pyogrio._ogr cimport *
|
|
8
|
-
from pyogrio._ogr import _get_driver_metadata_item
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
cdef str get_ogr_vsimem_write_path(object path_or_fp, str driver):
|
|
12
|
-
""" Return the original path or a /vsimem/ path
|
|
13
|
-
|
|
14
|
-
If passed a io.BytesIO object, this will return a /vsimem/ path that can be
|
|
15
|
-
used to create a new in-memory file with an extension inferred from the driver
|
|
16
|
-
if possible. Path will be contained in an in-memory directory to contain
|
|
17
|
-
sibling files (though drivers that create sibling files are not supported for
|
|
18
|
-
in-memory files).
|
|
19
|
-
|
|
20
|
-
Caller is responsible for deleting the directory via delete_vsimem_file()
|
|
21
|
-
|
|
22
|
-
Parameters
|
|
23
|
-
----------
|
|
24
|
-
path_or_fp : str or io.BytesIO object
|
|
25
|
-
driver : str
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
if not isinstance(path_or_fp, BytesIO):
|
|
29
|
-
return path_or_fp
|
|
30
|
-
|
|
31
|
-
# Create in-memory directory to contain auxiliary files
|
|
32
|
-
memfilename = uuid4().hex
|
|
33
|
-
VSIMkdir(f"/vsimem/{memfilename}".encode("UTF-8"), 0666)
|
|
34
|
-
|
|
35
|
-
# file extension is required for some drivers, set it based on driver metadata
|
|
36
|
-
ext = ""
|
|
37
|
-
recommended_ext = _get_driver_metadata_item(driver, "DMD_EXTENSIONS")
|
|
38
|
-
if recommended_ext is not None:
|
|
39
|
-
ext = "." + recommended_ext.split(" ")[0]
|
|
40
|
-
|
|
41
|
-
path = f"/vsimem/{memfilename}/{memfilename}{ext}"
|
|
42
|
-
|
|
43
|
-
# check for existing bytes
|
|
44
|
-
if path_or_fp.getbuffer().nbytes > 0:
|
|
45
|
-
raise NotImplementedError("writing to existing in-memory object is not supported")
|
|
46
|
-
|
|
47
|
-
return path
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
cdef str read_buffer_to_vsimem(bytes bytes_buffer):
|
|
51
|
-
""" Wrap the bytes (zero-copy) into an in-memory dataset
|
|
52
|
-
|
|
53
|
-
If the first 4 bytes indicate the bytes are a zip file, the returned path
|
|
54
|
-
will be prefixed with /vsizip/ and suffixed with .zip to enable proper
|
|
55
|
-
reading by GDAL.
|
|
56
|
-
|
|
57
|
-
Caller is responsible for deleting the in-memory file via delete_vsimem_file().
|
|
58
|
-
|
|
59
|
-
Parameters
|
|
60
|
-
----------
|
|
61
|
-
bytes_buffer : bytes
|
|
62
|
-
"""
|
|
63
|
-
cdef int num_bytes = len(bytes_buffer)
|
|
64
|
-
|
|
65
|
-
is_zipped = len(bytes_buffer) > 4 and bytes_buffer[:4].startswith(b"PK\x03\x04")
|
|
66
|
-
ext = ".zip" if is_zipped else ""
|
|
67
|
-
|
|
68
|
-
path = f"/vsimem/{uuid4().hex}{ext}"
|
|
69
|
-
|
|
70
|
-
# Create an in-memory object that references bytes_buffer
|
|
71
|
-
# NOTE: GDAL does not copy the contents of bytes_buffer; it must remain
|
|
72
|
-
# in scope through the duration of using this file
|
|
73
|
-
vsi_handle = VSIFileFromMemBuffer(path.encode("UTF-8"), <unsigned char *>bytes_buffer, num_bytes, 0)
|
|
74
|
-
|
|
75
|
-
if vsi_handle == NULL:
|
|
76
|
-
raise OSError("failed to read buffer into in-memory file")
|
|
77
|
-
|
|
78
|
-
if VSIFCloseL(vsi_handle) != 0:
|
|
79
|
-
raise OSError("failed to close in-memory file")
|
|
80
|
-
|
|
81
|
-
if is_zipped:
|
|
82
|
-
path = f"/vsizip/{path}"
|
|
83
|
-
|
|
84
|
-
return path
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
cdef read_vsimem_to_buffer(str path, object out_buffer):
|
|
88
|
-
"""Copy bytes from in-memory file to buffer
|
|
89
|
-
|
|
90
|
-
This will automatically unlink the in-memory file pointed to by path; caller
|
|
91
|
-
is still responsible for calling delete_vsimem_file() to cleanup any other
|
|
92
|
-
files contained in the in-memory directory.
|
|
93
|
-
|
|
94
|
-
Parameters:
|
|
95
|
-
-----------
|
|
96
|
-
path : str
|
|
97
|
-
path to in-memory file
|
|
98
|
-
buffer : BytesIO object
|
|
99
|
-
"""
|
|
100
|
-
|
|
101
|
-
cdef unsigned char *vsi_buffer = NULL
|
|
102
|
-
cdef vsi_l_offset vsi_buffer_size = 0
|
|
103
|
-
|
|
104
|
-
try:
|
|
105
|
-
# Take ownership of the buffer to avoid a copy; GDAL will automatically
|
|
106
|
-
# unlink the memory file
|
|
107
|
-
vsi_buffer = VSIGetMemFileBuffer(path.encode("UTF-8"), &vsi_buffer_size, 1)
|
|
108
|
-
if vsi_buffer == NULL:
|
|
109
|
-
raise RuntimeError("could not read bytes from in-memory file")
|
|
110
|
-
|
|
111
|
-
# write bytes to buffer
|
|
112
|
-
out_buffer.write(<bytes>vsi_buffer[:vsi_buffer_size])
|
|
113
|
-
# rewind to beginning to allow caller to read
|
|
114
|
-
out_buffer.seek(0)
|
|
115
|
-
|
|
116
|
-
finally:
|
|
117
|
-
if vsi_buffer != NULL:
|
|
118
|
-
CPLFree(vsi_buffer)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
cdef delete_vsimem_file(str path):
|
|
122
|
-
""" Recursively delete in-memory path or directory containing path
|
|
123
|
-
|
|
124
|
-
This is used for final cleanup of an in-memory dataset, which may have been
|
|
125
|
-
created within a directory to contain sibling files.
|
|
126
|
-
|
|
127
|
-
Additional VSI handlers may be chained to the left of /vsimem/ in path and
|
|
128
|
-
will be ignored.
|
|
129
|
-
|
|
130
|
-
Parameters:
|
|
131
|
-
-----------
|
|
132
|
-
path : str
|
|
133
|
-
path to in-memory file
|
|
134
|
-
"""
|
|
135
|
-
|
|
136
|
-
if "/vsimem/" not in path:
|
|
137
|
-
return
|
|
138
|
-
|
|
139
|
-
root = "/vsimem/" + path.split("/vsimem/")[1].split("/")[0]
|
|
140
|
-
VSIRmdirRecursive(root.encode("UTF-8"))
|
pyogrio/arrow_bridge.h
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
// Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
-
// or more contributor license agreements. See the NOTICE file
|
|
3
|
-
// distributed with this work for additional information
|
|
4
|
-
// regarding copyright ownership. The ASF licenses this file
|
|
5
|
-
// to you under the Apache License, Version 2.0 (the
|
|
6
|
-
// "License"); you may not use this file except in compliance
|
|
7
|
-
// with the License. You may obtain a copy of the License at
|
|
8
|
-
//
|
|
9
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
//
|
|
11
|
-
// Unless required by applicable law or agreed to in writing,
|
|
12
|
-
// software distributed under the License is distributed on an
|
|
13
|
-
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
-
// KIND, either express or implied. See the License for the
|
|
15
|
-
// specific language governing permissions and limitations
|
|
16
|
-
// under the License.
|
|
17
|
-
|
|
18
|
-
// This file is an extract https://github.com/apache/arrow/blob/master/cpp/src/arrow/c/abi.h
|
|
19
|
-
// commit 9cbb8a1a626ee301cfe85905b6c18c5d880e176b (2022-06-14)
|
|
20
|
-
// WARNING: DO NOT MODIFY the content as it would break interoperability !
|
|
21
|
-
|
|
22
|
-
#pragma once
|
|
23
|
-
|
|
24
|
-
#include <stdint.h>
|
|
25
|
-
|
|
26
|
-
#ifdef __cplusplus
|
|
27
|
-
extern "C" {
|
|
28
|
-
#endif
|
|
29
|
-
|
|
30
|
-
#ifndef ARROW_C_DATA_INTERFACE
|
|
31
|
-
#define ARROW_C_DATA_INTERFACE
|
|
32
|
-
|
|
33
|
-
#define ARROW_FLAG_DICTIONARY_ORDERED 1
|
|
34
|
-
#define ARROW_FLAG_NULLABLE 2
|
|
35
|
-
#define ARROW_FLAG_MAP_KEYS_SORTED 4
|
|
36
|
-
|
|
37
|
-
struct ArrowSchema {
|
|
38
|
-
// Array type description
|
|
39
|
-
const char* format;
|
|
40
|
-
const char* name;
|
|
41
|
-
const char* metadata;
|
|
42
|
-
int64_t flags;
|
|
43
|
-
int64_t n_children;
|
|
44
|
-
struct ArrowSchema** children;
|
|
45
|
-
struct ArrowSchema* dictionary;
|
|
46
|
-
|
|
47
|
-
// Release callback
|
|
48
|
-
void (*release)(struct ArrowSchema*);
|
|
49
|
-
// Opaque producer-specific data
|
|
50
|
-
void* private_data;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
struct ArrowArray {
|
|
54
|
-
// Array data description
|
|
55
|
-
int64_t length;
|
|
56
|
-
int64_t null_count;
|
|
57
|
-
int64_t offset;
|
|
58
|
-
int64_t n_buffers;
|
|
59
|
-
int64_t n_children;
|
|
60
|
-
const void** buffers;
|
|
61
|
-
struct ArrowArray** children;
|
|
62
|
-
struct ArrowArray* dictionary;
|
|
63
|
-
|
|
64
|
-
// Release callback
|
|
65
|
-
void (*release)(struct ArrowArray*);
|
|
66
|
-
// Opaque producer-specific data
|
|
67
|
-
void* private_data;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
#endif // ARROW_C_DATA_INTERFACE
|
|
71
|
-
|
|
72
|
-
#ifndef ARROW_C_STREAM_INTERFACE
|
|
73
|
-
#define ARROW_C_STREAM_INTERFACE
|
|
74
|
-
|
|
75
|
-
struct ArrowArrayStream {
|
|
76
|
-
// Callback to get the stream type
|
|
77
|
-
// (will be the same for all arrays in the stream).
|
|
78
|
-
//
|
|
79
|
-
// Return value: 0 if successful, an `errno`-compatible error code otherwise.
|
|
80
|
-
//
|
|
81
|
-
// If successful, the ArrowSchema must be released independently from the stream.
|
|
82
|
-
int (*get_schema)(struct ArrowArrayStream*, struct ArrowSchema* out);
|
|
83
|
-
|
|
84
|
-
// Callback to get the next array
|
|
85
|
-
// (if no error and the array is released, the stream has ended)
|
|
86
|
-
//
|
|
87
|
-
// Return value: 0 if successful, an `errno`-compatible error code otherwise.
|
|
88
|
-
//
|
|
89
|
-
// If successful, the ArrowArray must be released independently from the stream.
|
|
90
|
-
int (*get_next)(struct ArrowArrayStream*, struct ArrowArray* out);
|
|
91
|
-
|
|
92
|
-
// Callback to get optional detailed error information.
|
|
93
|
-
// This must only be called if the last stream operation failed
|
|
94
|
-
// with a non-0 return code.
|
|
95
|
-
//
|
|
96
|
-
// Return value: pointer to a null-terminated character array describing
|
|
97
|
-
// the last error, or NULL if no description is available.
|
|
98
|
-
//
|
|
99
|
-
// The returned pointer is only valid until the next operation on this stream
|
|
100
|
-
// (including release).
|
|
101
|
-
const char* (*get_last_error)(struct ArrowArrayStream*);
|
|
102
|
-
|
|
103
|
-
// Release callback: release the stream's own resources.
|
|
104
|
-
// Note that arrays returned by `get_next` must be individually released.
|
|
105
|
-
void (*release)(struct ArrowArrayStream*);
|
|
106
|
-
|
|
107
|
-
// Opaque producer-specific data
|
|
108
|
-
void* private_data;
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
#endif // ARROW_C_STREAM_INTERFACE
|
|
112
|
-
|
|
113
|
-
#ifdef __cplusplus
|
|
114
|
-
}
|
|
115
|
-
#endif
|