def open(fp, mode='r', driver=None, width=None, height=None, count=None, crs=None, transform=None, dtype=None, nodata=None, sharing=False, **kwargs): """Open a dataset for reading or writing. The dataset may be located in a local file, in a resource located by a URL, or contained within a stream of bytes. In read ('r') or read/write ('r+') mode, no keyword arguments are required: these attributes are supplied by the opened dataset. In write ('w' or 'w+') mode, the driver, width, height, count, and dtype keywords are strictly required. Parameters ---------- fp : str, file object or pathlib.Path object A filename or URL, a file object opened in binary ('rb') mode, or a Path object. mode : str, optional 'r' (read, the default), 'r+' (read/write), 'w' (write), or 'w+' (write/read). driver : str, optional A short format driver name (e.g. "GTiff" or "JPEG") or a list of such names (see GDAL docs at http://www.gdal.org/formats_list.html). In 'w' or 'w+' modes a single name is required. In 'r' or 'r+' modes the driver can usually be omitted. Registered drivers will be tried sequentially until a match is found. When multiple drivers are available for a format such as JPEG2000, one of them can be selected by using this keyword argument. width : int, optional The number of columns of the raster dataset. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. height : int, optional The number of rows of the raster dataset. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. count : int, optional The count of dataset bands. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. crs : str, dict, or CRS; optional The coordinate reference system. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. transform : Affine instance, optional Affine transformation mapping the pixel space to geographic space. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. dtype : str or numpy dtype The data type for bands. For example: 'uint8' or ``rasterio.uint16``. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. nodata : int, float, or nan; optional Defines the pixel value to be interpreted as not valid data. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. sharing : bool; optional To reduce overhead and prevent programs from running out of file descriptors, rasterio maintains a pool of shared low level dataset handles. When `True` this function will use a shared handle if one is available. Multithreaded programs must avoid sharing and should set *sharing* to `False`. kwargs : optional These are passed to format drivers as directives for creating or interpreting datasets. For example: in 'w' or 'w+' modes a `tiled=True` keyword argument will direct the GeoTIFF format driver to create a tiled, rather than striped, TIFF. Returns ------- A ``DatasetReader`` or ``DatasetWriter`` object. Examples -------- To open a GeoTIFF for reading using standard driver discovery and no directives: >>> import rasterio >>> with rasterio.open('example.tif') as dataset: ... print(dataset.profile) To open a JPEG2000 using only the JP2OpenJPEG driver: >>> with rasterio.open( ... 'example.jp2', driver='JP2OpenJPEG') as dataset: ... print(dataset.profile) To create a new 8-band, 16-bit unsigned, tiled, and LZW-compressed GeoTIFF with a global extent and 0.5 degree resolution: >>> from rasterio.transform import from_origin >>> with rasterio.open( ... 'example.tif', 'w', driver='GTiff', dtype='uint16', ... width=720, height=360, count=8, crs='EPSG:4326', ... transform=from_origin(-180.0, 90.0, 0.5, 0.5), ... nodata=0, tiled=True, compress='lzw') as dataset: ... dataset.write(...) """ if not isinstance(fp, string_types): if not (hasattr(fp, 'read') or hasattr(fp, 'write') or isinstance(fp, Path)): raise TypeError("invalid path or file: {0!r}".format(fp)) if mode and not isinstance(mode, string_types): raise TypeError("invalid mode: {0!r}".format(mode)) if driver and not isinstance(driver, string_types): raise TypeError("invalid driver: {0!r}".format(driver)) if dtype and not check_dtype(dtype): raise TypeError("invalid dtype: {0!r}".format(dtype)) if nodata is not None: nodata = float(nodata) if transform: transform = guard_transform(transform) # Check driver/mode blacklist. if driver and is_blacklisted(driver, mode): raise RasterioIOError("Blacklisted: file cannot be opened by " "driver '{0}' in '{1}' mode".format( driver, mode)) # Special case for file object argument. if mode == 'r' and hasattr(fp, 'read'): @contextmanager def fp_reader(fp): memfile = MemoryFile(fp.read()) dataset = memfile.open(driver=driver, sharing=sharing) try: yield dataset finally: dataset.close() memfile.close() return fp_reader(fp) elif mode in ('w', 'w+') and hasattr(fp, 'write'): @contextmanager def fp_writer(fp): memfile = MemoryFile() dataset = memfile.open(driver=driver, width=width, height=height, count=count, crs=crs, transform=transform, dtype=dtype, nodata=nodata, sharing=sharing, **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) # The 'normal' filename or URL path. path = parse_path(fp) # Create dataset instances and pass the given env, which will # be taken over by the dataset's context manager if it is not # None. if mode == 'r': s = DatasetReader(path, driver=driver, sharing=sharing, **kwargs) elif mode == "r+": s = get_writer_for_path(path, driver=driver)(path, mode, driver=driver, sharing=sharing, **kwargs) elif mode.startswith("w"): if not driver: driver = driver_from_extension(path) writer = get_writer_for_driver(driver) if writer is not None: s = writer(path, mode, driver=driver, width=width, height=height, count=count, crs=crs, transform=transform, dtype=dtype, nodata=nodata, sharing=sharing, **kwargs) else: raise DriverCapabilityError( "Writer does not exist for driver: %s" % str(driver)) else: raise DriverCapabilityError( "mode must be one of 'r', 'r+', or 'w', not %s" % mode) return s
def open(fp, mode='r', driver=None, width=None, height=None, count=None, crs=None, transform=None, dtype=None, nodata=None, sharing=False, **kwargs): """Open a dataset for reading or writing. The dataset may be located in a local file, in a resource located by a URL, or contained within a stream of bytes. In read ('r') or read/write ('r+') mode, no keyword arguments are required: these attributes are supplied by the opened dataset. In write ('w' or 'w+') mode, the driver, width, height, count, and dtype keywords are strictly required. Parameters ---------- fp : str, file object, PathLike object, FilePath, or MemoryFile A filename or URL, a file object opened in binary ('rb') mode, a Path object, or one of the rasterio classes that provides the dataset-opening interface (has an open method that returns a dataset). mode : str, optional 'r' (read, the default), 'r+' (read/write), 'w' (write), or 'w+' (write/read). driver : str, optional A short format driver name (e.g. "GTiff" or "JPEG") or a list of such names (see GDAL docs at https://gdal.org/drivers/raster/index.html). In 'w' or 'w+' modes a single name is required. In 'r' or 'r+' modes the driver can usually be omitted. Registered drivers will be tried sequentially until a match is found. When multiple drivers are available for a format such as JPEG2000, one of them can be selected by using this keyword argument. width : int, optional The number of columns of the raster dataset. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. height : int, optional The number of rows of the raster dataset. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. count : int, optional The count of dataset bands. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. crs : str, dict, or CRS; optional The coordinate reference system. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. transform : Affine instance, optional Affine transformation mapping the pixel space to geographic space. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. dtype : str or numpy dtype The data type for bands. For example: 'uint8' or ``rasterio.uint16``. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. nodata : int, float, or nan; optional Defines the pixel value to be interpreted as not valid data. Required in 'w' or 'w+' modes, it is ignored in 'r' or 'r+' modes. sharing : bool; optional To reduce overhead and prevent programs from running out of file descriptors, rasterio maintains a pool of shared low level dataset handles. When `True` this function will use a shared handle if one is available. Multithreaded programs must avoid sharing and should set *sharing* to `False`. kwargs : optional These are passed to format drivers as directives for creating or interpreting datasets. For example: in 'w' or 'w+' modes a `tiled=True` keyword argument will direct the GeoTIFF format driver to create a tiled, rather than striped, TIFF. Returns ------- A ``DatasetReader`` or ``DatasetWriter`` object. Examples -------- To open a GeoTIFF for reading using standard driver discovery and no directives: >>> import rasterio >>> with rasterio.open('example.tif') as dataset: ... print(dataset.profile) To open a JPEG2000 using only the JP2OpenJPEG driver: >>> with rasterio.open( ... 'example.jp2', driver='JP2OpenJPEG') as dataset: ... print(dataset.profile) To create a new 8-band, 16-bit unsigned, tiled, and LZW-compressed GeoTIFF with a global extent and 0.5 degree resolution: >>> from rasterio.transform import from_origin >>> with rasterio.open( ... 'example.tif', 'w', driver='GTiff', dtype='uint16', ... width=720, height=360, count=8, crs='EPSG:4326', ... transform=from_origin(-180.0, 90.0, 0.5, 0.5), ... nodata=0, tiled=True, compress='lzw') as dataset: ... dataset.write(...) """ if not isinstance(fp, str): if not ( hasattr(fp, "read") or hasattr(fp, "write") or isinstance(fp, (os.PathLike, MemoryFile, FilePath)) ): raise TypeError("invalid path or file: {0!r}".format(fp)) if mode and not isinstance(mode, str): raise TypeError("invalid mode: {0!r}".format(mode)) if driver and not isinstance(driver, str): raise TypeError("invalid driver: {0!r}".format(driver)) if dtype and not check_dtype(dtype): raise TypeError("invalid dtype: {0!r}".format(dtype)) if nodata is not None: nodata = float(nodata) if transform: transform = guard_transform(transform) # Check driver/mode blacklist. if driver and is_blacklisted(driver, mode): raise RasterioIOError( "Blacklisted: file cannot be opened by " "driver '{0}' in '{1}' mode".format(driver, mode)) # If the fp argument is a file-like object and can be adapted by # rasterio's FilePath we do so. Otherwise, we use a MemoryFile to # hold fp's contents and store that in an ExitStack attached to the # dataset object that we will return. When a dataset's close method # is called, this ExitStack will be unwound and the MemoryFile's # storage will be cleaned up. if mode == 'r' and hasattr(fp, 'read'): if have_vsi_plugin: return FilePath(fp).open(driver=driver, sharing=sharing, **kwargs) else: memfile = MemoryFile(fp.read()) dataset = memfile.open(driver=driver, sharing=sharing, **kwargs) dataset._env.enter_context(memfile) return dataset elif mode in ('w', 'w+') and hasattr(fp, 'write'): memfile = MemoryFile() dataset = memfile.open( driver=driver, width=width, height=height, count=count, crs=crs, transform=transform, dtype=dtype, nodata=nodata, sharing=sharing, **kwargs ) dataset._env.enter_context(memfile) # For the writing case we push an extra callback onto the # ExitStack. It ensures that the MemoryFile's contents are # copied to the open file object. def func(*args, **kwds): memfile.seek(0) fp.write(memfile.read()) dataset._env.callback(func) return dataset # TODO: test for a shared base class or abstract type. elif isinstance(fp, (FilePath, MemoryFile)): if mode.startswith("r"): dataset = fp.open(driver=driver, sharing=sharing, **kwargs) # Note: FilePath does not support writing and an exception will # result from this. elif mode.startswith("w"): dataset = fp.open( driver=driver, width=width, height=height, count=count, crs=crs, transform=transform, dtype=dtype, nodata=nodata, sharing=sharing, **kwargs ) return dataset # At this point, the fp argument is a string or path-like object # which can be converted to a string. else: raw_dataset_path = os.fspath(fp) path = _parse_path(raw_dataset_path) if mode == "r": dataset = DatasetReader(path, driver=driver, sharing=sharing, **kwargs) elif mode == "r+": dataset = get_writer_for_path(path, driver=driver)( path, mode, driver=driver, sharing=sharing, **kwargs ) elif mode.startswith("w"): if not driver: driver = driver_from_extension(path) writer = get_writer_for_driver(driver) if writer is not None: dataset = writer( path, mode, driver=driver, width=width, height=height, count=count, crs=crs, transform=transform, dtype=dtype, nodata=nodata, sharing=sharing, **kwargs ) else: raise DriverCapabilityError( "Writer does not exist for driver: %s" % str(driver) ) else: raise DriverCapabilityError( "mode must be one of 'r', 'r+', or 'w', not %s" % mode) return dataset