Exemple #1
0
    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"
                        )
Exemple #4
0
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()
Exemple #6
0
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:
Exemple #7
0
    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()
Exemple #8
0
# -*- 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
Exemple #9
0
    )
    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',