pyogrio 0.9.0__cp312-cp312-manylinux_2_28_aarch64.whl → 0.11.0__cp312-cp312-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.

Files changed (86) hide show
  1. pyogrio/__init__.py +28 -21
  2. pyogrio/_compat.py +15 -1
  3. pyogrio/_env.py +4 -6
  4. pyogrio/_err.cpython-312-aarch64-linux-gnu.so +0 -0
  5. pyogrio/_geometry.cpython-312-aarch64-linux-gnu.so +0 -0
  6. pyogrio/_io.cpython-312-aarch64-linux-gnu.so +0 -0
  7. pyogrio/_ogr.cpython-312-aarch64-linux-gnu.so +0 -0
  8. pyogrio/_version.py +3 -3
  9. pyogrio/_vsi.cpython-312-aarch64-linux-gnu.so +0 -0
  10. pyogrio/core.py +86 -20
  11. pyogrio/errors.py +9 -16
  12. pyogrio/gdal_data/GDAL-targets-release.cmake +3 -3
  13. pyogrio/gdal_data/GDAL-targets.cmake +2 -2
  14. pyogrio/gdal_data/GDALConfig.cmake +0 -1
  15. pyogrio/gdal_data/GDALConfigVersion.cmake +3 -3
  16. pyogrio/gdal_data/MM_m_idofic.csv +321 -0
  17. pyogrio/gdal_data/gdalinfo_output.schema.json +3 -3
  18. pyogrio/gdal_data/gdaltileindex.xsd +253 -0
  19. pyogrio/gdal_data/gdalvrt.xsd +178 -63
  20. pyogrio/gdal_data/nitf_spec.xml +1 -17
  21. pyogrio/gdal_data/nitf_spec.xsd +1 -17
  22. pyogrio/gdal_data/ogrinfo_output.schema.json +23 -0
  23. pyogrio/gdal_data/ogrvrt.xsd +4 -17
  24. pyogrio/gdal_data/osmconf.ini +3 -1
  25. pyogrio/gdal_data/pci_datum.txt +222 -155
  26. pyogrio/gdal_data/pci_ellips.txt +90 -38
  27. pyogrio/gdal_data/pdfcomposition.xsd +1 -17
  28. pyogrio/gdal_data/vcpkg.spdx.json +32 -27
  29. pyogrio/gdal_data/vcpkg_abi_info.txt +30 -29
  30. pyogrio/gdal_data/vdv452.xml +1 -17
  31. pyogrio/gdal_data/vdv452.xsd +1 -17
  32. pyogrio/geopandas.py +122 -66
  33. pyogrio/proj_data/ITRF2014 +1 -1
  34. pyogrio/proj_data/ITRF2020 +91 -0
  35. pyogrio/proj_data/proj-config-version.cmake +2 -2
  36. pyogrio/proj_data/proj-config.cmake +1 -1
  37. pyogrio/proj_data/proj-targets.cmake +3 -3
  38. pyogrio/proj_data/proj.db +0 -0
  39. pyogrio/proj_data/proj.ini +11 -3
  40. pyogrio/proj_data/proj4-targets.cmake +3 -3
  41. pyogrio/proj_data/projjson.schema.json +1 -1
  42. pyogrio/proj_data/usage +7 -2
  43. pyogrio/proj_data/vcpkg.spdx.json +27 -22
  44. pyogrio/proj_data/vcpkg_abi_info.txt +17 -16
  45. pyogrio/raw.py +46 -30
  46. pyogrio/tests/conftest.py +214 -12
  47. pyogrio/tests/fixtures/README.md +32 -13
  48. pyogrio/tests/fixtures/curve.gpkg +0 -0
  49. pyogrio/tests/fixtures/{test_multisurface.gpkg → curvepolygon.gpkg} +0 -0
  50. pyogrio/tests/fixtures/line_zm.gpkg +0 -0
  51. pyogrio/tests/fixtures/multisurface.gpkg +0 -0
  52. pyogrio/tests/test_arrow.py +181 -24
  53. pyogrio/tests/test_core.py +170 -76
  54. pyogrio/tests/test_geopandas_io.py +483 -135
  55. pyogrio/tests/test_path.py +39 -17
  56. pyogrio/tests/test_raw_io.py +170 -55
  57. pyogrio/tests/test_util.py +56 -0
  58. pyogrio/util.py +69 -32
  59. pyogrio-0.11.0.dist-info/METADATA +124 -0
  60. {pyogrio-0.9.0.dist-info → pyogrio-0.11.0.dist-info}/RECORD +200 -214
  61. {pyogrio-0.9.0.dist-info → pyogrio-0.11.0.dist-info}/WHEEL +1 -1
  62. {pyogrio-0.9.0.dist-info → pyogrio-0.11.0.dist-info/licenses}/LICENSE +1 -1
  63. pyogrio.libs/{libgdal-6ff0914e.so.34.3.8.5 → libgdal-4bc0d15f.so.36.3.10.3} +0 -0
  64. pyogrio/_err.pxd +0 -4
  65. pyogrio/_err.pyx +0 -250
  66. pyogrio/_geometry.pxd +0 -4
  67. pyogrio/_geometry.pyx +0 -129
  68. pyogrio/_io.pxd +0 -0
  69. pyogrio/_io.pyx +0 -2742
  70. pyogrio/_ogr.pxd +0 -444
  71. pyogrio/_ogr.pyx +0 -346
  72. pyogrio/_vsi.pxd +0 -4
  73. pyogrio/_vsi.pyx +0 -140
  74. pyogrio/arrow_bridge.h +0 -115
  75. pyogrio/gdal_data/bag_template.xml +0 -201
  76. pyogrio/gdal_data/gmlasconf.xml +0 -169
  77. pyogrio/gdal_data/gmlasconf.xsd +0 -1066
  78. pyogrio/gdal_data/netcdf_config.xsd +0 -143
  79. pyogrio/tests/fixtures/poly_not_enough_points.shp.zip +0 -0
  80. pyogrio/tests/fixtures/test_datetime.geojson +0 -7
  81. pyogrio/tests/fixtures/test_datetime_tz.geojson +0 -8
  82. pyogrio/tests/fixtures/test_fgdb.gdb.zip +0 -0
  83. pyogrio/tests/fixtures/test_nested.geojson +0 -18
  84. pyogrio/tests/fixtures/test_ogr_types_list.geojson +0 -12
  85. pyogrio-0.9.0.dist-info/METADATA +0 -100
  86. {pyogrio-0.9.0.dist-info → pyogrio-0.11.0.dist-info}/top_level.txt +0 -0
pyogrio/util.py CHANGED
@@ -1,13 +1,19 @@
1
- from pathlib import Path
1
+ """Utility functions."""
2
+
2
3
  import re
3
4
  import sys
5
+ from packaging.version import Version
6
+ from pathlib import Path
7
+ from typing import Union
4
8
  from urllib.parse import urlparse
5
9
 
6
- from packaging.version import Version
10
+ from pyogrio._vsi import vsimem_rmtree_toplevel as _vsimem_rmtree_toplevel
11
+
12
+ MULTI_EXTENSIONS = (".gpkg.zip", ".shp.zip")
7
13
 
8
14
 
9
15
  def get_vsi_path_or_buffer(path_or_buffer):
10
- """Get vsi-prefixed path or bytes buffer depending on type of path_or_buffer
16
+ """Get VSI-prefixed path or bytes buffer depending on type of path_or_buffer.
11
17
 
12
18
  If path_or_buffer is a bytes object, it will be returned directly and will
13
19
  be read into an in-memory dataset when passed to one of the Cython functions.
@@ -21,15 +27,17 @@ def get_vsi_path_or_buffer(path_or_buffer):
21
27
  Parameters
22
28
  ----------
23
29
  path_or_buffer : str, pathlib.Path, bytes, or file-like
30
+ A dataset path or URI, raw buffer, or file-like object with a read method.
24
31
 
25
32
  Returns
26
33
  -------
27
34
  str or bytes
28
- """
29
35
 
30
- # force path objects to string to specifically ignore their read method
36
+ """
37
+ # treat Path objects here already to ignore their read method + to avoid backslashes
38
+ # on Windows.
31
39
  if isinstance(path_or_buffer, Path):
32
- return vsi_path(str(path_or_buffer))
40
+ return vsi_path(path_or_buffer)
33
41
 
34
42
  if isinstance(path_or_buffer, bytes):
35
43
  return path_or_buffer
@@ -38,7 +46,7 @@ def get_vsi_path_or_buffer(path_or_buffer):
38
46
  bytes_buffer = path_or_buffer.read()
39
47
 
40
48
  # rewind buffer if possible so that subsequent operations do not need to rewind
41
- if hasattr(path_or_buffer, "seek"):
49
+ if hasattr(path_or_buffer, "seekable") and path_or_buffer.seekable():
42
50
  path_or_buffer.seek(0)
43
51
 
44
52
  return bytes_buffer
@@ -46,16 +54,14 @@ def get_vsi_path_or_buffer(path_or_buffer):
46
54
  return vsi_path(str(path_or_buffer))
47
55
 
48
56
 
49
- def vsi_path(path: str) -> str:
50
- """
51
- Ensure path is a local path or a GDAL-compatible vsi path.
52
-
53
- """
54
-
55
- if "/vsimem/" in path:
56
- raise ValueError(
57
- "path cannot contain /vsimem/ directly; to use an in-memory dataset a bytes object must be passed instead"
58
- )
57
+ def vsi_path(path: Union[str, Path]) -> str:
58
+ """Ensure path is a local path or a GDAL-compatible VSI path."""
59
+ # Convert Path objects to string, but for VSI paths, keep posix style path.
60
+ if isinstance(path, Path):
61
+ if sys.platform == "win32" and path.as_posix().startswith("/vsi"):
62
+ path = path.as_posix()
63
+ else:
64
+ path = str(path)
59
65
 
60
66
  # path is already in GDAL format
61
67
  if path.startswith("/vsi"):
@@ -64,15 +70,23 @@ def vsi_path(path: str) -> str:
64
70
  # Windows drive letters (e.g. "C:\") confuse `urlparse` as they look like
65
71
  # URL schemes
66
72
  if sys.platform == "win32" and re.match("^[a-zA-Z]\\:", path):
73
+ # If it is not a zip file or it is multi-extension zip file that is directly
74
+ # supported by a GDAL driver, return the path as is.
67
75
  if not path.split("!")[0].endswith(".zip"):
68
76
  return path
77
+ if path.split("!")[0].endswith(MULTI_EXTENSIONS):
78
+ return path
69
79
 
70
80
  # prefix then allow to proceed with remaining parsing
71
81
  path = f"zip://{path}"
72
82
 
73
83
  path, archive, scheme = _parse_uri(path)
74
84
 
75
- if scheme or archive or path.endswith(".zip"):
85
+ if (
86
+ scheme
87
+ or archive
88
+ or (path.endswith(".zip") and not path.endswith(MULTI_EXTENSIONS))
89
+ ):
76
90
  return _construct_vsi_path(path, archive, scheme)
77
91
 
78
92
  return path
@@ -98,12 +112,11 @@ SCHEMES = {
98
112
  # those are for now not added as supported URI
99
113
  }
100
114
 
101
- CURLSCHEMES = set([k for k, v in SCHEMES.items() if v == "curl"])
115
+ CURLSCHEMES = {k for k, v in SCHEMES.items() if v == "curl"}
102
116
 
103
117
 
104
118
  def _parse_uri(path: str):
105
- """
106
- Parse a URI
119
+ """Parse a URI.
107
120
 
108
121
  Returns a tuples of (path, archive, scheme)
109
122
 
@@ -138,19 +151,19 @@ def _parse_uri(path: str):
138
151
 
139
152
 
140
153
  def _construct_vsi_path(path, archive, scheme) -> str:
141
- """Convert a parsed path to a GDAL VSI path"""
142
-
154
+ """Convert a parsed path to a GDAL VSI path."""
143
155
  prefix = ""
144
156
  suffix = ""
145
157
  schemes = scheme.split("+")
146
158
 
147
- if "zip" not in schemes and (archive.endswith(".zip") or path.endswith(".zip")):
159
+ if "zip" not in schemes and (
160
+ archive.endswith(".zip")
161
+ or (path.endswith(".zip") and not path.endswith(MULTI_EXTENSIONS))
162
+ ):
148
163
  schemes.insert(0, "zip")
149
164
 
150
165
  if schemes:
151
- prefix = "/".join(
152
- "vsi{0}".format(SCHEMES[p]) for p in schemes if p and p != "file"
153
- )
166
+ prefix = "/".join(f"vsi{SCHEMES[p]}" for p in schemes if p and p != "file")
154
167
 
155
168
  if schemes[-1] in CURLSCHEMES:
156
169
  suffix = f"{schemes[-1]}://"
@@ -159,15 +172,15 @@ def _construct_vsi_path(path, archive, scheme) -> str:
159
172
  if archive:
160
173
  return "/{}/{}{}/{}".format(prefix, suffix, archive, path.lstrip("/"))
161
174
  else:
162
- return "/{}/{}{}".format(prefix, suffix, path)
175
+ return f"/{prefix}/{suffix}{path}"
163
176
 
164
177
  return path
165
178
 
166
179
 
167
180
  def _preprocess_options_key_value(options):
168
- """
169
- Preprocess options, eg `spatial_index=True` gets converted
170
- to `SPATIAL_INDEX="YES"`.
181
+ """Preprocess options.
182
+
183
+ For example, `spatial_index=True` gets converted to `SPATIAL_INDEX="YES"`.
171
184
  """
172
185
  if not isinstance(options, dict):
173
186
  raise TypeError(f"Expected options to be a dict, got {type(options)}")
@@ -191,6 +204,7 @@ def _mask_to_wkb(mask):
191
204
  Parameters
192
205
  ----------
193
206
  mask : Shapely geometry
207
+ The geometry to convert to WKB.
194
208
 
195
209
  Returns
196
210
  -------
@@ -201,8 +215,8 @@ def _mask_to_wkb(mask):
201
215
  ValueError
202
216
  raised if Shapely >= 2.0 is not available or mask is not a Shapely
203
217
  Geometry object
204
- """
205
218
 
219
+ """
206
220
  if mask is None:
207
221
  return mask
208
222
 
@@ -221,3 +235,26 @@ def _mask_to_wkb(mask):
221
235
  raise ValueError("'mask' parameter must be a Shapely geometry")
222
236
 
223
237
  return shapely.to_wkb(mask)
238
+
239
+
240
+ def vsimem_rmtree_toplevel(path: Union[str, Path]):
241
+ """Remove the parent directory of the file path recursively.
242
+
243
+ This is used for final cleanup of an in-memory dataset, which may have been
244
+ created within a directory to contain sibling files.
245
+
246
+ Additional VSI handlers may be chained to the left of /vsimem/ in path and
247
+ will be ignored.
248
+
249
+ Remark: function is defined here to be able to run tests on it.
250
+
251
+ Parameters
252
+ ----------
253
+ path : str or pathlib.Path
254
+ path to in-memory file
255
+
256
+ """
257
+ if isinstance(path, Path):
258
+ path = path.as_posix()
259
+
260
+ _vsimem_rmtree_toplevel(path)
@@ -0,0 +1,124 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyogrio
3
+ Version: 0.11.0
4
+ Summary: Vectorized spatial vector file format I/O using GDAL/OGR
5
+ Author: pyogrio contributors
6
+ Author-email: "Brendan C. Ward" <bcward@astutespruce.com>
7
+ Maintainer: pyogrio contributors
8
+ License: MIT License
9
+
10
+ Copyright (c) 2020-2024 Brendan C. Ward and pyogrio contributors
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+
30
+ Project-URL: Home, https://pyogrio.readthedocs.io/
31
+ Project-URL: Repository, https://github.com/geopandas/pyogrio
32
+ Classifier: Development Status :: 5 - Production/Stable
33
+ Classifier: Intended Audience :: Science/Research
34
+ Classifier: License :: OSI Approved :: MIT License
35
+ Classifier: Operating System :: OS Independent
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Topic :: Scientific/Engineering :: GIS
38
+ Requires-Python: >=3.9
39
+ Description-Content-Type: text/markdown
40
+ License-File: LICENSE
41
+ Requires-Dist: certifi
42
+ Requires-Dist: numpy
43
+ Requires-Dist: packaging
44
+ Provides-Extra: dev
45
+ Requires-Dist: cython; extra == "dev"
46
+ Provides-Extra: test
47
+ Requires-Dist: pytest; extra == "test"
48
+ Requires-Dist: pytest-cov; extra == "test"
49
+ Provides-Extra: benchmark
50
+ Requires-Dist: pytest-benchmark; extra == "benchmark"
51
+ Provides-Extra: geopandas
52
+ Requires-Dist: geopandas; extra == "geopandas"
53
+ Dynamic: license-file
54
+
55
+ # pyogrio - bulk-oriented spatial vector file I/O using GDAL/OGR
56
+
57
+ Pyogrio provides fast, bulk-oriented read and write access to
58
+ [GDAL/OGR](https://gdal.org/en/latest/drivers/vector/index.html) vector data
59
+ sources, such as ESRI Shapefile, GeoPackage, GeoJSON, and several others.
60
+ Vector data sources typically have geometries, such as points, lines, or
61
+ polygons, and associated records with potentially many columns worth of data.
62
+
63
+ The typical use is to read or write these data sources to/from
64
+ [GeoPandas](https://github.com/geopandas/geopandas) `GeoDataFrames`. Because
65
+ the geometry column is optional, reading or writing only non-spatial data is
66
+ also possible. Hence, GeoPackage attribute tables, DBF files, or CSV files are
67
+ also supported.
68
+
69
+ Pyogrio is fast because it uses pre-compiled bindings for GDAL/OGR to read and
70
+ write the data records in bulk. This approach avoids multiple steps of
71
+ converting to and from Python data types within Python, so performance becomes
72
+ primarily limited by the underlying I/O speed of data source drivers in
73
+ GDAL/OGR.
74
+
75
+ We have seen \>5-10x speedups reading files and \>5-20x speedups writing files
76
+ compared to using row-per-row approaches (e.g. Fiona).
77
+
78
+ Read the documentation for more information:
79
+ [https://pyogrio.readthedocs.io](https://pyogrio.readthedocs.io/en/latest/).
80
+
81
+ ## Requirements
82
+
83
+ Supports Python 3.9 - 3.13 and GDAL 3.4.x - 3.9.x.
84
+
85
+ Reading to GeoDataFrames requires `geopandas>=0.12` with `shapely>=2`.
86
+
87
+ Additionally, installing `pyarrow` in combination with GDAL 3.6+ enables
88
+ a further speed-up when specifying `use_arrow=True`.
89
+
90
+ ## Installation
91
+
92
+ Pyogrio is currently available on
93
+ [conda-forge](https://anaconda.org/conda-forge/pyogrio)
94
+ and [PyPI](https://pypi.org/project/pyogrio/)
95
+ for Linux, MacOS, and Windows.
96
+
97
+ Please read the
98
+ [installation documentation](https://pyogrio.readthedocs.io/en/latest/install.html)
99
+ for more information.
100
+
101
+ ## Supported vector formats
102
+
103
+ Pyogrio supports most common vector data source formats (provided they are also
104
+ supported by GDAL/OGR), including ESRI Shapefile, GeoPackage, GeoJSON, and
105
+ FlatGeobuf.
106
+
107
+ Please see the [list of supported formats](https://pyogrio.readthedocs.io/en/latest/supported_formats.html)
108
+ for more information.
109
+
110
+ ## Getting started
111
+
112
+ Please read the [introduction](https://pyogrio.readthedocs.io/en/latest/supported_formats.html)
113
+ for more information and examples to get started using Pyogrio.
114
+
115
+ You can also check out the [API documentation](https://pyogrio.readthedocs.io/en/latest/api.html)
116
+ for full details on using the API.
117
+
118
+ ## Credits
119
+
120
+ This project is made possible by the tremendous efforts of the GDAL, Fiona, and
121
+ Geopandas communities.
122
+
123
+ - Core I/O methods and supporting functions adapted from [Fiona](https://github.com/Toblerity/Fiona)
124
+ - Inspired by [Fiona PR](https://github.com/Toblerity/Fiona/pull/540/files)