pyogrio 0.9.0__cp310-cp310-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.
Potentially problematic release.
This version of pyogrio might be problematic. Click here for more details.
- pyogrio/.dylibs/libgdal.34.3.8.5.dylib +0 -0
- pyogrio/__init__.py +48 -0
- pyogrio/_compat.py +41 -0
- pyogrio/_env.py +61 -0
- pyogrio/_err.cpython-310-darwin.so +0 -0
- pyogrio/_err.pxd +4 -0
- pyogrio/_err.pyx +250 -0
- pyogrio/_geometry.cpython-310-darwin.so +0 -0
- pyogrio/_geometry.pxd +4 -0
- pyogrio/_geometry.pyx +129 -0
- pyogrio/_io.cpython-310-darwin.so +0 -0
- pyogrio/_io.pxd +0 -0
- pyogrio/_io.pyx +2742 -0
- pyogrio/_ogr.cpython-310-darwin.so +0 -0
- pyogrio/_ogr.pxd +444 -0
- pyogrio/_ogr.pyx +346 -0
- pyogrio/_version.py +21 -0
- pyogrio/_vsi.cpython-310-darwin.so +0 -0
- pyogrio/_vsi.pxd +4 -0
- pyogrio/_vsi.pyx +140 -0
- pyogrio/arrow_bridge.h +115 -0
- pyogrio/core.py +320 -0
- pyogrio/errors.py +32 -0
- pyogrio/gdal_data/GDAL-targets-release.cmake +19 -0
- pyogrio/gdal_data/GDAL-targets.cmake +105 -0
- pyogrio/gdal_data/GDALConfig.cmake +25 -0
- pyogrio/gdal_data/GDALConfigVersion.cmake +85 -0
- pyogrio/gdal_data/GDALLogoBW.svg +138 -0
- pyogrio/gdal_data/GDALLogoColor.svg +126 -0
- pyogrio/gdal_data/GDALLogoGS.svg +126 -0
- pyogrio/gdal_data/LICENSE.TXT +467 -0
- pyogrio/gdal_data/bag_template.xml +201 -0
- pyogrio/gdal_data/copyright +467 -0
- pyogrio/gdal_data/cubewerx_extra.wkt +48 -0
- pyogrio/gdal_data/default.rsc +0 -0
- pyogrio/gdal_data/ecw_cs.wkt +1453 -0
- pyogrio/gdal_data/eedaconf.json +23 -0
- pyogrio/gdal_data/epsg.wkt +1 -0
- pyogrio/gdal_data/esri_StatePlane_extra.wkt +631 -0
- pyogrio/gdal_data/gdalicon.png +0 -0
- pyogrio/gdal_data/gdalinfo_output.schema.json +346 -0
- pyogrio/gdal_data/gdalmdiminfo_output.schema.json +321 -0
- pyogrio/gdal_data/gdalvrt.xsd +772 -0
- pyogrio/gdal_data/gfs.xsd +246 -0
- pyogrio/gdal_data/gml_registry.xml +117 -0
- pyogrio/gdal_data/gml_registry.xsd +66 -0
- pyogrio/gdal_data/gmlasconf.xml +169 -0
- pyogrio/gdal_data/gmlasconf.xsd +1066 -0
- pyogrio/gdal_data/grib2_center.csv +251 -0
- pyogrio/gdal_data/grib2_process.csv +102 -0
- pyogrio/gdal_data/grib2_subcenter.csv +63 -0
- pyogrio/gdal_data/grib2_table_4_2_0_0.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_1.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_13.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_14.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_15.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_16.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_17.csv +11 -0
- pyogrio/gdal_data/grib2_table_4_2_0_18.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_19.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_190.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_191.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_2.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_20.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_21.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_3.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_4.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_5.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_6.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_0_7.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_10_0.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_10_1.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_10_191.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_10_2.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_10_3.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_10_4.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_1_0.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_1_1.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_1_2.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_20_0.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_20_1.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_20_2.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_2_0.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_2_3.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_2_4.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_2_5.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_2_6.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_3_0.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_3_1.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_3_2.csv +28 -0
- pyogrio/gdal_data/grib2_table_4_2_3_3.csv +8 -0
- pyogrio/gdal_data/grib2_table_4_2_3_4.csv +14 -0
- pyogrio/gdal_data/grib2_table_4_2_3_5.csv +11 -0
- pyogrio/gdal_data/grib2_table_4_2_3_6.csv +11 -0
- pyogrio/gdal_data/grib2_table_4_2_4_0.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_4_1.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_4_10.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_4_2.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_4_3.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_4_4.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_4_5.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_4_6.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_4_7.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_4_8.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_4_9.csv +261 -0
- pyogrio/gdal_data/grib2_table_4_2_local_Canada.csv +5 -0
- pyogrio/gdal_data/grib2_table_4_2_local_HPC.csv +2 -0
- pyogrio/gdal_data/grib2_table_4_2_local_MRMS.csv +175 -0
- pyogrio/gdal_data/grib2_table_4_2_local_NCEP.csv +401 -0
- pyogrio/gdal_data/grib2_table_4_2_local_NDFD.csv +38 -0
- pyogrio/gdal_data/grib2_table_4_2_local_index.csv +7 -0
- pyogrio/gdal_data/grib2_table_4_5.csv +261 -0
- pyogrio/gdal_data/grib2_table_versions.csv +3 -0
- pyogrio/gdal_data/gt_datum.csv +229 -0
- pyogrio/gdal_data/gt_ellips.csv +24 -0
- pyogrio/gdal_data/header.dxf +1124 -0
- pyogrio/gdal_data/inspire_cp_BasicPropertyUnit.gfs +57 -0
- pyogrio/gdal_data/inspire_cp_CadastralBoundary.gfs +60 -0
- pyogrio/gdal_data/inspire_cp_CadastralParcel.gfs +81 -0
- pyogrio/gdal_data/inspire_cp_CadastralZoning.gfs +161 -0
- pyogrio/gdal_data/jpfgdgml_AdmArea.gfs +59 -0
- pyogrio/gdal_data/jpfgdgml_AdmBdry.gfs +49 -0
- pyogrio/gdal_data/jpfgdgml_AdmPt.gfs +59 -0
- pyogrio/gdal_data/jpfgdgml_BldA.gfs +54 -0
- pyogrio/gdal_data/jpfgdgml_BldL.gfs +54 -0
- pyogrio/gdal_data/jpfgdgml_Cntr.gfs +54 -0
- pyogrio/gdal_data/jpfgdgml_CommBdry.gfs +49 -0
- pyogrio/gdal_data/jpfgdgml_CommPt.gfs +59 -0
- pyogrio/gdal_data/jpfgdgml_Cstline.gfs +54 -0
- pyogrio/gdal_data/jpfgdgml_ElevPt.gfs +54 -0
- pyogrio/gdal_data/jpfgdgml_GCP.gfs +94 -0
- pyogrio/gdal_data/jpfgdgml_LeveeEdge.gfs +49 -0
- pyogrio/gdal_data/jpfgdgml_RailCL.gfs +54 -0
- pyogrio/gdal_data/jpfgdgml_RdASL.gfs +44 -0
- pyogrio/gdal_data/jpfgdgml_RdArea.gfs +54 -0
- pyogrio/gdal_data/jpfgdgml_RdCompt.gfs +59 -0
- pyogrio/gdal_data/jpfgdgml_RdEdg.gfs +59 -0
- pyogrio/gdal_data/jpfgdgml_RdMgtBdry.gfs +49 -0
- pyogrio/gdal_data/jpfgdgml_RdSgmtA.gfs +59 -0
- pyogrio/gdal_data/jpfgdgml_RvrMgtBdry.gfs +49 -0
- pyogrio/gdal_data/jpfgdgml_SBAPt.gfs +49 -0
- pyogrio/gdal_data/jpfgdgml_SBArea.gfs +54 -0
- pyogrio/gdal_data/jpfgdgml_SBBdry.gfs +44 -0
- pyogrio/gdal_data/jpfgdgml_WA.gfs +54 -0
- pyogrio/gdal_data/jpfgdgml_WL.gfs +54 -0
- pyogrio/gdal_data/jpfgdgml_WStrA.gfs +54 -0
- pyogrio/gdal_data/jpfgdgml_WStrL.gfs +54 -0
- pyogrio/gdal_data/netcdf_config.xsd +143 -0
- pyogrio/gdal_data/nitf_spec.xml +3306 -0
- pyogrio/gdal_data/nitf_spec.xsd +189 -0
- pyogrio/gdal_data/ogrinfo_output.schema.json +505 -0
- pyogrio/gdal_data/ogrvrt.xsd +543 -0
- pyogrio/gdal_data/osmconf.ini +132 -0
- pyogrio/gdal_data/ozi_datum.csv +131 -0
- pyogrio/gdal_data/ozi_ellips.csv +35 -0
- pyogrio/gdal_data/pci_datum.txt +463 -0
- pyogrio/gdal_data/pci_ellips.txt +77 -0
- pyogrio/gdal_data/pdfcomposition.xsd +721 -0
- pyogrio/gdal_data/pds4_template.xml +65 -0
- pyogrio/gdal_data/plscenesconf.json +1985 -0
- pyogrio/gdal_data/ruian_vf_ob_v1.gfs +1455 -0
- pyogrio/gdal_data/ruian_vf_st_uvoh_v1.gfs +86 -0
- pyogrio/gdal_data/ruian_vf_st_v1.gfs +1489 -0
- pyogrio/gdal_data/ruian_vf_v1.gfs +2126 -0
- pyogrio/gdal_data/s57agencies.csv +249 -0
- pyogrio/gdal_data/s57attributes.csv +484 -0
- pyogrio/gdal_data/s57expectedinput.csv +1008 -0
- pyogrio/gdal_data/s57objectclasses.csv +287 -0
- pyogrio/gdal_data/seed_2d.dgn +0 -0
- pyogrio/gdal_data/seed_3d.dgn +0 -0
- pyogrio/gdal_data/stateplane.csv +259 -0
- pyogrio/gdal_data/template_tiles.mapml +28 -0
- pyogrio/gdal_data/tms_LINZAntarticaMapTileGrid.json +190 -0
- pyogrio/gdal_data/tms_MapML_APSTILE.json +268 -0
- pyogrio/gdal_data/tms_MapML_CBMTILE.json +346 -0
- pyogrio/gdal_data/tms_NZTM2000.json +243 -0
- pyogrio/gdal_data/trailer.dxf +434 -0
- pyogrio/gdal_data/usage +4 -0
- pyogrio/gdal_data/vcpkg-cmake-wrapper.cmake +23 -0
- pyogrio/gdal_data/vcpkg.spdx.json +264 -0
- pyogrio/gdal_data/vcpkg_abi_info.txt +41 -0
- pyogrio/gdal_data/vdv452.xml +367 -0
- pyogrio/gdal_data/vdv452.xsd +63 -0
- pyogrio/gdal_data/vicar.json +164 -0
- pyogrio/geopandas.py +675 -0
- pyogrio/proj_data/CH +22 -0
- pyogrio/proj_data/GL27 +23 -0
- pyogrio/proj_data/ITRF2000 +24 -0
- pyogrio/proj_data/ITRF2008 +94 -0
- pyogrio/proj_data/ITRF2014 +55 -0
- pyogrio/proj_data/copyright +34 -0
- pyogrio/proj_data/deformation_model.schema.json +582 -0
- pyogrio/proj_data/nad.lst +142 -0
- pyogrio/proj_data/nad27 +810 -0
- pyogrio/proj_data/nad83 +745 -0
- pyogrio/proj_data/other.extra +53 -0
- pyogrio/proj_data/proj-config-version.cmake +44 -0
- pyogrio/proj_data/proj-config.cmake +79 -0
- pyogrio/proj_data/proj-targets-release.cmake +19 -0
- pyogrio/proj_data/proj-targets.cmake +107 -0
- pyogrio/proj_data/proj.db +0 -0
- pyogrio/proj_data/proj.ini +51 -0
- pyogrio/proj_data/proj4-targets-release.cmake +19 -0
- pyogrio/proj_data/proj4-targets.cmake +107 -0
- pyogrio/proj_data/projjson.schema.json +1174 -0
- pyogrio/proj_data/triangulation.schema.json +214 -0
- pyogrio/proj_data/usage +4 -0
- pyogrio/proj_data/vcpkg.spdx.json +198 -0
- pyogrio/proj_data/vcpkg_abi_info.txt +27 -0
- pyogrio/proj_data/world +214 -0
- pyogrio/raw.py +871 -0
- pyogrio/tests/__init__.py +0 -0
- pyogrio/tests/conftest.py +204 -0
- pyogrio/tests/fixtures/README.md +89 -0
- pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.cpg +1 -0
- pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.dbf +0 -0
- pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.prj +1 -0
- pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.shp +0 -0
- pyogrio/tests/fixtures/naturalearth_lowres/naturalearth_lowres.shx +0 -0
- pyogrio/tests/fixtures/poly_not_enough_points.shp.zip +0 -0
- pyogrio/tests/fixtures/sample.osm.pbf +0 -0
- pyogrio/tests/fixtures/test_datetime.geojson +7 -0
- pyogrio/tests/fixtures/test_datetime_tz.geojson +8 -0
- pyogrio/tests/fixtures/test_fgdb.gdb.zip +0 -0
- pyogrio/tests/fixtures/test_gpkg_nulls.gpkg +0 -0
- pyogrio/tests/fixtures/test_multisurface.gpkg +0 -0
- pyogrio/tests/fixtures/test_nested.geojson +18 -0
- pyogrio/tests/fixtures/test_ogr_types_list.geojson +12 -0
- pyogrio/tests/test_arrow.py +1041 -0
- pyogrio/tests/test_core.py +588 -0
- pyogrio/tests/test_geopandas_io.py +2174 -0
- pyogrio/tests/test_path.py +352 -0
- pyogrio/tests/test_raw_io.py +1404 -0
- pyogrio/util.py +223 -0
- pyogrio-0.9.0.dist-info/LICENSE +21 -0
- pyogrio-0.9.0.dist-info/METADATA +100 -0
- pyogrio-0.9.0.dist-info/RECORD +239 -0
- pyogrio-0.9.0.dist-info/WHEEL +5 -0
- pyogrio-0.9.0.dist-info/top_level.txt +1 -0
|
Binary file
|
pyogrio/__init__.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
try:
|
|
2
|
+
# we try importing shapely, to ensure it is imported (and it can load its
|
|
3
|
+
# own GEOS copy) before we load GDAL and its linked GEOS
|
|
4
|
+
import shapely # noqa
|
|
5
|
+
import shapely.geos # noqa
|
|
6
|
+
except Exception:
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
from pyogrio.core import (
|
|
10
|
+
list_drivers,
|
|
11
|
+
detect_write_driver,
|
|
12
|
+
list_layers,
|
|
13
|
+
read_bounds,
|
|
14
|
+
read_info,
|
|
15
|
+
set_gdal_config_options,
|
|
16
|
+
get_gdal_config_option,
|
|
17
|
+
get_gdal_data_path,
|
|
18
|
+
__gdal_version__,
|
|
19
|
+
__gdal_version_string__,
|
|
20
|
+
__gdal_geos_version__,
|
|
21
|
+
)
|
|
22
|
+
from pyogrio.raw import read_arrow, open_arrow, write_arrow
|
|
23
|
+
from pyogrio.geopandas import read_dataframe, write_dataframe
|
|
24
|
+
from pyogrio._version import get_versions
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
__version__ = get_versions()["version"]
|
|
28
|
+
del get_versions
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
"list_drivers",
|
|
32
|
+
"detect_write_driver",
|
|
33
|
+
"list_layers",
|
|
34
|
+
"read_bounds",
|
|
35
|
+
"read_info",
|
|
36
|
+
"set_gdal_config_options",
|
|
37
|
+
"get_gdal_config_option",
|
|
38
|
+
"get_gdal_data_path",
|
|
39
|
+
"read_arrow",
|
|
40
|
+
"open_arrow",
|
|
41
|
+
"write_arrow",
|
|
42
|
+
"read_dataframe",
|
|
43
|
+
"write_dataframe",
|
|
44
|
+
"__gdal_version__",
|
|
45
|
+
"__gdal_version_string__",
|
|
46
|
+
"__gdal_geos_version__",
|
|
47
|
+
"__version__",
|
|
48
|
+
]
|
pyogrio/_compat.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from packaging.version import Version
|
|
2
|
+
|
|
3
|
+
from pyogrio.core import __gdal_version__, __gdal_geos_version__
|
|
4
|
+
|
|
5
|
+
# detect optional dependencies
|
|
6
|
+
try:
|
|
7
|
+
import pyarrow
|
|
8
|
+
except ImportError:
|
|
9
|
+
pyarrow = None
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
import shapely
|
|
13
|
+
except ImportError:
|
|
14
|
+
shapely = None
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
import geopandas
|
|
18
|
+
except ImportError:
|
|
19
|
+
geopandas = None
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
import pandas
|
|
23
|
+
except ImportError:
|
|
24
|
+
pandas = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
HAS_ARROW_API = __gdal_version__ >= (3, 6, 0)
|
|
28
|
+
HAS_ARROW_WRITE_API = __gdal_version__ >= (3, 8, 0)
|
|
29
|
+
HAS_PYARROW = pyarrow is not None
|
|
30
|
+
|
|
31
|
+
HAS_GEOPANDAS = geopandas is not None
|
|
32
|
+
|
|
33
|
+
PANDAS_GE_15 = pandas is not None and Version(pandas.__version__) >= Version("1.5.0")
|
|
34
|
+
PANDAS_GE_20 = pandas is not None and Version(pandas.__version__) >= Version("2.0.0")
|
|
35
|
+
PANDAS_GE_22 = pandas is not None and Version(pandas.__version__) >= Version("2.2.0")
|
|
36
|
+
|
|
37
|
+
GDAL_GE_38 = __gdal_version__ >= (3, 8, 0)
|
|
38
|
+
|
|
39
|
+
HAS_GDAL_GEOS = __gdal_geos_version__ is not None
|
|
40
|
+
|
|
41
|
+
HAS_SHAPELY = shapely is not None and Version(shapely.__version__) >= Version("2.0.0")
|
pyogrio/_env.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# With Python >= 3.8 on Windows directories in PATH are not automatically
|
|
2
|
+
# searched for DLL dependencies and must be added manually with
|
|
3
|
+
# os.add_dll_directory.
|
|
4
|
+
# adapted from Fiona: https://github.com/Toblerity/Fiona/pull/875
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
from contextlib import contextmanager
|
|
8
|
+
import logging
|
|
9
|
+
import os
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
import platform
|
|
12
|
+
import sys
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
log = logging.getLogger(__name__)
|
|
16
|
+
log.addHandler(logging.NullHandler())
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
# set GDAL_CURL_CA_BUNDLE / PROJ_CURL_CA_BUNDLE for GDAL >= 3.2
|
|
21
|
+
import certifi
|
|
22
|
+
|
|
23
|
+
ca_bundle = certifi.where()
|
|
24
|
+
os.environ.setdefault("GDAL_CURL_CA_BUNDLE", ca_bundle)
|
|
25
|
+
os.environ.setdefault("PROJ_CURL_CA_BUNDLE", ca_bundle)
|
|
26
|
+
except ImportError:
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
gdal_dll_dir = None
|
|
31
|
+
|
|
32
|
+
if platform.system() == "Windows" and sys.version_info >= (3, 8):
|
|
33
|
+
# if loading of extension modules fails, search for gdal dll directory
|
|
34
|
+
try:
|
|
35
|
+
import pyogrio._io # NOQA
|
|
36
|
+
|
|
37
|
+
except ImportError:
|
|
38
|
+
for path in os.getenv("PATH", "").split(os.pathsep):
|
|
39
|
+
if list(Path(path).glob("gdal*.dll")):
|
|
40
|
+
log.info(f"Found GDAL at {path}")
|
|
41
|
+
gdal_dll_dir = path
|
|
42
|
+
break
|
|
43
|
+
|
|
44
|
+
if not gdal_dll_dir:
|
|
45
|
+
raise ImportError(
|
|
46
|
+
"GDAL DLL could not be found. It must be on the system PATH."
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@contextmanager
|
|
51
|
+
def GDALEnv():
|
|
52
|
+
dll_dir = None
|
|
53
|
+
|
|
54
|
+
if gdal_dll_dir:
|
|
55
|
+
dll_dir = os.add_dll_directory(gdal_dll_dir)
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
yield None
|
|
59
|
+
finally:
|
|
60
|
+
if dll_dir is not None:
|
|
61
|
+
dll_dir.close()
|
|
Binary file
|
pyogrio/_err.pxd
ADDED
pyogrio/_err.pyx
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# ported from fiona::_err.pyx
|
|
2
|
+
from enum import IntEnum
|
|
3
|
+
import warnings
|
|
4
|
+
|
|
5
|
+
from pyogrio._ogr cimport (
|
|
6
|
+
CE_None, CE_Debug, CE_Warning, CE_Failure, CE_Fatal, CPLErrorReset,
|
|
7
|
+
CPLGetLastErrorType, CPLGetLastErrorNo, CPLGetLastErrorMsg, OGRErr,
|
|
8
|
+
CPLErr, CPLErrorHandler, CPLDefaultErrorHandler, CPLPushErrorHandler)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# CPL Error types as an enum.
|
|
12
|
+
class GDALError(IntEnum):
|
|
13
|
+
none = CE_None
|
|
14
|
+
debug = CE_Debug
|
|
15
|
+
warning = CE_Warning
|
|
16
|
+
failure = CE_Failure
|
|
17
|
+
fatal = CE_Fatal
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class CPLE_BaseError(Exception):
|
|
22
|
+
"""Base CPL error class.
|
|
23
|
+
For internal use within Cython only.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, error, errno, errmsg):
|
|
27
|
+
self.error = error
|
|
28
|
+
self.errno = errno
|
|
29
|
+
self.errmsg = errmsg
|
|
30
|
+
|
|
31
|
+
def __str__(self):
|
|
32
|
+
return self.__unicode__()
|
|
33
|
+
|
|
34
|
+
def __unicode__(self):
|
|
35
|
+
return u"{}".format(self.errmsg)
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def args(self):
|
|
39
|
+
return self.error, self.errno, self.errmsg
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class CPLE_AppDefinedError(CPLE_BaseError):
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class CPLE_OutOfMemoryError(CPLE_BaseError):
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class CPLE_FileIOError(CPLE_BaseError):
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class CPLE_OpenFailedError(CPLE_BaseError):
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class CPLE_IllegalArgError(CPLE_BaseError):
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class CPLE_NotSupportedError(CPLE_BaseError):
|
|
63
|
+
pass
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class CPLE_AssertionFailedError(CPLE_BaseError):
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class CPLE_NoWriteAccessError(CPLE_BaseError):
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class CPLE_UserInterruptError(CPLE_BaseError):
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class ObjectNullError(CPLE_BaseError):
|
|
79
|
+
pass
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class CPLE_HttpResponseError(CPLE_BaseError):
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class CPLE_AWSBucketNotFoundError(CPLE_BaseError):
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class CPLE_AWSObjectNotFoundError(CPLE_BaseError):
|
|
91
|
+
pass
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class CPLE_AWSAccessDeniedError(CPLE_BaseError):
|
|
95
|
+
pass
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class CPLE_AWSInvalidCredentialsError(CPLE_BaseError):
|
|
99
|
+
pass
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class CPLE_AWSSignatureDoesNotMatchError(CPLE_BaseError):
|
|
103
|
+
pass
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class NullPointerError(CPLE_BaseError):
|
|
107
|
+
"""
|
|
108
|
+
Returned from exc_wrap_pointer when a NULL pointer is passed, but no GDAL
|
|
109
|
+
error was raised.
|
|
110
|
+
"""
|
|
111
|
+
pass
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# Map of GDAL error numbers to the Python exceptions.
|
|
116
|
+
exception_map = {
|
|
117
|
+
1: CPLE_AppDefinedError,
|
|
118
|
+
2: CPLE_OutOfMemoryError,
|
|
119
|
+
3: CPLE_FileIOError,
|
|
120
|
+
4: CPLE_OpenFailedError,
|
|
121
|
+
5: CPLE_IllegalArgError,
|
|
122
|
+
6: CPLE_NotSupportedError,
|
|
123
|
+
7: CPLE_AssertionFailedError,
|
|
124
|
+
8: CPLE_NoWriteAccessError,
|
|
125
|
+
9: CPLE_UserInterruptError,
|
|
126
|
+
10: ObjectNullError,
|
|
127
|
+
|
|
128
|
+
# error numbers 11-16 are introduced in GDAL 2.1. See
|
|
129
|
+
# https://github.com/OSGeo/gdal/pull/98.
|
|
130
|
+
11: CPLE_HttpResponseError,
|
|
131
|
+
12: CPLE_AWSBucketNotFoundError,
|
|
132
|
+
13: CPLE_AWSObjectNotFoundError,
|
|
133
|
+
14: CPLE_AWSAccessDeniedError,
|
|
134
|
+
15: CPLE_AWSInvalidCredentialsError,
|
|
135
|
+
16: CPLE_AWSSignatureDoesNotMatchError
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
cdef inline object exc_check():
|
|
140
|
+
"""Checks GDAL error stack for fatal or non-fatal errors
|
|
141
|
+
Returns
|
|
142
|
+
-------
|
|
143
|
+
An Exception, SystemExit, or None
|
|
144
|
+
"""
|
|
145
|
+
cdef const char *msg_c = NULL
|
|
146
|
+
|
|
147
|
+
err_type = CPLGetLastErrorType()
|
|
148
|
+
err_no = CPLGetLastErrorNo()
|
|
149
|
+
err_msg = CPLGetLastErrorMsg()
|
|
150
|
+
|
|
151
|
+
if err_msg == NULL:
|
|
152
|
+
msg = "No error message."
|
|
153
|
+
else:
|
|
154
|
+
# Reformat messages.
|
|
155
|
+
msg_b = err_msg
|
|
156
|
+
|
|
157
|
+
try:
|
|
158
|
+
msg = msg_b.decode('utf-8')
|
|
159
|
+
msg = msg.replace("`", "'")
|
|
160
|
+
msg = msg.replace("\n", " ")
|
|
161
|
+
except UnicodeDecodeError as exc:
|
|
162
|
+
msg = f"Could not decode error message to UTF-8. Raw error: {msg_b}"
|
|
163
|
+
|
|
164
|
+
if err_type == 3:
|
|
165
|
+
CPLErrorReset()
|
|
166
|
+
return exception_map.get(
|
|
167
|
+
err_no, CPLE_BaseError)(err_type, err_no, msg)
|
|
168
|
+
|
|
169
|
+
if err_type == 4:
|
|
170
|
+
return SystemExit("Fatal error: {0}".format((err_type, err_no, msg)))
|
|
171
|
+
|
|
172
|
+
else:
|
|
173
|
+
return
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
cdef void *exc_wrap_pointer(void *ptr) except NULL:
|
|
177
|
+
"""Wrap a GDAL/OGR function that returns GDALDatasetH etc (void *)
|
|
178
|
+
Raises an exception if a non-fatal error has be set or if pointer is NULL.
|
|
179
|
+
"""
|
|
180
|
+
if ptr == NULL:
|
|
181
|
+
exc = exc_check()
|
|
182
|
+
if exc:
|
|
183
|
+
raise exc
|
|
184
|
+
else:
|
|
185
|
+
# null pointer was passed, but no error message from GDAL
|
|
186
|
+
raise NullPointerError(-1, -1, "NULL pointer error")
|
|
187
|
+
return ptr
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
cdef int exc_wrap_int(int err) except -1:
|
|
191
|
+
"""Wrap a GDAL/OGR function that returns CPLErr or OGRErr (int)
|
|
192
|
+
Raises an exception if a non-fatal error has be set.
|
|
193
|
+
|
|
194
|
+
Copied from Fiona (_err.pyx).
|
|
195
|
+
"""
|
|
196
|
+
if err:
|
|
197
|
+
exc = exc_check()
|
|
198
|
+
if exc:
|
|
199
|
+
raise exc
|
|
200
|
+
else:
|
|
201
|
+
# no error message from GDAL
|
|
202
|
+
raise CPLE_BaseError(-1, -1, "Unspecified OGR / GDAL error")
|
|
203
|
+
return err
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
cdef int exc_wrap_ogrerr(int err) except -1:
|
|
207
|
+
"""Wrap a function that returns OGRErr (int) but does not use the
|
|
208
|
+
CPL error stack.
|
|
209
|
+
|
|
210
|
+
Adapted from Fiona (_err.pyx).
|
|
211
|
+
"""
|
|
212
|
+
if err != 0:
|
|
213
|
+
raise CPLE_BaseError(3, err, f"OGR Error code {err}")
|
|
214
|
+
|
|
215
|
+
return err
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
cdef void error_handler(CPLErr err_class, int err_no, const char* err_msg) nogil:
|
|
219
|
+
"""Custom CPL error handler to match the Python behaviour.
|
|
220
|
+
|
|
221
|
+
Generally we want to suppress error printing to stderr (behaviour of the
|
|
222
|
+
default GDAL error handler) because we already raise a Python exception
|
|
223
|
+
that includes the error message.
|
|
224
|
+
"""
|
|
225
|
+
if err_class == CE_Fatal:
|
|
226
|
+
# If the error class is CE_Fatal, we want to have a message issued
|
|
227
|
+
# because the CPL support code does an abort() before any exception
|
|
228
|
+
# can be generated
|
|
229
|
+
CPLDefaultErrorHandler(err_class, err_no, err_msg)
|
|
230
|
+
return
|
|
231
|
+
|
|
232
|
+
elif err_class == CE_Failure:
|
|
233
|
+
# For Failures, do nothing as those are explicitly caught
|
|
234
|
+
# with error return codes and translated into Python exceptions
|
|
235
|
+
return
|
|
236
|
+
|
|
237
|
+
elif err_class == CE_Warning:
|
|
238
|
+
with gil:
|
|
239
|
+
msg_b = err_msg
|
|
240
|
+
msg = msg_b.decode('utf-8')
|
|
241
|
+
warnings.warn(msg, RuntimeWarning)
|
|
242
|
+
return
|
|
243
|
+
|
|
244
|
+
# Fall back to the default handler for non-failure messages since
|
|
245
|
+
# they won't be translated into exceptions.
|
|
246
|
+
CPLDefaultErrorHandler(err_class, err_no, err_msg)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def _register_error_handler():
|
|
250
|
+
CPLPushErrorHandler(<CPLErrorHandler>error_handler)
|
|
Binary file
|
pyogrio/_geometry.pxd
ADDED
pyogrio/_geometry.pyx
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
from pyogrio._ogr cimport *
|
|
3
|
+
from pyogrio._err cimport *
|
|
4
|
+
from pyogrio._err import CPLE_BaseError, NullPointerError
|
|
5
|
+
from pyogrio.errors import DataLayerError, GeometryError
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Mapping of OGR integer geometry types to GeoJSON type names.
|
|
9
|
+
|
|
10
|
+
GEOMETRY_TYPES = {
|
|
11
|
+
wkbUnknown: 'Unknown',
|
|
12
|
+
wkbPoint: 'Point',
|
|
13
|
+
wkbLineString: 'LineString',
|
|
14
|
+
wkbPolygon: 'Polygon',
|
|
15
|
+
wkbMultiPoint: 'MultiPoint',
|
|
16
|
+
wkbMultiLineString: 'MultiLineString',
|
|
17
|
+
wkbMultiPolygon: 'MultiPolygon',
|
|
18
|
+
wkbGeometryCollection: 'GeometryCollection',
|
|
19
|
+
wkbNone: None,
|
|
20
|
+
wkbLinearRing: 'LinearRing',
|
|
21
|
+
# WARNING: Measured types are not supported in GEOS and downstream uses
|
|
22
|
+
# these are stripped automatically to their corresponding 2D / 3D types
|
|
23
|
+
wkbPointM: 'PointM',
|
|
24
|
+
wkbLineStringM: 'Measured LineString',
|
|
25
|
+
wkbPolygonM: 'Measured Polygon',
|
|
26
|
+
wkbMultiPointM: 'Measured MultiPoint',
|
|
27
|
+
wkbMultiLineStringM: 'Measured MultiLineString',
|
|
28
|
+
wkbMultiPolygonM: 'Measured MultiPolygon',
|
|
29
|
+
wkbGeometryCollectionM: 'Measured GeometryCollection',
|
|
30
|
+
wkbPointZM: 'Measured 3D Point',
|
|
31
|
+
wkbLineStringZM: 'Measured 3D LineString',
|
|
32
|
+
wkbPolygonZM: 'Measured 3D Polygon',
|
|
33
|
+
wkbMultiPointZM: 'Measured 3D MultiPoint',
|
|
34
|
+
wkbMultiLineStringZM: 'Measured 3D MultiLineString',
|
|
35
|
+
wkbMultiPolygonZM: 'Measured 3D MultiPolygon',
|
|
36
|
+
wkbGeometryCollectionZM: 'Measured 3D GeometryCollection',
|
|
37
|
+
wkbPoint25D: 'Point Z',
|
|
38
|
+
wkbLineString25D: 'LineString Z',
|
|
39
|
+
wkbPolygon25D: 'Polygon Z',
|
|
40
|
+
wkbMultiPoint25D: 'MultiPoint Z',
|
|
41
|
+
wkbMultiLineString25D: 'MultiLineString Z',
|
|
42
|
+
wkbMultiPolygon25D: 'MultiPolygon Z',
|
|
43
|
+
wkbGeometryCollection25D: 'GeometryCollection Z',
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
GEOMETRY_TYPE_CODES = {v:k for k, v in GEOMETRY_TYPES.items()}
|
|
47
|
+
|
|
48
|
+
# add additional aliases from 2.5D format
|
|
49
|
+
GEOMETRY_TYPE_CODES.update({
|
|
50
|
+
'2.5D Point': wkbPoint25D,
|
|
51
|
+
'2.5D LineString': wkbLineString25D,
|
|
52
|
+
'2.5D Polygon': wkbPolygon25D,
|
|
53
|
+
'2.5D MultiPoint': wkbMultiPoint25D,
|
|
54
|
+
'2.5D MultiLineString': wkbMultiLineString25D,
|
|
55
|
+
'2.5D MultiPolygon': wkbMultiPolygon25D,
|
|
56
|
+
'2.5D GeometryCollection': wkbGeometryCollection25D
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
# 2.5D also represented using negative numbers not enumerated above
|
|
60
|
+
GEOMETRY_TYPES.update({
|
|
61
|
+
-2147483647: 'Point Z',
|
|
62
|
+
-2147483646: 'LineString Z',
|
|
63
|
+
-2147483645: 'Polygon Z',
|
|
64
|
+
-2147483644: 'MultiPoint Z',
|
|
65
|
+
-2147483643: 'MultiLineString Z',
|
|
66
|
+
-2147483642: 'MultiPolygon Z',
|
|
67
|
+
-2147483641: 'GeometryCollection Z',
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
cdef str get_geometry_type(void *ogr_layer):
|
|
72
|
+
"""Get geometry type for layer.
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
ogr_layer : pointer to open OGR layer
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
str
|
|
81
|
+
geometry type
|
|
82
|
+
"""
|
|
83
|
+
cdef void *cogr_featuredef = NULL
|
|
84
|
+
cdef OGRwkbGeometryType ogr_type
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
ogr_featuredef = exc_wrap_pointer(OGR_L_GetLayerDefn(ogr_layer))
|
|
88
|
+
except NullPointerError:
|
|
89
|
+
raise DataLayerError("Could not get layer definition")
|
|
90
|
+
|
|
91
|
+
except CPLE_BaseError as exc:
|
|
92
|
+
raise DataLayerError(str(exc))
|
|
93
|
+
|
|
94
|
+
ogr_type = OGR_FD_GetGeomType(ogr_featuredef)
|
|
95
|
+
|
|
96
|
+
if ogr_type not in GEOMETRY_TYPES:
|
|
97
|
+
raise GeometryError(f"Geometry type is not supported: {ogr_type}")
|
|
98
|
+
|
|
99
|
+
if OGR_GT_HasM(ogr_type):
|
|
100
|
+
original_type = GEOMETRY_TYPES[ogr_type]
|
|
101
|
+
|
|
102
|
+
# Downgrade the type to 2D / 3D
|
|
103
|
+
ogr_type = OGR_GT_SetModifier(ogr_type, OGR_GT_HasZ(ogr_type), 0)
|
|
104
|
+
|
|
105
|
+
# TODO: review; this might be annoying...
|
|
106
|
+
warnings.warn(
|
|
107
|
+
"Measured (M) geometry types are not supported. "
|
|
108
|
+
f"Original type '{original_type}' "
|
|
109
|
+
f"is converted to '{GEOMETRY_TYPES[ogr_type]}'")
|
|
110
|
+
|
|
111
|
+
return GEOMETRY_TYPES[ogr_type]
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
cdef OGRwkbGeometryType get_geometry_type_code(str geometry_type) except *:
|
|
115
|
+
"""Get geometry type code for string geometry type.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
geometry_type : str
|
|
120
|
+
|
|
121
|
+
Returns
|
|
122
|
+
-------
|
|
123
|
+
int
|
|
124
|
+
geometry type code
|
|
125
|
+
"""
|
|
126
|
+
if geometry_type not in GEOMETRY_TYPE_CODES:
|
|
127
|
+
raise GeometryError(f"Geometry type is not supported: {geometry_type}")
|
|
128
|
+
|
|
129
|
+
return GEOMETRY_TYPE_CODES[geometry_type]
|
|
Binary file
|
pyogrio/_io.pxd
ADDED
|
File without changes
|