pyogrio 0.10.0__cp311-cp311-manylinux_2_28_x86_64.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 (223) hide show
  1. pyogrio/__init__.py +55 -0
  2. pyogrio/_compat.py +47 -0
  3. pyogrio/_env.py +59 -0
  4. pyogrio/_err.cpython-311-x86_64-linux-gnu.so +0 -0
  5. pyogrio/_geometry.cpython-311-x86_64-linux-gnu.so +0 -0
  6. pyogrio/_io.cpython-311-x86_64-linux-gnu.so +0 -0
  7. pyogrio/_ogr.cpython-311-x86_64-linux-gnu.so +0 -0
  8. pyogrio/_version.py +21 -0
  9. pyogrio/_vsi.cpython-311-x86_64-linux-gnu.so +0 -0
  10. pyogrio/core.py +386 -0
  11. pyogrio/errors.py +25 -0
  12. pyogrio/gdal_data/GDAL-targets-release.cmake +19 -0
  13. pyogrio/gdal_data/GDAL-targets.cmake +105 -0
  14. pyogrio/gdal_data/GDALConfig.cmake +24 -0
  15. pyogrio/gdal_data/GDALConfigVersion.cmake +85 -0
  16. pyogrio/gdal_data/GDALLogoBW.svg +138 -0
  17. pyogrio/gdal_data/GDALLogoColor.svg +126 -0
  18. pyogrio/gdal_data/GDALLogoGS.svg +126 -0
  19. pyogrio/gdal_data/LICENSE.TXT +467 -0
  20. pyogrio/gdal_data/MM_m_idofic.csv +321 -0
  21. pyogrio/gdal_data/copyright +467 -0
  22. pyogrio/gdal_data/cubewerx_extra.wkt +48 -0
  23. pyogrio/gdal_data/default.rsc +0 -0
  24. pyogrio/gdal_data/ecw_cs.wkt +1453 -0
  25. pyogrio/gdal_data/eedaconf.json +23 -0
  26. pyogrio/gdal_data/epsg.wkt +1 -0
  27. pyogrio/gdal_data/esri_StatePlane_extra.wkt +631 -0
  28. pyogrio/gdal_data/gdalicon.png +0 -0
  29. pyogrio/gdal_data/gdalinfo_output.schema.json +346 -0
  30. pyogrio/gdal_data/gdalmdiminfo_output.schema.json +321 -0
  31. pyogrio/gdal_data/gdaltileindex.xsd +269 -0
  32. pyogrio/gdal_data/gdalvrt.xsd +880 -0
  33. pyogrio/gdal_data/gfs.xsd +246 -0
  34. pyogrio/gdal_data/gml_registry.xml +117 -0
  35. pyogrio/gdal_data/gml_registry.xsd +66 -0
  36. pyogrio/gdal_data/grib2_center.csv +251 -0
  37. pyogrio/gdal_data/grib2_process.csv +102 -0
  38. pyogrio/gdal_data/grib2_subcenter.csv +63 -0
  39. pyogrio/gdal_data/grib2_table_4_2_0_0.csv +261 -0
  40. pyogrio/gdal_data/grib2_table_4_2_0_1.csv +261 -0
  41. pyogrio/gdal_data/grib2_table_4_2_0_13.csv +261 -0
  42. pyogrio/gdal_data/grib2_table_4_2_0_14.csv +261 -0
  43. pyogrio/gdal_data/grib2_table_4_2_0_15.csv +261 -0
  44. pyogrio/gdal_data/grib2_table_4_2_0_16.csv +261 -0
  45. pyogrio/gdal_data/grib2_table_4_2_0_17.csv +11 -0
  46. pyogrio/gdal_data/grib2_table_4_2_0_18.csv +261 -0
  47. pyogrio/gdal_data/grib2_table_4_2_0_19.csv +261 -0
  48. pyogrio/gdal_data/grib2_table_4_2_0_190.csv +261 -0
  49. pyogrio/gdal_data/grib2_table_4_2_0_191.csv +261 -0
  50. pyogrio/gdal_data/grib2_table_4_2_0_2.csv +261 -0
  51. pyogrio/gdal_data/grib2_table_4_2_0_20.csv +261 -0
  52. pyogrio/gdal_data/grib2_table_4_2_0_21.csv +261 -0
  53. pyogrio/gdal_data/grib2_table_4_2_0_3.csv +261 -0
  54. pyogrio/gdal_data/grib2_table_4_2_0_4.csv +261 -0
  55. pyogrio/gdal_data/grib2_table_4_2_0_5.csv +261 -0
  56. pyogrio/gdal_data/grib2_table_4_2_0_6.csv +261 -0
  57. pyogrio/gdal_data/grib2_table_4_2_0_7.csv +261 -0
  58. pyogrio/gdal_data/grib2_table_4_2_10_0.csv +261 -0
  59. pyogrio/gdal_data/grib2_table_4_2_10_1.csv +261 -0
  60. pyogrio/gdal_data/grib2_table_4_2_10_191.csv +261 -0
  61. pyogrio/gdal_data/grib2_table_4_2_10_2.csv +261 -0
  62. pyogrio/gdal_data/grib2_table_4_2_10_3.csv +261 -0
  63. pyogrio/gdal_data/grib2_table_4_2_10_4.csv +261 -0
  64. pyogrio/gdal_data/grib2_table_4_2_1_0.csv +261 -0
  65. pyogrio/gdal_data/grib2_table_4_2_1_1.csv +261 -0
  66. pyogrio/gdal_data/grib2_table_4_2_1_2.csv +261 -0
  67. pyogrio/gdal_data/grib2_table_4_2_20_0.csv +261 -0
  68. pyogrio/gdal_data/grib2_table_4_2_20_1.csv +261 -0
  69. pyogrio/gdal_data/grib2_table_4_2_20_2.csv +261 -0
  70. pyogrio/gdal_data/grib2_table_4_2_2_0.csv +261 -0
  71. pyogrio/gdal_data/grib2_table_4_2_2_3.csv +261 -0
  72. pyogrio/gdal_data/grib2_table_4_2_2_4.csv +261 -0
  73. pyogrio/gdal_data/grib2_table_4_2_2_5.csv +261 -0
  74. pyogrio/gdal_data/grib2_table_4_2_2_6.csv +261 -0
  75. pyogrio/gdal_data/grib2_table_4_2_3_0.csv +261 -0
  76. pyogrio/gdal_data/grib2_table_4_2_3_1.csv +261 -0
  77. pyogrio/gdal_data/grib2_table_4_2_3_2.csv +28 -0
  78. pyogrio/gdal_data/grib2_table_4_2_3_3.csv +8 -0
  79. pyogrio/gdal_data/grib2_table_4_2_3_4.csv +14 -0
  80. pyogrio/gdal_data/grib2_table_4_2_3_5.csv +11 -0
  81. pyogrio/gdal_data/grib2_table_4_2_3_6.csv +11 -0
  82. pyogrio/gdal_data/grib2_table_4_2_4_0.csv +261 -0
  83. pyogrio/gdal_data/grib2_table_4_2_4_1.csv +261 -0
  84. pyogrio/gdal_data/grib2_table_4_2_4_10.csv +261 -0
  85. pyogrio/gdal_data/grib2_table_4_2_4_2.csv +261 -0
  86. pyogrio/gdal_data/grib2_table_4_2_4_3.csv +261 -0
  87. pyogrio/gdal_data/grib2_table_4_2_4_4.csv +261 -0
  88. pyogrio/gdal_data/grib2_table_4_2_4_5.csv +261 -0
  89. pyogrio/gdal_data/grib2_table_4_2_4_6.csv +261 -0
  90. pyogrio/gdal_data/grib2_table_4_2_4_7.csv +261 -0
  91. pyogrio/gdal_data/grib2_table_4_2_4_8.csv +261 -0
  92. pyogrio/gdal_data/grib2_table_4_2_4_9.csv +261 -0
  93. pyogrio/gdal_data/grib2_table_4_2_local_Canada.csv +5 -0
  94. pyogrio/gdal_data/grib2_table_4_2_local_HPC.csv +2 -0
  95. pyogrio/gdal_data/grib2_table_4_2_local_MRMS.csv +175 -0
  96. pyogrio/gdal_data/grib2_table_4_2_local_NCEP.csv +401 -0
  97. pyogrio/gdal_data/grib2_table_4_2_local_NDFD.csv +38 -0
  98. pyogrio/gdal_data/grib2_table_4_2_local_index.csv +7 -0
  99. pyogrio/gdal_data/grib2_table_4_5.csv +261 -0
  100. pyogrio/gdal_data/grib2_table_versions.csv +3 -0
  101. pyogrio/gdal_data/gt_datum.csv +229 -0
  102. pyogrio/gdal_data/gt_ellips.csv +24 -0
  103. pyogrio/gdal_data/header.dxf +1124 -0
  104. pyogrio/gdal_data/inspire_cp_BasicPropertyUnit.gfs +57 -0
  105. pyogrio/gdal_data/inspire_cp_CadastralBoundary.gfs +60 -0
  106. pyogrio/gdal_data/inspire_cp_CadastralParcel.gfs +81 -0
  107. pyogrio/gdal_data/inspire_cp_CadastralZoning.gfs +161 -0
  108. pyogrio/gdal_data/jpfgdgml_AdmArea.gfs +59 -0
  109. pyogrio/gdal_data/jpfgdgml_AdmBdry.gfs +49 -0
  110. pyogrio/gdal_data/jpfgdgml_AdmPt.gfs +59 -0
  111. pyogrio/gdal_data/jpfgdgml_BldA.gfs +54 -0
  112. pyogrio/gdal_data/jpfgdgml_BldL.gfs +54 -0
  113. pyogrio/gdal_data/jpfgdgml_Cntr.gfs +54 -0
  114. pyogrio/gdal_data/jpfgdgml_CommBdry.gfs +49 -0
  115. pyogrio/gdal_data/jpfgdgml_CommPt.gfs +59 -0
  116. pyogrio/gdal_data/jpfgdgml_Cstline.gfs +54 -0
  117. pyogrio/gdal_data/jpfgdgml_ElevPt.gfs +54 -0
  118. pyogrio/gdal_data/jpfgdgml_GCP.gfs +94 -0
  119. pyogrio/gdal_data/jpfgdgml_LeveeEdge.gfs +49 -0
  120. pyogrio/gdal_data/jpfgdgml_RailCL.gfs +54 -0
  121. pyogrio/gdal_data/jpfgdgml_RdASL.gfs +44 -0
  122. pyogrio/gdal_data/jpfgdgml_RdArea.gfs +54 -0
  123. pyogrio/gdal_data/jpfgdgml_RdCompt.gfs +59 -0
  124. pyogrio/gdal_data/jpfgdgml_RdEdg.gfs +59 -0
  125. pyogrio/gdal_data/jpfgdgml_RdMgtBdry.gfs +49 -0
  126. pyogrio/gdal_data/jpfgdgml_RdSgmtA.gfs +59 -0
  127. pyogrio/gdal_data/jpfgdgml_RvrMgtBdry.gfs +49 -0
  128. pyogrio/gdal_data/jpfgdgml_SBAPt.gfs +49 -0
  129. pyogrio/gdal_data/jpfgdgml_SBArea.gfs +54 -0
  130. pyogrio/gdal_data/jpfgdgml_SBBdry.gfs +44 -0
  131. pyogrio/gdal_data/jpfgdgml_WA.gfs +54 -0
  132. pyogrio/gdal_data/jpfgdgml_WL.gfs +54 -0
  133. pyogrio/gdal_data/jpfgdgml_WStrA.gfs +54 -0
  134. pyogrio/gdal_data/jpfgdgml_WStrL.gfs +54 -0
  135. pyogrio/gdal_data/nitf_spec.xml +3306 -0
  136. pyogrio/gdal_data/nitf_spec.xsd +189 -0
  137. pyogrio/gdal_data/ogrinfo_output.schema.json +528 -0
  138. pyogrio/gdal_data/ogrvrt.xsd +546 -0
  139. pyogrio/gdal_data/osmconf.ini +132 -0
  140. pyogrio/gdal_data/ozi_datum.csv +131 -0
  141. pyogrio/gdal_data/ozi_ellips.csv +35 -0
  142. pyogrio/gdal_data/pci_datum.txt +530 -0
  143. pyogrio/gdal_data/pci_ellips.txt +129 -0
  144. pyogrio/gdal_data/pdfcomposition.xsd +721 -0
  145. pyogrio/gdal_data/pds4_template.xml +65 -0
  146. pyogrio/gdal_data/plscenesconf.json +1985 -0
  147. pyogrio/gdal_data/ruian_vf_ob_v1.gfs +1455 -0
  148. pyogrio/gdal_data/ruian_vf_st_uvoh_v1.gfs +86 -0
  149. pyogrio/gdal_data/ruian_vf_st_v1.gfs +1489 -0
  150. pyogrio/gdal_data/ruian_vf_v1.gfs +2126 -0
  151. pyogrio/gdal_data/s57agencies.csv +249 -0
  152. pyogrio/gdal_data/s57attributes.csv +484 -0
  153. pyogrio/gdal_data/s57expectedinput.csv +1008 -0
  154. pyogrio/gdal_data/s57objectclasses.csv +287 -0
  155. pyogrio/gdal_data/seed_2d.dgn +0 -0
  156. pyogrio/gdal_data/seed_3d.dgn +0 -0
  157. pyogrio/gdal_data/stateplane.csv +259 -0
  158. pyogrio/gdal_data/tms_LINZAntarticaMapTileGrid.json +190 -0
  159. pyogrio/gdal_data/tms_MapML_APSTILE.json +268 -0
  160. pyogrio/gdal_data/tms_MapML_CBMTILE.json +346 -0
  161. pyogrio/gdal_data/tms_NZTM2000.json +243 -0
  162. pyogrio/gdal_data/trailer.dxf +434 -0
  163. pyogrio/gdal_data/usage +4 -0
  164. pyogrio/gdal_data/vcpkg-cmake-wrapper.cmake +23 -0
  165. pyogrio/gdal_data/vcpkg.spdx.json +264 -0
  166. pyogrio/gdal_data/vcpkg_abi_info.txt +41 -0
  167. pyogrio/gdal_data/vdv452.xml +367 -0
  168. pyogrio/gdal_data/vdv452.xsd +63 -0
  169. pyogrio/gdal_data/vicar.json +164 -0
  170. pyogrio/geopandas.py +683 -0
  171. pyogrio/proj_data/CH +22 -0
  172. pyogrio/proj_data/GL27 +23 -0
  173. pyogrio/proj_data/ITRF2000 +24 -0
  174. pyogrio/proj_data/ITRF2008 +94 -0
  175. pyogrio/proj_data/ITRF2014 +55 -0
  176. pyogrio/proj_data/copyright +34 -0
  177. pyogrio/proj_data/deformation_model.schema.json +582 -0
  178. pyogrio/proj_data/nad.lst +142 -0
  179. pyogrio/proj_data/nad27 +810 -0
  180. pyogrio/proj_data/nad83 +745 -0
  181. pyogrio/proj_data/other.extra +53 -0
  182. pyogrio/proj_data/proj-config-version.cmake +44 -0
  183. pyogrio/proj_data/proj-config.cmake +79 -0
  184. pyogrio/proj_data/proj-targets-release.cmake +19 -0
  185. pyogrio/proj_data/proj-targets.cmake +107 -0
  186. pyogrio/proj_data/proj.db +0 -0
  187. pyogrio/proj_data/proj.ini +51 -0
  188. pyogrio/proj_data/proj4-targets-release.cmake +19 -0
  189. pyogrio/proj_data/proj4-targets.cmake +107 -0
  190. pyogrio/proj_data/projjson.schema.json +1174 -0
  191. pyogrio/proj_data/triangulation.schema.json +214 -0
  192. pyogrio/proj_data/usage +4 -0
  193. pyogrio/proj_data/vcpkg.spdx.json +198 -0
  194. pyogrio/proj_data/vcpkg_abi_info.txt +27 -0
  195. pyogrio/proj_data/world +214 -0
  196. pyogrio/raw.py +887 -0
  197. pyogrio/tests/__init__.py +0 -0
  198. pyogrio/tests/conftest.py +398 -0
  199. pyogrio/tests/fixtures/README.md +108 -0
  200. pyogrio/tests/fixtures/curve.gpkg +0 -0
  201. pyogrio/tests/fixtures/curvepolygon.gpkg +0 -0
  202. pyogrio/tests/fixtures/line_zm.gpkg +0 -0
  203. pyogrio/tests/fixtures/multisurface.gpkg +0 -0
  204. pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.cpg +1 -0
  205. pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.dbf +0 -0
  206. pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.prj +1 -0
  207. pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.shp +0 -0
  208. pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.shx +0 -0
  209. pyogrio/tests/fixtures/sample.osm.pbf +0 -0
  210. pyogrio/tests/fixtures/test_gpkg_nulls.gpkg +0 -0
  211. pyogrio/tests/test_arrow.py +1195 -0
  212. pyogrio/tests/test_core.py +678 -0
  213. pyogrio/tests/test_geopandas_io.py +2314 -0
  214. pyogrio/tests/test_path.py +364 -0
  215. pyogrio/tests/test_raw_io.py +1515 -0
  216. pyogrio/tests/test_util.py +56 -0
  217. pyogrio/util.py +247 -0
  218. pyogrio-0.10.0.dist-info/LICENSE +21 -0
  219. pyogrio-0.10.0.dist-info/METADATA +129 -0
  220. pyogrio-0.10.0.dist-info/RECORD +223 -0
  221. pyogrio-0.10.0.dist-info/WHEEL +5 -0
  222. pyogrio-0.10.0.dist-info/top_level.txt +1 -0
  223. pyogrio.libs/libgdal-44263852.so.35.3.9.1 +0 -0
File without changes
@@ -0,0 +1,398 @@
1
+ from io import BytesIO
2
+ from pathlib import Path
3
+ from zipfile import ZIP_DEFLATED, ZipFile
4
+
5
+ import numpy as np
6
+
7
+ from pyogrio import (
8
+ __gdal_version_string__,
9
+ __version__,
10
+ list_drivers,
11
+ )
12
+ from pyogrio._compat import (
13
+ HAS_ARROW_API,
14
+ HAS_ARROW_WRITE_API,
15
+ HAS_GDAL_GEOS,
16
+ HAS_PYARROW,
17
+ HAS_PYPROJ,
18
+ HAS_SHAPELY,
19
+ )
20
+ from pyogrio.core import vsi_rmtree
21
+ from pyogrio.raw import read, write
22
+
23
+ import pytest
24
+
25
+ _data_dir = Path(__file__).parent.resolve() / "fixtures"
26
+
27
+ # mapping of driver extension to driver name for well-supported drivers
28
+ DRIVERS = {
29
+ ".fgb": "FlatGeobuf",
30
+ ".geojson": "GeoJSON",
31
+ ".geojsonl": "GeoJSONSeq",
32
+ ".geojsons": "GeoJSONSeq",
33
+ ".gpkg": "GPKG",
34
+ ".shp": "ESRI Shapefile",
35
+ }
36
+
37
+ # mapping of driver name to extension
38
+ DRIVER_EXT = {driver: ext for ext, driver in DRIVERS.items()}
39
+
40
+ ALL_EXTS = [".fgb", ".geojson", ".geojsonl", ".gpkg", ".shp"]
41
+
42
+ START_FID = {
43
+ ".fgb": 0,
44
+ ".geojson": 0,
45
+ ".geojsonl": 0,
46
+ ".geojsons": 0,
47
+ ".gpkg": 1,
48
+ ".shp": 0,
49
+ }
50
+
51
+
52
+ def pytest_report_header(config):
53
+ drivers = ", ".join(
54
+ f"{driver}({capability})"
55
+ for driver, capability in sorted(list_drivers().items())
56
+ )
57
+ return (
58
+ f"pyogrio {__version__}\n"
59
+ f"GDAL {__gdal_version_string__}\n"
60
+ f"Supported drivers: {drivers}"
61
+ )
62
+
63
+
64
+ # marks to skip tests if optional dependecies are not present
65
+ requires_arrow_api = pytest.mark.skipif(not HAS_ARROW_API, reason="GDAL>=3.6 required")
66
+ requires_pyarrow_api = pytest.mark.skipif(
67
+ not HAS_ARROW_API or not HAS_PYARROW, reason="GDAL>=3.6 and pyarrow required"
68
+ )
69
+
70
+ requires_pyproj = pytest.mark.skipif(not HAS_PYPROJ, reason="pyproj required")
71
+
72
+ requires_arrow_write_api = pytest.mark.skipif(
73
+ not HAS_ARROW_WRITE_API or not HAS_PYARROW,
74
+ reason="GDAL>=3.8 required for Arrow write API",
75
+ )
76
+
77
+ requires_gdal_geos = pytest.mark.skipif(
78
+ not HAS_GDAL_GEOS, reason="GDAL compiled with GEOS required"
79
+ )
80
+
81
+ requires_shapely = pytest.mark.skipif(not HAS_SHAPELY, reason="Shapely >= 2.0 required")
82
+
83
+
84
+ def prepare_testfile(testfile_path, dst_dir, ext):
85
+ if ext == testfile_path.suffix:
86
+ return testfile_path
87
+
88
+ dst_path = dst_dir / f"{testfile_path.stem}{ext}"
89
+ if dst_path.exists():
90
+ return dst_path
91
+
92
+ meta, _, geometry, field_data = read(testfile_path)
93
+
94
+ if ext == ".fgb":
95
+ # For .fgb, spatial_index=False to avoid the rows being reordered
96
+ meta["spatial_index"] = False
97
+ # allow mixed Polygons/MultiPolygons type
98
+ meta["geometry_type"] = "Unknown"
99
+
100
+ elif ext == ".gpkg":
101
+ # For .gpkg, spatial_index=False to avoid the rows being reordered
102
+ meta["spatial_index"] = False
103
+ meta["geometry_type"] = "MultiPolygon"
104
+
105
+ write(dst_path, geometry, field_data, **meta)
106
+ return dst_path
107
+
108
+
109
+ @pytest.fixture(scope="session")
110
+ def data_dir():
111
+ return _data_dir
112
+
113
+
114
+ @pytest.fixture(scope="function")
115
+ def naturalearth_lowres(tmp_path, request):
116
+ ext = getattr(request, "param", ".shp")
117
+ testfile_path = _data_dir / Path("naturalearth_lowres/naturalearth_lowres.shp")
118
+
119
+ return prepare_testfile(testfile_path, tmp_path, ext)
120
+
121
+
122
+ @pytest.fixture(scope="function", params=ALL_EXTS)
123
+ def naturalearth_lowres_all_ext(tmp_path, naturalearth_lowres, request):
124
+ return prepare_testfile(naturalearth_lowres, tmp_path, request.param)
125
+
126
+
127
+ @pytest.fixture(scope="function")
128
+ def naturalearth_lowres_vsi(tmp_path, naturalearth_lowres):
129
+ """Wrap naturalearth_lowres as a zip file for VSI tests"""
130
+
131
+ path = tmp_path / f"{naturalearth_lowres.name}.zip"
132
+ with ZipFile(path, mode="w", compression=ZIP_DEFLATED, compresslevel=5) as out:
133
+ for ext in ["dbf", "prj", "shp", "shx", "cpg"]:
134
+ filename = f"{naturalearth_lowres.stem}.{ext}"
135
+ out.write(naturalearth_lowres.parent / filename, filename)
136
+
137
+ return path, f"/vsizip/{path}/{naturalearth_lowres.name}"
138
+
139
+
140
+ @pytest.fixture(scope="function")
141
+ def naturalearth_lowres_vsimem(naturalearth_lowres):
142
+ """Write naturalearth_lowres to a vsimem file for VSI tests"""
143
+
144
+ meta, _, geometry, field_data = read(naturalearth_lowres)
145
+ name = f"pyogrio_fixture_{naturalearth_lowres.stem}"
146
+ dst_path = Path(f"/vsimem/{name}/{name}.gpkg")
147
+ meta["spatial_index"] = False
148
+ meta["geometry_type"] = "MultiPolygon"
149
+
150
+ write(dst_path, geometry, field_data, layer="naturalearth_lowres", **meta)
151
+ yield dst_path
152
+
153
+ vsi_rmtree(dst_path.parent)
154
+
155
+
156
+ @pytest.fixture(scope="session")
157
+ def line_zm_file():
158
+ return _data_dir / "line_zm.gpkg"
159
+
160
+
161
+ @pytest.fixture(scope="session")
162
+ def curve_file():
163
+ return _data_dir / "curve.gpkg"
164
+
165
+
166
+ @pytest.fixture(scope="session")
167
+ def curve_polygon_file():
168
+ return _data_dir / "curvepolygon.gpkg"
169
+
170
+
171
+ @pytest.fixture(scope="session")
172
+ def multisurface_file():
173
+ return _data_dir / "multisurface.gpkg"
174
+
175
+
176
+ @pytest.fixture(scope="session")
177
+ def test_gpkg_nulls():
178
+ return _data_dir / "test_gpkg_nulls.gpkg"
179
+
180
+
181
+ @pytest.fixture(scope="function")
182
+ def no_geometry_file(tmp_path):
183
+ # create a GPKG layer that does not include geometry
184
+ filename = tmp_path / "test_no_geometry.gpkg"
185
+ write(
186
+ filename,
187
+ layer="no_geometry",
188
+ geometry=None,
189
+ field_data=[np.array(["a", "b", "c"])],
190
+ fields=["col"],
191
+ )
192
+
193
+ return filename
194
+
195
+
196
+ @pytest.fixture(scope="function")
197
+ def list_field_values_file(tmp_path):
198
+ # Create a GeoJSON file with list values in a property
199
+ list_geojson = """{
200
+ "type": "FeatureCollection",
201
+ "features": [
202
+ {
203
+ "type": "Feature",
204
+ "properties": { "int64": 1, "list_int64": [0, 1] },
205
+ "geometry": { "type": "Point", "coordinates": [0, 2] }
206
+ },
207
+ {
208
+ "type": "Feature",
209
+ "properties": { "int64": 2, "list_int64": [2, 3] },
210
+ "geometry": { "type": "Point", "coordinates": [1, 2] }
211
+ },
212
+ {
213
+ "type": "Feature",
214
+ "properties": { "int64": 3, "list_int64": [4, 5] },
215
+ "geometry": { "type": "Point", "coordinates": [2, 2] }
216
+ },
217
+ {
218
+ "type": "Feature",
219
+ "properties": { "int64": 4, "list_int64": [6, 7] },
220
+ "geometry": { "type": "Point", "coordinates": [3, 2] }
221
+ },
222
+ {
223
+ "type": "Feature",
224
+ "properties": { "int64": 5, "list_int64": [8, 9] },
225
+ "geometry": { "type": "Point", "coordinates": [4, 2] }
226
+ }
227
+ ]
228
+ }"""
229
+
230
+ filename = tmp_path / "test_ogr_types_list.geojson"
231
+ with open(filename, "w") as f:
232
+ _ = f.write(list_geojson)
233
+
234
+ return filename
235
+
236
+
237
+ @pytest.fixture(scope="function")
238
+ def nested_geojson_file(tmp_path):
239
+ # create GeoJSON file with nested properties
240
+ nested_geojson = """{
241
+ "type": "FeatureCollection",
242
+ "features": [
243
+ {
244
+ "type": "Feature",
245
+ "geometry": {
246
+ "type": "Point",
247
+ "coordinates": [0, 0]
248
+ },
249
+ "properties": {
250
+ "top_level": "A",
251
+ "intermediate_level": {
252
+ "bottom_level": "B"
253
+ }
254
+ }
255
+ }
256
+ ]
257
+ }"""
258
+
259
+ filename = tmp_path / "test_nested.geojson"
260
+ with open(filename, "w") as f:
261
+ _ = f.write(nested_geojson)
262
+
263
+ return filename
264
+
265
+
266
+ @pytest.fixture(scope="function")
267
+ def datetime_file(tmp_path):
268
+ # create GeoJSON file with millisecond precision
269
+ datetime_geojson = """{
270
+ "type": "FeatureCollection",
271
+ "features": [
272
+ {
273
+ "type": "Feature",
274
+ "properties": { "col": "2020-01-01T09:00:00.123" },
275
+ "geometry": { "type": "Point", "coordinates": [1, 1] }
276
+ },
277
+ {
278
+ "type": "Feature",
279
+ "properties": { "col": "2020-01-01T10:00:00" },
280
+ "geometry": { "type": "Point", "coordinates": [2, 2] }
281
+ }
282
+ ]
283
+ }"""
284
+
285
+ filename = tmp_path / "test_datetime.geojson"
286
+ with open(filename, "w") as f:
287
+ _ = f.write(datetime_geojson)
288
+
289
+ return filename
290
+
291
+
292
+ @pytest.fixture(scope="function")
293
+ def datetime_tz_file(tmp_path):
294
+ # create GeoJSON file with datetimes with timezone
295
+ datetime_tz_geojson = """{
296
+ "type": "FeatureCollection",
297
+ "features": [
298
+ {
299
+ "type": "Feature",
300
+ "properties": { "datetime_col": "2020-01-01T09:00:00.123-05:00" },
301
+ "geometry": { "type": "Point", "coordinates": [1, 1] }
302
+ },
303
+ {
304
+ "type": "Feature",
305
+ "properties": { "datetime_col": "2020-01-01T10:00:00-05:00" },
306
+ "geometry": { "type": "Point", "coordinates": [2, 2] }
307
+ }
308
+ ]
309
+ }"""
310
+
311
+ filename = tmp_path / "test_datetime_tz.geojson"
312
+ with open(filename, "w") as f:
313
+ f.write(datetime_tz_geojson)
314
+
315
+ return filename
316
+
317
+
318
+ @pytest.fixture(scope="function")
319
+ def geojson_bytes(tmp_path):
320
+ """Extracts first 3 records from naturalearth_lowres and writes to GeoJSON,
321
+ returning bytes"""
322
+ meta, _, geometry, field_data = read(
323
+ _data_dir / Path("naturalearth_lowres/naturalearth_lowres.shp"), max_features=3
324
+ )
325
+
326
+ filename = tmp_path / "test.geojson"
327
+ write(filename, geometry, field_data, **meta)
328
+
329
+ with open(filename, "rb") as f:
330
+ bytes_buffer = f.read()
331
+
332
+ return bytes_buffer
333
+
334
+
335
+ @pytest.fixture(scope="function")
336
+ def geojson_filelike(tmp_path):
337
+ """Extracts first 3 records from naturalearth_lowres and writes to GeoJSON,
338
+ returning open file handle"""
339
+ meta, _, geometry, field_data = read(
340
+ _data_dir / Path("naturalearth_lowres/naturalearth_lowres.shp"), max_features=3
341
+ )
342
+
343
+ filename = tmp_path / "test.geojson"
344
+ write(filename, geometry, field_data, layer="test", **meta)
345
+
346
+ with open(filename, "rb") as f:
347
+ yield f
348
+
349
+
350
+ @pytest.fixture(scope="function")
351
+ def nonseekable_bytes(tmp_path):
352
+ # mock a non-seekable byte stream, such as a zstandard handle
353
+ class NonSeekableBytesIO(BytesIO):
354
+ def seekable(self):
355
+ return False
356
+
357
+ def seek(self, *args, **kwargs):
358
+ raise OSError("cannot seek")
359
+
360
+ # wrap GeoJSON into a non-seekable BytesIO
361
+ geojson = """{
362
+ "type": "FeatureCollection",
363
+ "features": [
364
+ {
365
+ "type": "Feature",
366
+ "properties": { },
367
+ "geometry": { "type": "Point", "coordinates": [1, 1] }
368
+ }
369
+ ]
370
+ }"""
371
+
372
+ return NonSeekableBytesIO(geojson.encode("UTF-8"))
373
+
374
+
375
+ @pytest.fixture(
376
+ scope="session",
377
+ params=[
378
+ # Japanese
379
+ ("CP932", "ホ"),
380
+ # Chinese
381
+ ("CP936", "中文"),
382
+ # Central European
383
+ ("CP1250", "Đ"),
384
+ # Latin 1 / Western European
385
+ ("CP1252", "ÿ"),
386
+ # Greek
387
+ ("CP1253", "Φ"),
388
+ # Arabic
389
+ ("CP1256", "ش"),
390
+ ],
391
+ )
392
+ def encoded_text(request):
393
+ """Return tuple with encoding name and very short sample text in that encoding
394
+ NOTE: it was determined through testing that code pages for MS-DOS do not
395
+ consistently work across all Python installations (in particular, fail with conda),
396
+ but ANSI code pages appear to work properly.
397
+ """
398
+ return request.param
@@ -0,0 +1,108 @@
1
+ # Test datasets
2
+
3
+ ## Obtaining / creating test datasets
4
+
5
+ If a test dataset can be created in code, do that instead. If it is used in a
6
+ single test, create the test dataset as part of that test. If it is used in
7
+ more than a single test, add it to `pyogrio/tests/conftest.py` instead, as a
8
+ function-scoped test fixture.
9
+
10
+ If you need to obtain 3rd party test files:
11
+
12
+ - add a section below that describes the source location and processing steps
13
+ to derive that dataset
14
+ - make sure the license is compatible with including in Pyogrio (public domain or open-source)
15
+ and record that license below
16
+
17
+ Please keep the test files no larger than necessary to use in tests.
18
+
19
+ ## Included test datasets
20
+
21
+ ### Natural Earth lowres
22
+
23
+ `naturalearth_lowres.shp` was copied from GeoPandas.
24
+
25
+ License: public domain
26
+
27
+ ### GPKG test dataset with null values
28
+
29
+ `test_gpkg_nulls.gpkg` was created using Fiona backend to GeoPandas:
30
+
31
+ ```
32
+ from collections import OrderedDict
33
+
34
+ import fiona
35
+ import geopandas as gp
36
+ import numpy as np
37
+ from pyogrio import write_dataframe
38
+
39
+ filename = "test_gpkg_nulls.gpkg"
40
+
41
+ df = gp.GeoDataFrame(
42
+ {
43
+ "col_bool": np.array([True, False, True], dtype="bool"),
44
+ "col_int8": np.array([1, 2, 3], dtype="int8"),
45
+ "col_int16": np.array([1, 2, 3], dtype="int16"),
46
+ "col_int32": np.array([1, 2, 3], dtype="int32"),
47
+ "col_int64": np.array([1, 2, 3], dtype="int64"),
48
+ "col_uint8": np.array([1, 2, 3], dtype="uint8"),
49
+ "col_uint16": np.array([1, 2, 3], dtype="uint16"),
50
+ "col_uint32": np.array([1, 2, 3], dtype="uint32"),
51
+ "col_uint64": np.array([1, 2, 3], dtype="uint64"),
52
+ "col_float32": np.array([1.5, 2.5, 3.5], dtype="float32"),
53
+ "col_float64": np.array([1.5, 2.5, 3.5], dtype="float64"),
54
+ },
55
+ geometry=gp.points_from_xy([0, 1, 2], [0, 1, 2]),
56
+ crs="EPSG:4326",
57
+ )
58
+
59
+ write_dataframe(df, filename)
60
+
61
+ # construct row with null values
62
+ # Note: np.nan can only be used for float values
63
+ null_row = {
64
+ "type": "Fetaure",
65
+ "id": 4,
66
+ "properties": OrderedDict(
67
+ [
68
+ ("col_bool", None),
69
+ ("col_int8", None),
70
+ ("col_int16", None),
71
+ ("col_int32", None),
72
+ ("col_int64", None),
73
+ ("col_uint8", None),
74
+ ("col_uint16", None),
75
+ ("col_uint32", None),
76
+ ("col_uint64", None),
77
+ ("col_float32", np.nan),
78
+ ("col_float64", np.nan),
79
+ ]
80
+ ),
81
+ "geometry": {"type": "Point", "coordinates": (4.0, 4.0)},
82
+ }
83
+
84
+ # append row with nulls to GPKG
85
+ with fiona.open(filename, "a") as c:
86
+ c.write(null_row)
87
+ ```
88
+
89
+ NOTE: Reading boolean values into GeoPandas using Fiona backend treats those
90
+ values as `None` and column dtype as `object`; Pyogrio treats those values as
91
+ `np.nan` and column dtype as `float64`.
92
+
93
+ License: same as Pyogrio
94
+
95
+ ### OSM PBF test
96
+
97
+ This was downloaded from https://github.com/openstreetmap/OSM-binary/blob/master/resources/sample.pbf
98
+
99
+ License: [Open Data Commons Open Database License (ODbL)](https://opendatacommons.org/licenses/odbl/)
100
+
101
+ ### Test files for geometry types that are downgraded on read
102
+
103
+ `line_zm.gpkg` was created using QGIS to digitize a LineString GPKG layer with Z and M enabled. Downgraded to LineString Z on read.
104
+ `curve.gpkg` was created using QGIS to digitize a Curve GPKG layer. Downgraded to LineString on read.
105
+ `curvepolygon.gpkg` was created using QGIS to digitize a CurvePolygon GPKG layer. Downgraded to Polygon on read.
106
+ `multisurface.gpkg` was created using QGIS to digitize a MultiSurface GPKG layer. Downgraded to MultiPolygon on read.
107
+
108
+ License: same as Pyogrio
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
Binary file