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 rasterize_inplace(rast, inshape, prefill=0): """ Overwrites a raster with the output of a polygon rasterization *Parameters* rast : str path to EXISTING raster file that will store values from rasterized inshape : str path to vector dataset that will be rasterized prefill : int Value to write to raster before writing polygonization result """ img = gdal.Open(rast, gdal.GA_Update) arr = img.ReadAsArray() arr[:] = prefill img.GetRasterBand(1).WriteArray(arr) img.FlushCache() del img rst = gdal.Open(rast, gdal.GA_Update) gdal.Rasterize(rst, inshape, burnValues=[1]) del rst
def _rasterize(raster_class, geodataframe, burn_values, attribute, gdal_driver, projection, x_size, y_size, nb_band, geo_transform, data_type, no_data, all_touched): """ Rasterize geographic layer Parameters ---------- raster_class: RasterBase Raster class to return geodataframe: geopandas.GeoDataFrame or gistools.layer.GeoLayer Geographic layer to be rasterized burn_values: None or list[float] or list[int] list of values to burn in each band, excusive with attribute attribute: str attribute in layer from which burn value must be retrieved gdal_driver projection x_size: int y_size: int nb_band: int geo_transform: tuple data_type no_data all_touched: bool Returns ------- """ with ShapeTempFile() as shp_file, \ RasterTempFile(gdal_driver.GetMetadata()['DMD_EXTENSION']) as out_file: geodataframe.to_file(shp_file.path, driver=ESRI_DRIVER) out_ds = _gdal_temp_dataset(out_file.path, gdal_driver, projection, x_size, y_size, nb_band, geo_transform, data_type, no_data) gdal.Rasterize(out_ds, shp_file.path, bands=[bd + 1 for bd in range(nb_band)], burnValues=burn_values, attribute=attribute, allTouched=all_touched) out_ds = None # Be careful with the temp file, make a pointer to be sure # the Python garbage collector does not destroy it ! raster = raster_class(out_file.path) raster._temp_file = out_file return raster
def get_s2_cloud(self, ): if glob(self.s2_file_dir + '/cloud.tif') == []: print 'Rasterizing cloud mask' g = gdal.Open(self.s2_file_dir + '/B04.jp2') geo_t = g.GetGeoTransform() x_size, y_size = g.RasterXSize, g.RasterYSize xmin, xmax = min(geo_t[0], geo_t[0] + x_size * geo_t[1]), \ max(geo_t[0], geo_t[0] + x_size * geo_t[1]) ymin, ymax = min(geo_t[3], geo_t[3] + y_size * geo_t[5]), \ max(geo_t[3], geo_t[3] + y_size * geo_t[5]) xRes, yRes = abs(geo_t[1]), abs(geo_t[5]) try: self.cirrus = gdal.Rasterize("", self.s2_file_dir+ "/qi/MSK_CLOUDS_B00.gml", \ format="MEM", xRes=xRes, yRes=yRes, where="maskType='CIRRUS'", \ outputBounds=[xmin, ymin, xmax, ymax], noData=np.nan, burnValues=1).ReadAsArray() except: self.cirrus = np.zeros((x_size, y_size)).astype(bool) try: self.cloud = gdal.Rasterize("", self.s2_file_dir+ "/qi/MSK_CLOUDS_B00.gml", \ format="MEM", xRes=xRes, yRes=yRes, where="maskType='OPAQUE'", \ outputBounds=[xmin, ymin, xmax, ymax], noData=np.nan, burnValues=2).ReadAsArray() except: self.cloud = np.zeros((x_size, y_size)).astype(bool) cloud_mask = self.cirrus + self.cloud driver = gdal.GetDriverByName('GTiff') g1 = driver.Create(self.s2_file_dir+'/cloud.tif', \ g.RasterXSize, g.RasterYSize, 1, gdal.GDT_Byte) projection = g.GetProjection() geotransform = g.GetGeoTransform() g1.SetGeoTransform(geotransform) g1.SetProjection(projection) gcp_count = g.GetGCPs() if gcp_count != 0: g1.SetGCPs(gcp_count, g.GetGCPProjection()) g1.GetRasterBand(1).WriteArray(cloud_mask) g1 = None g = None else: cloud_mask = gdal.Open(self.s2_file_dir+\ '/cloud.tif').ReadAsArray() self.cirrus = (cloud_mask == 1) self.cloud = (cloud_mask >= 2) #self.cloud[:] = False self.cloud_cover = 1. * (self.cloud == 2) / self.cloud.size
def process_image(tiles, db_graph, input_filename, color, out_raster_srs): """Update the cache for an input OPI.""" tile_matix_set_limits = get_tile_matrix_set_limits(tiles, input_filename) input_image = gdal.Open(input_filename) stem = Path(input_filename).stem # for z in tiles: for tile_z in range(10, 22): print('Niveau de zoom : ', tile_z) for tile_x in range(tile_matix_set_limits[tile_z]['MinTileCol'], tile_matix_set_limits[tile_z]['MaxTileCol']): for tile_y in range(tile_matix_set_limits[tile_z]['MinTileRow'], tile_matix_set_limits[tile_z]['MaxTileRow']): # on cree une image 3 canaux pour la tuile opi = create_blank_tile(tiles, {'x': tile_x, 'y': tile_y, 'z': tile_z}, 3, out_raster_srs) # on reech l'OPI dans cette image gdal.Warp(opi, input_image) # si necessaire on cree le dossier de la tuile tile_dir = 'cache/'+str(tile_z)+'/'+str(tile_y)+'/'+str(tile_x) Path(tile_dir).mkdir(parents=True, exist_ok=True) # on export en jpeg (todo: gerer le niveau de Q) PNG_DRIVER.CreateCopy(tile_dir+"/"+stem+".png", opi) # on cree une image mono canal pour la tuile mask = create_blank_tile(tiles, {'x': tile_x, 'y': tile_y, 'z': tile_z}, 3, out_raster_srs) # on rasterise la partie du graphe qui concerne ce cliche gdal.Rasterize(mask, db_graph, SQLStatement='select geom from ' + graphtbl + ' where cliche = \''+stem+'\' ') img_mask = mask.GetRasterBand(1).ReadAsArray() # si le mask est vide, on a termine val_max = np.amax(img_mask) if val_max > 0: # on cree le graphe et l'ortho ortho = create_blank_tile(tiles, {'x': tile_x, 'y': tile_y, 'z': tile_z}, 3, out_raster_srs) graph = create_blank_tile(tiles, {'x': tile_x, 'y': tile_y, 'z': tile_z}, 3, out_raster_srs) if Path(tile_dir+"/ortho.png").is_file(): existing_ortho = gdal.Open(tile_dir+"/ortho.png") existing_graph = gdal.Open(tile_dir+"/graph.png") else: existing_ortho = False existing_graph = False for i in range(3): opi_i = opi.GetRasterBand(i+1).ReadAsArray() if existing_ortho: ortho_i = existing_ortho.GetRasterBand(i+1).ReadAsArray() else: ortho_i = ortho.GetRasterBand(i+1).ReadAsArray() opi_i[(img_mask == 0)] = 0 ortho_i[(img_mask != 0)] = 0 ortho.GetRasterBand(i+1).WriteArray(np.add(opi_i, ortho_i)) if existing_graph: graph_i = existing_graph.GetRasterBand(i+1).ReadAsArray() else: graph_i = graph.GetRasterBand(i+1).ReadAsArray() graph_i[(img_mask != 0)] = color[i] graph.GetRasterBand(i+1).WriteArray(graph_i) PNG_DRIVER.CreateCopy(tile_dir+"/ortho.png", ortho) PNG_DRIVER.CreateCopy(tile_dir+"/graph.png", graph)
def rasterize(ogrData, raster_fn, ref_image=None, pixel_size=None, outputSRS=None): """矢量数据栅格化. Args: ogrData (ogr支持矢量格式): 输入数据. raster_fn (str): The target raster file. ref_image (str): 参考数据,如果存在,从中读取相关参数. pixel_size (float): 分辨率,如果有参考影像,与参考数据一致,如果没有参考影像 并且没有指定,则默认为x或y方向范围较小的值除以250. outputSRS (SpatialReference object): 输出栅格投影, 默认与参考影像或输入矢量数据一致. Returns: str: Output raster file.Mask value is 0,other value is 1. """ outputBounds = [] if ref_image is not None: inDS = read_raster_gdal(ref_image) geoMatrix = inDS[1] rows, cols = inDS[0].shape extent = get_extent(geoMatrix, cols, rows) pixel_size = min(geoMatrix[1], abs(geoMatrix[5])) outputBounds = [extent[0], extent[1], extent[2], extent[3]] if outputSRS is None: outputSRS = inDS[2] else: # Open the data source and read in the extent source_ds = ogr.Open(ogrData) source_layer = source_ds.GetLayer() x_min, x_max, y_min, y_max = source_layer.GetExtent() outputBounds = [x_min, y_min, x_max, y_max] if outputSRS is None: outputSRS = source_layer.GetSpatialRef() if pixel_size is None: pixel_size = min(y_max - y_min, x_max - x_min) / 250. gdal.Rasterize(raster_fn, ogrData, format="GTiff", initValues=1, burnValues=0, xRes=pixel_size, yRes=pixel_size, outputBounds=outputBounds, outputType=gdal.GDT_Byte, outputSRS=outputSRS) return raster_fn
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 as_raster_layer(self, srs, min_pixel_size, block_extent, requested_pixel_size=None, data_type=None, bounds=None): tmp_dir = self._make_name() cleanup.register_temp_dir(tmp_dir) if not os.path.exists(tmp_dir): os.makedirs(tmp_dir) reproj_path = os.path.join(tmp_dir, self._make_name(".shp")) gdal.VectorTranslate(reproj_path, self._path, dstSRS=srs, reproject=True) if not self._raw: self._build_attribute_table(reproj_path, self._nodata_value) tmp_raster_path = os.path.join(tmp_dir, self._make_name(".tmp.tiff")) gdal.Rasterize(tmp_raster_path, reproj_path, xRes=min_pixel_size, yRes=min_pixel_size, attribute=self._id_attribute, noData=self._nodata_value, creationOptions=["COMPRESS=DEFLATE"], outputBounds=bounds) raster_path = os.path.join(tmp_dir, self._make_name(".tiff")) info = gdal.Info(tmp_raster_path, format="json") is_float = "Float" in info["bands"][0]["type"] if self._raw else False output_type = data_type if data_type is not None \ else self._data_type if self._data_type is not None \ else gdal.GDT_Float32 if is_float \ else self.best_fit_data_type(self._get_min_max(tmp_raster_path)) gdal.Translate(raster_path, tmp_raster_path, outputType=output_type, creationOptions=["COMPRESS=DEFLATE"]) return RasterLayer(raster_path, self.attributes, self._attribute_table)
def _clip_raster_by_mask(raster, geodataframe, no_data, all_touched): """ Clip raster by mask from geographic layer Parameters ---------- raster: pyrasta.raster.RasterBase raster to clip geodataframe: geopandas.GeoDataFrame or gistools.layer.GeoLayer no_data: float or int No data value all_touched: bool if True, clip all pixels that are touched, otherwise clip if pixel's centroids are within boundaries Returns ------- RasterBase """ clip_raster = raster.clip(bounds=geodataframe.total_bounds) with ShapeTempFile() as shp_file, \ RasterTempFile(clip_raster._gdal_driver.GetMetadata()['DMD_EXTENSION']) as r_file: geodataframe.to_file(shp_file.path, driver=ESRI_DRIVER) out_ds = _gdal_temp_dataset(r_file.path, clip_raster._gdal_driver, clip_raster._gdal_dataset.GetProjection(), clip_raster.x_size, clip_raster.y_size, clip_raster.nb_band, clip_raster.geo_transform, clip_raster.data_type, clip_raster.no_data) gdal.Rasterize(out_ds, shp_file.path, burnValues=[1], allTouched=all_touched) out_ds = None return clip_raster.__class__.raster_calculation( [clip_raster, clip_raster.__class__(r_file.path)], lambda x, y: x * y, no_data=no_data, showprogressbar=False)
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 convert_shp_2_tiff(shape_file, raster_file, pixel_size=0.1, burn_value=1, epsg=4326): input_shp = ogr.Open(shape_file) shp_layer = input_shp.GetLayer() # get extent values to set size of output raster. x_min, x_max, y_min, y_max = shp_layer.GetExtent() # calculate size/resolution of the raster. x_res = int((x_max - x_min) / pixel_size) y_res = int((y_max - y_min) / pixel_size) # get GeoTiff driver by image_type = 'GTiff' driver = gdal.GetDriverByName(image_type) # passing the filename, x and y direction resolution, no. of bands, new raster. raster_handle = driver.Create(raster_file, x_res, y_res, 1, gdal.GDT_Byte) # transforms between pixel raster space to projection coordinate space. raster_handle.SetGeoTransform((x_min, pixel_size, 0, y_min, 0, pixel_size)) # get required raster band. band = raster_handle.GetRasterBand(1) # assign no data value to empty cells. no_data_value = -9999 band.SetNoDataValue(no_data_value) band.FlushCache() # adding a spatial reference raster_srs = osr.SpatialReference() raster_srs.ImportFromEPSG(epsg) raster_handle.SetProjection(raster_srs.ExportToWkt()) # main conversion method ds = gdal.Rasterize(raster_handle, shape_file, burnValues=[burn_value]) ds = None
def as_raster_layer(self, srs, min_pixel_size, block_extent, requested_pixel_size=None, data_type=None, bounds=None): tmp_dir = self._make_name() cleanup.register_temp_dir(tmp_dir) if not os.path.exists(tmp_dir): os.makedirs(tmp_dir) reproj_path = os.path.join(tmp_dir, self._make_name(".shp")) gdal.VectorTranslate(reproj_path, self._path, dstSRS=srs, reproject=True, layers=[self._layer]) if not self._raw: self._build_attribute_table(reproj_path, self._nodata_value) tmp_raster_path = os.path.join(tmp_dir, self._make_name(".tmp.tiff")) gdal.Rasterize(tmp_raster_path, reproj_path, xRes=min_pixel_size, yRes=min_pixel_size, attribute=self._id_attribute, noData=self._nodata_value, creationOptions=["COMPRESS=DEFLATE"], outputBounds=bounds) raster_path = os.path.join(tmp_dir, self._make_name(".tiff")) output_type = data_type or self.best_fit_data_type( self._get_min_max(tmp_raster_path)) gdal.Translate(raster_path, tmp_raster_path, outputType=output_type, creationOptions=["COMPRESS=DEFLATE"]) return RasterLayer(raster_path, self._attributes, self._attribute_table)
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 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}
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 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
dstDS.SetGeoTransform(geot) dstDS.SetProjection(proj) #unit = abs(geot[5]) mskBand = mskDS.GetRasterBand(1) dstFilename = r'E:\20180401中文\data\dataLab\H51G030014\polygon.shp' dstLayername = "POLYGONIZED" drv = ogr.GetDriverByName("ESRI Shapefile") dst_ds = drv.CreateDataSource(dstFilename) dst_layer = dst_ds.CreateLayer(dstLayername, srs=None) fd = ogr.FieldDefn("Status", ogr.OFTInteger) dst_layer.CreateField(fd) dst_field = dst_layer.FindFieldIndex("Status", 1) gdal.Polygonize(mskBand, None, dst_layer, dst_field, [], callback=None) #polygonDS = ogr.Open(r'E:\20180401中文\data\H51G030014\polygon.shp', 1) #layer = polygonDS.GetLayer(0) feat = dst_layer.GetFeature(0) #dst_layer.DeleteFeature(1) geo = feat.geometry() geobf = geo.Buffer(distance=0 - (delNum * 0.000005) , quadsecs = 1) feat.SetGeometry(geobf) dst_layer.SetFeature(feat) dst_ds = None gdal.Rasterize(dstDS,dstFilename,attribute = 'status')
def rasterise_vector(raster_fname, vector_fname, where_statement=None, output_fname="", output_format="MEM", verbose=False): """Rasterises a vector file to produce a mask where some condition in the vector dataset is true. The mask will have the same extent and projection as a (provided) 'master' dataset. The selection of the feature for the mask will be performed by a command of the form field_name='Value', where the single quotes are mandatory (e.g. NAME='Ireland'). Parameters ----------- raster_fname: str A GDAL-compatible raster filename that will be used to extract the shape, projection, resolution, ... for the rasterisation. vector_fname: str The vector filename (e.g. Shapefile) where_statement: str The where statement (e.g. "NAME='Colombia'"). output_fname: str, optinal The output filename, if not provided, an "in-memory array" will be selected. If not provided and the output_format is other than `MEM` an error will be raised. output_format: str, optional An output format. By default, `MEM` verbose: Boolean Whether to get some extra inforamation Returns -------- The mask as a Numpy array, 0 where the mask is off, 1 where it is on. """ if output_fname == "" and output_format != "MEM": raise ValueError("You need to provide an ouput filename" + " for format{:s}".format(output_format)) g = gdal.Open(raster_fname) if g is None: raise IOError("Could not open file {:s}".format(raster_fname)) raster_proj = g.GetProjectionRef() geoT = g.GetGeoTransform() if verbose: print(">>> Opened file {:s}".format(raster_fname)) print(">>> Projection: {:s}".format(raster_proj)) xs = [] ys = [] for x, y in [[0, 0], [0, g.RasterYSize], [g.RasterXSize, g.RasterYSize], [g.RasterXSize, 0]]: xx, yy = gdal.ApplyGeoTransform(geoT, x, y) xs.append(xx) ys.append(yy) extent = [min(xs), min(ys), max(xs), max(ys)] xRes = geoT[1] yRes = geoT[-1] nx = g.RasterXSize ny = g.RasterYSize if verbose: print(">>> File size {:d} rows, {:d} columns".format(nx, ny)) print(">>> UL corner: {:g}, {:g}".format(min(xs), max(ys))) src_ds = gdal.OpenEx(vector_fname) if src_ds is None: raise IOError("Can't read the vector file {}".format(vector_fname)) v = gdal.VectorTranslate('', src_ds, format='Memory', dstSRS=raster_proj, where=where_statement) gg = gdal.Rasterize(output_fname, v, format=output_format, outputType=gdal.GDT_Byte, xRes=xRes, yRes=yRes, where=where_statement, outputBounds=[min(xs), min(ys), max(xs), max(ys)], width=nx, height=ny, noData=0, burnValues=1) if gg is not None: if verbose: print("Done! {:d} non-zero pixels".format(gg.ReadAsArray().sum())) else: raise ValueError("Couldn't generate the mask. Check input parameters") return gg.ReadAsArray()
def get_angle(view_ang_name_gml, vaa, vza, band_dict): band_name, view_ang_name, gml = view_ang_name_gml band_ind = band_dict[gml[-7:-4]] _va = np.nanmean([vaa[i] for i in vaa.keys() if i[0] == band_ind]) _vz = np.nanmean([vza[i] for i in vza.keys() if i[0] == band_ind]) if np.isnan(_va) or np.isnan(_vz): return False g = ogr.Open(gml) xRes = 10 yRes = 10 g1 = gdal.Open(band_name) geo_t = g1.GetGeoTransform() x_size, y_size = g1.RasterXSize, g1.RasterYSize vas = np.zeros((y_size, x_size), dtype=np.float32) vas[:] = -327.67 vzs = np.zeros((y_size, x_size), dtype=np.float32) vzs[:] = -327.67 x_min, x_max = min(geo_t[0], geo_t[0] + x_size * geo_t[1]), \ max(geo_t[0], geo_t[0] + x_size * geo_t[1]) y_min, y_max = min(geo_t[3], geo_t[3] + y_size * geo_t[5]), \ max(geo_t[3], geo_t[3] + y_size * geo_t[5]) xRes, yRes = abs(geo_t[1]), abs(geo_t[5]) x_scale = 5000. / xRes y_scale = 5000. / yRes foot1 = None foot2 = None va1 = None vz1 = None va2 = None vz2 = None try: layer = g.GetLayer() dets = [] for i in range(layer.GetFeatureCount()): dets.append(layer.GetFeature(i).items()['gml_id']) dets = sorted(dets, key=lambda i: int(i.split('-')[2])) for i in range(len(dets)): det = dets[i] foot1 = gdal.Rasterize("", gml, format="MEM", xRes=xRes, yRes=yRes, \ where="gml_id='%s'"%det, outputBounds=[ x_min, y_min, x_max, y_max], \ noData=0, burnValues=1, outputType=gdal.GDT_Byte).ReadAsArray() foot1 = binary_dilation(foot1) key = band_dict[det.split('-')[-3]], int(det.split('-')[-2]) va1 = vaa[key] vz1 = vza[key] if i > 0: overlap = foot1 * foot2 if overlap.sum() < 10: foot1 = foot2 else: x, y = np.where(overlap) xmin, xmax, ymin, ymax = x.min(), x.max(), y.min(), y.max() ll = x[x == xmax][-1], y[x == xmax][-1] lr = x[y == ymax][-1], y[y == ymax][-1] ul = x[y == ymin][0], y[y == ymin][0] ur = x[x == xmin][0], y[x == xmin][0] p1 = np.mean([lr, ur], axis=0) p2 = np.mean([ll, ul], axis=0) x1, y1 = np.where(foot2) vamax, vamin = np.nanmax(va2), np.nanmin(va2) vzmax, vzmin = np.nanmax(vz2), np.nanmin(vz2) if not (p1 == p2).all(): p = np.poly1d( np.polyfit([p1[1], p2[1]], [p1[0], p2[0]], 1)) foot2[x[x > p(y)], y[x > p(y)]] = False minx, miny = np.where(va2 == vamin) maxx, maxy = np.where(va2 == vamax) min_dst = abs(p(miny * y_scale) - minx * x_scale) / ( np.sqrt(1 + p.c[0]**2)) max_dst = abs(p(maxy * y_scale) - maxx * x_scale) / ( np.sqrt(1 + p.c[0]**2)) if (max_dst < min_dst).any(): tmp1 = vamin.copy() vamin = vamax vamax = tmp1 minx, miny = np.where(vz2 == vzmin) maxx, maxy = np.where(vz2 == vzmax) min_dst = abs(p(miny * y_scale) - minx * x_scale) / ( np.sqrt(1 + p.c[0]**2)) max_dst = abs(p(maxy * y_scale) - maxx * x_scale) / ( np.sqrt(1 + p.c[0]**2)) if (max_dst < min_dst).any(): tmp2 = vzmin.copy() vzmin = vzmax vzmax = tmp2 dist = abs(p(y1) - x1) / (np.sqrt(1 + p.c[0]**2)) vas[x1, y1] = vamin + dist / (dist.max() - dist.min()) * (vamax - vamin) vzs[x1, y1] = vzmin + dist / (dist.max() - dist.min()) * (vzmax - vzmin) else: vas[x1, y1] = vamin vzs[x1, y1] = vzmin x1, y1 = np.where(foot1) if i == layer.GetFeatureCount() - 1: vamax, vamin = np.nanmax(va1), np.nanmin(va1) vzmax, vzmin = np.nanmax(vz1), np.nanmin(vz1) if not (p1 == p2).all(): foot1[x[x <= p(y)], y[x <= p(y)]] = False minx, miny = np.where(va1 == vamin) maxx, maxy = np.where(va1 == vamax) min_dst = abs(p(miny * y_scale) - minx * x_scale) / (np.sqrt(1 + p.c[0]**2)) max_dst = abs(p(maxy * y_scale) - maxx * x_scale) / (np.sqrt(1 + p.c[0]**2)) if (max_dst < min_dst).any(): tmp1 = vamin.copy() vamin = vamax vamax = tmp1 minx, miny = np.where(vz1 == vzmin) maxx, maxy = np.where(vz1 == vzmax) min_dst = abs(p(miny * y_scale) - minx * x_scale) / (np.sqrt(1 + p.c[0]**2)) max_dst = abs(p(maxy * y_scale) - maxx * x_scale) / (np.sqrt(1 + p.c[0]**2)) if (max_dst < min_dst).any(): tmp2 = vzmin.copy() vzmin = vzmax vzmax = tmp2 dist = abs(p(y1) - x1) / (np.sqrt(1 + p.c[0]**2)) vas[x1, y1] = vamin + dist / ( dist.max() - dist.min()) * (vamax - vamin) vzs[x1, y1] = vzmin + dist / ( dist.max() - dist.min()) * (vzmax - vzmin) else: vas[x1, y1] = vamin vas[x1, y1] = vamin foot2 = foot1 va2 = va1 vz2 = vz1 # vas[:] = np.nanmean(vaa.values()) # vzs[:] = np.nanmean(vza.values()) # mask = vas < -180 # if (~mask).sum()<1: # vas[:] = np.nanmean(va1) # #vas = fill_bad(vas, ~mask) # mask = vzs < 0 # if (~mask).sum()<1: # vzs[:] = np.nanmean(vz1) #vzs = fill_bad(vzs, ~mask) #vas[(vas>180) & (vas<=360)] = vas[(vas>180) & (vas<=360)].mean() - 360 #vas[(vas>=0) & (vas<=180)] = vas[(vas>=0) & (vas<=180)].mean() # if os.path.exists(view_ang_name): # os.remove(view_ang_name) # dst_ds = gdal.GetDriverByName('GTiff').Create(view_ang_name, x_size, y_size, 2, gdal.GDT_Int16, options=["TILED=YES", "COMPRESS=DEFLATE"]) # dst_ds.SetGeoTransform(g1.GetGeoTransform()) # dst_ds.SetProjection(g1.GetProjection()) # dst_ds.GetRasterBand(1).WriteArray((vas * 100).astype(int)) # dst_ds.GetRasterBand(2).WriteArray((vzs * 100).astype(int)) # dst_ds.GetRasterBand(1).SetNoDataValue(-32767) # dst_ds.GetRasterBand(2).SetNoDataValue(-32767) # dst_ds.FlushCache() # dst_ds = None # g1 = None # return True except: band_ind = band_dict[gml[-7:-4]] vas[:] = np.nanmean([vaa[i] for i in vaa.keys() if i[0] == band_ind]) vzs[:] = np.nanmean([vza[i] for i in vza.keys() if i[0] == band_ind]) if os.path.exists(view_ang_name): os.remove(view_ang_name) dst_ds = gdal.GetDriverByName('GTiff').Create( view_ang_name, x_size, y_size, 2, gdal.GDT_Int16, options=["TILED=YES", "COMPRESS=DEFLATE"]) dst_ds.SetGeoTransform(g1.GetGeoTransform()) dst_ds.SetProjection(g1.GetProjection()) mask = vas < -180 if (~mask).sum() < 1: vas[:] = np.nanmean(va1) #vas = fill_bad(vas, ~mask) mask = vzs < 0 if (~mask).sum() < 1: vzs[:] = np.nanmean(vz1) #vzs = fill_bad(vzs, ~mask) #vas[(vas>180) & (vas<=360)] = vas[(vas>180) & (vas<=360)].mean() - 360 #vas[(vas>=0) & (vas<=180)] = vas[(vas>=0) & (vas<=180)].mean() dst_ds.GetRasterBand(1).WriteArray((vas * 100).astype(int)) dst_ds.GetRasterBand(2).WriteArray((vzs * 100).astype(int)) dst_ds.GetRasterBand(1).SetNoDataValue(-32767) dst_ds.GetRasterBand(2).SetNoDataValue(-32767) dst_ds.FlushCache() dst_ds = None g1 = None return True
from WindFetch import Waterbody, Fetch import gdal import matplotlib.pyplot as plt import numpy as np #Examples of functionality in WindFetch.py script #Danish lake Gurre (source: OpenStreetMap) attached as .sqlite file in projected crs lake_vec = "test_files/gurre_lake" #Rasterize vector file using gdal lake_rast = gdal.Rasterize(lake_vec + ".tif", lake_vec + ".sqlite", xRes=5, yRes=5, burnValues=[1], noData=0, outputType=gdal.GDT_Byte, creationOptions=["COMPRESS=LZW"]) lake_rast = None #Read lake from .tif file lake = Waterbody.read_waterbody(lake_vec + ".tif", 1) dirs = [0, 45, 90, 135, 180, 225, 270, 315] #Fetch along main directions fetch_main = lake.fetch(dirs) #Summary statistics of calculated fetches fetch_main_summary = fetch_main.summary(["min", "mean", "max"])