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) path, vsi, archive = parse_paths(path, vfs) if archive: if not os.path.exists(archive): raise IOError("no such archive file: %r" % archive) elif not os.path.exists(path): raise IOError("no such file or directory: %r" % path) with drivers(): return _listlayers(vsi_path(path, vsi, archive))
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, 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: # Parse the vfs into a vsi and an archive path. path, vsi, archive = parse_paths(fp, vfs) if mode in ('a', 'r'): if is_remote(vsi): pass elif archive: if not os.path.exists(archive): raise IOError("no such archive file: %r" % archive) elif path != '-' and not os.path.exists(path): raise IOError("no such file or directory: %r" % path) c = Collection(path, mode, driver=driver, encoding=encoding, layer=layer, vsi=vsi, archive=archive, 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, vsi=vsi, archive=archive, 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 test_parse_vfs(): assert parse_paths("/", "zip://foo.zip") == ("/", "zip", "foo.zip")
def test_parse_path2(): assert parse_paths("foo") == ("foo", None, None)
def test_parse_path(): assert parse_paths("zip://foo.zip") == ("foo.zip", "zip", None)
def open(path, mode='r', driver=None, schema=None, crs=None, encoding=None, layer=None, vfs=None, enabled_drivers=None, crs_wkt=None, **kwargs): """Open file at ``path`` in ``mode`` "r" (read), "a" (append), or "w" (write) and return a ``Collection`` object. 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``. 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. 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']) """ # Parse the vfs into a vsi and an archive path. path, vsi, archive = parse_paths(path, vfs) if mode in ('a', 'r'): if is_remote(vsi): pass elif archive: if not os.path.exists(archive): raise IOError("no such archive file: %r" % archive) elif path != '-' and not os.path.exists(path): raise IOError("no such file or directory: %r" % path) c = Collection(path, mode, driver=driver, encoding=encoding, layer=layer, vsi=vsi, archive=archive, 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, vsi=vsi, archive=archive, 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 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) # Parse the vfs into a vsi and an archive path. path, vsi, archive = parse_paths(fp, vfs) if mode in ('a', 'r'): if is_remote(vsi): pass elif archive: if not os.path.exists(archive): raise IOError("no such archive file: %r" % archive) elif path != '-' and not os.path.exists(path): raise IOError("no such file or directory: %r" % path) c = Collection(path, mode, driver=driver, encoding=encoding, layer=layer, vsi=vsi, archive=archive, 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, vsi=vsi, archive=archive, 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