def shp_to_raster(src_ds, out_tiff_path= '', output_bounds=None, no_data_value=None, attribute=None, cell_size = None, output_type=gdal.GDT_Unknown, res_format='GTiff'): """ 矢量转栅格 :param src_ds: shp 路径 :param out_tiff_path: 输出的 tiff 路径, 输入 '' 就是不需要输出路径 :param output_bounds: 输出范围,[ulx, uly, lrx, lry], 左下角点经纬度,右上角点经纬度 :param no_data_value: 无效值设置 :param attribute: 栅格化时使用的矢量字段,需要是数值类型字段 :param cell_size: 单元格大小 :param output_type: :param res_format: 输出的模式, "GTiff" :return: """ # FIXME 当输出为 MEM 类型时,无效值(no_data_value)的设置不起作用,看看是不是哪里想错了 # ------------------------------------------------------------------------------------------------------------------ if cell_size: x_res, y_res = cell_size[0], cell_size[1] else: raise ValueError('cell size is needed') # ------------------------------------------------------------------------------------------------------------------ rasterize_options = gdal.RasterizeOptions(outputBounds=output_bounds, outputType=output_type, noData=no_data_value, attribute=attribute, useZ=False, xRes=x_res, yRes=y_res, format=res_format) return gdal.Rasterize(out_tiff_path, src_ds, options=rasterize_options) # 转栅格
def Funcao_Rasterize(outputFile, inputFile, tam_pixel, nome_arq): sql = "select field_4, * from " + nome_arq rasterizeOptions = gdal.RasterizeOptions(options=[], format='Gtiff', creationOptions=None, noData=0, initValues=None, outputBounds=None, outputSRS=None, width=None, height=None, xRes=tam_pixel, yRes=tam_pixel, targetAlignedPixels=False, bands=None, inverse=False, allTouched=True, burnValues=None, attribute='field_4', useZ=False, layers=None, SQLStatement=sql, SQLDialect=None, where=None, callback=None, callback_data=None) gdal.Rasterize(outputFile, inputFile, options=rasterizeOptions)
def segment_image(in_path, out_path, seeds_band_width=5, cores=1, shape_dir=None): """Uses SAGA to create a segmentation of the input raster.""" with TemporaryDirectory() as td: temp_shape_path = os.path.join(td, "shapes.shp") saga_cmd = [ "saga_cmd", #"--cores", str(corepaths), "imagery", "obia", "-FEATURES", in_path, "-OBJECTS", temp_shape_path, "-SEEDS_BAND_WIDTH", str(seeds_band_width) ] subprocess.run(saga_cmd) if shape_dir: shutil.copy(td, shape_dir) in_raster = gdal.Open(in_path) shape_projection = osr.SpatialReference() shape_projection.ImportFromWkt(in_raster.GetProjection()) image_gt = in_raster.GetGeoTransform() x_res, y_res = image_gt[1], image_gt[ 5] * -1 # Negative 'y' values, you've foiled me again! width = in_raster.RasterXSize height = in_raster.RasterYSize ras_params = gdal.RasterizeOptions(noData=0, attribute="ID", xRes=x_res, yRes=y_res, outputType=gdal.GDT_UInt32, outputSRS=shape_projection, width=width, height=height) out_path = os.path.abspath(out_path) gdal.Rasterize(out_path, temp_shape_path, options=ras_params)
def create_supplemental_allclasses_rasters(recalculate: bool) -> None: _logger.info('Create supplemental response rasters') filepaths_supplements = sorted([ os.path.join(paths.DIR_DATA_TRAIN_CLEAN, filename) for filename in os.listdir(paths.DIR_DATA_TRAIN_CLEAN) if filename.endswith(SUFFIX_SUPPL) ]) for filepath_supplement in tqdm( filepaths_supplements, desc='Create supplemental training data rasters'): filepath_features = re.sub(SUFFIX_SUPPL, SUFFIX_FEAT, filepath_supplement) filepath_responses = re.sub(SUFFIX_SUPPL, SUFFIX_RESP, filepath_supplement) if os.path.exists(filepath_responses) and not recalculate: _logger.debug('Skipping, raster already processed') continue # Get rasterize parameters from existing features file raster_features = gdal.Open(filepath_features) srs = osr.SpatialReference(wkt=raster_features.GetProjection()) cols = raster_features.RasterXSize rows = raster_features.RasterYSize llx, xres, _, y0, _, yres = raster_features.GetGeoTransform() urx = llx + cols * xres y1 = y0 + rows * yres lly = min([y0, y1]) ury = max([y0, y1]) output_bounds = (llx, lly, urx, ury) # Rasterize to responses filepath options_rasterize = gdal.RasterizeOptions( outputType=gdal.GDT_Int16, creationOptions=['COMPRESS=DEFLATE', 'TILED=YES'], outputBounds=output_bounds, outputSRS=srs, xRes=xres, yRes=yres, noData=-9999, initValues=-9999, attribute='dn', ) gdal.Rasterize(filepath_responses, filepath_supplement, options=options_rasterize)
def rasterize_feat_shp_ds(shp_ds, raster_ds, layer_name='NA', feat_id='ID', feat_val='1', all_touched=False, exclude=False): if not exclude: str_eq = "='" else: str_eq = "!='" sql_stat = 'SELECT * FROM ' + layer_name + ' WHERE ' + feat_id + str_eq + feat_val + "'" opts = gdal.RasterizeOptions(burnValues=[1], bands=[1], SQLStatement=sql_stat, allTouched=all_touched) gdal.Rasterize(raster_ds, shp_ds, options=opts)
def get_training_data(image_path, shape_path, attribute="CODE", shape_projection_id=4326): """Given an image and a shapefile with categories, return x and y suitable for feeding into random_forest.fit. Note: THIS WILL FAIL IF YOU HAVE ANY CLASSES NUMBERED '0' WRITE A TEST FOR THIS TOO; if this goes wrong, it'll go wrong quietly and in a way that'll cause the most issues further on down the line.""" with TemporaryDirectory() as td: shape_projection = osr.SpatialReference() shape_projection.ImportFromEPSG(shape_projection_id) image = gdal.Open(image_path) image_gt = image.GetGeoTransform() x_res, y_res = image_gt[1], image_gt[5] ras_path = os.path.join(td, "poly_ras") ras_params = gdal.RasterizeOptions(noData=0, attribute=attribute, xRes=x_res, yRes=y_res, outputType=gdal.GDT_Int16, outputSRS=shape_projection) # This produces a rasterised geotiff that's right, but not perfectly aligned to pixels. # This can probably be fixed. gdal.Rasterize(ras_path, shape_path, options=ras_params) rasterised_shapefile = gdal.Open(ras_path) shape_array = rasterised_shapefile.GetVirtualMemArray() local_x, local_y = get_local_top_left(image, rasterised_shapefile) shape_sparse = sp.coo_matrix(shape_array) y, x, features = sp.find(shape_sparse) training_data = np.empty((len(features), image.RasterCount)) image_array = image.GetVirtualMemArray() image_view = image_array[:, local_y:local_y + rasterised_shapefile.RasterYSize, local_x:local_x + rasterised_shapefile.RasterXSize] for index in range(len(features)): training_data[index, :] = image_view[:, y[index], x[index]] return training_data, features
def create_supplemental_landwater_rasters(recalculate: bool) -> None: raise AssertionError('This script has not been tested since being updated, be careful') _logger.info('Create supplemental response rasters') filepaths_boundaries = sorted([ os.path.join(paths.DIR_DATA_TRAIN_CLEAN, filename) for filename in os.listdir(paths.DIR_DATA_TRAIN_CLEAN) if any([filename.endswith(suffix) for suffix in (SUFFIX_LAND, SUFFIX_WATER)]) ]) for idx, filepath_boundary in enumerate(filepaths_boundaries): _logger.debug('Processing raster {} of {}'.format(1+idx, len(filepaths_boundaries))) filepath_features = re.sub(r'_\w*\.shp', '_features.tif', filepath_boundary) filepath_responses = re.sub(r'\.shp', '.tif', filepath_boundary) if os.path.exists(filepath_responses) and not recalculate: _logger.debug('Skipping, raster already processed') continue # Get rasterize parameters from existing features file raster_features = gdal.Open(filepath_features) srs = osr.SpatialReference(wkt=raster_features.GetProjection()) cols = raster_features.RasterXSize rows = raster_features.RasterYSize llx, xres, _, y0, _, yres = raster_features.GetGeoTransform() urx = llx + cols * xres y1 = y0 + rows * yres lly = min([y0, y1]) ury = max([y0, y1]) output_bounds = (llx, lly, urx, ury) if filepath_boundary.endswith(SUFFIX_LAND): burn_value = encodings.MAPPINGS[encodings.LAND] elif filepath_boundary.endswith(SUFFIX_WATER): burn_value = encodings.MAPPINGS[encodings.WATER] else: raise AssertionError('Filepath does not end with land or water pattern, need to specify burn value') # Rasterize to responses filepath options_rasterize = gdal.RasterizeOptions( outputType=gdal.GDT_Int16, creationOptions=['COMPRESS=DEFLATE', 'TILED=YES'], outputBounds=output_bounds, outputSRS=srs, xRes=xres, yRes=yres, noData=-9999, initValues=-9999, burnValues=burn_value, ) gdal.Rasterize(filepath_responses, filepath_boundary, options=options_rasterize)
def get_training_data(image_path, shape_path, attribute="CODE", shape_projection_id=4326): """ Given an image and a shapefile with categories, returns training data and features suitable for fitting a scikit-learn classifier. For full details of how to create an appropriate shapefile, see [here](../index.html#training_data). Parameters ---------- image_path : str The path to the raster image to extract signatures from shape_path : str The path to the shapefile containing labelled class polygons attribute : str, optional The shapefile field containing the class labels. Defaults to "CODE". shape_projection_id : int, optional The EPSG number of the projection of the shapefile. Defaults to EPSG 4326. Returns ------- training_data : array_like A numpy array of shape (n_pixels, bands), where n_pixels is the number of pixels covered by the training polygons features : array_like A 1-d numpy array of length (n_pixels) containing the class labels for the corresponding pixel in training_data Notes ----- For performance, this uses scikit's sparse.nonzero() function to get the location of each training data pixel. This means that this will ignore any classes with a label of '0'. """ # TODO: WRITE A TEST FOR THIS TOO; if this goes wrong, it'll go wrong # quietly and in a way that'll cause the most issues further on down the line FILL_VALUE = -9999 with TemporaryDirectory() as td: # Step 1; rasterise shapefile into .tif of class values shape_projection = osr.SpatialReference() shape_projection.ImportFromEPSG(shape_projection_id) image = gdal.Open(image_path) image_gt = image.GetGeoTransform() x_res, y_res = image_gt[1], image_gt[5] ras_path = os.path.join(td, "poly_ras") ras_params = gdal.RasterizeOptions(noData=0, attribute=attribute, xRes=x_res, yRes=y_res, outputType=gdal.GDT_Int16, outputSRS=shape_projection) # This produces a rasterised geotiff that's right, but not perfectly aligned to pixels. # This can probably be fixed. gdal.Rasterize(ras_path, shape_path, options=ras_params) rasterised_shapefile = gdal.Open(ras_path) shape_array = rasterised_shapefile.GetVirtualMemArray() local_x, local_y = get_local_top_left(image, rasterised_shapefile) shape_sparse = sp.coo_matrix(np.asarray(shape_array).squeeze()) y, x, features = sp.find(shape_sparse) training_data = np.empty((len(features), image.RasterCount)) image_array = image.GetVirtualMemArray() image_view = image_array[:, local_y:local_y + rasterised_shapefile.RasterYSize, local_x:local_x + rasterised_shapefile.RasterXSize] for index in range(len(features)): training_data[index, :] = image_view[:, y[index], x[index]] image_view = None image_array = None shape_array = None rasterised_shapefile = None return training_data, features
def rasterize_response_quads() -> None: raise AssertionError( 'This script has not been tested since being updated, be careful') _assert_encoding_assumptions_hold() filenames = [ filename for filename in os.listdir(paths.DIR_DATA_TRAIN_RAW) if filename.endswith('.shp') ] for idx_filename, filename in enumerate(filenames): print('\rRasterizing shapefile {} of {}'.format( 1 + idx_filename, len(filenames))) # Get quad and filepaths quad = re.search(r'L15-\d{4}E-\d{4}N', filename).group() filepath_features = os.path.join( paths.DIR_DATA_TRAIN_CLEAN, quad + data_bucket.FILENAME_SUFFIX_FEATURES) filepath_source_responses = os.path.join(paths.DIR_DATA_TRAIN_RAW, filename) filepath_dest_lwr = re.sub('features.tif', 'responses_lwr.tif', filepath_features) filepath_dest_lwrn = re.sub('features.tif', 'responses_lwrn.tif', filepath_features) assert os.path.exists( filepath_features ), 'Download all feature quads before rasterizing response quads' # Get rasterize parameters raster_features = gdal.Open(filepath_features) srs = osr.SpatialReference(wkt=raster_features.GetProjection()) cols = raster_features.RasterXSize rows = raster_features.RasterYSize llx, xres, _, y0, _, yres = raster_features.GetGeoTransform() urx = llx + cols * xres y1 = y0 + rows * yres lly = min([y0, y1]) ury = max([y0, y1]) # Rasterize into Land-Water-Reef-NotReef options_rasterize = gdal.RasterizeOptions( outputType=gdal.GDT_Int16, creationOptions=['COMPRESS=DEFLATE', 'TILED=YES'], outputBounds=[llx, lly, urx, ury], outputSRS=srs, xRes=xres, yRes=yres, noData=-9999, initValues=-9999, attribute='class_code') raster_out = gdal.Rasterize(filepath_dest_lwrn, filepath_source_responses, options=options_rasterize) del raster_out # Remove cloud-shade and unknown classes. Unknown classes could be anything from water to reef to clouds, while # cloud-shade is not reliable as the map was created with the analytical mosaic rather than the visual mosaic. min_nodata = min(encodings.MAPPINGS[encodings.CLOUD_SHADE], encodings.MAPPINGS[encodings.UNKNOWN]) command = 'gdal_calc.py -A {filepath} --outfile {filepath} --NoDataValue=-9999 --overwrite ' + \ '--calc="A * (A < {min_nodata}) + -9999 * (A >= {min_nodata})"' command = command.format(filepath=filepath_dest_lwrn, min_nodata=min_nodata) gdal_command_line.run_gdal_command(command, _logger) # Create Land-Water-Reef val_reef = encodings.MAPPINGS[encodings.REEF_TOP] val_notreef = encodings.MAPPINGS[encodings.NOT_REEF_TOP] command = 'gdal_calc.py -A {filepath_lwrn} --outfile={filepath_lwr} --NoDataValue=-9999 --overwrite ' + \ '--calc="A * (A != {val_notreef}) + {val_reef} * (A == {val_notreef})"' command = command.format(filepath_lwrn=filepath_dest_lwrn, filepath_lwr=filepath_dest_lwr, val_notreef=val_notreef, val_reef=val_reef) gdal_command_line.run_gdal_command(command, _logger)
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) res = self.parameterAsDouble(parameters, self.RES, context) outwidth = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) PINF = -3.402823466e+38 ext = source.sourceExtent() Xmin = ext.xMinimum() + res Xmax = ext.xMaximum() - res Ymin = ext.yMinimum() + res Ymax = ext.yMaximum() - res SizeX = Xmax - Xmin SizeY = Ymax - Ymin Nx = int(round(SizeX / res) + 1) Ny = int(round(SizeY / res) + 1) StepX = SizeX / (Nx - 1) StepY = SizeY / (Ny - 1) outRasterSRS = osr.SpatialReference() srs = source.sourceCrs() wkt = srs.toWkt() outRasterSRS.ImportFromWkt(wkt) opts = gdal.RasterizeOptions(outputBounds=[Xmin, Ymin, Xmax, Ymax], xRes=res, yRes=res, format="GTiff", burnValues=[1], outputSRS=outRasterSRS) QgsMessageLog.logMessage(outwidth) QgsMessageLog.logMessage(source.sourceName()) rasterized = "/Users/tsamsonov/GitHub/raster-space/rasterized.tif" gdal.Rasterize( rasterized, "/Users/tsamsonov/GitHub/raster-space/output/buildings_dem_s.shp", options=opts) src_ds = gdal.Open(rasterized) srcband = src_ds.GetRasterBand(1) drv = gdal.GetDriverByName('GTiff') outdist = '/Users/tsamsonov/GitHub/raster-space/dist.tif' dst_ds = drv.Create('/Users/tsamsonov/GitHub/raster-space/dist.tif', src_ds.RasterXSize, src_ds.RasterYSize, 1, gdal.GetDataTypeByName('Float32')) dst_ds.SetGeoTransform(src_ds.GetGeoTransform()) dst_ds.SetProjection(src_ds.GetProjectionRef()) dstband = dst_ds.GetRasterBand(1) # In this example I'm using target pixel values of 100 and 300. I'm also using Distance units as GEO but you can change that to PIXELS. gdal.ComputeProximity(srcband, dstband, ["DISTUNITS=GEO"]) dstband.FlushCache() dist = gdal.Open(outdist) if dist is None: QgsMessageLog.logMessage('Unable to open ' + outwidth) else: QgsMessageLog.logMessage(str(dist.RasterCount)) # npdist = np.array(dstband.ReadAsArray()) npdist = np.array(srcband.ReadAsArray()) # length testing QgsMessageLog.logMessage(str(npdist.shape)) npwid = np.full(npdist.shape, 0) QgsMessageLog.logMessage(str(npwid.shape)) nodata = -1 # npres = rspace.estimate_width(npdist, npwid, StepX, nodata) npres = rspace.estimate_length(npdist, npwid, StepX, nodata, 2048, 2000) QgsMessageLog.logMessage(str(StepX)) QgsMessageLog.logMessage(str(np.min(npdist))) QgsMessageLog.logMessage(str(np.max(npdist))) QgsMessageLog.logMessage(rspace.__file__) res = drv.Create(outwidth, src_ds.RasterXSize, src_ds.RasterYSize, 1, gdal.GetDataTypeByName('Float32')) res.SetGeoTransform(src_ds.GetGeoTransform()) res.SetProjection(src_ds.GetProjectionRef()) outband = res.GetRasterBand(1) outband.WriteArray(npres, 0, 0) outband.FlushCache() outband.SetNoDataValue(-1) return {self.OUTPUT: source}