def __new__(cls, op): assert isinstance(op, DaskMeta) self = super(IpeImage, cls).create(op) self._ipe_op = op if self.ipe.metadata["georef"] is None: tfm = RatPolyTransform.from_rpcs(self.ipe.metadata["rpcs"]) else: tfm = AffineTransform.from_georef(self.ipe.metadata["georef"]) img_md = self.ipe.metadata["image"] xshift = img_md["minTileX"]*img_md["tileXSize"] yshift = img_md["minTileY"]*img_md["tileYSize"] self.__geo_transform__ = tfm + (xshift, yshift) self.__geo_interface__ = mapping(self._reproject(wkt.loads(self.ipe.metadata["image"]["imageBoundsWGS84"]))) minx = img_md["minX"] - xshift maxx = img_md["maxX"] - xshift miny = img_md["minY"] - yshift maxy = img_md["maxY"] - yshift return self[:, miny:maxy, minx:maxx]
def __geo_transform__(self): tfm = transform_from_bounds(*tuple( e for e in chain(self.bounds, self.shape[2:0:-1]))) return AffineTransform(tfm, "EPSG:3857")
def __geo_transform__(self): west, south, east, north = self.bounds tfm = Affine.translation(west, north) * Affine.scale( (east - west) / self.shape[2], (south - north) / self.shape[1]) return AffineTransform(tfm, "EPSG:3857")
def warp(self, dem=None, proj="EPSG:4326", **kwargs): """ Delayed warp across an entire AOI or Image creates a new dask image by deferring calls to the warp_geometry on chunks kwargs: dem (ndarray): optional. A DEM for warping to specific elevation planes proj (str): optional. An EPSG proj string to project the image data into ("EPSG:32612") Returns: image (dask): a warped image as deferred image array (a dask) """ try: img_md = self.ipe.metadata["image"] x_size = img_md["tileXSize"] y_size = img_md["tileYSize"] except (AttributeError, KeyError): x_size = kwargs.get("chunk_size", 256) y_size = kwargs.get("chunk_size", 256) # Create an affine transform to convert between real-world and pixels if self.proj is None: from_proj = "EPSG:4326" else: from_proj = self.proj try: # NOTE: this only works on images that have IPE rpcs metadata center = wkt.loads( self.ipe.metadata["image"]["imageBoundsWGS84"]).centroid g = box(*(center.buffer(self.ipe.metadata["rpcs"]["gsd"] / 2).bounds)) # print "Input GSD (deg):", self.ipe.metadata["rpcs"]["gsd"] tfm = partial(pyproj.transform, pyproj.Proj(init="EPSG:4326"), pyproj.Proj(init=proj)) gsd = kwargs.get("gsd", ops.transform(tfm, g).area**0.5) current_bounds = wkt.loads( self.ipe.metadata["image"]["imageBoundsWGS84"]).bounds except (AttributeError, KeyError, TypeError): tfm = partial(pyproj.transform, pyproj.Proj(init=self.proj), pyproj.Proj(init=proj)) gsd = kwargs.get("gsd", (ops.transform(tfm, shape(self)).area / (self.shape[1] * self.shape[2]))**0.5) current_bounds = self.bounds tfm = partial(pyproj.transform, pyproj.Proj(init=from_proj), pyproj.Proj(init=proj)) itfm = partial(pyproj.transform, pyproj.Proj(init=proj), pyproj.Proj(init=from_proj)) output_bounds = ops.transform(tfm, box(*current_bounds)).bounds gtf = Affine.from_gdal(output_bounds[0], gsd, 0.0, output_bounds[3], 0.0, -1 * gsd) ll = ~gtf * (output_bounds[:2]) ur = ~gtf * (output_bounds[2:]) x_chunks = int((ur[0] - ll[0]) / x_size) + 1 y_chunks = int((ll[1] - ur[1]) / y_size) + 1 num_bands = self.shape[0] try: dtype = IPE_TO_DTYPE[img_md["dataType"]] except: dtype = 'uint8' daskmeta = { "dask": {}, "chunks": (num_bands, y_size, x_size), "dtype": dtype, "name": "warp-{}".format(self.name), "shape": (num_bands, y_chunks * y_size, x_chunks * x_size) } def px_to_geom(xmin, ymin): xmax = int(xmin + x_size) ymax = int(ymin + y_size) bounds = list((gtf * (xmin, ymax)) + (gtf * (xmax, ymin))) return box(*bounds) full_bounds = box(*output_bounds) dasks = [] if isinstance(dem, GeoImage): if dem.proj != proj: dem = dem.warp(proj=proj, dem=dem) dasks.append(dem.dask) for y in xrange(y_chunks): for x in xrange(x_chunks): xmin = x * x_size ymin = y * y_size geometry = px_to_geom(xmin, ymin) daskmeta["dask"][(daskmeta["name"], 0, y, x)] = (self._warp, geometry, gsd, dem, proj, dtype, 5) daskmeta["dask"], _ = optimize.cull( sharedict.merge(daskmeta["dask"], *dasks), list(daskmeta["dask"].keys())) result = GeoDaskWrapper(daskmeta, self) result.__geo_interface__ = mapping(full_bounds) result.__geo_transform__ = AffineTransform(gtf, proj) return GeoImage.__getitem__(result, box(*output_bounds))