def _search_sgrid_tiles(self, geom, sgrid_id, coverland): """ Search the tiles which are overlapping with the given grid. Parameters ---------- area_geometry : geometry It is a polygon geometry representing the region of interest. sgrid_id : string sub grid ID to specified which continent you want to search. Default value is None for searching all continents. Returns ------- list Return a list of the overlapped tiles' name. If not found, return empty list. """ subgrid = getattr(self, sgrid_id) # get the spatial reference of the subgrid grid_sr = subgrid.projection.osr_spref # get the intersection of the area of interest and grid zone geom.TransformTo(grid_sr) intersect = geom.Intersection(geom.Intersection(subgrid.polygon_proj)) if not intersect: return list() # The spatial reference need to be set again after intersection #intersect.AssignSpatialReference(geom.GetSpatialReference()) # transform the area of interest to the grid coordinate system #grid_sr = getattr(self, sgrid_id).projection.osr_spref #intersect.TransformTo(grid_sr) # get envelope of the Geometry and cal the bounding tile of the envelope = intersect.GetEnvelope() x_min = int(envelope[0]) / self.core.tile_xsize_m * self.core.tile_xsize_m x_max = (int(envelope[1]) / self.core.tile_xsize_m + 1) * self.core.tile_xsize_m y_min = int(envelope[2]) / self.core.tile_ysize_m * self.core.tile_ysize_m y_max = (int(envelope[3]) / self.core.tile_ysize_m + 1) * self.core.tile_ysize_m # make sure x_min and y_min greater or equal 0 x_min = 0 if x_min < 0 else x_min y_min = 0 if y_min < 0 else y_min # get overlapped tiles overlapped_tiles = list() for x, y in itertools.product(xrange(x_min, x_max, self.core.tile_xsize_m), xrange(y_min, y_max, self.core.tile_ysize_m)): geom_tile = geometry.extent2polygon((x, y, x + self.core.tile_xsize_m, y + self.core.tile_xsize_m)) if geom_tile.Intersects(intersect): ftile = subgrid.tilesys.point2tilename(x, y) if not coverland or subgrid.tilesys.check_land_coverage(ftile): overlapped_tiles.append(ftile) return overlapped_tiles
def warp2tiledgeotiff(TPS, image, output_dir, gdal_path=None, subgrid_ids=None, accurate_boundary=True, e7_folder=True, ftiles=None, roi=None, coverland=True, outshortname=None, withtilenameprefix=False, withtilenamesuffix=True, compress=True, compresstype="LZW", resampling_type="near", overwrite=False, image_nodata=None, tile_nodata=None, tiledtiff=True, blocksize=512): """warp the image to tiles in target TPS. Parameters ---------- grid : TiledProjectionSystem a compatible TPS object, e.g. a Equi7Grid(500) object. image : string Image file path. ouput_dir : string Output directory path. e7_folder: boolean if set (default), the output data will be stored in equi7 folder structure gdal_path : string Gdal utilities location. subgrid_ids : list Only resample to the specified continents, default is to resample to all continents. roi : OGRGeometry Region of interest. The roi will beignored if ftiles keyword is provided ftiles : list of tile names full name of tiles to which data should be resampled coverland : bool Only resample to the tiles that cover land. outshortname : string The short name will be main part of the output tile name. withtilenameprefix : bool Prepend the tile name in the tile file name. withtilenamesuffix : bool Append the tile name in the tile file name. compress : bool The output tiles is compressed or not. resampling_type : string Resampling method. overwrite : bool Overwrite the old tile or not. image_nodata : double The nodata value of input images. tile_nodata : double The nodata value of tile. tiledtiff : bool Set to yes for tiled geotiff output blocksize: integer sets tile width, in x and y direction """ # get the output shortname if not provided grid = TPS if not outshortname: outshortname = os.path.splitext(os.path.basename(image))[0] # find overlapping tiles if ftiles is None: if roi is None: if accurate_boundary: try: roi_geom = gdalport.retrieve_raster_boundary( image, gdal_path=gdal_path, nodata=image_nodata) except Exception as e: print("retrieve_raster_boundary failed:", str(e)) roi_geom = None else: roi_geom = None if roi_geom: ftiles = grid.search_tiles_in_geo_roi(geom_area=roi_geom, subgrid_ids=subgrid_ids, coverland=coverland, gdal_path=gdal_path) else: ds = gdalport.open_image(image) img_extent = ds.get_extent() geo_extent = geometry.extent2polygon(img_extent) geo_sr = osr.SpatialReference() geo_sr.ImportFromWkt(ds.projection()) geo_extent.AssignSpatialReference(geo_sr) ftiles = grid.search_tiles_in_geo_roi(geom_area=geo_extent, subgrid_ids=subgrid_ids, coverland=coverland, gdal_path=gdal_path) else: ftiles = grid.search_tiles_in_geo_roi(geom_area=roi, subgrid_ids=subgrid_ids, coverland=coverland, gdal_path=gdal_path) else: if type(ftiles) != list: ftiles = [ftiles] # keep the full path of the output(resampled) files dst_file_names = [] # resample for each tile sequentially for ftile in ftiles: # create grid folder if e7_folder: grid_folder = "EQUI7_{}".format(ftile[0:6]) tile_path = os.path.join(output_dir, grid_folder, ftile[7:]) if not os.path.exists(tile_path): makedirs(tile_path) else: tile_path = output_dir # make output filename outbasename = outshortname if withtilenameprefix: outbasename = "_".join((ftile, outbasename)) if withtilenamesuffix: outbasename = "_".join((outbasename, ftile)) filename = os.path.join(tile_path, "".join((outbasename, ".tif"))) # get grid tile object # TODO Generalise! Now only the Equi7Grid case is consideres (2 digits for subgrid) gridtile = getattr(grid, ftile[0:2]).tilesys.create_tile(ftile) # prepare options for gdalwarp options = { '-t_srs': gridtile.core.projection.wkt, '-of': 'GTiff', '-r': resampling_type, '-te': " ".join(map(str, gridtile.limits_m())), '-tr': "{} -{}".format(grid.core.res, grid.core.res) } options["-co"] = list() if compress: options["-co"].append("COMPRESS={0}".format(compresstype)) if image_nodata != None: options["-srcnodata"] = image_nodata if tile_nodata != None: options["-dstnodata"] = tile_nodata if overwrite: options["-overwrite"] = " " if tiledtiff: options["-co"].append("TILED=YES") options["-co"].append("BLOCKXSIZE={0}".format(blocksize)) options["-co"].append("BLOCKYSIZE={0}".format(blocksize)) # call gdalwarp for resampling succeed, _ = gdalport.call_gdal_util('gdalwarp', src_files=image, dst_file=filename, gdal_path=gdal_path, options=options) # full path to the output(resampled) files if succeed: dst_file_names.extend([filename]) return dst_file_names
def search_tiles_in_geo_roi(self, geom_area=None, extent=None, epsg=4326, wkt=None, subgrid_ids=None, coverland=False, gdal_path=None): """ Search the tiles which are intersected by the poly_roi area. Parameters ---------- geom_area : geometry a polygon or multipolygon geometery object representing the ROI extent : list It is a polygon representing the rectangle region of interest in the format of [xmin, ymin, xmax, ymax]. epsg : str EPSG CODE defining the spatial reference system, in which the geometry or extent is given. Default is LatLon (EPSG:4326) subgrid_ids : list grid ID to specified which continents you want to search. Default value is None for searching all continents. Returns ------- list return a list of the overlapped tiles' name. If not found, return empty list. """ # check input grids if subgrid_ids is None: subgrid_ids = self.subgrids.keys() else: subgrid_ids = [x.upper() for x in subgrid_ids] if set(subgrid_ids).issubset(set(self.subgrids.keys())): subgrid_ids = list(subgrid_ids) else: raise ValueError("Invalid agrument: grid must one of [ %s ]." % " ".join(self.subgrids.keys())) if not geom_area and not extent: print("Error: either geom or extent should be given as the ROI.") return list() # obtain the geometry of ROI if not geom_area: if epsg is not None: geom_area = geometry.extent2polygon(extent, epsg=epsg) elif wkt is not None: geom_area = geometry.extent2polygon(extent, wkt=wkt) else: raise ValueError("Error: either epsg or wkt of ROI coordinates must be defined!") # load lat-lon spatial reference as the default geo_sr = TPSProjection(epsg=4326).osr_spref geom_sr = geom_area.GetSpatialReference() if geom_sr is None: geom_area.AssignSpatialReference(geo_sr) elif not geom_sr.IsSame(geo_sr): geom_area.TransformTo(geo_sr) # intersect the given grid ids and the overlapped ids overlapped_grids = self.locate_geometry_in_subgrids(geom_area) subgrid_ids = list(set(subgrid_ids) & set(overlapped_grids)) # finding tiles overlapped_tiles = list() for sgrid_id in subgrid_ids: overlapped_tiles.extend( self._search_sgrid_tiles(geom_area, sgrid_id, coverland)) return overlapped_tiles