def _check_schema_driver_support(self): """Check support for the schema against the driver See GH#572 for discussion. """ gdal_version_major = get_gdal_version_tuple().major for field in self._schema["properties"].values(): field_type = field.split(":")[0] if self._driver == "ESRI Shapefile": if field_type == "datetime": raise DriverSupportError("ESRI Shapefile does not support datetime fields") elif field_type == "time": raise DriverSupportError("ESRI Shapefile does not support time fields") elif self._driver == "GPKG": if field_type == "time": raise DriverSupportError("GPKG does not support time fields") elif gdal_version_major == 1: if field_type == "datetime": raise DriverSupportError("GDAL 1.x GPKG driver does not support datetime fields") elif self._driver == "GeoJSON": if gdal_version_major == 1: if field_type == "date": warnings.warn("GeoJSON driver in GDAL 1.x silently converts date to string in non-standard format") elif field_type == "datetime": warnings.warn("GeoJSON driver in GDAL 1.x silently converts datetime to string in non-standard format") elif field_type == "time": warnings.warn("GeoJSON driver in GDAL 1.x silently converts time to string")
def _check_schema_driver_support(self): """Check support for the schema against the driver See GH#572 for discussion. """ gdal_version_major = get_gdal_version_tuple().major for field in self._schema["properties"].values(): field_type = field.split(":")[0] if not _driver_supports_field(self.driver, field_type): if self.driver == 'GPKG' and gdal_version_major < 2 and field_type == "datetime": raise DriverSupportError( "GDAL 1.x GPKG driver does not support datetime fields" ) else: raise DriverSupportError( "{driver} does not support {field_type} " "fields".format(driver=self.driver, field_type=field_type)) elif field_type in { 'time', 'datetime', 'date' } and _driver_converts_field_type_silently_to_str( self.driver, field_type): if self._driver == "GeoJSON" and gdal_version_major < 2 and field_type in { 'datetime', 'date' }: warnings.warn( "GeoJSON driver in GDAL 1.x silently converts {} to string" " in non-standard format".format(field_type)) else: warnings.warn( "{driver} driver silently converts {field_type} " "to string".format(driver=self.driver, field_type=field_type))
def _check_schema_driver_support(self): """Check support for the schema against the driver See GH#572 for discussion. """ gdal_version_major = get_gdal_version_tuple().major for field in self._schema["properties"].values(): field_type = field.split(":")[0] if self._driver == "ESRI Shapefile": if field_type == "datetime": raise DriverSupportError( "ESRI Shapefile does not support datetime fields") elif field_type == "time": raise DriverSupportError( "ESRI Shapefile does not support time fields") elif self._driver == "GPKG": if field_type == "time": raise DriverSupportError( "GPKG does not support time fields") elif gdal_version_major == 1: if field_type == "datetime": raise DriverSupportError( "GDAL 1.x GPKG driver does not support datetime fields" ) elif self._driver == "GeoJSON": if gdal_version_major == 1: if field_type == "date": warnings.warn( "GeoJSON driver in GDAL 1.x silently converts date to string in non-standard format" ) elif field_type == "datetime": warnings.warn( "GeoJSON driver in GDAL 1.x silently converts datetime to string in non-standard format" ) elif field_type == "time": warnings.warn( "GeoJSON driver in GDAL 1.x silently converts time to string" )
from fiona.compat import OrderedDict from fiona.io import MemoryFile from fiona.ogrext import _bounds, _listlayers, FIELD_TYPES_MAP, _remove, _remove_layer from fiona.path import ParsedPath, parse_path, vsi_path from fiona.vfs import parse_paths as vfs_parse_paths # These modules are imported by fiona.ogrext, but are also import here to # help tools like cx_Freeze find them automatically from fiona import _geometry, _err, rfc3339 import uuid __all__ = ['bounds', 'listlayers', 'open', 'prop_type', 'prop_width'] __version__ = "1.8.3" __gdal_version__ = get_gdal_release_name() gdal_version = get_gdal_version_tuple() log = logging.getLogger(__name__) log.addHandler(logging.NullHandler()) @ensure_env_with_credentials def open(fp, mode='r', driver=None, schema=None, crs=None, encoding=None, layer=None, vfs=None, enabled_drivers=None,
def __init__(self, path, mode='r', driver=None, schema=None, crs=None, encoding=None, layer=None, vsi=None, archive=None, enabled_drivers=None, crs_wkt=None, ignore_fields=None, ignore_geometry=False, **kwargs): """The required ``path`` is the absolute or relative path to a file, such as '/data/test_uk.shp'. In ``mode`` 'r', data can be read only. In ``mode`` 'a', data can be appended to a file. In ``mode`` 'w', data overwrites the existing contents of a file. In ``mode`` 'w', an OGR ``driver`` name and a ``schema`` are required. A Proj4 ``crs`` string is recommended. If both ``crs`` and ``crs_wkt`` keyword arguments are passed, the latter will trump the former. In 'w' mode, kwargs will be mapped to OGR layer creation options. """ if not isinstance(path, (string_types, Path)): raise TypeError("invalid path: %r" % path) if not isinstance(mode, string_types) or mode not in ('r', 'w', 'a'): raise TypeError("invalid mode: %r" % mode) if driver and not isinstance(driver, string_types): raise TypeError("invalid driver: %r" % driver) if schema and not hasattr(schema, 'get'): raise TypeError("invalid schema: %r" % schema) if crs and not isinstance(crs, compat.DICT_TYPES + string_types): raise TypeError("invalid crs: %r" % crs) if crs_wkt and not isinstance(crs_wkt, string_types): raise TypeError("invalid crs_wkt: %r" % crs_wkt) if encoding and not isinstance(encoding, string_types): raise TypeError("invalid encoding: %r" % encoding) if layer and not isinstance(layer, tuple(list(string_types) + [int])): raise TypeError("invalid name: %r" % layer) if vsi: if not isinstance(vsi, string_types) or not vfs.valid_vsi(vsi): raise TypeError("invalid vsi: %r" % vsi) if archive and not isinstance(archive, string_types): raise TypeError("invalid archive: %r" % archive) # Check GDAL version against drivers if (driver == "GPKG" and get_gdal_version_tuple() < (1, 11, 0)): raise DriverError( "GPKG driver requires GDAL 1.11.0, fiona was compiled " "against: {}".format(get_gdal_release_name())) self.session = None self.iterator = None self._len = 0 self._bounds = None self._driver = None self._schema = None self._crs = None self._crs_wkt = None self.env = None self.enabled_drivers = enabled_drivers self.ignore_fields = ignore_fields self.ignore_geometry = bool(ignore_geometry) if vsi: self.path = vfs.vsi_path(path, vsi, archive) path = parse_path(self.path) else: path = parse_path(path) self.path = vsi_path(path) if mode == 'w': if layer and not isinstance(layer, string_types): raise ValueError("in 'w' mode, layer names must be strings") if driver == 'GeoJSON': if layer is not None: raise ValueError("the GeoJSON format does not have layers") self.name = 'OgrGeoJSON' # TODO: raise ValueError as above for other single-layer formats. else: self.name = layer or os.path.basename( os.path.splitext(path.path)[0]) else: if layer in (0, None): self.name = 0 else: self.name = layer or os.path.basename( os.path.splitext(path)[0]) self.mode = mode if self.mode == 'w': if driver == 'Shapefile': driver = 'ESRI Shapefile' if not driver: raise DriverError("no driver") elif driver not in supported_drivers: raise DriverError("unsupported driver: %r" % driver) elif self.mode not in supported_drivers[driver]: raise DriverError("unsupported mode: %r" % self.mode) self._driver = driver if not schema: raise SchemaError("no schema") elif 'properties' not in schema: raise SchemaError("schema lacks: properties") elif 'geometry' not in schema: raise SchemaError("schema lacks: geometry") self._schema = schema self._check_schema_driver_support() if crs_wkt or crs: self._crs_wkt = crs_to_wkt(crs_wkt or crs) self._driver = driver kwargs.update(encoding=encoding) self.encoding = encoding try: if self.mode == 'r': self.session = Session() self.session.start(self, **kwargs) elif self.mode in ('a', 'w'): self.session = WritingSession() self.session.start(self, **kwargs) except IOError: self.session = None raise if self.session is not None: self.guard_driver_mode() if self.mode in ("a", "w"): self._valid_geom_types = _get_valid_geom_types( self.schema, self.driver) self.field_skip_log_filter = FieldSkipLogFilter()
from fiona.io import MemoryFile from fiona.ogrext import _bounds, _listlayers, FIELD_TYPES_MAP, _remove, _remove_layer from fiona.path import ParsedPath, parse_path, vsi_path from fiona.vfs import parse_paths as vfs_parse_paths # These modules are imported by fiona.ogrext, but are also import here to # help tools like cx_Freeze find them automatically from fiona import _geometry, _err, rfc3339 import uuid __all__ = ['bounds', 'listlayers', 'open', 'prop_type', 'prop_width'] __version__ = "1.8.6" __gdal_version__ = get_gdal_release_name() gdal_version = get_gdal_version_tuple() log = logging.getLogger(__name__) log.addHandler(logging.NullHandler()) @ensure_env_with_credentials def open(fp, mode='r', driver=None, schema=None, crs=None, encoding=None, layer=None, vfs=None, enabled_drivers=None, crs_wkt=None, **kwargs): """Open a collection for read, append, or write In write mode, a driver name such as "ESRI Shapefile" or "GPX" (see OGR docs or ``ogr2ogr --help`` on the command line) and a schema mapping such as:
def __init__(self, path, mode='r', driver=None, schema=None, crs=None, encoding=None, layer=None, vsi=None, archive=None, enabled_drivers=None, crs_wkt=None, ignore_fields=None, ignore_geometry=False, **kwargs): """The required ``path`` is the absolute or relative path to a file, such as '/data/test_uk.shp'. In ``mode`` 'r', data can be read only. In ``mode`` 'a', data can be appended to a file. In ``mode`` 'w', data overwrites the existing contents of a file. In ``mode`` 'w', an OGR ``driver`` name and a ``schema`` are required. A Proj4 ``crs`` string is recommended. If both ``crs`` and ``crs_wkt`` keyword arguments are passed, the latter will trump the former. In 'w' mode, kwargs will be mapped to OGR layer creation options. """ if not isinstance(path, (string_types, Path)): raise TypeError("invalid path: %r" % path) if not isinstance(mode, string_types) or mode not in ('r', 'w', 'a'): raise TypeError("invalid mode: %r" % mode) if driver and not isinstance(driver, string_types): raise TypeError("invalid driver: %r" % driver) if schema and not hasattr(schema, 'get'): raise TypeError("invalid schema: %r" % schema) if crs and not isinstance(crs, compat.DICT_TYPES + string_types): raise TypeError("invalid crs: %r" % crs) if crs_wkt and not isinstance(crs_wkt, string_types): raise TypeError("invalid crs_wkt: %r" % crs_wkt) if encoding and not isinstance(encoding, string_types): raise TypeError("invalid encoding: %r" % encoding) if layer and not isinstance(layer, tuple(list(string_types) + [int])): raise TypeError("invalid name: %r" % layer) if vsi: if not isinstance(vsi, string_types) or not vfs.valid_vsi(vsi): raise TypeError("invalid vsi: %r" % vsi) if archive and not isinstance(archive, string_types): raise TypeError("invalid archive: %r" % archive) # Check GDAL version against drivers if (driver == "GPKG" and get_gdal_version_tuple() < (1, 11, 0)): raise DriverError( "GPKG driver requires GDAL 1.11.0, fiona was compiled " "against: {}".format(get_gdal_release_name())) self.session = None self.iterator = None self._len = 0 self._bounds = None self._driver = None self._schema = None self._crs = None self._crs_wkt = None self.enabled_drivers = enabled_drivers self.ignore_fields = ignore_fields self.ignore_geometry = bool(ignore_geometry) if vsi: self.path = vfs.vsi_path(path, vsi, archive) path = parse_path(self.path) else: path = parse_path(path) self.path = vsi_path(path) if mode == 'w': if layer and not isinstance(layer, string_types): raise ValueError("in 'w' mode, layer names must be strings") if driver == 'GeoJSON': if layer is not None: raise ValueError("the GeoJSON format does not have layers") self.name = 'OgrGeoJSON' # TODO: raise ValueError as above for other single-layer formats. else: self.name = layer or os.path.basename(os.path.splitext(path.path)[0]) else: if layer in (0, None): self.name = 0 else: self.name = layer or os.path.basename(os.path.splitext(path)[0]) self.mode = mode if self.mode == 'w': if driver == 'Shapefile': driver = 'ESRI Shapefile' if not driver: raise DriverError("no driver") elif driver not in supported_drivers: raise DriverError( "unsupported driver: %r" % driver) elif self.mode not in supported_drivers[driver]: raise DriverError( "unsupported mode: %r" % self.mode) self._driver = driver if not schema: raise SchemaError("no schema") elif 'properties' not in schema: raise SchemaError("schema lacks: properties") elif 'geometry' not in schema: raise SchemaError("schema lacks: geometry") 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") self._driver = driver kwargs.update(encoding=encoding) self.encoding = encoding try: if self.mode == 'r': self.session = Session() self.session.start(self, **kwargs) elif self.mode in ('a', 'w'): self.session = WritingSession() self.session.start(self, **kwargs) except IOError: self.session = None raise if self.session is not None: self.guard_driver_mode() if self.mode in ("a", "w"): self._valid_geom_types = _get_valid_geom_types(self.schema, self.driver) self.field_skip_log_filter = FieldSkipLogFilter()
# -*- coding: utf-8 -*- from fiona.env import Env from fiona._env import get_gdal_version_tuple _GDAL_VERSION = get_gdal_version_tuple() # Here is the list of available drivers as (name, modes) tuples. Currently, # we only expose the defaults (excepting FileGDB). We also don't expose # the CSV or GeoJSON drivers. Use Python's csv and json modules instead. # Might still exclude a few more of these after making a pass through the # entries for each at https://gdal.org/drivers/vector/index.html to screen # out the multi-layer formats. supported_drivers = dict([ # OGR Vector Formats # Format Name Code Creation Georeferencing Compiled by default # Aeronav FAA files AeronavFAA No Yes Yes ("AeronavFAA", "r"), # ESRI ArcObjects ArcObjects No Yes No, needs ESRI ArcObjects # Arc/Info Binary Coverage AVCBin No Yes Yes # multi-layer # ("AVCBin", "r"), # Arc/Info .E00 (ASCII) Coverage AVCE00 No Yes Yes # multi-layer # ("AVCE00", "r"), # Arc/Info Generate ARCGEN No No Yes ("ARCGEN", "r"), # Atlas BNA BNA Yes No Yes ("BNA", "rw"), # AutoCAD DWG DWG No No No # AutoCAD DXF DXF Yes No Yes
) 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 from fiona.drvsupport import ( supported_drivers, driver_mode_mingdal, _driver_converts_field_type_silently_to_str, _driver_supports_field, ) from fiona.path import Path, vsi_path, parse_path from six import string_types, binary_type _GDAL_VERSION_TUPLE = get_gdal_version_tuple() _GDAL_RELEASE_NAME = get_gdal_release_name() log = logging.getLogger(__name__) class Collection(object): """A file-like interface to features of a vector dataset Python text file objects are iterators over lines of a file. Fiona Collections are similar iterators (not lists!) over features represented as GeoJSON-like mappings. """ def __init__(self, path, mode='r',