Esempio n. 1
0
    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
Esempio n. 2
0
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
Esempio n. 3
0
    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