def from_path(path, *args, **kwargs): """Create a session object suited to the data at `path`. Parameters ---------- path : str A dataset path or identifier. args : sequence Positional arguments for the foreign session constructor. kwargs : dict Keyword arguments for the foreign session constructor. Returns ------- Session """ if not path: return DummySession() path = parse_path(path) if isinstance(path, UnparsedPath) or path.is_local: return DummySession() elif path.scheme == "s3" or path.scheme.endswith( "+s3") or "amazonaws.com" in path.path: return AWSSession(*args, **kwargs) # This factory can be extended to other cloud providers here. # elif path.scheme == "cumulonimbus": # for example. # return CumulonimbusSession(*args, **kwargs) else: return DummySession()
def from_path(path, *args, **kwargs): """Create a session object suited to the data at `path`. Parameters ---------- path : str A dataset path or identifier. args : sequence Positional arguments for the foreign session constructor. kwargs : dict Keyword arguments for the foreign session constructor. Returns ------- Session """ if not path: return DummySession() path = parse_path(path) if isinstance(path, UnparsedPath) or path.is_local: return DummySession() elif path.scheme == "s3" or path.scheme.endswith("+s3") or "amazonaws.com" in path.path: return AWSSession(*args, **kwargs) # This factory can be extended to other cloud providers here. # elif path.scheme == "cumulonimbus": # for example. # return CumulonimbusSession(*args, **kwargs) else: return DummySession()
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. Returns ------- list A list of layer name strings. """ if hasattr(fp, 'read'): with MemoryFile(fp.read()) as memfile: return _listlayers(memfile.name) else: 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 listlayers(path, vfs=None): """Returns a list of layer names in their index order. The required ``path`` argument may be an absolute or relative file or directory path. 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) else: pobj = parse_path(path) return _listlayers(vsi_path(pobj))
def listdir(path): """List files in a directory Parameters ---------- path : URI (str or pathlib.Path) A dataset resource identifier. Returns ------- list A list of filename strings. """ if isinstance(path, Path): path = str(path) if not isinstance(path, string_types): raise TypeError("invalid path: %r" % path) pobj = parse_path(path) return _listdir(vsi_path(pobj))
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: {'geometry': 'Point', 'properties': [('class', 'int'), ('label', 'str'), ('value', 'float')]} must be provided. If a particular ordering of properties ("fields" in GIS parlance) in the written file is desired, a list of (key, value) pairs as above or an ordered dict is required. If no ordering is needed, a standard dict will suffice. A coordinate reference system for collections in write mode can be defined by the ``crs`` parameter. It takes Proj4 style mappings like {'proj': 'longlat', 'ellps': 'WGS84', 'datum': 'WGS84', 'no_defs': True} short hand strings like EPSG:4326 or WKT representations of coordinate reference systems. The drivers used by Fiona will try to detect the encoding of data files. If they fail, you may provide the proper ``encoding``, such as 'Windows-1252' for the Natural Earth datasets. When the provided path is to a file containing multiple named layers of data, a layer can be singled out by ``layer``. The drivers enabled for opening datasets may be restricted to those listed in the ``enabled_drivers`` parameter. This and the ``driver`` parameter afford much control over opening of files. # Trying only the GeoJSON driver when opening to read, the # following raises ``DataIOError``: fiona.open('example.shp', driver='GeoJSON') # Trying first the GeoJSON driver, then the Shapefile driver, # the following succeeds: fiona.open( 'example.shp', enabled_drivers=['GeoJSON', 'ESRI Shapefile']) Parameters ---------- fp : URI (str or pathlib.Path), or file-like object A dataset resource identifier or file object. mode : str One of 'r', to read (the default); 'a', to append; or 'w', to write. driver : str In 'w' mode a format driver name is required. In 'r' or 'a' mode this parameter has no effect. schema : dict Required in 'w' mode, has no effect in 'r' or 'a' mode. crs : str or dict Required in 'w' mode, has no effect in 'r' or 'a' mode. encoding : str Name of the encoding used to encode or decode the dataset. layer : int or str The integer index or name of a layer in a multi-layer dataset. vfs : str This is a deprecated parameter. A URI scheme such as "zip://" should be used instead. enabled_drivers : list An optional list of driver names to used when opening a collection. crs_wkt : str An optional WKT representation of a coordinate reference system. kwargs : mapping Other driver-specific parameters that will be interpreted by the OGR library as layer creation or opening options. Returns ------- Collection """ if mode == 'r' and hasattr(fp, 'read'): @contextmanager def fp_reader(fp): memfile = MemoryFile(fp.read()) dataset = memfile.open() try: yield dataset finally: dataset.close() memfile.close() return fp_reader(fp) elif mode == 'w' and hasattr(fp, 'write'): if schema: # Make an ordered dict of schema properties. this_schema = schema.copy() this_schema['properties'] = OrderedDict(schema['properties']) else: this_schema = None @contextmanager def fp_writer(fp): memfile = MemoryFile() dataset = memfile.open(driver=driver, crs=crs, schema=schema, layer=layer, encoding=encoding, enabled_drivers=enabled_drivers, **kwargs) try: yield dataset finally: dataset.close() memfile.seek(0) fp.write(memfile.read()) memfile.close() return fp_writer(fp) else: # If a pathlib.Path instance is given, convert it to a string path. if isinstance(fp, Path): fp = str(fp) if vfs: # Parse the vfs into a vsi and an archive path. path, scheme, archive = vfs_parse_paths(fp, vfs=vfs) path = ParsedPath(path, archive, scheme) else: path = parse_path(fp) if mode in ('a', 'r'): c = Collection(path, mode, driver=driver, encoding=encoding, layer=layer, enabled_drivers=enabled_drivers, **kwargs) elif mode == 'w': if schema: # Make an ordered dict of schema properties. this_schema = schema.copy() this_schema['properties'] = OrderedDict(schema['properties']) else: this_schema = None c = Collection(path, mode, crs=crs, driver=driver, schema=this_schema, encoding=encoding, layer=layer, enabled_drivers=enabled_drivers, crs_wkt=crs_wkt, **kwargs) else: raise ValueError( "mode string must be one of 'r', 'w', or 'a', not %s" % mode) return c
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()
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: {'geometry': 'Point', 'properties': [('class', 'int'), ('label', 'str'), ('value', 'float')]} must be provided. If a particular ordering of properties ("fields" in GIS parlance) in the written file is desired, a list of (key, value) pairs as above or an ordered dict is required. If no ordering is needed, a standard dict will suffice. A coordinate reference system for collections in write mode can be defined by the ``crs`` parameter. It takes Proj4 style mappings like {'proj': 'longlat', 'ellps': 'WGS84', 'datum': 'WGS84', 'no_defs': True} short hand strings like EPSG:4326 or WKT representations of coordinate reference systems. The drivers used by Fiona will try to detect the encoding of data files. If they fail, you may provide the proper ``encoding``, such as 'Windows-1252' for the Natural Earth datasets. When the provided path is to a file containing multiple named layers of data, a layer can be singled out by ``layer``. The drivers enabled for opening datasets may be restricted to those listed in the ``enabled_drivers`` parameter. This and the ``driver`` parameter afford much control over opening of files. # Trying only the GeoJSON driver when opening to read, the # following raises ``DataIOError``: fiona.open('example.shp', driver='GeoJSON') # Trying first the GeoJSON driver, then the Shapefile driver, # the following succeeds: fiona.open( 'example.shp', enabled_drivers=['GeoJSON', 'ESRI Shapefile']) Parameters ---------- fp : URI (str or pathlib.Path), or file-like object A dataset resource identifier or file object. mode : str One of 'r', to read (the default); 'a', to append; or 'w', to write. driver : str In 'w' mode a format driver name is required. In 'r' or 'a' mode this parameter has no effect. schema : dict Required in 'w' mode, has no effect in 'r' or 'a' mode. crs : str or dict Required in 'w' mode, has no effect in 'r' or 'a' mode. encoding : str Name of the encoding used to encode or decode the dataset. layer : int or str The integer index or name of a layer in a multi-layer dataset. vfs : str This is a deprecated parameter. A URI scheme such as "zip://" should be used instead. enabled_drivers : list An optional list of driver names to used when opening a collection. crs_wkt : str An optional WKT representation of a coordinate reference system. kwargs : mapping Other driver-specific parameters that will be interpreted by the OGR library as layer creation or opening options. Returns ------- Collection """ if mode == 'r' and hasattr(fp, 'read'): @contextmanager def fp_reader(fp): memfile = MemoryFile(fp.read()) dataset = memfile.open() try: yield dataset finally: dataset.close() memfile.close() return fp_reader(fp) elif mode == 'w' and hasattr(fp, 'write'): if schema: # Make an ordered dict of schema properties. this_schema = schema.copy() this_schema['properties'] = OrderedDict(schema['properties']) else: this_schema = None @contextmanager def fp_writer(fp): memfile = MemoryFile() dataset = memfile.open( driver=driver, crs=crs, schema=schema, layer=layer, encoding=encoding, enabled_drivers=enabled_drivers, **kwargs) try: yield dataset finally: dataset.close() memfile.seek(0) fp.write(memfile.read()) memfile.close() return fp_writer(fp) else: # If a pathlib.Path instance is given, convert it to a string path. if isinstance(fp, Path): fp = str(fp) if vfs: # Parse the vfs into a vsi and an archive path. path, scheme, archive = vfs_parse_paths(fp, vfs=vfs) path = ParsedPath(path, archive, scheme) else: path = parse_path(fp) if mode in ('a', 'r'): c = Collection(path, mode, driver=driver, encoding=encoding, layer=layer, enabled_drivers=enabled_drivers, **kwargs) elif mode == 'w': if schema: # Make an ordered dict of schema properties. this_schema = schema.copy() this_schema['properties'] = OrderedDict(schema['properties']) else: this_schema = None c = Collection(path, mode, crs=crs, driver=driver, schema=this_schema, encoding=encoding, layer=layer, enabled_drivers=enabled_drivers, crs_wkt=crs_wkt, **kwargs) else: raise ValueError( "mode string must be one of 'r', 'w', or 'a', not %s" % mode) return c
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()