[Git][debian-gis-team/fiona][upstream] 2 commits: New upstream version 1.8.10
Bas Couwenberg
gitlab at salsa.debian.org
Fri Nov 8 05:49:56 GMT 2019
Bas Couwenberg pushed to branch upstream at Debian GIS Project / fiona
Commits:
54d0f0b7 by Bas Couwenberg at 2019-11-08T05:29:24Z
New upstream version 1.8.10
- - - - -
fdeac4aa by Bas Couwenberg at 2019-11-08T05:29:33Z
New upstream version 1.8.11
- - - - -
27 changed files:
- .travis.yml
- CHANGES.txt
- appveyor.yml
- fiona/__init__.py
- fiona/_crs.pyx
- − fiona/_drivers.pyx
- fiona/_env.pyx
- fiona/_shim1.pxd
- fiona/_shim1.pyx
- fiona/_shim2.pxd
- fiona/_shim2.pyx
- fiona/_shim22.pxd
- fiona/_shim22.pyx
- fiona/_shim3.pxd
- fiona/_shim3.pyx
- fiona/collection.py
- fiona/env.py
- fiona/ogrext.pyx
- setup.py
- tests/conftest.py
- tests/test__env.py
- tests/test_collection.py
- tests/test_collection_crs.py
- tests/test_crs.py
- tests/test_env.py
- tests/test_listing.py
- tests/test_vfs.py
Changes:
=====================================
.travis.yml
=====================================
@@ -27,11 +27,11 @@ env:
- GDALVERSION="2.3.3" PROJVERSION="4.9.3"
- GDALVERSION="2.4.2" PROJVERSION="4.9.3"
- GDALVERSION="3.0.1" PROJVERSION="6.1.1"
- - GDALVERSION="trunk" PROJVERSION="6.1.1"
+ - GDALVERSION="master" PROJVERSION="6.1.1"
matrix:
allow_failures:
- - env: GDALVERSION="trunk" PROJVERSION="6.1.1"
+ - env: GDALVERSION="master" PROJVERSION="6.1.1"
addons:
apt:
@@ -55,7 +55,7 @@ before_install:
- gdal-config --version
install:
- - if [ "$GDALVERSION" = "trunk" ]; then echo "Using gdal trunk"; elif [ $(gdal-config --version) == "$GDALVERSION" ]; then echo "Using gdal $GDALVERSION"; else echo "NOT using gdal $GDALVERSION as expected; aborting"; exit 1; fi
+ - if [ "$GDALVERSION" = "master" ]; then echo "Using gdal master"; elif [ $(gdal-config --version) == "$GDALVERSION" ]; then echo "Using gdal $GDALVERSION"; else echo "NOT using gdal $GDALVERSION as expected; aborting"; exit 1; fi
- "python -m pip wheel -r requirements-dev.txt"
- "python -m pip install -r requirements-dev.txt"
- "GDAL_CONFIG=$GDALINST/gdal-$GDALVERSION/bin/gdal-config python -m pip install --upgrade --force-reinstall --no-use-pep517 -e .[test]"
=====================================
CHANGES.txt
=====================================
@@ -3,6 +3,45 @@ Changes
All issue numbers are relative to https://github.com/Toblerity/Fiona/issues.
+1.8.11 (2019-11-07)
+-------------------
+
+- Fix an access violation on Windows (#826).
+
+1.8.10 (2019-11-07)
+-------------------
+
+Deprecations:
+
+- Use of vfs keyword argument with open or listlayers has been previously noted
+ as deprecated, but now triggers a deprecation warning.
+
+Bug fixes:
+
+- fiona.open() can now create new datasets using CRS URNs (#823).
+- listlayers() now accepts file and Path objects, like open() (#825).
+- Use new set_proj_search_path() function to set the PROJ data search path. For
+ GDAL versions before 3.0 this sets the PROJ_LIB environment variable. For
+ GDAL version 3.0 this calls OSRSetPROJSearchPaths(), which overrides
+ PROJ_LIB.
+- Remove old and unused _drivers extension module.
+- Check for header.dxf file instead of pcs.csv when looking for installed GDAL
+ data. The latter is gone with GDAL 3.0 but the former remains (#818).
+
+1.8.9.post2 (2019-10-22)
+------------------------
+
+- The 1.8.9.post1 release introduced a bug affecting builds of the package from
+ a source distribution using GDAL 2.x. This bug has been fixed in commit
+ 960568d.
+
+1.8.9.post1 (2019-10-22)
+------------------------
+
+- A change has been made to the package setup script so that the shim module
+ for GDAL 3 is used when building the package from a source distribution.
+ There are no other changes to the package.
+
1.8.9 (2019-10-21)
------------------
=====================================
appveyor.yml
=====================================
@@ -125,7 +125,7 @@ build_script:
# install the wheel
- ps: python -m pip install --upgrade pip
- - ps: python -m pip install --force-reinstall --ignore-installed (gci dist\*.whl | % { "$_" })
+ - ps: python -m pip install (gci dist\*.whl | % { "$_" })
- ps: move fiona fiona.build
=====================================
fiona/__init__.py
=====================================
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
-Fiona is OGR's neat, nimble, no-nonsense API.
+Fiona is OGR's neat, nimble API.
Fiona provides a minimal, uncomplicated Python interface to the open
source GIS community's most trusted geodata access library and
@@ -76,6 +76,7 @@ except ImportError: # pragma: no cover
class Path:
pass
+# TODO: remove this? Or at least move it, flake8 complains.
if sys.platform == "win32":
libdir = os.path.join(os.path.dirname(__file__), ".libs")
os.environ["PATH"] = os.environ["PATH"] + ";" + libdir
@@ -101,7 +102,7 @@ import uuid
__all__ = ['bounds', 'listlayers', 'open', 'prop_type', 'prop_width']
-__version__ = "1.8.9"
+__version__ = "1.8.11"
__gdal_version__ = get_gdal_release_name()
gdal_version = get_gdal_version_tuple()
@@ -242,7 +243,7 @@ def open(fp, mode='r', driver=None, schema=None, crs=None, encoding=None,
fp = str(fp)
if vfs:
- # Parse the vfs into a vsi and an archive path.
+ warnings.warn("The vfs keyword argument is deprecated. Instead, pass a URL that uses a zip or tar (for example) scheme.", FionaDeprecationWarning, stacklevel=2)
path, scheme, archive = vfs_parse_paths(fp, vfs=vfs)
path = ParsedPath(path, archive, scheme)
else:
@@ -267,6 +268,7 @@ def open(fp, mode='r', driver=None, schema=None, crs=None, encoding=None,
return c
+
collection = open
@@ -299,30 +301,47 @@ def remove(path_or_collection, driver=None, layer=None):
@ensure_env_with_credentials
-def listlayers(path, vfs=None):
- """Returns a list of layer names in their index order.
+def listlayers(fp, vfs=None):
+ """List layer names in their index order
+
+ Parameters
+ ----------
+ fp : URI (str or pathlib.Path), or file-like object
+ A dataset resource identifier or file object.
+ vfs : str
+ This is a deprecated parameter. A URI scheme such as "zip://"
+ should be used instead.
- The required ``path`` argument may be an absolute or relative file or
- directory path.
+ Returns
+ -------
+ list
+ A list of layer name strings.
- A virtual filesystem can be specified. The ``vfs`` parameter may be
- an Apache Commons VFS style string beginning with "zip://" or
- "tar://"". In this case, the ``path`` must be an absolute path within
- that container.
"""
- if not isinstance(path, string_types):
- raise TypeError("invalid path: %r" % path)
- if vfs and not isinstance(vfs, string_types):
- raise TypeError("invalid vfs: %r" % vfs)
-
- if vfs:
- pobj_vfs = parse_path(vfs)
- pobj_path = parse_path(path)
- pobj = ParsedPath(pobj_path.path, pobj_vfs.path, pobj_vfs.scheme)
+ if hasattr(fp, 'read'):
+
+ with MemoryFile(fp.read()) as memfile:
+ return _listlayers(memfile.name)
+
else:
- pobj = parse_path(path)
- return _listlayers(vsi_path(pobj))
+ if isinstance(fp, Path):
+ fp = str(fp)
+
+ if not isinstance(fp, string_types):
+ raise TypeError("invalid path: %r" % fp)
+ if vfs and not isinstance(vfs, string_types):
+ raise TypeError("invalid vfs: %r" % vfs)
+
+ if vfs:
+ warnings.warn("The vfs keyword argument is deprecated. Instead, pass a URL that uses a zip or tar (for example) scheme.", FionaDeprecationWarning, stacklevel=2)
+ pobj_vfs = parse_path(vfs)
+ pobj_path = parse_path(fp)
+ pobj = ParsedPath(pobj_path.path, pobj_vfs.path, pobj_vfs.scheme)
+ else:
+ pobj = parse_path(fp)
+
+ return _listlayers(vsi_path(pobj))
def prop_width(val):
=====================================
fiona/_crs.pyx
=====================================
@@ -10,8 +10,10 @@ import logging
from six import string_types
from fiona cimport _cpl
+from fiona._err cimport exc_wrap_pointer
+from fiona._err import CPLE_BaseError
from fiona._shim cimport osr_get_name, osr_set_traditional_axis_mapping_strategy
-
+from fiona.compat import DICT_TYPES
from fiona.errors import CRSError
@@ -26,9 +28,10 @@ def crs_to_wkt(crs):
cdef OGRSpatialReferenceH cogr_srs = NULL
cdef char *proj_c = NULL
- cogr_srs = OSRNewSpatialReference(NULL)
- if cogr_srs == NULL:
- raise CRSError("NULL spatial reference")
+ try:
+ cogr_srs = exc_wrap_pointer(OSRNewSpatialReference(NULL))
+ except CPLE_BaseError as exc:
+ raise CRSError(u"{}".format(exc))
# First, check for CRS strings like "EPSG:3857".
if isinstance(crs, string_types):
@@ -36,7 +39,7 @@ def crs_to_wkt(crs):
proj_c = proj_b
OSRSetFromUserInput(cogr_srs, proj_c)
- elif isinstance(crs, dict):
+ elif isinstance(crs, DICT_TYPES):
# EPSG is a special case.
init = crs.get('init')
if init:
@@ -60,15 +63,18 @@ def crs_to_wkt(crs):
OSRImportFromProj4(cogr_srs, proj_c)
else:
- raise ValueError("Invalid CRS")
+ raise CRSError("Invalid input to create CRS: {}".format(crs))
osr_set_traditional_axis_mapping_strategy(cogr_srs)
OSRExportToWkt(cogr_srs, &proj_c)
if proj_c == NULL:
- raise CRSError("Null projection")
+ raise CRSError("Invalid input to create CRS: {}".format(crs))
proj_b = proj_c
_cpl.CPLFree(proj_c)
+ if not proj_b:
+ raise CRSError("Invalid input to create CRS: {}".format(crs))
+
return proj_b.decode('utf-8')
=====================================
fiona/_drivers.pyx deleted
=====================================
@@ -1,201 +0,0 @@
-# The GDAL and OGR driver registry.
-# GDAL driver management.
-
-from __future__ import absolute_import
-
-import os
-import os.path
-import logging
-import sys
-
-from six import string_types
-
-
-cdef extern from "cpl_conv.h":
- void CPLFree (void *ptr)
- void CPLSetThreadLocalConfigOption (char *key, char *val)
- const char * CPLGetConfigOption ( const char *key, const char *default)
-
-
-cdef extern from "cpl_error.h":
- ctypedef void (*CPLErrorHandler)(int, int, const char*);
- void CPLSetErrorHandler (CPLErrorHandler handler)
-
-
-cdef extern from "gdal.h":
- void GDALAllRegister()
- void GDALDestroyDriverManager()
- int GDALGetDriverCount()
- void * GDALGetDriver(int i)
- const char * GDALGetDriverShortName(void *driver)
- const char * GDALGetDriverLongName(void *driver)
- const char * GDALVersionInfo(const char *key)
-
-
-cdef extern from "ogr_api.h":
- void OGRRegisterDriver(void *driver)
- void OGRDeregisterDriver(void *driver)
- void OGRRegisterAll()
- void OGRCleanupAll()
- int OGRGetDriverCount()
- void * OGRGetDriver(int i)
- void * OGRGetDriverByName(const char *name)
- const char * OGR_Dr_GetName(void *driver)
-
-
-log = logging.getLogger(__name__)
-class NullHandler(logging.Handler):
- def emit(self, record):
- pass
-log.addHandler(NullHandler())
-
-
-level_map = {
- 0: 0,
- 1: logging.DEBUG,
- 2: logging.WARNING,
- 3: logging.ERROR,
- 4: logging.CRITICAL }
-
-code_map = {
- 0: 'CPLE_None',
- 1: 'CPLE_AppDefined',
- 2: 'CPLE_OutOfMemory',
- 3: 'CPLE_FileIO',
- 4: 'CPLE_OpenFailed',
- 5: 'CPLE_IllegalArg',
- 6: 'CPLE_NotSupported',
- 7: 'CPLE_AssertionFailed',
- 8: 'CPLE_NoWriteAccess',
- 9: 'CPLE_UserInterrupt',
- 10: 'CPLE_ObjectNull'
-}
-
-
-IF UNAME_SYSNAME == "Windows":
- cdef void * __stdcall errorHandler(int eErrClass, int err_no, char *msg) with gil:
- log.log(level_map[eErrClass], "%s in %s", code_map[err_no], msg)
-ELSE:
- cdef void * errorHandler(int eErrClass, int err_no, char *msg) with gil:
- log.log(level_map[eErrClass], "%s in %s", code_map[err_no], msg)
-
-
-def driver_count():
- return OGRGetDriverCount()
-
-
-cdef class GDALEnv(object):
-
- cdef public object options
-
- def __init__(self, **options):
- self.options = options.copy()
-
- def __enter__(self):
- self.start()
- return self
-
- def __exit__(self, exc_type=None, exc_val=None, exc_tb=None):
- self.stop()
-
- def start(self):
- cdef const char *key_c = NULL
- cdef const char *val_c = NULL
-
- if GDALGetDriverCount() == 0:
- GDALAllRegister()
- if OGRGetDriverCount() == 0:
- OGRRegisterAll()
- CPLSetErrorHandler(<CPLErrorHandler>errorHandler)
- if OGRGetDriverCount() == 0:
- raise ValueError("Drivers not registered")
-
- if 'GDAL_DATA' in os.environ:
- log.debug("GDAL_DATA: %s", os.environ['GDAL_DATA'])
- else:
- # We will try a few well-known paths, starting with the
- # official wheel path.
- whl_datadir = os.path.abspath(
- os.path.join(os.path.dirname(__file__), "gdal_data"))
- fhs_share_datadir = os.path.join(sys.prefix, 'share/gdal')
-
- # Debian supports multiple GDAL installs.
- gdal_release_name = GDALVersionInfo("RELEASE_NAME")
- gdal_release_name = gdal_release_name.decode('utf-8')
- deb_share_datadir = os.path.join(
- fhs_share_datadir,
- "{}.{}".format(*gdal_release_name.split('.')[:2]))
-
- # If we find GDAL data at the well-known paths, we will
- # add a GDAL_DATA key to the config options dict.
- if os.path.exists(os.path.join(whl_datadir, 'pcs.csv')):
- log.debug("Set GDAL_DATA = %r", whl_datadir)
- self.options['GDAL_DATA'] = whl_datadir
-
- elif os.path.exists(os.path.join(deb_share_datadir, 'pcs.csv')):
- log.debug("Set GDAL_DATA = %r", deb_share_datadir)
- self.options['GDAL_DATA'] = deb_share_datadir
-
- elif os.path.exists(os.path.join(fhs_share_datadir, 'pcs.csv')):
- log.debug("Set GDAL_DATA = %r", fhs_share_datadir)
- self.options['GDAL_DATA'] = fhs_share_datadir
-
- else:
- log.warning("GDAL data files not located, GDAL_DATA not set")
-
- if 'PROJ_LIB' in os.environ:
- log.debug("PROJ_LIB: %s", os.environ['PROJ_LIB'])
- else:
- whl_datadir = os.path.abspath(
- os.path.join(os.path.dirname(__file__), "proj_data"))
- share_datadir = os.path.join(sys.prefix, 'share/proj')
-
- if os.path.exists(whl_datadir):
- log.debug("Set PROJ_LIB = %r", whl_datadir)
- os.environ['PROJ_LIB'] = whl_datadir
-
- elif os.path.exists(share_datadir):
- log.debug("Set PROJ_LIB = %r", share_datadir)
- os.environ['PROJ_LIB'] = share_datadir
-
- else:
- log.warning("PROJ data files not located, PROJ_LIB not set")
-
- for key, val in self.options.items():
- key_b = key.upper().encode('utf-8')
- key_c = key_b
- if isinstance(val, string_types):
- val_b = val.encode('utf-8')
- else:
- val_b = ('ON' if val else 'OFF').encode('utf-8')
- val_c = val_b
- CPLSetThreadLocalConfigOption(key_c, val_c)
- # Logging of config options has been disabled to prevent
- # credential leakage and will be completely
- # removed as soon as the Fiona driver environment and
- # AWS authentication interactions are stable.
- # log.debug("Option %s=%s", key, CPLGetConfigOption(key_c, NULL))
- return self
-
- def stop(self):
- cdef const char *key_c = NULL
- for key in self.options:
- key_b = key.upper().encode('utf-8')
- key_c = key_b
- CPLSetThreadLocalConfigOption(key_c, NULL)
- CPLSetErrorHandler(NULL)
-
- def drivers(self):
- cdef void *drv = NULL
- cdef const char *key = NULL
- cdef const char *val = NULL
- cdef int i
- result = {}
- for i in range(OGRGetDriverCount()):
- drv = OGRGetDriver(i)
- key = OGR_Dr_GetName(drv)
- key_b = key
- val = OGR_Dr_GetName(drv)
- val_b = val
- result[key_b.decode('utf-8')] = val_b.decode('utf-8')
- return result
=====================================
fiona/_env.pyx
=====================================
@@ -18,6 +18,7 @@ import sys
import threading
from fiona._err cimport exc_wrap_int, exc_wrap_ogrerr
+from fiona._shim cimport set_proj_search_path
from fiona._err import CPLE_BaseError
from fiona.errors import EnvError
@@ -295,18 +296,18 @@ class GDALDataFinder(object):
if prefix is None:
prefix = __file__
datadir = os.path.abspath(os.path.join(os.path.dirname(prefix), "gdal_data"))
- return datadir if os.path.exists(os.path.join(datadir, 'pcs.csv')) else None
+ return datadir if os.path.exists(os.path.join(datadir, 'header.dxf')) else None
def search_prefix(self, prefix=sys.prefix):
"""Check sys.prefix location"""
datadir = os.path.join(prefix, 'share', 'gdal')
- return datadir if os.path.exists(os.path.join(datadir, 'pcs.csv')) else None
+ return datadir if os.path.exists(os.path.join(datadir, 'header.dxf')) else None
def search_debian(self, prefix=sys.prefix):
"""Check Debian locations"""
gdal_release_name = GDALVersionInfo("RELEASE_NAME")
datadir = os.path.join(prefix, 'share', 'gdal', '{}.{}'.format(*gdal_release_name.split('.')[:2]))
- return datadir if os.path.exists(os.path.join(datadir, 'pcs.csv')) else None
+ return datadir if os.path.exists(os.path.join(datadir, 'header.dxf')) else None
class PROJDataFinder(object):
@@ -326,7 +327,7 @@ class PROJDataFinder(object):
cdef OGRSpatialReferenceH osr = OSRNewSpatialReference(NULL)
try:
- exc_wrap_ogrerr(exc_wrap_int(OSRImportFromProj4(osr, "+init=epsg:4326")))
+ exc_wrap_ogrerr(exc_wrap_int(OSRImportFromEPSG(osr, 4326)))
except CPLE_BaseError:
return False
else:
@@ -402,6 +403,8 @@ cdef class GDALEnv(ConfigEnv):
if 'PROJ_LIB' in os.environ:
log.debug("PROJ_LIB found in environment: %r.", os.environ['PROJ_LIB'])
+ path = os.environ["PROJ_LIB"]
+ set_proj_data_search_path(path)
elif PROJDataFinder().has_data():
log.debug("PROJ data files are available at built-in paths")
@@ -410,8 +413,8 @@ cdef class GDALEnv(ConfigEnv):
path = PROJDataFinder().search()
if path:
- os.environ['PROJ_LIB'] = path
- log.debug("PROJ data not found in environment, set to %r.", path)
+ log.debug("PROJ data not found in environment, setting to %r.", path)
+ set_proj_data_search_path(path)
if driver_count() == 0:
CPLPopErrorHandler()
@@ -447,3 +450,8 @@ cdef class GDALEnv(ConfigEnv):
result[key] = val
return result
+
+
+def set_proj_data_search_path(path):
+ """Set PROJ data search path"""
+ set_proj_search_path(path)
=====================================
fiona/_shim1.pxd
=====================================
@@ -21,6 +21,7 @@ cdef bint check_capability_create_layer(void *cogr_ds)
cdef void *get_linear_geometry(void *geom)
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs)
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs)
+cdef void set_proj_search_path(object path)
from fiona._shim cimport OGR_F_GetFieldAsInteger as OGR_F_GetFieldAsInteger64
from fiona._shim cimport OGR_F_SetFieldInteger as OGR_F_SetFieldInteger64
=====================================
fiona/_shim1.pyx
=====================================
@@ -1,6 +1,6 @@
"""Shims on top of ogrext for GDAL versions < 2"""
-import logging
+import os
from fiona.ogrext1 cimport *
from fiona._err cimport exc_wrap_pointer
@@ -8,8 +8,6 @@ from fiona._err import cpl_errs, CPLE_BaseError, FionaNullPointerError
from fiona.errors import DriverError
-log = logging.getLogger(__name__)
-
cdef int OGRERR_NONE = 0
@@ -80,7 +78,6 @@ cdef void* gdal_create(void* cogr_driver, const char *path_c, options) except NU
v = ('ON' if v else 'OFF').encode('utf-8')
else:
v = str(v).encode('utf-8')
- log.debug("Set option %r: %r", k, v)
opts = CSLAddNameValue(opts, <const char *>k, <const char *>v)
try:
@@ -131,3 +128,7 @@ cdef const char* osr_get_name(OGRSpatialReferenceH hSrs):
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs):
OSRFixup(hSrs)
+
+
+cdef void set_proj_search_path(object path):
+ os.environ["PROJ_LIB"] = path
=====================================
fiona/_shim2.pxd
=====================================
@@ -14,3 +14,4 @@ cdef bint check_capability_create_layer(void *cogr_ds)
cdef void *get_linear_geometry(void *geom)
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs)
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs)
+cdef void set_proj_search_path(object path)
=====================================
fiona/_shim2.pyx
=====================================
@@ -1,12 +1,13 @@
"""Shims on top of ogrext for GDAL versions > 2"""
+import logging
+import os
+
from fiona.ogrext2 cimport *
from fiona._err cimport exc_wrap_pointer
from fiona._err import cpl_errs, CPLE_BaseError, FionaNullPointerError
from fiona.errors import DriverError
-import logging
-
log = logging.getLogger(__name__)
@@ -42,7 +43,6 @@ cdef void* gdal_open_vector(const char* path_c, int mode, drivers, options) exce
for name in drivers:
name_b = name.encode()
name_c = name_b
- #log.debug("Trying driver: %s", name)
drv = GDALGetDriverByName(name_c)
if drv != NULL:
drvs = CSLAddString(drvs, name_c)
@@ -130,3 +130,7 @@ cdef const char* osr_get_name(OGRSpatialReferenceH hSrs):
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs):
OSRFixup(hSrs)
+
+
+cdef void set_proj_search_path(object path):
+ os.environ["PROJ_LIB"] = path
=====================================
fiona/_shim22.pxd
=====================================
@@ -14,3 +14,4 @@ cdef bint check_capability_create_layer(void *cogr_ds)
cdef void *get_linear_geometry(void *geom)
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs)
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs)
+cdef void set_proj_search_path(object path)
=====================================
fiona/_shim22.pyx
=====================================
@@ -4,14 +4,15 @@ cdef extern from "ogr_api.h":
int OGR_F_IsFieldNull(void *feature, int n)
+import logging
+import os
from fiona.ogrext2 cimport *
from fiona._err cimport exc_wrap_pointer
+
from fiona._err import cpl_errs, CPLE_BaseError, FionaNullPointerError
from fiona.errors import DriverError
-import logging
-
log = logging.getLogger(__name__)
@@ -133,8 +134,13 @@ cdef bint check_capability_create_layer(void *cogr_ds):
cdef void *get_linear_geometry(void *geom):
return OGR_G_GetLinearGeometry(geom, 0.0, NULL)
+
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs):
return ''
+
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs):
OSRFixup(hSrs)
+
+cdef void set_proj_search_path(object path):
+ os.environ["PROJ_LIB"] = path
=====================================
fiona/_shim3.pxd
=====================================
@@ -14,3 +14,4 @@ cdef bint check_capability_create_layer(void *cogr_ds)
cdef void *get_linear_geometry(void *geom)
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs)
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs)
+cdef void set_proj_search_path(object path)
=====================================
fiona/_shim3.pyx
=====================================
@@ -12,6 +12,7 @@ cdef extern from "ogr_srs_api.h" nogil:
const char* OSRGetName(OGRSpatialReferenceH hSRS)
void OSRSetAxisMappingStrategy(OGRSpatialReferenceH hSRS, OSRAxisMappingStrategy)
+ void OSRSetPROJSearchPaths(const char *const *papszPaths)
from fiona.ogrext2 cimport *
@@ -142,8 +143,19 @@ cdef bint check_capability_create_layer(void *cogr_ds):
cdef void *get_linear_geometry(void *geom):
return OGR_G_GetLinearGeometry(geom, 0.0, NULL)
+
cdef const char* osr_get_name(OGRSpatialReferenceH hSrs):
return OSRGetName(hSrs)
+
cdef void osr_set_traditional_axis_mapping_strategy(OGRSpatialReferenceH hSrs):
OSRSetAxisMappingStrategy(hSrs, OAMS_TRADITIONAL_GIS_ORDER)
+
+
+cdef void set_proj_search_path(object path):
+ cdef char **paths = NULL
+ cdef const char *path_c = NULL
+ path_b = path.encode("utf-8")
+ path_c = path_b
+ paths = CSLAddString(paths, path_c)
+ OSRSetPROJSearchPaths(paths)
=====================================
fiona/collection.py
=====================================
@@ -11,6 +11,7 @@ from fiona.ogrext import Session, WritingSession
from fiona.ogrext import buffer_to_virtual_file, remove_virtual_file, GEOMETRY_TYPES
from fiona.errors import (DriverError, SchemaError, CRSError, UnsupportedGeometryTypeError, DriverSupportError)
from fiona.logutils import FieldSkipLogFilter
+from fiona._crs import crs_to_wkt
from fiona._env import get_gdal_release_name, get_gdal_version_tuple
from fiona.env import env_ctx_if_needed
from fiona.errors import FionaDeprecationWarning
@@ -140,14 +141,8 @@ class Collection(object):
self._schema = schema
self._check_schema_driver_support()
-
- if crs_wkt:
- self._crs_wkt = crs_wkt
- elif crs:
- if 'init' in crs or 'proj' in crs or 'epsg' in crs.lower():
- self._crs = crs
- else:
- raise CRSError("crs lacks init or proj parameter")
+ if crs_wkt or crs:
+ self._crs_wkt = crs_to_wkt(crs_wkt or crs)
self._driver = driver
kwargs.update(encoding=encoding)
=====================================
fiona/env.py
=====================================
@@ -12,7 +12,8 @@ from six import string_types
from fiona._env import (
GDALEnv, calc_gdal_version_num, get_gdal_version_num, get_gdal_config,
- set_gdal_config, get_gdal_release_name, GDALDataFinder, PROJDataFinder)
+ set_gdal_config, get_gdal_release_name, GDALDataFinder, PROJDataFinder,
+ set_proj_data_search_path)
from fiona.compat import getargspec
from fiona.errors import EnvError, GDALVersionError
from fiona.session import Session, DummySession
@@ -586,7 +587,7 @@ def require_gdal_version(version, param=None, values=None, is_max_version=False,
# Patch the environment if needed, such as in the installed wheel case.
-if 'GDAL_DATA' not in os.environ:
+if "GDAL_DATA" not in os.environ:
# See https://github.com/mapbox/rasterio/issues/1631.
if GDALDataFinder().find_file("header.dxf"):
@@ -599,15 +600,17 @@ if 'GDAL_DATA' not in os.environ:
os.environ['GDAL_DATA'] = path
log.debug("GDAL_DATA not found in environment, set to %r.", path)
-if 'PROJ_LIB' not in os.environ:
+if "PROJ_LIB" in os.environ:
+ path = os.environ["PROJ_LIB"]
+ set_proj_data_search_path(path)
- # See https://github.com/mapbox/rasterio/issues/1631.
- if PROJDataFinder().has_data():
- log.debug("PROJ data files are available at built-in paths")
+# See https://github.com/mapbox/rasterio/issues/1631.
+elif PROJDataFinder().has_data():
+ log.debug("PROJ data files are available at built-in paths")
- else:
- path = PROJDataFinder().search()
+else:
+ path = PROJDataFinder().search()
- if path:
- os.environ['PROJ_LIB'] = path
- log.debug("PROJ data not found in environment, set to %r.", path)
+ if path:
+ log.debug("PROJ data not found in environment, setting to %r.", path)
+ set_proj_data_search_path(path)
=====================================
fiona/ogrext.pyx
=====================================
@@ -970,51 +970,18 @@ cdef class WritingSession(Session):
self.cogr_ds = cogr_ds
# Set the spatial reference system from the crs given to the
- # collection constructor. We by-pass the crs_wkt and crs
+ # collection constructor. We by-pass the crs_wkt
# properties because they aren't accessible until the layer
# is constructed (later).
try:
-
- col_crs = collection._crs_wkt or collection._crs
-
+ col_crs = collection._crs_wkt
if col_crs:
cogr_srs = exc_wrap_pointer(OSRNewSpatialReference(NULL))
-
- # First, check for CRS strings like "EPSG:3857".
- if isinstance(col_crs, string_types):
- proj_b = col_crs.encode('utf-8')
- proj_c = proj_b
- OSRSetFromUserInput(cogr_srs, proj_c)
-
- elif isinstance(col_crs, compat.DICT_TYPES):
- # EPSG is a special case.
- init = col_crs.get('init')
- if init:
- log.debug("Init: %s", init)
- auth, val = init.split(':')
- if auth.upper() == 'EPSG':
- log.debug("Setting EPSG: %s", val)
- OSRImportFromEPSG(cogr_srs, int(val))
- osr_set_traditional_axis_mapping_strategy(cogr_srs)
- else:
- params = []
- col_crs['wktext'] = True
- for k, v in col_crs.items():
- if v is True or (k in ('no_defs', 'wktext') and v):
- params.append("+%s" % k)
- else:
- params.append("+%s=%s" % (k, v))
- proj = " ".join(params)
- log.debug("PROJ.4 to be imported: %r", proj)
- proj_b = proj.encode('utf-8')
- proj_c = proj_b
- OSRImportFromProj4(cogr_srs, proj_c)
- osr_set_traditional_axis_mapping_strategy(cogr_srs)
-
- else:
- raise ValueError("Invalid CRS")
-
- except (ValueError, CPLE_BaseError) as exc:
+ proj_b = col_crs.encode('utf-8')
+ proj_c = proj_b
+ OSRSetFromUserInput(cogr_srs, proj_c)
+ osr_set_traditional_axis_mapping_strategy(cogr_srs)
+ except CPLE_BaseError as exc:
OGRReleaseDataSource(self.cogr_ds)
self.cogr_ds = NULL
self.cogr_layer = NULL
=====================================
setup.py
=====================================
@@ -236,7 +236,6 @@ if source_is_repo and "clean" not in sys.argv:
Extension('fiona._transform', ['fiona/_transform.pyx'], **ext_options_cpp),
Extension('fiona._crs', ['fiona/_crs.pyx'], **ext_options),
Extension('fiona._env', ['fiona/_env.pyx'], **ext_options),
- Extension('fiona._drivers', ['fiona/_drivers.pyx'], **ext_options),
Extension('fiona._err', ['fiona/_err.pyx'], **ext_options),
Extension('fiona._shim', ['fiona/_shim.pyx'], **ext_options),
Extension('fiona.ogrext', ['fiona/ogrext.pyx'], **ext_options)
@@ -252,7 +251,6 @@ elif "clean" not in sys.argv:
Extension('fiona._geometry', ['fiona/_geometry.c'], **ext_options),
Extension('fiona._crs', ['fiona/_crs.c'], **ext_options),
Extension('fiona._env', ['fiona/_env.c'], **ext_options),
- Extension('fiona._drivers', ['fiona/_drivers.c'], **ext_options),
Extension('fiona._err', ['fiona/_err.c'], **ext_options),
Extension('fiona.ogrext', ['fiona/ogrext.c'], **ext_options),
]
@@ -261,7 +259,7 @@ elif "clean" not in sys.argv:
log.info("Building Fiona for gdal 1.x: {0}".format(gdalversion))
ext_modules.append(
Extension('fiona._shim', ['fiona/_shim1.c'], **ext_options))
- else:
+ elif gdal_major_version == 2:
if gdal_minor_version >= 2:
log.info("Building Fiona for gdal 2.2+: {0}".format(gdalversion))
ext_modules.append(
@@ -270,6 +268,10 @@ elif "clean" not in sys.argv:
log.info("Building Fiona for gdal 2.0.x-2.1.x: {0}".format(gdalversion))
ext_modules.append(
Extension('fiona._shim', ['fiona/_shim2.c'], **ext_options))
+ elif gdal_major_version == 3:
+ log.info("Building Fiona for gdal >= 3.0.x: {0}".format(gdalversion))
+ ext_modules.append(
+ Extension('fiona._shim', ['fiona/_shim3.c'], **ext_options))
requirements = [
'attrs>=17',
=====================================
tests/conftest.py
=====================================
@@ -268,6 +268,10 @@ requires_gdal_lt_3 = pytest.mark.skipif(
not gdal_version.major < 3,
reason="Requires GDAL < 3")
+requires_gdal3 = pytest.mark.skipif(
+ not gdal_version.major >= 3,
+ reason="Requires GDAL 3.x")
+
@pytest.fixture(scope="class")
def unittest_data_dir(data_dir, request):
=====================================
tests/test__env.py
=====================================
@@ -17,7 +17,7 @@ def mock_wheel(tmpdir):
moduledir = tmpdir.mkdir("rasterio")
moduledir.ensure("__init__.py")
moduledir.ensure("_env.py")
- moduledir.ensure("gdal_data/pcs.csv")
+ moduledir.ensure("gdal_data/header.dxf")
moduledir.ensure("proj_data/epsg")
return moduledir
@@ -25,7 +25,7 @@ def mock_wheel(tmpdir):
@pytest.fixture
def mock_fhs(tmpdir):
"""A fake FHS system"""
- tmpdir.ensure("share/gdal/pcs.csv")
+ tmpdir.ensure("share/gdal/header.dxf")
tmpdir.ensure("share/proj/epsg")
return tmpdir
@@ -33,13 +33,13 @@ def mock_fhs(tmpdir):
@pytest.fixture
def mock_debian(tmpdir):
"""A fake Debian multi-install system"""
- tmpdir.ensure("share/gdal/1.11/pcs.csv")
- tmpdir.ensure("share/gdal/2.0/pcs.csv")
- tmpdir.ensure("share/gdal/2.1/pcs.csv")
- tmpdir.ensure("share/gdal/2.2/pcs.csv")
- tmpdir.ensure("share/gdal/2.3/pcs.csv")
- tmpdir.ensure("share/gdal/2.4/pcs.csv")
- tmpdir.ensure("share/gdal/3.0/pcs.csv")
+ tmpdir.ensure("share/gdal/1.11/header.dxf")
+ tmpdir.ensure("share/gdal/2.0/header.dxf")
+ tmpdir.ensure("share/gdal/2.1/header.dxf")
+ tmpdir.ensure("share/gdal/2.2/header.dxf")
+ tmpdir.ensure("share/gdal/2.3/header.dxf")
+ tmpdir.ensure("share/gdal/2.4/header.dxf")
+ tmpdir.ensure("share/gdal/3.0/header.dxf")
tmpdir.ensure("share/proj/epsg")
return tmpdir
=====================================
tests/test_collection.py
=====================================
@@ -9,7 +9,7 @@ import pytest
import fiona
from fiona.collection import Collection, supported_drivers
from fiona.env import getenv
-from fiona.errors import FionaValueError, DriverError
+from fiona.errors import FionaValueError, DriverError, FionaDeprecationWarning
from .conftest import WGS84PATTERN
@@ -80,7 +80,7 @@ class TestCollectionArgs(object):
class TestOpenException(object):
def test_no_archive(self):
- with pytest.raises(DriverError):
+ with pytest.warns(FionaDeprecationWarning), pytest.raises(DriverError):
fiona.open("/", mode='r', vfs="zip:///foo.zip")
=====================================
tests/test_collection_crs.py
=====================================
@@ -1,10 +1,12 @@
import os
import re
+import pytest
+
import fiona
import fiona.crs
-
-from .conftest import WGS84PATTERN, requires_gdal2
+from fiona.errors import CRSError
+from .conftest import WGS84PATTERN, requires_gdal2, requires_gdal3
def test_collection_crs_wkt(path_coutwildrnp_shp):
@@ -27,10 +29,35 @@ def test_collection_no_crs_wkt(tmpdir, path_coutwildrnp_shp):
@requires_gdal2
def test_collection_create_crs_wkt(tmpdir):
"""A collection can be created using crs_wkt"""
- filename = str(tmpdir.join("test.shp"))
+ filename = str(tmpdir.join("test.geojson"))
wkt = 'GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["EPSG","4326"]]'
with fiona.open(filename, 'w', schema={'geometry': 'Point', 'properties': {'foo': 'int'}}, crs_wkt=wkt, driver='GeoJSON') as dst:
- assert dst.crs_wkt == wkt
+ assert dst.crs_wkt.startswith('GEOGCS["WGS 84') or dst.crs_wkt.startswith('GEOGCS["GCS_WGS_1984')
+
+ with fiona.open(filename) as col:
+ assert col.crs_wkt.startswith('GEOGCS["WGS 84') or col.crs_wkt.startswith('GEOGCS["GCS_WGS_1984')
+
+
+ at requires_gdal3
+def test_collection_urn_crs(tmpdir):
+ filename = str(tmpdir.join("test.geojson"))
+ crs = "urn:ogc:def:crs:OGC:1.3:CRS84"
+ with fiona.open(filename, 'w', schema={'geometry': 'Point', 'properties': {'foo': 'int'}}, crs=crs, driver='GeoJSON') as dst:
+ assert dst.crs_wkt.startswith('GEOGCS["WGS 84')
with fiona.open(filename) as col:
assert col.crs_wkt.startswith('GEOGCS["WGS 84')
+
+
+
+def test_collection_invalid_crs(tmpdir):
+ filename = str(tmpdir.join("test.geojson"))
+ with pytest.raises(CRSError):
+ with fiona.open(filename, 'w', schema={'geometry': 'Point', 'properties': {'foo': 'int'}}, crs="12ab-invalid", driver='GeoJSON') as dst:
+ pass
+
+def test_collection_invalid_crs_wkt(tmpdir):
+ filename = str(tmpdir.join("test.geojson"))
+ with pytest.raises(CRSError):
+ with fiona.open(filename, 'w', schema={'geometry': 'Point', 'properties': {'foo': 'int'}}, crs_wkt="12ab-invalid", driver='GeoJSON') as dst:
+ pass
=====================================
tests/test_crs.py
=====================================
@@ -1,4 +1,7 @@
+import pytest
+
from fiona import crs, _crs
+from fiona.errors import CRSError
from .conftest import requires_gdal_lt_3
@@ -119,3 +122,13 @@ def test_towgs84_wkt():
wkt = _crs.crs_to_wkt(proj4)
assert 'towgs84' in wkt
assert 'wktext' in _crs.crs_to_wkt(proj4)
+
+
+ at pytest.mark.parametrize("invalid_input", [
+ "a random string that is invalid",
+ ("a", "tuple"),
+ "-48567=409 =2095"
+])
+def test_invalid_crs(invalid_input):
+ with pytest.raises(CRSError):
+ _crs.crs_to_wkt(invalid_input)
=====================================
tests/test_env.py
=====================================
@@ -58,7 +58,7 @@ def test_ensure_env_decorator_sets_gdal_data_prefix(find_file, gdalenv, monkeypa
return getenv()['GDAL_DATA']
find_file.return_value = None
- tmpdir.ensure("share/gdal/pcs.csv")
+ tmpdir.ensure("share/gdal/header.dxf")
monkeypatch.delenv('GDAL_DATA', raising=False)
monkeypatch.setattr(_env, '__file__', str(tmpdir.join("fake.py")))
monkeypatch.setattr(sys, 'prefix', str(tmpdir))
@@ -74,7 +74,7 @@ def test_ensure_env_decorator_sets_gdal_data_wheel(find_file, gdalenv, monkeypat
return getenv()['GDAL_DATA']
find_file.return_value = None
- tmpdir.ensure("gdal_data/pcs.csv")
+ tmpdir.ensure("gdal_data/header.dxf")
monkeypatch.delenv('GDAL_DATA', raising=False)
monkeypatch.setattr(_env, '__file__', str(tmpdir.join(os.path.basename(_env.__file__))))
@@ -89,7 +89,7 @@ def test_ensure_env_with_decorator_sets_gdal_data_wheel(find_file, gdalenv, monk
return getenv()['GDAL_DATA']
find_file.return_value = None
- tmpdir.ensure("gdal_data/pcs.csv")
+ tmpdir.ensure("gdal_data/header.dxf")
monkeypatch.delenv('GDAL_DATA', raising=False)
monkeypatch.setattr(_env, '__file__', str(tmpdir.join(os.path.basename(_env.__file__))))
=====================================
tests/test_listing.py
=====================================
@@ -8,7 +8,7 @@ import pytest
import fiona
import fiona.ogrext
-from fiona.errors import DriverError
+from fiona.errors import DriverError, FionaDeprecationWarning
def test_single_file_private(path_coutwildrnp_shp):
@@ -36,7 +36,8 @@ def test_zip_path(path_coutwildrnp_zip):
def test_zip_path_arch(path_coutwildrnp_zip):
vfs = 'zip://{}'.format(path_coutwildrnp_zip)
- assert fiona.listlayers('/coutwildrnp.shp', vfs=vfs) == ['coutwildrnp']
+ with pytest.warns(FionaDeprecationWarning):
+ assert fiona.listlayers('/coutwildrnp.shp', vfs=vfs) == ['coutwildrnp']
def test_list_not_existing(data_dir):
@@ -59,3 +60,15 @@ def test_invalid_vfs():
def test_invalid_path_ioerror():
with pytest.raises(DriverError):
fiona.listlayers("foobar")
+
+
+def test_listing_file(path_coutwildrnp_json):
+ """list layers from an open file object"""
+ with open(path_coutwildrnp_json, "rb") as f:
+ assert len(fiona.listlayers(f)) == 1
+
+
+def test_listing_pathobj(path_coutwildrnp_json):
+ """list layers from a Path object"""
+ pathlib = pytest.importorskip("pathlib")
+ assert len(fiona.listlayers(pathlib.Path(path_coutwildrnp_json))) == 1
=====================================
tests/test_vfs.py
=====================================
@@ -6,6 +6,7 @@ import pytest
import boto3
import fiona
+from fiona.errors import FionaDeprecationWarning
from fiona.vfs import vsi_path, parse_paths
from .test_collection import TestReading
@@ -92,7 +93,7 @@ class TestZipArchiveReading(TestVsiReading):
@pytest.fixture(autouse=True)
def zipfile(self, data_dir, path_coutwildrnp_zip):
vfs = 'zip://{}'.format(path_coutwildrnp_zip)
- self.c = fiona.open("/coutwildrnp.shp", "r", vfs=vfs)
+ self.c = fiona.open(vfs + "!coutwildrnp.shp", "r")
self.path = os.path.join(data_dir, 'coutwildrnp.zip')
yield
self.c.close()
@@ -123,7 +124,7 @@ class TestZipArchiveReadingAbsPath(TestZipArchiveReading):
@pytest.fixture(autouse=True)
def zipfile(self, path_coutwildrnp_zip):
vfs = 'zip://{}'.format(os.path.abspath(path_coutwildrnp_zip))
- self.c = fiona.open("/coutwildrnp.shp", "r", vfs=vfs)
+ self.c = fiona.open(vfs + "!coutwildrnp.shp", "r")
yield
self.c.close()
@@ -138,19 +139,12 @@ class TestZipArchiveReadingAbsPath(TestZipArchiveReading):
assert self.c.path.startswith('/vsizip/')
-#class TestTarArchiveReading(TestVsiReading):
-# @pytest.fixture(autouse=True)
-# def tarfile(self, data_dir, path_coutwildrnp_tar):
-# vfs = "tar://{}".format(path_coutwildrnp_tar)
-# self.c = fiona.open("/testing/coutwildrnp.shp", "r", vfs=vfs)
-# self.path = os.path.join(data_dir, 'coutwildrnp.tar')
-# yield
@pytest.mark.usefixtures('uttc_path_coutwildrnp_tar', 'uttc_data_dir')
class TarArchiveReadingTest(VsiReadingTest):
def setUp(self):
vfs = "tar://{}".format(self.path_coutwildrnp_tar)
- self.c = fiona.open("/testing/coutwildrnp.shp", "r", vfs=vfs)
+ self.c = fiona.open(vfs + "!testing/coutwildrnp.shp", "r")
self.path = os.path.join(self.data_dir, 'coutwildrnp.tar')
def tearDown(self):
View it on GitLab: https://salsa.debian.org/debian-gis-team/fiona/compare/bb128d7ed69adb54d57c5ff5a63401f0180f8bac...fdeac4aaf792a7ad0a9d7f163614c1d621db1dc0
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/fiona/compare/bb128d7ed69adb54d57c5ff5a63401f0180f8bac...fdeac4aaf792a7ad0a9d7f163614c1d621db1dc0
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20191108/72519249/attachment-0001.html>
More information about the Pkg-grass-devel
mailing list