def get_source_and_dest_rect(self, dataset, subsets): size_x, size_y = dataset.RasterXSize, dataset.RasterYSize image_rect = Rect(0, 0, size_x, size_y) if not subsets: subset_rect = image_rect # pixel subset elif subsets.srid is None: # means "imageCRS" minx, miny, maxx, maxy = subsets.xy_bbox minx = int(minx) if minx is not None else image_rect.offset_x miny = int(miny) if miny is not None else image_rect.offset_y maxx = int(maxx) if maxx is not None else image_rect.upper_x maxy = int(maxy) if maxy is not None else image_rect.upper_y subset_rect = Rect(minx, miny, maxx - minx + 1, maxy - miny + 1) # subset in geographical coordinates else: vrt = VRTBuilder(*image_rect.size) vrt.copy_gcps(dataset) options = reftools.suggest_transformer(dataset) subset_rect = reftools.rect_from_subset(vrt.dataset, subsets.srid, *subsets.xy_bbox, **options) # check whether or not the subsets intersect with the image if not image_rect.intersects(subset_rect): raise RenderException("Subset outside coverage extent.", "subset") src_rect = subset_rect # & image_rect # TODO: why no intersection?? dst_rect = src_rect - subset_rect.offset return src_rect, dst_rect
def read(self, obj): ds = open_gdal(obj) if ds is not None: driver = ds.GetDriver() size = (ds.RasterXSize, ds.RasterYSize) gt = ds.GetGeoTransform() extent = None if gt != (0.0, 1.0, 0.0, 0.0, 0.0, 1.0): x_extent = (gt[0], gt[0] + size[0] * gt[1]) y_extent = (gt[3] + size[1] * gt[5], gt[3]) extent = ( min(x_extent), min(y_extent), max(x_extent), max(y_extent) ) projection = ds.GetProjection() values = { "size": (ds.RasterXSize, ds.RasterYSize), } if projection: values["projection"] = (projection, "WKT") if extent: values["extent"] = extent reader = self._find_additional_reader(ds) if reader: additional_values = reader.read_ds(ds) for key, value in additional_values.items(): values.setdefault(key, value) if ds.GetGCPCount() > 0: rt_prm = rt.suggest_transformer(raw_metadata) fp_wkt = rt.get_footprint_wkt(raw_metadata,**rt_prm) values["footprint"] = GEOSGeometry( fp_wkt ) driver_metadata = driver.GetMetadata() frmt = driver_metadata.get("DMD_MIMETYPE") if frmt: values["format"] = frmt return values raise Exception("Could not parse from obj '%s'." % repr(obj))
def getExtentFromReferenceableDS( ds ): """ Calculates the extent tuple of the given gdal.Dataset. The dataset must be encoded using the tie-points. """ filelist = ds.GetFileList() if 1 != len( filelist ) : raise RuntimeError( "Cannot get a single dataset filename!" ) rt_prm = rt.suggest_transformer(filelist[0]) fp_wkt = rt.get_footprint_wkt(filelist[0],**rt_prm) return GEOSGeometry( fp_wkt ).extent
def get_source_and_dest_rect(self, dataset, subsets): size_x, size_y = dataset.RasterXSize, dataset.RasterYSize image_rect = Rect(0, 0, size_x, size_y) if not subsets: subset_rect = image_rect # pixel subset elif subsets.srid is None: # means "imageCRS" minx, miny, maxx, maxy = subsets.xy_bbox minx = int(minx) if minx is not None else image_rect.offset_x miny = int(miny) if miny is not None else image_rect.offset_y maxx = int(maxx) if maxx is not None else image_rect.upper_x maxy = int(maxy) if maxy is not None else image_rect.upper_y subset_rect = Rect(minx, miny, maxx - minx + 1, maxy - miny + 1) # subset in geographical coordinates else: vrt = VRTBuilder(*image_rect.size) vrt.copy_gcps(dataset) options = reftools.suggest_transformer(dataset) subset_rect = reftools.rect_from_subset(vrt.dataset, subsets.srid, *subsets.xy_bbox, **options) # check whether or not the subsets intersect with the image if not image_rect.intersects(subset_rect): raise RenderException("Subset outside coverage extent.", "subset") src_rect = subset_rect #& image_rect # TODO: why no intersection?? dst_rect = src_rect - subset_rect.offset return src_rect, dst_rect
def read(self, obj): ds = open_gdal(obj) if ds is None: raise Exception("Could not parse from obj '%s'." % repr(obj)) driver = ds.GetDriver() size = (ds.RasterXSize, ds.RasterYSize) values = {"size": size} # --= rectified datasets =-- # NOTE: If the projection is a non-zero string then # the geocoding is given by the Geo-Trasnformation # matrix - not matter what are the values. if ds.GetProjection(): values["coverage_type"] = "RectifiedDataset" values["projection"] = (ds.GetProjection(), "WKT") # get coordinates of all four image corners gt = ds.GetGeoTransform() def gtrans(x, y): return gt[0] + x*gt[1] + y*gt[2], gt[3] + x*gt[4] + y*gt[5] vpix = [(0, 0), (0, size[1]), (size[0], 0), (size[0], size[1])] vx, vy = zip(*(gtrans(x, y) for x, y in vpix)) # find the extent values["extent"] = (min(vx), min(vy), max(vx), max(vy)) # --= tie-point encoded referenceable datasets =-- # NOTE: If the GCP projection is a non-zero string and # there are GCPs we are dealing with a tie-point geocoded # referenceable dataset. The extent is given by the image # footprint. The fooprint must not be wrapped arround # the date-line! elif ds.GetGCPProjection() and ds.GetGCPCount() > 0: values["coverage_type"] = "ReferenceableDataset" projection = ds.GetGCPProjection() values["projection"] = (projection, "WKT") # parse the spatial reference to get the EPSG code sr = osr.SpatialReference(projection, "WKT") # NOTE: GeosGeometry can't handle non-EPSG geometry projections. if sr.GetAuthorityName(None) == "EPSG": srid = int(sr.GetAuthorityCode(None)) # get the footprint rt_prm = rt.suggest_transformer(ds) fp_wkt = rt.get_footprint_wkt(ds, **rt_prm) footprint = GEOSGeometry(fp_wkt, srid) if isinstance(footprint, Polygon): footprint = MultiPolygon(footprint) elif not isinstance(footprint, MultiPolygon): raise TypeError( "Got invalid geometry %s" % type(footprint).__name__ ) values["footprint"] = footprint values["extent"] = footprint.extent # --= dataset with no geocoding =-- # TODO: Handling of other types of GDAL geocoding (e.g, RPC). else: pass reader = self._find_additional_reader(ds) if reader: additional_values = reader.read_ds(ds) for key, value in additional_values.items(): values.setdefault(key, value) driver_metadata = driver.GetMetadata() frmt = driver_metadata.get("DMD_MIMETYPE") if frmt is None: _driver_name = "GDAL/" + driver.ShortName _frmt = getFormatRegistry().getFormatsByDriver(_driver_name) if _frmt: frmt = _frmt[0].mimeType if frmt: values["format"] = frmt return values
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
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
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
def read(self, obj): ds = open_gdal(obj) if ds is None: raise Exception("Could not parse from obj '%s'." % repr(obj)) driver = ds.GetDriver() size = (ds.RasterXSize, ds.RasterYSize) values = {"size": size} # --= rectified datasets =-- # NOTE: If the projection is a non-zero string then # the geocoding is given by the Geo-Trasnformation # matrix - not matter what are the values. if ds.GetProjection(): values["coverage_type"] = "RectifiedDataset" values["projection"] = (ds.GetProjection(), "WKT") # get coordinates of all four image corners gt = ds.GetGeoTransform() def gtrans(x, y): return gt[0] + x * gt[1] + y * gt[2], gt[ 3] + x * gt[4] + y * gt[5] vpix = [(0, 0), (0, size[1]), (size[0], 0), (size[0], size[1])] vx, vy = zip(*(gtrans(x, y) for x, y in vpix)) # find the extent values["extent"] = (min(vx), min(vy), max(vx), max(vy)) # --= tie-point encoded referenceable datasets =-- # NOTE: If the GCP projection is a non-zero string and # there are GCPs we are dealing with a tie-point geocoded # referenceable dataset. The extent is given by the image # footprint. The fooprint must not be wrapped arround # the date-line! elif ds.GetGCPProjection() and ds.GetGCPCount() > 0: values["coverage_type"] = "ReferenceableDataset" projection = ds.GetGCPProjection() values["projection"] = (projection, "WKT") # parse the spatial reference to get the EPSG code sr = osr.SpatialReference(projection, "WKT") # NOTE: GeosGeometry can't handle non-EPSG geometry projections. if sr.GetAuthorityName(None) == "EPSG": srid = int(sr.GetAuthorityCode(None)) # get the footprint rt_prm = rt.suggest_transformer(ds) fp_wkt = rt.get_footprint_wkt(ds, **rt_prm) footprint = GEOSGeometry(fp_wkt, srid) if isinstance(footprint, Polygon): footprint = MultiPolygon(footprint) elif not isinstance(footprint, MultiPolygon): raise TypeError("Got invalid geometry %s" % type(footprint).__name__) values["footprint"] = footprint values["extent"] = footprint.extent # --= dataset with no geocoding =-- # TODO: Handling of other types of GDAL geocoding (e.g, RPC). else: pass reader = self._find_additional_reader(ds) if reader: additional_values = reader.read_ds(ds) for key, value in additional_values.items(): values.setdefault(key, value) driver_metadata = driver.GetMetadata() frmt = driver_metadata.get("DMD_MIMETYPE") if frmt: values["format"] = frmt return values
""" Print simple usage help. """ exename = basename(sys.argv[0]) print >>sys.stderr, ( "USAGE: %s <input image> [%s]" % (exename, "|".join(OUTPUT_FORMATS)) ) if __name__ == "__main__": DEBUG = False FORMAT = "WKB" try: INPUT = sys.argv[1] for arg in sys.argv[2:]: if arg in OUTPUT_FORMATS: FORMAT = arg # output format elif arg == "DEBUG": DEBUG = True # dump debugging output except IndexError: error("Not enough input arguments!\n") usage() sys.exit(1) # get the referenceable dataset outline #NOTE: It is assumed, that the outline is not wrapped around the date-line. ds = gdal.Open(INPUT) prm = rt.suggest_transformer(ds) geom = setSR(parseGeom(rt.get_footprint_wkt(ds, **prm)), OSR_WGS84) # print geometry sys.stdout.write(dumpGeom(geom, FORMAT))
def read(self, obj): ds = open_gdal(obj) if ds is None: raise Exception("Could not parse from obj '%s'." % repr(obj)) driver = ds.GetDriver() size = (ds.RasterXSize, ds.RasterYSize) values = {"size": size} projection = ds.GetProjection() # --= rectified datasets =-- # NOTE: If the projection is a non-zero string then # the geocoding is given by the Geo-Trasnformation # matrix - not matter what are the values. if projection and not (ds.GetGCPProjection() and ds.GetGCPCount() > 0): sr = osr.SpatialReference(projection) if sr.srid is not None: projection = 'EPSG:%d' % sr.srid gt = ds.GetGeoTransform() values['origin'] = [gt[0], gt[3]] values['grid'] = { 'coordinate_reference_system': projection, 'axis_offsets': [gt[1], gt[5]], 'axis_types': ['spatial', 'spatial'], 'axis_names': ['x', 'y'] if sr.IsProjected() else ['long', 'lat'], } if sr.GetLinearUnitsName() in ('metre', 'meter', 'm') \ and abs(gt[1]) == abs(gt[5]): values['grid']['resolution'] = abs(gt[1]) # --= tie-point encoded referenceable datasets =-- # NOTE: If the GCP projection is a non-zero string and # there are GCPs we are dealing with a tie-point geocoded # referenceable dataset. The extent is given by the image # footprint. The fooprint must not be wrapped arround # the date-line! elif ds.GetGCPProjection() and ds.GetGCPCount() > 0: projection = ds.GetGCPProjection() sr = osr.SpatialReference(projection) if sr.srid is not None: projection = 'EPSG:%d' % sr.srid values['grid'] = { 'coordinate_reference_system': projection, 'axis_offsets': [None, None], 'axis_types': ['spatial', 'spatial'], 'axis_names': ['x', 'y'] if sr.IsProjected() else ['long', 'lat'] } values['origin'] = [None, None] # # parse the spatial reference to get the EPSG code sr = osr.SpatialReference(ds.GetGCPProjection(), "WKT") # NOTE: GeosGeometry can't handle non-EPSG geometry projections. if sr.GetAuthorityName(None) == "EPSG": srid = int(sr.GetAuthorityCode(None)) # get the footprint rt_prm = rt.suggest_transformer(ds) fp_wkt = rt.get_footprint_wkt(ds, **rt_prm) footprint = GEOSGeometry(fp_wkt, srid) if isinstance(footprint, Polygon): footprint = MultiPolygon(footprint) elif not isinstance(footprint, MultiPolygon): raise TypeError("Got invalid geometry %s" % type(footprint).__name__) values['footprint'] = footprint pass # --= dataset with no geocoding =-- # TODO: Handling of other types of GDAL geocoding (e.g, RPC). else: pass reader = self._find_additional_reader(ds) if reader: additional_values = reader.read_ds(ds) for key, value in additional_values.items(): values.setdefault(key, value) driver_metadata = driver.GetMetadata() frmt = driver_metadata.get("DMD_MIMETYPE") if frmt: values["format"] = frmt return values