def _add_band(self, idx, ds, bidx): """ Add a band to VRT Args: idx (int): Index of band in VRT ds (RasterReader): `rasterio` dataset bidx (int): Band index of `ds` """ band = SubElement(self.root, 'VRTRasterBand') band.set('dataType', dtypes._gdal_typename(ds.dtypes[bidx - 1])) band.set('band', str(idx + 1)) # Color interpretation ci = SubElement(band, 'ColorInterp') ci.text = COLOR_INTERP[idx] # Add NoDataValue if ds.nodatavals: ndv = SubElement(band, 'NoDataValue') ndv.text = str(ds.nodatavals[bidx - 1]) # Add SimpleSource source = SubElement(band, 'SimpleSource') source_path = SubElement(source, 'SourceFilename') source_path.text = os.path.abspath(ds.name) source_props = SubElement(source, 'SourceProperties') source_props.set('RasterXSize', str(ds.width)) source_props.set('RasterYSize', str(ds.height)) source_props.set('DataType', dtypes._gdal_typename(ds.dtypes[bidx - 1])) source_props.set('BlockXSize', str(ds.block_shapes[bidx - 1][1])) source_props.set('BlockYSize', str(ds.block_shapes[bidx - 1][0])) return source
def add_band(self, dtype, band_idx, color_interp, nodata=None, hidenodata=False): vrtrasterband = ET.SubElement(self.vrtdataset, 'VRTRasterBand') dtype = dtype if isinstance(dtype, str) else dtype.name vrtrasterband.attrib['dataType'] = _gdal_typename( dtype) if check_dtype(dtype) else dtype vrtrasterband.attrib['band'] = str(band_idx) if nodata is not None: nodatavalue = ET.SubElement(vrtrasterband, 'NoDataValue') nodatavalue.text = str(nodata) if hidenodata: hidenodatavalue = ET.SubElement(vrtrasterband, 'HideNoDataValue') hidenodatavalue.text = "1" if hidenodata else "0" colorinterp = ET.SubElement(vrtrasterband, 'ColorInterp') colorinterp.text = color_interp.capitalize() return vrtrasterband
def _setup_band_simplesource(self, simplesource, band_idx, dtype, relative_to_vrt, file_name, rasterxsize, rasterysize, blockxsize, blockysize, nodata): sourcefilename = ET.SubElement(simplesource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "1" if relative_to_vrt else "0" sourcefilename.text = vsi_path(parse_path(file_name)) sourceband = ET.SubElement(simplesource, 'SourceBand') sourceband.text = str(band_idx) sourceproperties = ET.SubElement(simplesource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(rasterxsize) sourceproperties.attrib['RasterYSize'] = str(rasterysize) if blockxsize is not None and blockysize is not None: sourceproperties.attrib['BlockXSize'] = str(blockxsize) sourceproperties.attrib['BlockYSize'] = str(blockysize) dtype = dtype if isinstance(dtype, str) else dtype.name sourceproperties.attrib['DataType'] = _gdal_typename(dtype) if check_dtype(dtype) else dtype
def resize_array( data: numpy.ndarray, height: int, width: int, resampling_method: Resampling = "nearest", ) -> numpy.ndarray: """resize array to a given height and width.""" out_shape: Union[Tuple[int, int], Tuple[int, int, int]] if len(data.shape) == 2: count = 1 h = data.shape[0] w = data.shape[1] out_shape = (height, width) else: count = data.shape[0] h = data.shape[1] w = data.shape[2] out_shape = (count, height, width) # We are using GDAL MEM driver to create a new dataset from the numpy array # ref: https://github.com/rasterio/rasterio/blob/master/rasterio/_io.pyx#L1946-L1955 info = { "DATAPOINTER": data.__array_interface__["data"][0], "PIXELS": w, "LINES": h, "BANDS": count, "DATATYPE": _gdal_typename(data.dtype.name), } dataset_options = ",".join(f"{name}={val}" for name, val in info.items()) datasetname = f"MEM:::{dataset_options}" with rasterio.open(datasetname, "r+") as src: # if a 2D array is passed, using indexes=1 makes sure we return an 2D array indexes = 1 if len(data.shape) == 2 else None return src.read( out_shape=out_shape, indexes=indexes, resampling=Resampling[resampling_method], )
def _make_band(root, source_band, vrt_bidx, description=None, vrt_ndv=None): # Create <VRTRasterBand> band = ET.SubElement(root, 'VRTRasterBand') band.set('dataType', _gdal_typename(source_band.dtype)) band.set('band', str(vrt_bidx)) # Optional subelements # TODO: ColorTable, GDALRasterAttributeTable, UnitType, # Offset, Scale, CategoryNames colorinterp = gdal.GetColorInterpretationName( source_band.colorinterp.value) _make_subelement(band, 'ColorInterp', colorinterp) # Output band NDV defaults to source NDV vrt_ndv = vrt_ndv if vrt_ndv is not None else source_band.nodata if vrt_ndv is not None: _make_subelement(band, 'NoDataValue', str(vrt_ndv)) description = description or source_band.description if description: band.set('Description', description) return band
def _make_source_props(xml_parent, source_band): """Creates <SourceProperties ... /> tag Parameters ---------- xml_parent : xml.etree.Element.SubElement Parent XML element, like a "ComplexSource" or "SimpleSource" source_band : VRTSourceBand The source band Returns ------- xml.etree.Element.SubElement "SourceProperties" subelement """ ele = ET.SubElement(xml_parent, 'SourceProperties') ele.set('RasterXSize', str(source_band.width)) ele.set('RasterYSize', str(source_band.height)) ele.set('DataType', _gdal_typename(source_band.dtype)) ele.set('BlockXSize', str(source_band.blockxsize)) ele.set('BlockYSize', str(source_band.blockysize)) return ele
def _boundless_vrt_doc(src_dataset, nodata=None, background=None, hidenodata=False, width=None, height=None, transform=None): """Make a VRT XML document. Parameters ---------- src_dataset : Dataset The dataset to wrap. background : Dataset, optional A dataset that provides the optional VRT background. NB: this dataset must have the same number of bands as the src_dataset. Returns ------- bytes An ascii-encoded string (an ElementTree detail) """ nodata = nodata or src_dataset.nodata width = width or src_dataset.width height = height or src_dataset.height transform = transform or src_dataset.transform vrtdataset = ET.Element('VRTDataset') vrtdataset.attrib['rasterYSize'] = str(height) vrtdataset.attrib['rasterXSize'] = str(width) srs = ET.SubElement(vrtdataset, 'SRS') srs.text = src_dataset.crs.wkt if src_dataset.crs else "" geotransform = ET.SubElement(vrtdataset, 'GeoTransform') geotransform.text = ','.join([str(v) for v in transform.to_gdal()]) for bidx, ci, block_shape, dtype in zip(src_dataset.indexes, src_dataset.colorinterp, src_dataset.block_shapes, src_dataset.dtypes): vrtrasterband = ET.SubElement(vrtdataset, 'VRTRasterBand') vrtrasterband.attrib['dataType'] = _gdal_typename(dtype) vrtrasterband.attrib['band'] = str(bidx) if nodata is not None: nodatavalue = ET.SubElement(vrtrasterband, 'NoDataValue') nodatavalue.text = str(nodata) if hidenodata: hidenodatavalue = ET.SubElement(vrtrasterband, 'HideNoDataValue') hidenodatavalue.text = "1" colorinterp = ET.SubElement(vrtrasterband, 'ColorInterp') colorinterp.text = ci.name.capitalize() if background is not None: simplesource = ET.SubElement(vrtrasterband, 'SimpleSource') sourcefilename = ET.SubElement(simplesource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.text = vsi_path(parse_path(background.name)) sourceband = ET.SubElement(simplesource, 'SourceBand') sourceband.text = str(bidx) sourceproperties = ET.SubElement(simplesource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = _gdal_typename(dtype) sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(simplesource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(background.width) srcrect.attrib['ySize'] = str(background.height) dstrect = ET.SubElement(simplesource, 'DstRect') dstrect.attrib['xOff'] = '0' dstrect.attrib['yOff'] = '0' dstrect.attrib['xSize'] = str(width) dstrect.attrib['ySize'] = str(height) simplesource = ET.SubElement(vrtrasterband, 'SimpleSource') sourcefilename = ET.SubElement(simplesource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.text = vsi_path(parse_path(src_dataset.name)) sourceband = ET.SubElement(simplesource, 'SourceBand') sourceband.text = str(bidx) sourceproperties = ET.SubElement(simplesource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = _gdal_typename(dtype) sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(simplesource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(src_dataset.width) srcrect.attrib['ySize'] = str(src_dataset.height) dstrect = ET.SubElement(simplesource, 'DstRect') dstrect.attrib['xOff'] = str( (src_dataset.transform.xoff - transform.xoff) / transform.a) dstrect.attrib['yOff'] = str( (src_dataset.transform.yoff - transform.yoff) / transform.e) dstrect.attrib['xSize'] = str(src_dataset.width * src_dataset.transform.a / transform.a) dstrect.attrib['ySize'] = str(src_dataset.height * src_dataset.transform.e / transform.e) if src_dataset.nodata is not None: nodata_elem = ET.SubElement(simplesource, 'NODATA') nodata_elem.text = str(src_dataset.nodata) if all(MaskFlags.per_dataset in flags for flags in src_dataset.mask_flag_enums): maskband = ET.SubElement(vrtdataset, 'MaskBand') vrtrasterband = ET.SubElement(maskband, 'VRTRasterBand') vrtrasterband.attrib['dataType'] = 'Byte' simplesource = ET.SubElement(vrtrasterband, 'SimpleSource') sourcefilename = ET.SubElement(simplesource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.text = vsi_path(parse_path(src_dataset.name)) sourceband = ET.SubElement(simplesource, 'SourceBand') sourceband.text = 'mask,1' sourceproperties = ET.SubElement(simplesource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = 'Byte' sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(simplesource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(src_dataset.width) srcrect.attrib['ySize'] = str(src_dataset.height) dstrect = ET.SubElement(simplesource, 'DstRect') dstrect.attrib['xOff'] = str( (src_dataset.transform.xoff - transform.xoff) / transform.a) dstrect.attrib['yOff'] = str( (src_dataset.transform.yoff - transform.yoff) / transform.e) dstrect.attrib['xSize'] = str(src_dataset.width) dstrect.attrib['ySize'] = str(src_dataset.height) return ET.tostring(vrtdataset)
def test_gdal_name(dtype, name): assert _gdal_typename(dtype) == name
def test_gdal_name(): assert _gdal_typename(ubyte) == 'Byte' assert _gdal_typename(np.uint8) == 'Byte' assert _gdal_typename(np.uint16) == 'UInt16'
def _boundless_vrt_doc(src_dataset, nodata=None, background=None, hidenodata=False, width=None, height=None, transform=None, masked=False): """Make a VRT XML document. Parameters ---------- src_dataset : Dataset The dataset to wrap. background : int or float, optional The background fill value for the boundless VRT. masked : bool If True, the src_dataset is replaced by its valid data mask. Returns ------- str An XML text string. """ nodata = nodata or src_dataset.nodata width = width or src_dataset.width height = height or src_dataset.height transform = transform or src_dataset.transform vrtdataset = ET.Element('VRTDataset') vrtdataset.attrib['rasterYSize'] = str(height) vrtdataset.attrib['rasterXSize'] = str(width) srs = ET.SubElement(vrtdataset, 'SRS') srs.text = src_dataset.crs.wkt if src_dataset.crs else "" geotransform = ET.SubElement(vrtdataset, 'GeoTransform') geotransform.text = ','.join([str(v) for v in transform.to_gdal()]) for bidx, ci, block_shape, dtype in zip(src_dataset.indexes, src_dataset.colorinterp, src_dataset.block_shapes, src_dataset.dtypes): vrtrasterband = ET.SubElement(vrtdataset, 'VRTRasterBand') vrtrasterband.attrib['dataType'] = _gdal_typename(dtype) vrtrasterband.attrib['band'] = str(bidx) if background is not None or nodata is not None: nodatavalue = ET.SubElement(vrtrasterband, 'NoDataValue') nodatavalue.text = str(background or nodata) if hidenodata: hidenodatavalue = ET.SubElement(vrtrasterband, 'HideNoDataValue') hidenodatavalue.text = "1" colorinterp = ET.SubElement(vrtrasterband, 'ColorInterp') colorinterp.text = ci.name.capitalize() complexsource = ET.SubElement(vrtrasterband, 'ComplexSource') sourcefilename = ET.SubElement(complexsource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.attrib["shared"] = "0" sourcefilename.text = parse_path(src_dataset.name).as_vsi() sourceband = ET.SubElement(complexsource, 'SourceBand') sourceband.text = str(bidx) sourceproperties = ET.SubElement(complexsource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = _gdal_typename(dtype) sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(complexsource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(src_dataset.width) srcrect.attrib['ySize'] = str(src_dataset.height) dstrect = ET.SubElement(complexsource, 'DstRect') dstrect.attrib['xOff'] = str( (src_dataset.transform.xoff - transform.xoff) / transform.a) dstrect.attrib['yOff'] = str( (src_dataset.transform.yoff - transform.yoff) / transform.e) dstrect.attrib['xSize'] = str(src_dataset.width * src_dataset.transform.a / transform.a) dstrect.attrib['ySize'] = str(src_dataset.height * src_dataset.transform.e / transform.e) if src_dataset.nodata is not None: nodata_elem = ET.SubElement(complexsource, 'NODATA') nodata_elem.text = str(src_dataset.nodata) if src_dataset.options is not None: openoptions = ET.SubElement(complexsource, 'OpenOptions') for ookey, oovalue in src_dataset.options.items(): ooi = ET.SubElement(openoptions, 'OOI') ooi.attrib['key'] = str(ookey) ooi.text = str(oovalue) # Effectively replaces all values of the source dataset with # 255. Due to GDAL optimizations, the source dataset will not # be read, so we get a performance improvement. if masked: scaleratio = ET.SubElement(complexsource, 'ScaleRatio') scaleratio.text = '0' scaleoffset = ET.SubElement(complexsource, 'ScaleOffset') scaleoffset.text = '255' if all(MaskFlags.per_dataset in flags for flags in src_dataset.mask_flag_enums): maskband = ET.SubElement(vrtdataset, 'MaskBand') vrtrasterband = ET.SubElement(maskband, 'VRTRasterBand') vrtrasterband.attrib['dataType'] = 'Byte' simplesource = ET.SubElement(vrtrasterband, 'SimpleSource') sourcefilename = ET.SubElement(simplesource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.attrib["shared"] = "0" sourcefilename.text = parse_path(src_dataset.name).as_vsi() sourceband = ET.SubElement(simplesource, 'SourceBand') sourceband.text = 'mask,1' sourceproperties = ET.SubElement(simplesource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = 'Byte' sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(simplesource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(src_dataset.width) srcrect.attrib['ySize'] = str(src_dataset.height) dstrect = ET.SubElement(simplesource, 'DstRect') dstrect.attrib['xOff'] = str( (src_dataset.transform.xoff - transform.xoff) / transform.a) dstrect.attrib['yOff'] = str( (src_dataset.transform.yoff - transform.yoff) / transform.e) dstrect.attrib['xSize'] = str(src_dataset.width) dstrect.attrib['ySize'] = str(src_dataset.height) return ET.tostring(vrtdataset).decode('ascii')
def test_gdal_name(): assert _gdal_typename(ubyte) == 'Byte' assert _gdal_typename(np.uint8) == 'Byte' assert _gdal_typename(np.uint16) == 'UInt16'
def _boundless_vrt_doc(src_dataset, nodata=None, width=None, height=None, transform=None): """Make a VRT XML document.""" nodata = nodata or src_dataset.nodata width = width or src_dataset.width height = height or src_dataset.height transform = transform or src_dataset.transform vrtdataset = ET.Element('VRTDataset') vrtdataset.attrib['rasterYSize'] = str(height) vrtdataset.attrib['rasterXSize'] = str(width) srs = ET.SubElement(vrtdataset, 'SRS') srs.text = src_dataset.crs.wkt geotransform = ET.SubElement(vrtdataset, 'GeoTransform') geotransform.text = ','.join([str(v) for v in transform.to_gdal()]) for bidx, ci, block_shape, dtype in zip(src_dataset.indexes, src_dataset.colorinterp, src_dataset.block_shapes, src_dataset.dtypes): vrtrasterband = ET.SubElement(vrtdataset, 'VRTRasterBand') vrtrasterband.attrib['dataType'] = _gdal_typename(dtype) vrtrasterband.attrib['band'] = str(bidx) if nodata is not None: nodatavalue = ET.SubElement(vrtrasterband, 'NoDataValue') nodatavalue.text = str(nodata) colorinterp = ET.SubElement(vrtrasterband, 'ColorInterp') colorinterp.text = ci.name.capitalize() simplesource = ET.SubElement(vrtrasterband, 'SimpleSource') sourcefilename = ET.SubElement(simplesource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.text = vsi_path(parse_path(src_dataset.name)) sourceband = ET.SubElement(simplesource, 'SourceBand') sourceband.text = str(bidx) sourceproperties = ET.SubElement(simplesource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = _gdal_typename(dtype) sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(simplesource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(src_dataset.width) srcrect.attrib['ySize'] = str(src_dataset.height) dstrect = ET.SubElement(simplesource, 'DstRect') dstrect.attrib['xOff'] = str((src_dataset.transform.xoff - transform.xoff) / transform.a) dstrect.attrib['yOff'] = str((src_dataset.transform.yoff - transform.yoff) / transform.e) dstrect.attrib['xSize'] = str(src_dataset.width) dstrect.attrib['ySize'] = str(src_dataset.height) if src_dataset.nodata is not None: nodata_elem = ET.SubElement(simplesource, 'NODATA') nodata_elem.text = str(src_dataset.nodata) if all(MaskFlags.per_dataset in flags for flags in src_dataset.mask_flag_enums): maskband = ET.SubElement(vrtdataset, 'MaskBand') vrtrasterband = ET.SubElement(maskband, 'VRTRasterBand') vrtrasterband.attrib['dataType'] = 'Byte' simplesource = ET.SubElement(vrtrasterband, 'SimpleSource') sourcefilename = ET.SubElement(simplesource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.text = vsi_path(parse_path(src_dataset.name)) sourceband = ET.SubElement(simplesource, 'SourceBand') sourceband.text = 'mask,1' sourceproperties = ET.SubElement(simplesource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = 'Byte' sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(simplesource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(src_dataset.width) srcrect.attrib['ySize'] = str(src_dataset.height) dstrect = ET.SubElement(simplesource, 'DstRect') dstrect.attrib['xOff'] = str((src_dataset.transform.xoff - transform.xoff) / transform.a) dstrect.attrib['yOff'] = str((src_dataset.transform.yoff - transform.yoff) / transform.e) dstrect.attrib['xSize'] = str(src_dataset.width) dstrect.attrib['ySize'] = str(src_dataset.height) return ET.tostring(vrtdataset)
def _boundless_vrt_doc( src_dataset, nodata=None, background=None, hidenodata=False, width=None, height=None, transform=None, masked=False): """Make a VRT XML document. Parameters ---------- src_dataset : Dataset The dataset to wrap. background : int or float, optional The background fill value for the boundless VRT. masked : book If True, the src_dataset is replaced by its valid data mask. Returns ------- str An XML text string. """ nodata = nodata or src_dataset.nodata width = width or src_dataset.width height = height or src_dataset.height transform = transform or src_dataset.transform vrtdataset = ET.Element('VRTDataset') vrtdataset.attrib['rasterYSize'] = str(height) vrtdataset.attrib['rasterXSize'] = str(width) srs = ET.SubElement(vrtdataset, 'SRS') srs.text = src_dataset.crs.wkt if src_dataset.crs else "" geotransform = ET.SubElement(vrtdataset, 'GeoTransform') geotransform.text = ','.join([str(v) for v in transform.to_gdal()]) for bidx, ci, block_shape, dtype in zip(src_dataset.indexes, src_dataset.colorinterp, src_dataset.block_shapes, src_dataset.dtypes): vrtrasterband = ET.SubElement(vrtdataset, 'VRTRasterBand') vrtrasterband.attrib['dataType'] = _gdal_typename(dtype) vrtrasterband.attrib['band'] = str(bidx) if nodata is not None: nodatavalue = ET.SubElement(vrtrasterband, 'NoDataValue') nodatavalue.text = str(nodata) if hidenodata: hidenodatavalue = ET.SubElement(vrtrasterband, 'HideNoDataValue') hidenodatavalue.text = "1" colorinterp = ET.SubElement(vrtrasterband, 'ColorInterp') colorinterp.text = ci.name.capitalize() if background is not None: complexsource = ET.SubElement(vrtrasterband, 'ComplexSource') sourcefilename = ET.SubElement(complexsource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = '1' sourcefilename.text = 'dummy.tif' # vsi_path(parse_path(background.name)) sourceband = ET.SubElement(complexsource, 'SourceBand') sourceband.text = str(bidx) sourceproperties = ET.SubElement(complexsource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = _gdal_typename(dtype) sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(complexsource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = '1' # str(background.width) srcrect.attrib['ySize'] = '1' # str(background.height) dstrect = ET.SubElement(complexsource, 'DstRect') dstrect.attrib['xOff'] = '0' dstrect.attrib['yOff'] = '0' dstrect.attrib['xSize'] = '1' # str(width) dstrect.attrib['ySize'] = '1' # str(height) scaleratio = ET.SubElement(complexsource, 'ScaleRatio') scaleratio.text = '0' scaleoffset = ET.SubElement(complexsource, 'ScaleOffset') scaleoffset.text = str(background) complexsource = ET.SubElement(vrtrasterband, 'ComplexSource') sourcefilename = ET.SubElement(complexsource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.text = vsi_path(parse_path(src_dataset.name)) sourceband = ET.SubElement(complexsource, 'SourceBand') sourceband.text = str(bidx) sourceproperties = ET.SubElement(complexsource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = _gdal_typename(dtype) sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(complexsource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(src_dataset.width) srcrect.attrib['ySize'] = str(src_dataset.height) dstrect = ET.SubElement(complexsource, 'DstRect') dstrect.attrib['xOff'] = str((src_dataset.transform.xoff - transform.xoff) / transform.a) dstrect.attrib['yOff'] = str((src_dataset.transform.yoff - transform.yoff) / transform.e) dstrect.attrib['xSize'] = str(src_dataset.width * src_dataset.transform.a / transform.a) dstrect.attrib['ySize'] = str(src_dataset.height * src_dataset.transform.e / transform.e) if src_dataset.nodata is not None: nodata_elem = ET.SubElement(complexsource, 'NODATA') nodata_elem.text = str(src_dataset.nodata) # Effectively replaces all values of the source dataset with # 255. Due to GDAL optimizations, the source dataset will not # be read, so we get a performance improvement. if masked: scaleratio = ET.SubElement(complexsource, 'ScaleRatio') scaleratio.text = '0' scaleoffset = ET.SubElement(complexsource, 'ScaleOffset') scaleoffset.text = '255' if all(MaskFlags.per_dataset in flags for flags in src_dataset.mask_flag_enums): maskband = ET.SubElement(vrtdataset, 'MaskBand') vrtrasterband = ET.SubElement(maskband, 'VRTRasterBand') vrtrasterband.attrib['dataType'] = 'Byte' simplesource = ET.SubElement(vrtrasterband, 'SimpleSource') sourcefilename = ET.SubElement(simplesource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.text = vsi_path(parse_path(src_dataset.name)) sourceband = ET.SubElement(simplesource, 'SourceBand') sourceband.text = 'mask,1' sourceproperties = ET.SubElement(simplesource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = 'Byte' sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(simplesource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(src_dataset.width) srcrect.attrib['ySize'] = str(src_dataset.height) dstrect = ET.SubElement(simplesource, 'DstRect') dstrect.attrib['xOff'] = str((src_dataset.transform.xoff - transform.xoff) / transform.a) dstrect.attrib['yOff'] = str((src_dataset.transform.yoff - transform.yoff) / transform.e) dstrect.attrib['xSize'] = str(src_dataset.width) dstrect.attrib['ySize'] = str(src_dataset.height) return ET.tostring(vrtdataset).decode('ascii')
def stack(_input, output, tile_x_size, tile_y_size, config=None, attrs=None, bbox=None): with rasterio.open(_input) as src: profile = src.profile trans = Affine.to_gdal(src.transform) dt = np.dtype(src.dtypes[0]) # read first band data type # read initial image metadata profile['driver'] = 'TileDB' profile['blockxsize'] = tile_x_size profile['blockysize'] = tile_y_size if 'tiled' in profile: del profile['tiled'] arr = xr.open_rasterio(_input, chunks={'x': tile_x_size, 'y': tile_y_size}) if bbox is None: w = profile['width'] h = profile['height'] bbox = (0, 0, w, h) else: w = bbox[2] - bbox[0] h = bbox[3] - bbox[1] nBlocksX = math.ceil(w / (tile_x_size * 1.0)) nBlocksY = math.ceil(h / (tile_y_size * 1.0)) # GDAL TileDB driver writes/reads blocks so bypass rasterio dom = tiledb.Domain( tiledb.Dim(name='BANDS', domain=(0, profile['count'] - 1), tile=1), tiledb.Dim(name='Y', domain=(0, (nBlocksY * tile_y_size) - 1), tile=tile_y_size, dtype=np.uint64), tiledb.Dim(name='X', domain=(0, (nBlocksX * tile_x_size) - 1), tile=tile_x_size, dtype=np.uint64)) cfg = tiledb.Config(config) ctx = tiledb.Ctx(config=cfg) schema = tiledb.ArraySchema( domain=dom, sparse=False, attrs=[tiledb.Attr(name="TDB_VALUES", dtype=dt)], ctx=ctx) tiledb.DenseArray.create(output, schema) with tiledb.DenseArray(output, 'w', ctx=ctx) as arr_output: arr[:, bbox[0]:bbox[2], bbox[1]:bbox[3]].data.to_tiledb(arr_output, storage_options=config) # write the GDAL metadata file from the source profile vfs = tiledb.VFS() meta = f"{output}/{os.path.basename(output)}.tdb.aux.xml" try: f = vfs.open(meta, "w") root = ET.Element('PAMDataset') geo = ET.SubElement(root, 'GeoTransform') geo.text = ', '.join(map(str, trans)) meta = ET.SubElement(root, 'Metadata') meta.set('domain', 'IMAGE_STRUCTURE') t = ET.SubElement(meta, 'MDI') t.set('key', 'DATA_TYPE') t.text = _gdal_typename(np.complex128) nbits = ET.SubElement(meta, 'MDI') nbits.set('key', 'NBITS') nbits.text = str(dt.itemsize * 8) xsize = ET.SubElement(meta, 'MDI') xsize.set('key', 'X_SIZE') xsize.text = str(w) ysize = ET.SubElement(meta, 'MDI') ysize.set('key', 'Y_SIZE') ysize.text = str(h) vfs.write(f, ET.tostring(root)) finally: vfs.close(f)
def add_mask_band(self, dtype): maskband = ET.SubElement(self.vrtdataset, 'MaskBand') vrtrasterband = ET.SubElement(maskband, 'VRTRasterBand') vrtrasterband.attrib['dataType'] = _gdal_typename(dtype) if check_dtype(dtype) else dtype return vrtrasterband
def _boundless_vrt_doc( src_dataset, nodata=None, background=None, hidenodata=False, width=None, height=None, transform=None): """Make a VRT XML document. Parameters ---------- src_dataset : Dataset The dataset to wrap. background : Dataset, optional A dataset that provides the optional VRT background. NB: this dataset must have the same number of bands as the src_dataset. Returns ------- bytes An ascii-encoded string (an ElementTree detail) """ nodata = nodata or src_dataset.nodata width = width or src_dataset.width height = height or src_dataset.height transform = transform or src_dataset.transform vrtdataset = ET.Element('VRTDataset') vrtdataset.attrib['rasterYSize'] = str(height) vrtdataset.attrib['rasterXSize'] = str(width) srs = ET.SubElement(vrtdataset, 'SRS') srs.text = src_dataset.crs.wkt if src_dataset.crs else "" geotransform = ET.SubElement(vrtdataset, 'GeoTransform') geotransform.text = ','.join([str(v) for v in transform.to_gdal()]) for bidx, ci, block_shape, dtype in zip(src_dataset.indexes, src_dataset.colorinterp, src_dataset.block_shapes, src_dataset.dtypes): vrtrasterband = ET.SubElement(vrtdataset, 'VRTRasterBand') vrtrasterband.attrib['dataType'] = _gdal_typename(dtype) vrtrasterband.attrib['band'] = str(bidx) if nodata is not None: nodatavalue = ET.SubElement(vrtrasterband, 'NoDataValue') nodatavalue.text = str(nodata) if hidenodata: hidenodatavalue = ET.SubElement(vrtrasterband, 'HideNoDataValue') hidenodatavalue.text = "1" colorinterp = ET.SubElement(vrtrasterband, 'ColorInterp') colorinterp.text = ci.name.capitalize() if background is not None: simplesource = ET.SubElement(vrtrasterband, 'SimpleSource') sourcefilename = ET.SubElement(simplesource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.text = vsi_path(parse_path(background.name)) sourceband = ET.SubElement(simplesource, 'SourceBand') sourceband.text = str(bidx) sourceproperties = ET.SubElement(simplesource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = _gdal_typename(dtype) sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(simplesource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(background.width) srcrect.attrib['ySize'] = str(background.height) dstrect = ET.SubElement(simplesource, 'DstRect') dstrect.attrib['xOff'] = '0' dstrect.attrib['yOff'] = '0' dstrect.attrib['xSize'] = str(width) dstrect.attrib['ySize'] = str(height) simplesource = ET.SubElement(vrtrasterband, 'SimpleSource') sourcefilename = ET.SubElement(simplesource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.text = vsi_path(parse_path(src_dataset.name)) sourceband = ET.SubElement(simplesource, 'SourceBand') sourceband.text = str(bidx) sourceproperties = ET.SubElement(simplesource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = _gdal_typename(dtype) sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(simplesource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(src_dataset.width) srcrect.attrib['ySize'] = str(src_dataset.height) dstrect = ET.SubElement(simplesource, 'DstRect') dstrect.attrib['xOff'] = str((src_dataset.transform.xoff - transform.xoff) / transform.a) dstrect.attrib['yOff'] = str((src_dataset.transform.yoff - transform.yoff) / transform.e) dstrect.attrib['xSize'] = str(src_dataset.width * src_dataset.transform.a / transform.a) dstrect.attrib['ySize'] = str(src_dataset.height * src_dataset.transform.e / transform.e) if src_dataset.nodata is not None: nodata_elem = ET.SubElement(simplesource, 'NODATA') nodata_elem.text = str(src_dataset.nodata) if all(MaskFlags.per_dataset in flags for flags in src_dataset.mask_flag_enums): maskband = ET.SubElement(vrtdataset, 'MaskBand') vrtrasterband = ET.SubElement(maskband, 'VRTRasterBand') vrtrasterband.attrib['dataType'] = 'Byte' simplesource = ET.SubElement(vrtrasterband, 'SimpleSource') sourcefilename = ET.SubElement(simplesource, 'SourceFilename') sourcefilename.attrib['relativeToVRT'] = "0" sourcefilename.text = vsi_path(parse_path(src_dataset.name)) sourceband = ET.SubElement(simplesource, 'SourceBand') sourceband.text = 'mask,1' sourceproperties = ET.SubElement(simplesource, 'SourceProperties') sourceproperties.attrib['RasterXSize'] = str(width) sourceproperties.attrib['RasterYSize'] = str(height) sourceproperties.attrib['dataType'] = 'Byte' sourceproperties.attrib['BlockYSize'] = str(block_shape[0]) sourceproperties.attrib['BlockXSize'] = str(block_shape[1]) srcrect = ET.SubElement(simplesource, 'SrcRect') srcrect.attrib['xOff'] = '0' srcrect.attrib['yOff'] = '0' srcrect.attrib['xSize'] = str(src_dataset.width) srcrect.attrib['ySize'] = str(src_dataset.height) dstrect = ET.SubElement(simplesource, 'DstRect') dstrect.attrib['xOff'] = str((src_dataset.transform.xoff - transform.xoff) / transform.a) dstrect.attrib['yOff'] = str((src_dataset.transform.yoff - transform.yoff) / transform.e) dstrect.attrib['xSize'] = str(src_dataset.width) dstrect.attrib['ySize'] = str(src_dataset.height) return ET.tostring(vrtdataset)
def close(self): from lxml.builder import ElementMaker logger.debug("%s new entries in %s", self.new_entries, self) if not self._new: logger.debug("no entries to write") return # combine existing and new entries all_entries = {**self._existing, **self._new} logger.debug("writing a total of %s entries", len(all_entries)) # get VRT attributes vrt_affine, vrt_shape = raster.tiles_to_affine_shape( list(all_entries.keys())) vrt_dtype = _gdal_typename(self._output.profile()["dtype"]) vrt_nodata = self._output.output_params["nodata"] # build XML E = ElementMaker() vrt = E.VRTDataset( E.SRS(self._tp.crs.wkt), E.GeoTransform(", ".join(map(str, vrt_affine.to_gdal()))), *[ E.VRTRasterBand( E.NoDataValue(str(vrt_nodata)), E.ColorInterp("Gray"), *[ E.ComplexSource( E.SourceFilename( _tile_path(orig_path=path, for_gdal=True) if path_is_remote(path) else relative_path( path=path, base_dir=os.path.split(self.path)[0]), relativeToVRT="0" if path_is_remote(path) else "1"), E.SourceBand(str(b_idx)), E.SourceProperties( RasterXSize=str(tile.shape.width), RasterYSize=str(tile.shape.height), DataType=vrt_dtype, BlockXSize=str(self._output.profile().get( "blockxsize", self._tp.tile_size)), BlockYSize=str(self._output.profile().get( "blockysize", self._tp.tile_size)), ), E.SrcRect( xOff="0", yOff="0", xSize=str(tile.shape.width), ySize=str(tile.shape.height), ), E.DstRect( xOff=str( list( raster.bounds_to_ranges( out_bounds=tile.bounds, in_affine=vrt_affine, in_shape=vrt_shape))[2]), yOff=str( list( raster.bounds_to_ranges( out_bounds=tile.bounds, in_affine=vrt_affine, in_shape=vrt_shape))[0]), xSize=str(tile.shape.width), ySize=str(tile.shape.height), ), E.NODATA(str(vrt_nodata))) for tile, path in sorted(all_entries.items(), key=operator.itemgetter(1)) ], dataType=vrt_dtype, band=str(b_idx)) for b_idx in range(1, self._output.profile()["count"] + 1) ], rasterXSize=str(vrt_shape.width), rasterYSize=str(vrt_shape.height), ) # generate pretty XML and write xmlstr = minidom.parseString(ET.tostring(vrt)).toprettyxml(indent=" ") if self._bucket: key = "/".join(self.path.split("/")[3:]) logger.debug("upload %s", key) self.bucket_resource.put_object(Key=key, Body=xmlstr) else: logger.debug("write to %s", self.path) with open(self.path, "w") as dst: dst.write(xmlstr)