示例#1
0
def get_image_bounds(image_file: str) -> str:
    """Loads the boundaries from an image file
    Arguments:
        image_file: path to the image to load the bounds from
    Return:
        Returns the GEOJSON of the bounds if they could be loaded and converted (if necessary).
        None is returned if the bounds are loaded or can't be converted
    """
    # If the file has a geo shape we store it for clipping
    bounds = image_get_geobounds(image_file)
    epsg = get_epsg(image_file)
    if bounds[0] != np.nan:
        ring = ogr.Geometry(ogr.wkbLinearRing)
        ring.AddPoint(bounds[2], bounds[1])     # Upper left
        ring.AddPoint(bounds[3], bounds[1])     # Upper right
        ring.AddPoint(bounds[3], bounds[0])     # lower right
        ring.AddPoint(bounds[2], bounds[0])     # lower left
        ring.AddPoint(bounds[2], bounds[1])     # Closing the polygon

        poly = ogr.Geometry(ogr.wkbPolygon)
        poly.AddGeometry(ring)

        ref_sys = osr.SpatialReference()
        if ref_sys.ImportFromEPSG(int(epsg)) == ogr.OGRERR_NONE:
            poly.AssignSpatialReference(ref_sys)
            return geometry_to_geojson(poly)

        logging.warning("Failed to import EPSG %s for image file %s", str(epsg), image_file)

    return None
示例#2
0
    def clip_raster_intersection(file_path: str, file_bounds: str,
                                 plot_bounds: str,
                                 out_file: str) -> Optional[int]:
        """Clips the raster to the intersection of the file bounds and plot bounds
        Arguments:
            file_path: the path to the source file
            file_bounds: the geometric boundary of the source file as JSON
            plot_bounds: the geometric boundary of the plot to clip to as JSON
            out_file: the path to store the clipped image
        Return:
            The number of pixels in the new image, or None if no pixels were saved
        Notes:
            Assumes the boundaries are in the same coordinate system
        Exceptions:
            Raises RuntimeError if the polygons are invalid
        """
        logging.debug(
            "Clip to intersect of plot boundary: File: '%s' '%s' Plot: '%s'",
            file_path, str(file_bounds), str(plot_bounds))
        try:
            file_poly = ogr.CreateGeometryFromJson(str(file_bounds))
            plot_poly = ogr.CreateGeometryFromJson(str(plot_bounds))

            if not file_poly or not plot_poly:
                logging.error(
                    "Invalid polygon specified for clip_raster_intersection: File: '%s' plot: '%s'",
                    str(file_bounds), str(plot_bounds))
                raise RuntimeError(
                    "One or more invalid polygons specified when clipping raster"
                )

            intersection = file_poly.Intersection(plot_poly)
            if not intersection or not intersection.Area():
                logging.info("File does not intersect plot boundary: %s",
                             file_path)
                return None

            # Make sure we pass a multipolygon down to the tuple converter
            if intersection.GetGeometryName().startswith('MULTI'):
                multi_polygon = intersection
            else:
                multi_polygon = ogr.Geometry(ogr.wkbMultiPolygon)
                multi_polygon.AddGeometry(intersection)

            # Proceed to clip to the intersection
            tuples = __internal__.geojson_to_tuples(
                geometry_to_geojson(multi_polygon))
            return clip_raster(file_path,
                               tuples,
                               out_path=out_file,
                               compress=True)

        except Exception as ex:
            logging.exception(
                "Exception caught while clipping image to plot intersection")
            raise ex
示例#3
0
    def get_image_bounds_json(file_path: str,
                              default_epsg: int = None) -> Optional[str]:
        """Loads the boundaries of the image file and returns the GeoJSON
           representing the bounds (including EPSG code)
        Arguments:
            file_path: path to the file from which to load the bounds
            default_epsg: the default EPSG to assume if a file has a boundary but not a coordinate system
        Return:
            Returns the JSON representing the image boundary, or None if the
            bounds could not be loaded
        Notes:
            If a file doesn't have a coordinate system and a default epsg is specified, the
            return JSON will use the default_epsg.
            If a file doesn't have a coordinate system and there isn't a default epsg specified, the boundary
            of the image is not returned (None) and a warning is logged.
        """
        # Get the bounds (if they exist)
        bounds = image_get_geobounds(file_path)
        if bounds[0] == np.nan:
            return None

        epsg = get_epsg(file_path)
        if epsg is None:
            if default_epsg:
                epsg = default_epsg
            else:
                logging.warning(
                    "Files does not have a coordinate system defined and no default was specified: '%s'",
                    file_path)
                return None

        ring = ogr.Geometry(ogr.wkbLinearRing)
        ring.AddPoint(bounds[2], bounds[1])  # Upper left
        ring.AddPoint(bounds[3], bounds[1])  # Upper right
        ring.AddPoint(bounds[3], bounds[0])  # lower right
        ring.AddPoint(bounds[2], bounds[0])  # lower left
        ring.AddPoint(bounds[2], bounds[1])  # Closing the polygon

        poly = ogr.Geometry(ogr.wkbPolygon)
        poly.AddGeometry(ring)

        ref_sys = osr.SpatialReference()
        if ref_sys.ImportFromEPSG(int(epsg)) == ogr.OGRERR_NONE:
            poly.AssignSpatialReference(ref_sys)
            return geometry_to_geojson(poly)

        logging.error("Failed to import EPSG %s for image file %s", str(epsg),
                      file_path)
        return None
示例#4
0
    def get_las_extents(file_path: str,
                        default_epsg: int = None) -> Optional[str]:
        """Calculate the extent of the given las file and return as GeoJSON.
        Arguments:
            file_path: path to the file from which to load the bounds
            default_epsg: the default EPSG to assume if a file has a boundary but not a coordinate system
        Return:
            Returns the JSON representing the image boundary, or None if the
            bounds could not be loaded
        Notes:
            If a file doesn't have a coordinate system and a default epsg is specified, the
            return JSON will use the default_epsg.
            If a file doesn't have a coordinate system and there isn't a default epsg specified, the boundary
            of the image is not returned (None) and a warning is logged.
        """
        # Get the bounds and the EPSG code
        las_info = liblas.file.File(file_path, mode='r')
        min_bound = las_info.header.min
        max_bound = las_info.header.max
        epsg = __internal__.get_las_epsg_from_header(las_info.header)
        if epsg is None:
            if default_epsg is not None:
                epsg = default_epsg
            else:
                logging.warning(
                    "Unable to find EPSG and not default is specified for file '%s'",
                    file_path)
                return None

        ring = ogr.Geometry(ogr.wkbLinearRing)
        ring.AddPoint(min_bound[1], min_bound[0])  # Upper left
        ring.AddPoint(min_bound[1], max_bound[0])  # Upper right
        ring.AddPoint(max_bound[1], max_bound[0])  # lower right
        ring.AddPoint(max_bound[1], min_bound[0])  # lower left
        ring.AddPoint(min_bound[1], min_bound[0])  # Closing the polygon

        poly = ogr.Geometry(ogr.wkbPolygon)
        poly.AddGeometry(ring)

        ref_sys = osr.SpatialReference()
        if ref_sys.ImportFromEPSG(int(epsg)) == ogr.OGRERR_NONE:
            poly.AssignSpatialReference(ref_sys)
            return geometry_to_geojson(poly)

        logging.error("Failed to import EPSG %s for las file %s", str(epsg),
                      file_path)
        return None