Exemple #1
0
    def __call__(self, src_ds):
        dst_ds = create_mem(src_ds.RasterXSize, src_ds.RasterYSize,
                            1, gdal.GDT_Byte)

        if not self.palette_file:
            # create a color table as a median of the given dataset
            ct = gdal.ColorTable()
            gdal.ComputeMedianCutPCT(src_ds.GetRasterBand(1),
                                     src_ds.GetRasterBand(2),
                                     src_ds.GetRasterBand(3),
                                     256, ct)

        else:
            # copy the color table from the given palette file
            pct_ds = gdal.Open(self.palette_file)
            pct_ct = pct_ds.GetRasterBand(1).GetRasterColorTable()
            if not pct_ct:
                raise ValueError("The palette file '%s' does not have a Color "
                                 "Table." % self.palette_file)
            ct = pct_ct.Clone()
            pct_ds = None

        dst_ds.GetRasterBand(1).SetRasterColorTable(ct)
        gdal.DitherRGB2PCT(src_ds.GetRasterBand(1),
                           src_ds.GetRasterBand(2),
                           src_ds.GetRasterBand(3),
                           dst_ds.GetRasterBand(1), ct)

        copy_projection(src_ds, dst_ds)
        copy_metadata(src_ds, dst_ds)

        return dst_ds
Exemple #2
0
    def __call__(self, src_ds):
        # setup
        src_sr = osr.SpatialReference()
        src_sr.ImportFromWkt(src_ds.GetProjection())

        dst_sr = osr.SpatialReference()
        dst_sr.ImportFromEPSG(self.srid)

        if src_sr.IsSame(dst_sr) and (src_ds.GetGeoTransform()[1] > 0) and (src_ds.GetGeoTransform()[5] < 0):
            logger.info(
                "Source and destination projection are equal and image "
                "is not flipped. Thus, no reprojection is required."
            )
            return src_ds

        # create a temporary dataset to get information about the output size
        tmp_ds = gdal.AutoCreateWarpedVRT(src_ds, None, dst_sr.ExportToWkt(), gdal.GRA_Bilinear, 0.125)

        # create the output dataset
        dst_ds = create_mem(
            tmp_ds.RasterXSize, tmp_ds.RasterYSize, src_ds.RasterCount, src_ds.GetRasterBand(1).DataType
        )

        # reproject the image
        dst_ds.SetProjection(dst_sr.ExportToWkt())
        dst_ds.SetGeoTransform(tmp_ds.GetGeoTransform())

        gdal.ReprojectImage(src_ds, dst_ds, src_sr.ExportToWkt(), dst_sr.ExportToWkt(), gdal.GRA_Bilinear)

        tmp_ds = None

        # copy the metadata
        copy_metadata(src_ds, dst_ds)

        return dst_ds
Exemple #3
0
    def __call__(self, src_ds):
        dst_ds = create_mem(src_ds.RasterXSize, src_ds.RasterYSize, len(self.bands), self.datatype)
        dst_range = get_limits(self.datatype)

        multiple = 0

        for dst_index, (src_index, dmin, dmax) in enumerate(self.bands, 1):
            # check if next band is equal
            if dst_index < len(self.bands) and (src_index, dmin, dmax) == self.bands[dst_index]:
                multiple += 1
                continue
            # check that src band is available
            if src_index > src_ds.RasterCount:
                continue

            # initialize with zeros if band is 0
            if src_index == 0:
                src_band = src_ds.GetRasterBand(1)
                data = numpy.zeros((src_band.YSize, src_band.XSize), dtype=gdal_array.codes[self.datatype])
                src_min, src_max = (0, 0)
            # use src_ds band otherwise
            else:
                src_band = src_ds.GetRasterBand(src_index)
                data = src_band.ReadAsArray()
                src_min, src_max = src_band.ComputeRasterMinMax()

            # get min/max values or calculate from band
            if dmin is None:
                dmin = get_limits(src_band.DataType)[0]
            elif dmin == "min":
                dmin = src_min
            if dmax is None:
                dmax = get_limits(src_band.DataType)[1]
            elif dmax == "max":
                dmax = src_max
            src_range = (float(dmin), float(dmax))

            # perform clipping and scaling
            data = (dst_range[1] - dst_range[0]) * (
                (numpy.clip(data, dmin, dmax) - src_range[0]) / (src_range[1] - src_range[0])
            )

            # set new datatype
            data = data.astype(gdal_array.codes[self.datatype])

            # write result
            dst_band = dst_ds.GetRasterBand(dst_index)
            dst_band.WriteArray(data)

            # write equal bands at once
            if multiple > 0:
                for i in range(multiple):
                    dst_band = dst_ds.GetRasterBand(dst_index - 1 - i)
                    dst_band.WriteArray(data)
                multiple = 0

        copy_projection(src_ds, dst_ds)
        copy_metadata(src_ds, dst_ds)

        return dst_ds
Exemple #4
0
    def __call__(self, src_ds):
        logger.info("Applying ReprojectionOptimization")
        # setup
        src_sr = osr.SpatialReference()
        src_sr.ImportFromWkt(src_ds.GetProjection())

        dst_sr = osr.SpatialReference()
        dst_sr.ImportFromEPSG(self.srid)

        if src_sr.IsSame(dst_sr) and (src_ds.GetGeoTransform()[1] > 0) \
                and (src_ds.GetGeoTransform()[5] < 0) \
                and (src_ds.GetGeoTransform()[2] == 0) \
                and (src_ds.GetGeoTransform()[4] == 0):
            logger.info(
                "Source and destination projection are equal and image "
                "is not flipped or has rotated axes. Thus, no "
                "reprojection is required.")
            return src_ds

        # create a temporary dataset to get information about the output size
        tmp_ds = gdal.AutoCreateWarpedVRT(src_ds, None, dst_sr.ExportToWkt(),
                                          gdal.GRA_Bilinear, 0.125)

        try:
            # create the output dataset
            dst_ds = create_temp(tmp_ds.RasterXSize,
                                 tmp_ds.RasterYSize,
                                 src_ds.RasterCount,
                                 src_ds.GetRasterBand(1).DataType,
                                 temp_root=self.temporary_directory)

            # initialize with no data
            for i in range(src_ds.RasterCount):
                src_band = src_ds.GetRasterBand(i + 1)
                if src_band.GetNoDataValue() is not None:
                    dst_band = dst_ds.GetRasterBand(i + 1)
                    dst_band.SetNoDataValue(src_band.GetNoDataValue())
                    dst_band.Fill(src_band.GetNoDataValue())

            # reproject the image
            dst_ds.SetProjection(dst_sr.ExportToWkt())
            dst_ds.SetGeoTransform(tmp_ds.GetGeoTransform())

            gdal.ReprojectImage(src_ds, dst_ds, src_sr.ExportToWkt(),
                                dst_sr.ExportToWkt(), gdal.GRA_Bilinear)

            tmp_ds = None

            # copy the metadata
            copy_metadata(src_ds, dst_ds)

            return dst_ds
        except:
            cleanup_temp(dst_ds)
            raise
Exemple #5
0
    def __call__(self, src_ds):
        logger.info("Applying ReprojectionOptimization")
        # setup
        src_sr = osr.SpatialReference()
        src_sr.ImportFromWkt(src_ds.GetProjection())

        dst_sr = osr.SpatialReference()
        dst_sr.ImportFromEPSG(self.srid)

        if src_sr.IsSame(dst_sr) and (src_ds.GetGeoTransform()[1] > 0) \
                and (src_ds.GetGeoTransform()[5] < 0) \
                and (src_ds.GetGeoTransform()[2] == 0) \
                and (src_ds.GetGeoTransform()[4] == 0):
            logger.info("Source and destination projection are equal and image "
                        "is not flipped or has rotated axes. Thus, no "
                        "reprojection is required.")
            return src_ds

        # create a temporary dataset to get information about the output size
        tmp_ds = gdal.AutoCreateWarpedVRT(src_ds, None, dst_sr.ExportToWkt(),
                                          gdal.GRA_Bilinear, 0.125)

        try:
            # create the output dataset
            dst_ds = create_temp(tmp_ds.RasterXSize, tmp_ds.RasterYSize,
                                 src_ds.RasterCount,
                                 src_ds.GetRasterBand(1).DataType,
                                 temp_root=self.temporary_directory)

            # initialize with no data
            for i in range(src_ds.RasterCount):
                src_band = src_ds.GetRasterBand(i+1)
                if src_band.GetNoDataValue() is not None:
                    dst_band = dst_ds.GetRasterBand(i+1)
                    dst_band.SetNoDataValue(src_band.GetNoDataValue())
                    dst_band.Fill(src_band.GetNoDataValue())

            # reproject the image
            dst_ds.SetProjection(dst_sr.ExportToWkt())
            dst_ds.SetGeoTransform(tmp_ds.GetGeoTransform())

            gdal.ReprojectImage(src_ds, dst_ds,
                                src_sr.ExportToWkt(),
                                dst_sr.ExportToWkt(),
                                gdal.GRA_Bilinear)

            tmp_ds = None

            # copy the metadata
            copy_metadata(src_ds, dst_ds)

            return dst_ds
        except:
            cleanup_temp(dst_ds)
            raise
Exemple #6
0
    def __call__(self, src_ds):
        logger.info("Applying ColorIndexOptimization")
        try:
            dst_ds = create_temp(src_ds.RasterXSize,
                                 src_ds.RasterYSize,
                                 1,
                                 gdal.GDT_Byte,
                                 temp_root=self.temporary_directory)

            if not self.palette_file:
                # create a color table as a median of the given dataset
                ct = gdal.ColorTable()
                gdal.ComputeMedianCutPCT(src_ds.GetRasterBand(1),
                                         src_ds.GetRasterBand(2),
                                         src_ds.GetRasterBand(3), 256, ct)

            else:
                # copy the color table from the given palette file
                pct_ds = gdal.Open(self.palette_file)
                pct_ct = pct_ds.GetRasterBand(1).GetRasterColorTable()
                if not pct_ct:
                    raise ValueError("The palette file '%s' does not have a "
                                     "Color Table." % self.palette_file)
                ct = pct_ct.Clone()
                pct_ds = None

            dst_ds.GetRasterBand(1).SetRasterColorTable(ct)
            gdal.DitherRGB2PCT(src_ds.GetRasterBand(1),
                               src_ds.GetRasterBand(2),
                               src_ds.GetRasterBand(3),
                               dst_ds.GetRasterBand(1), ct)

            copy_projection(src_ds, dst_ds)
            copy_metadata(src_ds, dst_ds)

            return dst_ds
        except:
            cleanup_temp(dst_ds)
            raise
Exemple #7
0
    def __call__(self, src_ds):
        logger.info("Applying ColorIndexOptimization")
        try:
            dst_ds = create_temp(src_ds.RasterXSize, src_ds.RasterYSize,
                                 1, gdal.GDT_Byte,
                                 temp_root=self.temporary_directory)

            if not self.palette_file:
                # create a color table as a median of the given dataset
                ct = gdal.ColorTable()
                gdal.ComputeMedianCutPCT(src_ds.GetRasterBand(1),
                                         src_ds.GetRasterBand(2),
                                         src_ds.GetRasterBand(3),
                                         256, ct)

            else:
                # copy the color table from the given palette file
                pct_ds = gdal.Open(self.palette_file)
                pct_ct = pct_ds.GetRasterBand(1).GetRasterColorTable()
                if not pct_ct:
                    raise ValueError("The palette file '%s' does not have a "
                                     "Color Table." % self.palette_file)
                ct = pct_ct.Clone()
                pct_ds = None

            dst_ds.GetRasterBand(1).SetRasterColorTable(ct)
            gdal.DitherRGB2PCT(src_ds.GetRasterBand(1),
                               src_ds.GetRasterBand(2),
                               src_ds.GetRasterBand(3),
                               dst_ds.GetRasterBand(1), ct)

            copy_projection(src_ds, dst_ds)
            copy_metadata(src_ds, dst_ds)

            return dst_ds
        except:
            cleanup_temp(dst_ds)
            raise
Exemple #8
0
    def __call__(self, src_ds):
        logger.info("Applying BandSelectionOptimization")
        try:
            dst_ds = create_temp(src_ds.RasterXSize,
                                 src_ds.RasterYSize,
                                 len(self.bands),
                                 self.datatype,
                                 temp_root=self.temporary_directory)
            dst_range = get_limits(self.datatype)

            multiple, multiple_written = 0, False

            for dst_index, (src_index, dmin, dmax) in enumerate(self.bands, 1):
                # check if next band is equal
                if dst_index < len(self.bands) and \
                        (src_index, dmin, dmax) == self.bands[dst_index]:
                    multiple += 1
                    continue
                # check that src band is available
                if src_index > src_ds.RasterCount:
                    continue

                # initialize with zeros if band is 0
                if src_index == 0:
                    src_band = src_ds.GetRasterBand(1)
                    data = numpy.zeros((src_band.YSize, src_band.XSize),
                                       dtype=gdal_array.codes[self.datatype])
                    src_min, src_max = (0, 0)
                # use src_ds band otherwise
                else:
                    src_band = src_ds.GetRasterBand(src_index)
                    src_min, src_max = src_band.ComputeRasterMinMax()

                # get min/max values or calculate from band
                if dmin is None:
                    dmin = get_limits(src_band.DataType)[0]
                elif dmin == "min":
                    dmin = src_min
                if dmax is None:
                    dmax = get_limits(src_band.DataType)[1]
                elif dmax == "max":
                    dmax = src_max
                src_range = (float(dmin), float(dmax))

                block_x_size, block_y_size = src_band.GetBlockSize()

                num_x = int(math.ceil(float(src_band.XSize) / block_x_size))
                num_y = int(math.ceil(float(src_band.YSize) / block_y_size))

                dst_band = dst_ds.GetRasterBand(dst_index)
                if src_band.GetNoDataValue() is not None:
                    dst_band.SetNoDataValue(src_band.GetNoDataValue())

                for block_x, block_y in product(range(num_x), range(num_y)):
                    offset_x = block_x * block_x_size
                    offset_y = block_y * block_y_size
                    size_x = min(src_band.XSize - offset_x, block_x_size)
                    size_y = min(src_band.YSize - offset_y, block_y_size)
                    data = src_band.ReadAsArray(offset_x, offset_y, size_x,
                                                size_y)

                    # perform clipping and scaling
                    data = ((dst_range[1] - dst_range[0]) *
                            ((numpy.clip(data, dmin, dmax) - src_range[0]) /
                             (src_range[1] - src_range[0])))

                    # set new datatype
                    data = data.astype(gdal_array.codes[self.datatype])

                    # write result
                    dst_band.WriteArray(data, offset_x, offset_y)

                    # write equal bands at once
                    if multiple > 0:
                        for i in range(multiple):
                            dst_band_multiple = dst_ds.GetRasterBand(
                                dst_index - 1 - i)
                            dst_band_multiple.WriteArray(
                                data, offset_x, offset_y)
                        multiple_written = True

                if multiple_written:
                    multiple = 0
                    multiple_written = False

            copy_projection(src_ds, dst_ds)
            copy_metadata(src_ds, dst_ds)

            return dst_ds

        except:
            cleanup_temp(dst_ds)
            raise
Exemple #9
0
    def __call__(self, src_ds):
        logger.info("Applying BandSelectionOptimization")
        try:
            dst_ds = create_temp(src_ds.RasterXSize, src_ds.RasterYSize,
                                 len(self.bands), self.datatype,
                                 temp_root=self.temporary_directory)
            dst_range = get_limits(self.datatype)

            multiple, multiple_written = 0, False

            for dst_index, (src_index, dmin, dmax) in enumerate(self.bands, 1):
                # check if next band is equal
                if dst_index < len(self.bands) and \
                        (src_index, dmin, dmax) == self.bands[dst_index]:
                    multiple += 1
                    continue
                # check that src band is available
                if src_index > src_ds.RasterCount:
                    continue

                # initialize with zeros if band is 0
                if src_index == 0:
                    src_band = src_ds.GetRasterBand(1)
                    data = numpy.zeros(
                        (src_band.YSize, src_band.XSize),
                        dtype=gdal_array.codes[self.datatype]
                    )
                    src_min, src_max = (0, 0)
                # use src_ds band otherwise
                else:
                    src_band = src_ds.GetRasterBand(src_index)
                    src_min, src_max = src_band.ComputeRasterMinMax()

                # get min/max values or calculate from band
                if dmin is None:
                    dmin = get_limits(src_band.DataType)[0]
                elif dmin == "min":
                    dmin = src_min
                if dmax is None:
                    dmax = get_limits(src_band.DataType)[1]
                elif dmax == "max":
                    dmax = src_max
                src_range = (float(dmin), float(dmax))

                block_x_size, block_y_size = src_band.GetBlockSize()

                num_x = int(math.ceil(float(src_band.XSize) / block_x_size))
                num_y = int(math.ceil(float(src_band.YSize) / block_y_size))

                dst_band = dst_ds.GetRasterBand(dst_index)
                if src_band.GetNoDataValue() is not None:
                    dst_band.SetNoDataValue(src_band.GetNoDataValue())

                for block_x, block_y in product(range(num_x), range(num_y)):
                    offset_x = block_x * block_x_size
                    offset_y = block_y * block_y_size
                    size_x = min(src_band.XSize - offset_x, block_x_size)
                    size_y = min(src_band.YSize - offset_y, block_y_size)
                    data = src_band.ReadAsArray(
                        offset_x, offset_y, size_x, size_y
                    )

                    # perform clipping and scaling
                    data = ((dst_range[1] - dst_range[0]) *
                            ((numpy.clip(data, dmin, dmax) - src_range[0]) /
                            (src_range[1] - src_range[0])))

                    # set new datatype
                    data = data.astype(gdal_array.codes[self.datatype])

                    # write result
                    dst_band.WriteArray(data, offset_x, offset_y)

                    # write equal bands at once
                    if multiple > 0:
                        for i in range(multiple):
                            dst_band_multiple = dst_ds.GetRasterBand(
                                dst_index-1-i
                            )
                            dst_band_multiple.WriteArray(
                                data, offset_x, offset_y
                            )
                        multiple_written = True

                if multiple_written:
                    multiple = 0
                    multiple_written = False

            copy_projection(src_ds, dst_ds)
            copy_metadata(src_ds, dst_ds)

            return dst_ds

        except:
            cleanup_temp(dst_ds)
            raise
Exemple #10
0
    def apply(self, src_ds):
        # setup
        dst_sr = osr.SpatialReference()
        gcp_sr = osr.SpatialReference()

        dst_sr.ImportFromEPSG(self.srid if self.srid is not None else self.gcp_srid)
        gcp_sr.ImportFromEPSG(self.gcp_srid)

        logger.debug("Using GCP Projection '%s'" % gcp_sr.ExportToWkt())
        logger.debug(
            "Applying GCPs: MULTIPOINT(%s) -> MULTIPOINT(%s)"
            % (
                ", ".join([("(%f %f)") % (gcp.GCPX, gcp.GCPY) for gcp in self.gcps]),
                ", ".join([("(%f %f)") % (gcp.GCPPixel, gcp.GCPLine) for gcp in self.gcps]),
            )
        )
        # set the GCPs
        src_ds.SetGCPs(self.gcps, gcp_sr.ExportToWkt())

        # Try to find and use the best transform method/order.
        # Orders are: -1 (TPS), 3, 2, and 1 (all GCP)
        # Loop over the min and max GCP number to order map.
        for min_gcpnum, max_gcpnum, order in [(3, None, -1), (10, None, 3), (6, None, 2), (3, None, 1)]:
            # if the number of GCP matches
            if len(self.gcps) >= min_gcpnum and (max_gcpnum is None or len(self.gcps) <= max_gcpnum):
                try:

                    if order < 0:
                        # let the reftools suggest the right interpolator
                        rt_prm = rt.suggest_transformer(src_ds)
                    else:
                        # use the polynomial GCP interpolation as requested
                        rt_prm = {"method": rt.METHOD_GCP, "order": order}

                    logger.debug(
                        "Trying order '%i' {method:%s,order:%s}"
                        % (order, rt.METHOD2STR[rt_prm["method"]], rt_prm["order"])
                    )
                    # get the suggested pixel size/geotransform
                    size_x, size_y, geotransform = rt.suggested_warp_output(
                        src_ds, None, dst_sr.ExportToWkt(), **rt_prm
                    )
                    if size_x > 100000 or size_y > 100000:
                        raise RuntimeError("Calculated size exceeds limit.")
                    logger.debug("New size is '%i x %i'" % (size_x, size_y))

                    # create the output dataset
                    dst_ds = create_mem(size_x, size_y, src_ds.RasterCount, src_ds.GetRasterBand(1).DataType)

                    # reproject the image
                    dst_ds.SetProjection(dst_sr.ExportToWkt())
                    dst_ds.SetGeoTransform(geotransform)

                    rt.reproject_image(src_ds, "", dst_ds, "", **rt_prm)

                    copy_metadata(src_ds, dst_ds)

                    # retrieve the footprint from the given GCPs
                    footprint_wkt = rt.get_footprint_wkt(src_ds, **rt_prm)

                except RuntimeError, e:
                    logger.debug("Failed using order '%i'. Error was '%s'." % (order, str(e)))
                    # the given method was not applicable, use the next one
                    continue

                else:
                    logger.debug("Successfully used order '%i'" % order)
                    # the transform method was successful, exit the loop
                    break
Exemple #11
0
    def apply(self, src_ds):
        # setup
        dst_sr = osr.SpatialReference()
        gcp_sr = osr.SpatialReference()

        dst_sr.ImportFromEPSG(self.srid if self.srid is not None
                              else self.gcp_srid)
        gcp_sr.ImportFromEPSG(self.gcp_srid)


        logger.debug("Using GCP Projection '%s'" % gcp_sr.ExportToWkt())
        logger.debug("Applying GCPs: MULTIPOINT(%s) -> MULTIPOINT(%s)"
                      % (", ".join([("(%f %f)") % (gcp.GCPX, gcp.GCPY) for gcp in self.gcps]) ,
                      ", ".join([("(%f %f)") % (gcp.GCPPixel, gcp.GCPLine) for gcp in self.gcps])))
        # set the GCPs
        src_ds.SetGCPs(self.gcps, gcp_sr.ExportToWkt())

        # Try to find and use the best transform method/order.
        # Orders are: -1 (TPS), 3, 2, and 1 (all GCP)
        # Loop over the min and max GCP number to order map.
        for min_gcpnum, max_gcpnum, order in [(3, None, -1), (10, None, 3), (6, None, 2), (3, None, 1)]:
            # if the number of GCP matches
            if len(self.gcps) >= min_gcpnum and (max_gcpnum is None or len(self.gcps) <= max_gcpnum):
                try:

                    if ( order < 0 ) :
                        # let the reftools suggest the right interpolator
                        rt_prm = rt.suggest_transformer( src_ds )
                    else:
                        # use the polynomial GCP interpolation as requested
                        rt_prm = { "method":rt.METHOD_GCP, "order":order }

                    logger.debug("Trying order '%i' {method:%s,order:%s}" % \
                        (order, rt.METHOD2STR[rt_prm["method"]] , rt_prm["order"] ) )
                    # get the suggested pixel size/geotransform
                    size_x, size_y, geotransform = rt.suggested_warp_output(
                        src_ds,
                        None,
                        dst_sr.ExportToWkt(),
                        **rt_prm
                    )
                    if size_x > 100000 or size_y > 100000:
                        raise RuntimeError("Calculated size exceeds limit.")
                    logger.debug("New size is '%i x %i'" % (size_x, size_y))

                    # create the output dataset
                    dst_ds = create_mem(size_x, size_y,
                                        src_ds.RasterCount,
                                        src_ds.GetRasterBand(1).DataType)

                    # reproject the image
                    dst_ds.SetProjection(dst_sr.ExportToWkt())
                    dst_ds.SetGeoTransform(geotransform)

                    rt.reproject_image(src_ds, "", dst_ds, "", **rt_prm )

                    copy_metadata(src_ds, dst_ds)

                    # retrieve the footprint from the given GCPs
                    footprint_wkt = rt.get_footprint_wkt(src_ds, **rt_prm )

                except RuntimeError as e:
                    logger.debug("Failed using order '%i'. Error was '%s'."
                                 % (order, str(e)))
                    # the given method was not applicable, use the next one
                    continue

                else:
                    logger.debug("Successfully used order '%i'" % order)
                    # the transform method was successful, exit the loop
                    break
        else:
            # no method worked, so raise an error
            raise GCPTransformException("Could not find a valid transform method.")

        # reproject the footprint to a lon/lat projection if necessary
        if not gcp_sr.IsGeographic():
            out_sr = osr.SpatialReference()
            out_sr.ImportFromEPSG(4326)
            geom = ogr.CreateGeometryFromWkt(footprint_wkt, gcp_sr)
            geom.TransformTo(out_sr)
            footprint_wkt = geom.ExportToWkt()

        logger.debug("Calculated footprint: '%s'." % footprint_wkt)

        return dst_ds, footprint_wkt
Exemple #12
0
    def apply(self, src_ds):
        # setup
        dst_sr = osr.SpatialReference()
        dst_sr.ImportFromEPSG(self.srid)

        logger.debug("Using internal GCP Projection.")
        num_gcps = src_ds.GetGCPCount()

        # Try to find and use the best transform method/order.
        # Orders are: -1 (TPS), 3, 2, and 1 (all GCP)
        # Loop over the min and max GCP number to order map.
        for min_gcpnum, max_gcpnum, order in [(3, None, -1), (10, None, 3),
                                              (6, None, 2), (3, None, 1)]:
            # if the number of GCP matches
            if num_gcps >= min_gcpnum and (max_gcpnum is None
                                           or num_gcps <= max_gcpnum):
                try:

                    if (order < 0):
                        # let the reftools suggest the right interpolator
                        rt_prm = reftools.suggest_transformer(src_ds)
                    else:
                        # use the polynomial GCP interpolation as requested
                        rt_prm = {
                            "method": reftools.METHOD_GCP,
                            "order": order
                        }

                    logger.debug("Trying order '%i' {method:%s,order:%s}" %
                                 (order, reftools.METHOD2STR[rt_prm["method"]],
                                  rt_prm["order"]))

                    # get the suggested pixel size/geotransform
                    size_x, size_y, gt = reftools.suggested_warp_output(
                        src_ds, None, dst_sr.ExportToWkt(), **rt_prm)
                    if size_x > 100000 or size_y > 100000:
                        raise RuntimeError("Calculated size exceeds limit.")
                    logger.debug("New size is '%i x %i'" % (size_x, size_y))

                    # create the output dataset
                    dst_ds = create_mem(size_x, size_y, src_ds.RasterCount,
                                        src_ds.GetRasterBand(1).DataType)

                    # reproject the image
                    dst_ds.SetProjection(dst_sr.ExportToWkt())
                    dst_ds.SetGeoTransform(gt)

                    reftools.reproject_image(src_ds, "", dst_ds, "", **rt_prm)

                    copy_metadata(src_ds, dst_ds)

                    # retrieve the footprint from the given GCPs
                    footprint_wkt = reftools.get_footprint_wkt(
                        src_ds, **rt_prm)

                except RuntimeError, e:
                    logger.debug("Failed using order '%i'. Error was '%s'." %
                                 (order, str(e)))
                    # the given method was not applicable, use the next one
                    continue

                else:
                    logger.debug("Successfully used order '%i'" % order)
                    # the transform method was successful, exit the loop
                    break