pyogrio 0.12.0__cp314-cp314t-macosx_12_0_arm64.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.
Files changed (231) hide show
  1. pyogrio/.dylibs/libgdal.37.3.11.4.dylib +0 -0
  2. pyogrio/__init__.py +57 -0
  3. pyogrio/_compat.py +54 -0
  4. pyogrio/_env.py +59 -0
  5. pyogrio/_err.cpython-314t-darwin.so +0 -0
  6. pyogrio/_geometry.cpython-314t-darwin.so +0 -0
  7. pyogrio/_io.cpython-314t-darwin.so +0 -0
  8. pyogrio/_ogr.cpython-314t-darwin.so +0 -0
  9. pyogrio/_version.py +21 -0
  10. pyogrio/_vsi.cpython-314t-darwin.so +0 -0
  11. pyogrio/core.py +387 -0
  12. pyogrio/errors.py +25 -0
  13. pyogrio/gdal_data/GDAL-targets-release.cmake +19 -0
  14. pyogrio/gdal_data/GDAL-targets.cmake +106 -0
  15. pyogrio/gdal_data/GDALConfig.cmake +24 -0
  16. pyogrio/gdal_data/GDALConfigVersion.cmake +65 -0
  17. pyogrio/gdal_data/GDALLogoBW.svg +138 -0
  18. pyogrio/gdal_data/GDALLogoColor.svg +126 -0
  19. pyogrio/gdal_data/GDALLogoGS.svg +126 -0
  20. pyogrio/gdal_data/LICENSE.TXT +467 -0
  21. pyogrio/gdal_data/MM_m_idofic.csv +321 -0
  22. pyogrio/gdal_data/copyright +467 -0
  23. pyogrio/gdal_data/cubewerx_extra.wkt +48 -0
  24. pyogrio/gdal_data/default.rsc +0 -0
  25. pyogrio/gdal_data/ecw_cs.wkt +1453 -0
  26. pyogrio/gdal_data/eedaconf.json +23 -0
  27. pyogrio/gdal_data/epsg.wkt +1 -0
  28. pyogrio/gdal_data/esri_StatePlane_extra.wkt +631 -0
  29. pyogrio/gdal_data/gdal_algorithm.schema.json +220 -0
  30. pyogrio/gdal_data/gdalg.schema.json +36 -0
  31. pyogrio/gdal_data/gdalicon.png +0 -0
  32. pyogrio/gdal_data/gdalinfo_output.schema.json +390 -0
  33. pyogrio/gdal_data/gdalmdiminfo_output.schema.json +326 -0
  34. pyogrio/gdal_data/gdaltileindex.xsd +253 -0
  35. pyogrio/gdal_data/gdalvrt.xsd +927 -0
  36. pyogrio/gdal_data/gfs.xsd +246 -0
  37. pyogrio/gdal_data/gml_registry.xml +117 -0
  38. pyogrio/gdal_data/gml_registry.xsd +66 -0
  39. pyogrio/gdal_data/grib2_center.csv +251 -0
  40. pyogrio/gdal_data/grib2_process.csv +102 -0
  41. pyogrio/gdal_data/grib2_subcenter.csv +63 -0
  42. pyogrio/gdal_data/grib2_table_4_2_0_0.csv +261 -0
  43. pyogrio/gdal_data/grib2_table_4_2_0_1.csv +261 -0
  44. pyogrio/gdal_data/grib2_table_4_2_0_13.csv +261 -0
  45. pyogrio/gdal_data/grib2_table_4_2_0_14.csv +261 -0
  46. pyogrio/gdal_data/grib2_table_4_2_0_15.csv +261 -0
  47. pyogrio/gdal_data/grib2_table_4_2_0_16.csv +261 -0
  48. pyogrio/gdal_data/grib2_table_4_2_0_17.csv +11 -0
  49. pyogrio/gdal_data/grib2_table_4_2_0_18.csv +261 -0
  50. pyogrio/gdal_data/grib2_table_4_2_0_19.csv +261 -0
  51. pyogrio/gdal_data/grib2_table_4_2_0_190.csv +261 -0
  52. pyogrio/gdal_data/grib2_table_4_2_0_191.csv +261 -0
  53. pyogrio/gdal_data/grib2_table_4_2_0_2.csv +261 -0
  54. pyogrio/gdal_data/grib2_table_4_2_0_20.csv +261 -0
  55. pyogrio/gdal_data/grib2_table_4_2_0_21.csv +261 -0
  56. pyogrio/gdal_data/grib2_table_4_2_0_3.csv +261 -0
  57. pyogrio/gdal_data/grib2_table_4_2_0_4.csv +261 -0
  58. pyogrio/gdal_data/grib2_table_4_2_0_5.csv +261 -0
  59. pyogrio/gdal_data/grib2_table_4_2_0_6.csv +261 -0
  60. pyogrio/gdal_data/grib2_table_4_2_0_7.csv +261 -0
  61. pyogrio/gdal_data/grib2_table_4_2_10_0.csv +261 -0
  62. pyogrio/gdal_data/grib2_table_4_2_10_1.csv +261 -0
  63. pyogrio/gdal_data/grib2_table_4_2_10_191.csv +261 -0
  64. pyogrio/gdal_data/grib2_table_4_2_10_2.csv +261 -0
  65. pyogrio/gdal_data/grib2_table_4_2_10_3.csv +261 -0
  66. pyogrio/gdal_data/grib2_table_4_2_10_4.csv +261 -0
  67. pyogrio/gdal_data/grib2_table_4_2_1_0.csv +261 -0
  68. pyogrio/gdal_data/grib2_table_4_2_1_1.csv +261 -0
  69. pyogrio/gdal_data/grib2_table_4_2_1_2.csv +261 -0
  70. pyogrio/gdal_data/grib2_table_4_2_20_0.csv +261 -0
  71. pyogrio/gdal_data/grib2_table_4_2_20_1.csv +261 -0
  72. pyogrio/gdal_data/grib2_table_4_2_20_2.csv +261 -0
  73. pyogrio/gdal_data/grib2_table_4_2_2_0.csv +261 -0
  74. pyogrio/gdal_data/grib2_table_4_2_2_3.csv +261 -0
  75. pyogrio/gdal_data/grib2_table_4_2_2_4.csv +261 -0
  76. pyogrio/gdal_data/grib2_table_4_2_2_5.csv +261 -0
  77. pyogrio/gdal_data/grib2_table_4_2_2_6.csv +261 -0
  78. pyogrio/gdal_data/grib2_table_4_2_3_0.csv +261 -0
  79. pyogrio/gdal_data/grib2_table_4_2_3_1.csv +261 -0
  80. pyogrio/gdal_data/grib2_table_4_2_3_2.csv +28 -0
  81. pyogrio/gdal_data/grib2_table_4_2_3_3.csv +8 -0
  82. pyogrio/gdal_data/grib2_table_4_2_3_4.csv +14 -0
  83. pyogrio/gdal_data/grib2_table_4_2_3_5.csv +11 -0
  84. pyogrio/gdal_data/grib2_table_4_2_3_6.csv +11 -0
  85. pyogrio/gdal_data/grib2_table_4_2_4_0.csv +261 -0
  86. pyogrio/gdal_data/grib2_table_4_2_4_1.csv +261 -0
  87. pyogrio/gdal_data/grib2_table_4_2_4_10.csv +261 -0
  88. pyogrio/gdal_data/grib2_table_4_2_4_2.csv +261 -0
  89. pyogrio/gdal_data/grib2_table_4_2_4_3.csv +261 -0
  90. pyogrio/gdal_data/grib2_table_4_2_4_4.csv +261 -0
  91. pyogrio/gdal_data/grib2_table_4_2_4_5.csv +261 -0
  92. pyogrio/gdal_data/grib2_table_4_2_4_6.csv +261 -0
  93. pyogrio/gdal_data/grib2_table_4_2_4_7.csv +261 -0
  94. pyogrio/gdal_data/grib2_table_4_2_4_8.csv +261 -0
  95. pyogrio/gdal_data/grib2_table_4_2_4_9.csv +261 -0
  96. pyogrio/gdal_data/grib2_table_4_2_local_Canada.csv +5 -0
  97. pyogrio/gdal_data/grib2_table_4_2_local_HPC.csv +2 -0
  98. pyogrio/gdal_data/grib2_table_4_2_local_MRMS.csv +175 -0
  99. pyogrio/gdal_data/grib2_table_4_2_local_NCEP.csv +401 -0
  100. pyogrio/gdal_data/grib2_table_4_2_local_NDFD.csv +38 -0
  101. pyogrio/gdal_data/grib2_table_4_2_local_index.csv +7 -0
  102. pyogrio/gdal_data/grib2_table_4_5.csv +261 -0
  103. pyogrio/gdal_data/grib2_table_versions.csv +3 -0
  104. pyogrio/gdal_data/gt_datum.csv +229 -0
  105. pyogrio/gdal_data/gt_ellips.csv +24 -0
  106. pyogrio/gdal_data/header.dxf +1124 -0
  107. pyogrio/gdal_data/inspire_cp_BasicPropertyUnit.gfs +57 -0
  108. pyogrio/gdal_data/inspire_cp_CadastralBoundary.gfs +60 -0
  109. pyogrio/gdal_data/inspire_cp_CadastralParcel.gfs +81 -0
  110. pyogrio/gdal_data/inspire_cp_CadastralZoning.gfs +161 -0
  111. pyogrio/gdal_data/jpfgdgml_AdmArea.gfs +59 -0
  112. pyogrio/gdal_data/jpfgdgml_AdmBdry.gfs +49 -0
  113. pyogrio/gdal_data/jpfgdgml_AdmPt.gfs +59 -0
  114. pyogrio/gdal_data/jpfgdgml_BldA.gfs +54 -0
  115. pyogrio/gdal_data/jpfgdgml_BldL.gfs +54 -0
  116. pyogrio/gdal_data/jpfgdgml_Cntr.gfs +54 -0
  117. pyogrio/gdal_data/jpfgdgml_CommBdry.gfs +49 -0
  118. pyogrio/gdal_data/jpfgdgml_CommPt.gfs +59 -0
  119. pyogrio/gdal_data/jpfgdgml_Cstline.gfs +54 -0
  120. pyogrio/gdal_data/jpfgdgml_ElevPt.gfs +54 -0
  121. pyogrio/gdal_data/jpfgdgml_GCP.gfs +94 -0
  122. pyogrio/gdal_data/jpfgdgml_LeveeEdge.gfs +49 -0
  123. pyogrio/gdal_data/jpfgdgml_RailCL.gfs +54 -0
  124. pyogrio/gdal_data/jpfgdgml_RdASL.gfs +44 -0
  125. pyogrio/gdal_data/jpfgdgml_RdArea.gfs +54 -0
  126. pyogrio/gdal_data/jpfgdgml_RdCompt.gfs +59 -0
  127. pyogrio/gdal_data/jpfgdgml_RdEdg.gfs +59 -0
  128. pyogrio/gdal_data/jpfgdgml_RdMgtBdry.gfs +49 -0
  129. pyogrio/gdal_data/jpfgdgml_RdSgmtA.gfs +59 -0
  130. pyogrio/gdal_data/jpfgdgml_RvrMgtBdry.gfs +49 -0
  131. pyogrio/gdal_data/jpfgdgml_SBAPt.gfs +49 -0
  132. pyogrio/gdal_data/jpfgdgml_SBArea.gfs +54 -0
  133. pyogrio/gdal_data/jpfgdgml_SBBdry.gfs +44 -0
  134. pyogrio/gdal_data/jpfgdgml_WA.gfs +54 -0
  135. pyogrio/gdal_data/jpfgdgml_WL.gfs +54 -0
  136. pyogrio/gdal_data/jpfgdgml_WStrA.gfs +54 -0
  137. pyogrio/gdal_data/jpfgdgml_WStrL.gfs +54 -0
  138. pyogrio/gdal_data/leaflet_template.html +102 -0
  139. pyogrio/gdal_data/nitf_spec.xml +3288 -0
  140. pyogrio/gdal_data/nitf_spec.xsd +171 -0
  141. pyogrio/gdal_data/ogr_fields_override.schema.json +125 -0
  142. pyogrio/gdal_data/ogrinfo_output.schema.json +528 -0
  143. pyogrio/gdal_data/ogrvrt.xsd +528 -0
  144. pyogrio/gdal_data/osmconf.ini +134 -0
  145. pyogrio/gdal_data/ozi_datum.csv +131 -0
  146. pyogrio/gdal_data/ozi_ellips.csv +35 -0
  147. pyogrio/gdal_data/pci_datum.txt +530 -0
  148. pyogrio/gdal_data/pci_ellips.txt +129 -0
  149. pyogrio/gdal_data/pdfcomposition.xsd +703 -0
  150. pyogrio/gdal_data/pds4_template.xml +65 -0
  151. pyogrio/gdal_data/plscenesconf.json +1985 -0
  152. pyogrio/gdal_data/ruian_vf_ob_v1.gfs +1455 -0
  153. pyogrio/gdal_data/ruian_vf_st_uvoh_v1.gfs +86 -0
  154. pyogrio/gdal_data/ruian_vf_st_v1.gfs +1489 -0
  155. pyogrio/gdal_data/ruian_vf_v1.gfs +2126 -0
  156. pyogrio/gdal_data/s57agencies.csv +249 -0
  157. pyogrio/gdal_data/s57attributes.csv +484 -0
  158. pyogrio/gdal_data/s57expectedinput.csv +1008 -0
  159. pyogrio/gdal_data/s57objectclasses.csv +287 -0
  160. pyogrio/gdal_data/seed_2d.dgn +0 -0
  161. pyogrio/gdal_data/seed_3d.dgn +0 -0
  162. pyogrio/gdal_data/stateplane.csv +259 -0
  163. pyogrio/gdal_data/template_tiles.mapml +28 -0
  164. pyogrio/gdal_data/tms_LINZAntarticaMapTileGrid.json +190 -0
  165. pyogrio/gdal_data/tms_MapML_APSTILE.json +268 -0
  166. pyogrio/gdal_data/tms_MapML_CBMTILE.json +346 -0
  167. pyogrio/gdal_data/tms_NZTM2000.json +243 -0
  168. pyogrio/gdal_data/trailer.dxf +434 -0
  169. pyogrio/gdal_data/usage +4 -0
  170. pyogrio/gdal_data/vcpkg-cmake-wrapper.cmake +23 -0
  171. pyogrio/gdal_data/vcpkg.spdx.json +291 -0
  172. pyogrio/gdal_data/vcpkg_abi_info.txt +45 -0
  173. pyogrio/gdal_data/vdv452.xml +349 -0
  174. pyogrio/gdal_data/vdv452.xsd +45 -0
  175. pyogrio/gdal_data/vicar.json +164 -0
  176. pyogrio/geopandas.py +978 -0
  177. pyogrio/proj_data/CH +22 -0
  178. pyogrio/proj_data/GL27 +23 -0
  179. pyogrio/proj_data/ITRF2000 +24 -0
  180. pyogrio/proj_data/ITRF2008 +94 -0
  181. pyogrio/proj_data/ITRF2014 +55 -0
  182. pyogrio/proj_data/ITRF2020 +91 -0
  183. pyogrio/proj_data/copyright +34 -0
  184. pyogrio/proj_data/deformation_model.schema.json +582 -0
  185. pyogrio/proj_data/nad.lst +142 -0
  186. pyogrio/proj_data/nad27 +810 -0
  187. pyogrio/proj_data/nad83 +745 -0
  188. pyogrio/proj_data/other.extra +53 -0
  189. pyogrio/proj_data/proj-config-version.cmake +44 -0
  190. pyogrio/proj_data/proj-config.cmake +79 -0
  191. pyogrio/proj_data/proj-targets-release.cmake +19 -0
  192. pyogrio/proj_data/proj-targets.cmake +107 -0
  193. pyogrio/proj_data/proj.db +0 -0
  194. pyogrio/proj_data/proj.ini +59 -0
  195. pyogrio/proj_data/proj4-targets-release.cmake +19 -0
  196. pyogrio/proj_data/proj4-targets.cmake +107 -0
  197. pyogrio/proj_data/projjson.schema.json +1174 -0
  198. pyogrio/proj_data/triangulation.schema.json +214 -0
  199. pyogrio/proj_data/usage +9 -0
  200. pyogrio/proj_data/vcpkg.spdx.json +203 -0
  201. pyogrio/proj_data/vcpkg_abi_info.txt +28 -0
  202. pyogrio/proj_data/world +214 -0
  203. pyogrio/raw.py +897 -0
  204. pyogrio/tests/__init__.py +0 -0
  205. pyogrio/tests/conftest.py +588 -0
  206. pyogrio/tests/fixtures/README.md +108 -0
  207. pyogrio/tests/fixtures/curve.gpkg +0 -0
  208. pyogrio/tests/fixtures/curvepolygon.gpkg +0 -0
  209. pyogrio/tests/fixtures/line_zm.gpkg +0 -0
  210. pyogrio/tests/fixtures/list_field_values_file.parquet +0 -0
  211. pyogrio/tests/fixtures/list_nested_struct_file.parquet +0 -0
  212. pyogrio/tests/fixtures/multisurface.gpkg +0 -0
  213. pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.cpg +1 -0
  214. pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.dbf +0 -0
  215. pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.prj +1 -0
  216. pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.shp +0 -0
  217. pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.shx +0 -0
  218. pyogrio/tests/fixtures/sample.osm.pbf +0 -0
  219. pyogrio/tests/fixtures/test_gpkg_nulls.gpkg +0 -0
  220. pyogrio/tests/test_arrow.py +1160 -0
  221. pyogrio/tests/test_core.py +702 -0
  222. pyogrio/tests/test_geopandas_io.py +3218 -0
  223. pyogrio/tests/test_path.py +374 -0
  224. pyogrio/tests/test_raw_io.py +1473 -0
  225. pyogrio/tests/test_util.py +56 -0
  226. pyogrio/util.py +258 -0
  227. pyogrio-0.12.0.dist-info/METADATA +125 -0
  228. pyogrio-0.12.0.dist-info/RECORD +231 -0
  229. pyogrio-0.12.0.dist-info/WHEEL +6 -0
  230. pyogrio-0.12.0.dist-info/licenses/LICENSE +21 -0
  231. pyogrio-0.12.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,56 @@
1
+ from pathlib import Path
2
+
3
+ from pyogrio import vsi_listtree, vsi_unlink
4
+ from pyogrio.raw import read, write
5
+ from pyogrio.util import vsimem_rmtree_toplevel
6
+
7
+ import pytest
8
+
9
+
10
+ def test_vsimem_rmtree_toplevel(naturalearth_lowres):
11
+ # Prepare test data in /vsimem/
12
+ meta, _, geometry, field_data = read(naturalearth_lowres)
13
+ meta["spatial_index"] = False
14
+ meta["geometry_type"] = "MultiPolygon"
15
+ test_dir_path = Path(f"/vsimem/test/{naturalearth_lowres.stem}.gpkg")
16
+ test_dir2_path = Path(f"/vsimem/test2/test2/{naturalearth_lowres.stem}.gpkg")
17
+
18
+ write(test_dir_path, geometry, field_data, **meta)
19
+ write(test_dir2_path, geometry, field_data, **meta)
20
+
21
+ # Check if everything was created properly with listtree
22
+ files = vsi_listtree("/vsimem/")
23
+ assert test_dir_path.as_posix() in files
24
+ assert test_dir2_path.as_posix() in files
25
+
26
+ # Test deleting parent dir of file in single directory
27
+ vsimem_rmtree_toplevel(test_dir_path)
28
+ files = vsi_listtree("/vsimem/")
29
+ assert test_dir_path.parent.as_posix() not in files
30
+ assert test_dir2_path.as_posix() in files
31
+
32
+ # Test deleting top-level dir of file in a subdirectory
33
+ vsimem_rmtree_toplevel(test_dir2_path)
34
+ assert test_dir2_path.as_posix() not in vsi_listtree("/vsimem/")
35
+
36
+
37
+ def test_vsimem_rmtree_toplevel_error(naturalearth_lowres):
38
+ # Prepare test data in /vsimem
39
+ meta, _, geometry, field_data = read(naturalearth_lowres)
40
+ meta["spatial_index"] = False
41
+ meta["geometry_type"] = "MultiPolygon"
42
+ test_file_path = Path(f"/vsimem/pyogrio_test_{naturalearth_lowres.stem}.gpkg")
43
+
44
+ write(test_file_path, geometry, field_data, **meta)
45
+ assert test_file_path.as_posix() in vsi_listtree("/vsimem/")
46
+
47
+ # Deleting parent dir of non-existent file should raise an error.
48
+ with pytest.raises(FileNotFoundError, match="Path does not exist"):
49
+ vsimem_rmtree_toplevel("/vsimem/test/non-existent.gpkg")
50
+
51
+ # File should still be there
52
+ assert test_file_path.as_posix() in vsi_listtree("/vsimem/")
53
+
54
+ # Cleanup.
55
+ vsi_unlink(test_file_path)
56
+ assert test_file_path not in vsi_listtree("/vsimem/")
pyogrio/util.py ADDED
@@ -0,0 +1,258 @@
1
+ """Utility functions."""
2
+
3
+ import re
4
+ import sys
5
+ from packaging.version import Version
6
+ from pathlib import Path
7
+ from urllib.parse import urlparse
8
+
9
+ from pyogrio._ogr import MULTI_EXTENSIONS
10
+ from pyogrio._vsi import vsimem_rmtree_toplevel as _vsimem_rmtree_toplevel
11
+
12
+
13
+ def get_vsi_path_or_buffer(path_or_buffer):
14
+ """Get VSI-prefixed path or bytes buffer depending on type of path_or_buffer.
15
+
16
+ If path_or_buffer is a bytes object, it will be returned directly and will
17
+ be read into an in-memory dataset when passed to one of the Cython functions.
18
+
19
+ If path_or_buffer is a file-like object with a read method, bytes will be
20
+ read from the file-like object and returned.
21
+
22
+ Otherwise, it will be converted to a string, and parsed to prefix with
23
+ appropriate GDAL /vsi*/ prefixes.
24
+
25
+ Parameters
26
+ ----------
27
+ path_or_buffer : str, pathlib.Path, bytes, or file-like
28
+ A dataset path or URI, raw buffer, or file-like object with a read method.
29
+
30
+ Returns
31
+ -------
32
+ str or bytes
33
+
34
+ """
35
+ # treat Path objects here already to ignore their read method + to avoid backslashes
36
+ # on Windows.
37
+ if isinstance(path_or_buffer, Path):
38
+ return vsi_path(path_or_buffer)
39
+
40
+ if isinstance(path_or_buffer, bytes):
41
+ return path_or_buffer
42
+
43
+ if hasattr(path_or_buffer, "read"):
44
+ bytes_buffer = path_or_buffer.read()
45
+
46
+ # rewind buffer if possible so that subsequent operations do not need to rewind
47
+ if hasattr(path_or_buffer, "seekable") and path_or_buffer.seekable():
48
+ path_or_buffer.seek(0)
49
+
50
+ return bytes_buffer
51
+
52
+ return vsi_path(str(path_or_buffer))
53
+
54
+
55
+ def vsi_path(path: str | Path) -> str:
56
+ """Ensure path is a local path or a GDAL-compatible VSI path."""
57
+ # Convert Path objects to string, but for VSI paths, keep posix style path.
58
+ if isinstance(path, Path):
59
+ if sys.platform == "win32" and path.as_posix().startswith("/vsi"):
60
+ path = path.as_posix()
61
+ else:
62
+ path = str(path)
63
+
64
+ # path is already in GDAL format
65
+ if path.startswith("/vsi"):
66
+ return path
67
+
68
+ # Windows drive letters (e.g. "C:\") confuse `urlparse` as they look like
69
+ # URL schemes
70
+ if sys.platform == "win32" and re.match("^[a-zA-Z]\\:", path):
71
+ # If it is not a zip file or it is multi-extension zip file that is directly
72
+ # supported by a GDAL driver, return the path as is.
73
+ if not path.split("!")[0].endswith(".zip"):
74
+ return path
75
+ if path.split("!")[0].endswith(MULTI_EXTENSIONS):
76
+ return path
77
+
78
+ # prefix then allow to proceed with remaining parsing
79
+ path = f"zip://{path}"
80
+
81
+ path, archive, scheme = _parse_uri(path)
82
+
83
+ if (
84
+ scheme
85
+ or archive
86
+ or (path.endswith(".zip") and not path.endswith(MULTI_EXTENSIONS))
87
+ ):
88
+ return _construct_vsi_path(path, archive, scheme)
89
+
90
+ return path
91
+
92
+
93
+ # Supported URI schemes and their mapping to GDAL's VSI suffix.
94
+ SCHEMES = {
95
+ "file": "file",
96
+ "zip": "zip",
97
+ "tar": "tar",
98
+ "gzip": "gzip",
99
+ "http": "curl",
100
+ "https": "curl",
101
+ "ftp": "curl",
102
+ "s3": "s3",
103
+ "gs": "gs",
104
+ "az": "az",
105
+ "adls": "adls",
106
+ "adl": "adls", # fsspec uses this
107
+ "hdfs": "hdfs",
108
+ "webhdfs": "webhdfs",
109
+ # GDAL additionally supports oss and swift for remote filesystems, but
110
+ # those are for now not added as supported URI
111
+ }
112
+
113
+ CURLSCHEMES = {k for k, v in SCHEMES.items() if v == "curl"}
114
+
115
+
116
+ def _parse_uri(path: str):
117
+ """Parse a URI.
118
+
119
+ Returns a tuples of (path, archive, scheme)
120
+
121
+ path : str
122
+ Parsed path. Includes the hostname and query string in the case
123
+ of a URI.
124
+ archive : str
125
+ Parsed archive path.
126
+ scheme : str
127
+ URI scheme such as "https" or "zip+s3".
128
+ """
129
+ parts = urlparse(path, allow_fragments=False)
130
+
131
+ # if the scheme is not one of GDAL's supported schemes, return raw path
132
+ if parts.scheme and not all(p in SCHEMES for p in parts.scheme.split("+")):
133
+ return path, "", ""
134
+
135
+ # we have a URI
136
+ path = parts.path
137
+ scheme = parts.scheme or ""
138
+
139
+ if parts.query:
140
+ path += "?" + parts.query
141
+
142
+ if parts.scheme and parts.netloc:
143
+ path = parts.netloc + path
144
+
145
+ parts = path.split("!")
146
+ path = parts.pop() if parts else ""
147
+ archive = parts.pop() if parts else ""
148
+ return (path, archive, scheme)
149
+
150
+
151
+ def _construct_vsi_path(path, archive, scheme) -> str:
152
+ """Convert a parsed path to a GDAL VSI path."""
153
+ prefix = ""
154
+ suffix = ""
155
+ schemes = scheme.split("+")
156
+
157
+ if "zip" not in schemes and (
158
+ archive.endswith(".zip")
159
+ or (path.endswith(".zip") and not path.endswith(MULTI_EXTENSIONS))
160
+ ):
161
+ schemes.insert(0, "zip")
162
+
163
+ if schemes:
164
+ prefix = "/".join(f"vsi{SCHEMES[p]}" for p in schemes if p and p != "file")
165
+
166
+ if schemes[-1] in CURLSCHEMES:
167
+ suffix = f"{schemes[-1]}://"
168
+
169
+ if prefix:
170
+ if archive:
171
+ return "/{}/{}{}/{}".format(prefix, suffix, archive, path.lstrip("/"))
172
+ else:
173
+ return f"/{prefix}/{suffix}{path}"
174
+
175
+ return path
176
+
177
+
178
+ def _preprocess_options_key_value(options):
179
+ """Preprocess options.
180
+
181
+ For example, `spatial_index=True` gets converted to `SPATIAL_INDEX="YES"`.
182
+ """
183
+ if not isinstance(options, dict):
184
+ raise TypeError(f"Expected options to be a dict, got {type(options)}")
185
+
186
+ result = {}
187
+ for k, v in options.items():
188
+ if v is None:
189
+ continue
190
+ k = k.upper()
191
+ if isinstance(v, bool):
192
+ v = "ON" if v else "OFF"
193
+ else:
194
+ v = str(v)
195
+ result[k] = v
196
+ return result
197
+
198
+
199
+ def _mask_to_wkb(mask):
200
+ """Convert a Shapely mask geometry to WKB.
201
+
202
+ Parameters
203
+ ----------
204
+ mask : Shapely geometry
205
+ The geometry to convert to WKB.
206
+
207
+ Returns
208
+ -------
209
+ WKB bytes or None
210
+
211
+ Raises
212
+ ------
213
+ ValueError
214
+ raised if Shapely >= 2.0 is not available or mask is not a Shapely
215
+ Geometry object
216
+
217
+ """
218
+ if mask is None:
219
+ return mask
220
+
221
+ try:
222
+ import shapely
223
+
224
+ if Version(shapely.__version__) < Version("2.0.0"):
225
+ shapely = None
226
+ except ImportError:
227
+ shapely = None
228
+
229
+ if not shapely:
230
+ raise ValueError("'mask' parameter requires Shapely >= 2.0")
231
+
232
+ if not isinstance(mask, shapely.Geometry):
233
+ raise ValueError("'mask' parameter must be a Shapely geometry")
234
+
235
+ return shapely.to_wkb(mask)
236
+
237
+
238
+ def vsimem_rmtree_toplevel(path: str | Path):
239
+ """Remove the parent directory of the file path recursively.
240
+
241
+ This is used for final cleanup of an in-memory dataset, which may have been
242
+ created within a directory to contain sibling files.
243
+
244
+ Additional VSI handlers may be chained to the left of /vsimem/ in path and
245
+ will be ignored.
246
+
247
+ Remark: function is defined here to be able to run tests on it.
248
+
249
+ Parameters
250
+ ----------
251
+ path : str or pathlib.Path
252
+ path to in-memory file
253
+
254
+ """
255
+ if isinstance(path, Path):
256
+ path = path.as_posix()
257
+
258
+ _vsimem_rmtree_toplevel(path)
@@ -0,0 +1,125 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyogrio
3
+ Version: 0.12.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
+ Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
39
+ Requires-Python: >=3.10
40
+ Description-Content-Type: text/markdown
41
+ License-File: LICENSE
42
+ Requires-Dist: certifi
43
+ Requires-Dist: numpy
44
+ Requires-Dist: packaging
45
+ Provides-Extra: dev
46
+ Requires-Dist: cython>=3.1; extra == "dev"
47
+ Provides-Extra: test
48
+ Requires-Dist: pytest; extra == "test"
49
+ Requires-Dist: pytest-cov; extra == "test"
50
+ Provides-Extra: benchmark
51
+ Requires-Dist: pytest-benchmark; extra == "benchmark"
52
+ Provides-Extra: geopandas
53
+ Requires-Dist: geopandas; extra == "geopandas"
54
+ Dynamic: license-file
55
+
56
+ # pyogrio - bulk-oriented spatial vector file I/O using GDAL/OGR
57
+
58
+ Pyogrio provides fast, bulk-oriented read and write access to
59
+ [GDAL/OGR](https://gdal.org/en/latest/drivers/vector/index.html) vector data
60
+ sources, such as ESRI Shapefile, GeoPackage, GeoJSON, and several others.
61
+ Vector data sources typically have geometries, such as points, lines, or
62
+ polygons, and associated records with potentially many columns worth of data.
63
+
64
+ The typical use is to read or write these data sources to/from
65
+ [GeoPandas](https://github.com/geopandas/geopandas) `GeoDataFrames`. Because
66
+ the geometry column is optional, reading or writing only non-spatial data is
67
+ also possible. Hence, GeoPackage attribute tables, DBF files, or CSV files are
68
+ also supported.
69
+
70
+ Pyogrio is fast because it uses pre-compiled bindings for GDAL/OGR to read and
71
+ write the data records in bulk. This approach avoids multiple steps of
72
+ converting to and from Python data types within Python, so performance becomes
73
+ primarily limited by the underlying I/O speed of data source drivers in
74
+ GDAL/OGR.
75
+
76
+ We have seen \>5-10x speedups reading files and \>5-20x speedups writing files
77
+ compared to using row-per-row approaches (e.g. Fiona).
78
+
79
+ Read the documentation for more information:
80
+ [https://pyogrio.readthedocs.io](https://pyogrio.readthedocs.io/en/latest/).
81
+
82
+ ## Requirements
83
+
84
+ Supports Python 3.10 - 3.14 and GDAL 3.6.x - 3.11.x.
85
+
86
+ Reading to GeoDataFrames requires `geopandas>=0.12` with `shapely>=2`.
87
+
88
+ Additionally, installing `pyarrow` in combination with GDAL 3.6+ enables
89
+ a further speed-up when specifying `use_arrow=True`.
90
+
91
+ ## Installation
92
+
93
+ Pyogrio is currently available on
94
+ [conda-forge](https://anaconda.org/conda-forge/pyogrio)
95
+ and [PyPI](https://pypi.org/project/pyogrio/)
96
+ for Linux, MacOS, and Windows.
97
+
98
+ Please read the
99
+ [installation documentation](https://pyogrio.readthedocs.io/en/latest/install.html)
100
+ for more information.
101
+
102
+ ## Supported vector formats
103
+
104
+ Pyogrio supports most common vector data source formats (provided they are also
105
+ supported by GDAL/OGR), including ESRI Shapefile, GeoPackage, GeoJSON, and
106
+ FlatGeobuf.
107
+
108
+ Please see the [list of supported formats](https://pyogrio.readthedocs.io/en/latest/supported_formats.html)
109
+ for more information.
110
+
111
+ ## Getting started
112
+
113
+ Please read the [introduction](https://pyogrio.readthedocs.io/en/latest/supported_formats.html)
114
+ for more information and examples to get started using Pyogrio.
115
+
116
+ You can also check out the [API documentation](https://pyogrio.readthedocs.io/en/latest/api.html)
117
+ for full details on using the API.
118
+
119
+ ## Credits
120
+
121
+ This project is made possible by the tremendous efforts of the GDAL, Fiona, and
122
+ Geopandas communities.
123
+
124
+ - Core I/O methods and supporting functions adapted from [Fiona](https://github.com/Toblerity/Fiona)
125
+ - Inspired by [Fiona PR](https://github.com/Toblerity/Fiona/pull/540/files)