def reproject(source, target, algorithm=gdal.GRA_NearestNeighbour): """ Reproject source to target. """ gdal.ReprojectImage( source, target, projections.get_wkt(source.GetProjection()), projections.get_wkt(target.GetProjection()), algorithm, 0.0, 0.125, )
def add(self, dataset): """ Add a copy of dataset as tif. If self.memory, create an in-memory copy as well. """ self._lock() # Create a file copy of dataset tif_driver = gdal.GetDriverByName(b"gtiff") create_args = [ str(self.tifpath), dataset, 1, # Strict, just default value ["TILED=YES", "COMPRESS={}".format(self.compression)], ] tif_dataset = tif_driver.CreateCopy(*create_args) # Apply default projection if there is none. tif_dataset.SetProjection(projections.get_wkt(dataset.GetProjection())) # Close and reopen dataset to force flush. tif_dataset = None tif_dataset = gdal.Open(str(self.tifpath)) # Set dataset attribute based on memory attribute if self.memory: mem_driver = gdal.GetDriverByName(b"mem") mem_dataset = mem_driver.CreateCopy(b"", tif_dataset) self.dataset = mem_dataset else: self.dataset = tif_dataset self._set_attributes_from_dataset() self._unlock()
def to_dataset(self, datatype=1, bands=1, projection=None): """ Return in-memory gdal dataset. """ driver = gdal.GetDriverByName(b"mem") dataset = driver.Create(b"", self.size[0], self.size[1], bands, datatype) dataset.SetGeoTransform(self.geotransform()) dataset.SetProjection(projections.get_wkt(projection)) return dataset
def make_pyramid(layer): """ Build a pyramid from a dataset. """ logger.info('Building pyramid for {}'.format(layer)) # Get paths pyramid_path = utils.get_pyramid_path(layer) dataset_path = utils.get_bathymetry_path(layer) # Create pyramid try: pyramid = rasters.Pyramid(path=pyramid_path, compression='DEFLATE') if pyramid.has_data(): logger.info('Pyramid has data for {}'.format(layer)) return dataset = gdal.Open(str(dataset_path)) logger.info("Pyramid path: %r" % pyramid_path) logger.info("Dataset path: %r" % dataset_path) # it defaults to rijksdriehoek (28992) bathy_srs = utils.get_bathymetry_srs(dataset_path) logger.info("Bathy srs: %r" % bathy_srs) dataset.SetProjection(projections.get_wkt(bathy_srs)) pyramid.add(dataset) except rasters.LockError: logger.info('Pyramid busy for {}'.format(layer)) return logger.info('Pyramid completed for {}'.format(layer))
def sync(self): """ Create or replace the peak with current data. """ ### XXX # Only create an empty file with name of peakpath open(self.peakpath, 'w') return cropped = [] for dataset in self.get_datasets(-1): cropped.append(crop(dataset)) extents = [dataset2outline(c).extent for c in cropped] x1, y1, x2, y2 = zip(*extents) x1, y1, x2, y2 = min(x1), min(y1), max(x2), max(y2) geotransform = x1, (x2 - x1) / 256, 0, y2, 0, (y1 - y2) / 256 # create fd, temppath = tempfile.mkstemp(dir=self.path, prefix=b'.pyramid.tmp.') dataset = GDAL_DRIVER_GTIFF.Create(temppath, 256, 256, self.raster_count, self.data_type, get_options(block_size=(256, 256))) dataset.SetProjection(projections.get_wkt(self.projection)) dataset.SetGeoTransform(geotransform) for i in range(self.raster_count): dataset.GetRasterBand(i + 1).SetNoDataValue(self.no_data_value) for c in cropped: rasters.reproject(c, dataset) dataset = None os.close(fd) os.rename(temppath, self.peakpath)
def array2dataset(array, extent=None, crs=None): """ Return gdal dataset. Fastest way to get a gdal dataset from a numpy array, but keep a refernce to the array around, or a segfault will occur. Also, don't forget to call FlushCache() on the dataset after any operation that affects the array. """ # Prepare dataset name pointing to array datapointer = array.ctypes.data bands, lines, pixels = array.shape datatypecode = gdal_array.NumericTypeCodeToGDALTypeCode(array.dtype.type) datatype = gdal.GetDataTypeName(datatypecode) bandoffset, lineoffset, pixeloffset = array.strides dataset_name_template = ( "MEM:::" "DATAPOINTER={datapointer}," "PIXELS={pixels}," "LINES={lines}," "BANDS={bands}," "DATATYPE={datatype}," "PIXELOFFSET={pixeloffset}," "LINEOFFSET={lineoffset}," "BANDOFFSET={bandoffset}" ) dataset_name = dataset_name_template.format( datapointer=datapointer, pixels=pixels, lines=lines, bands=bands, datatype=datatype, pixeloffset=pixeloffset, lineoffset=lineoffset, bandoffset=bandoffset, ) # Acces the array memory as gdal dataset dataset = gdal.Open(dataset_name, gdal.GA_Update) # Add georeferencing based on extent and projection if extent is not None: x1, y1, x2, y2 = extent geotransform = (x1, (x2 - x1) / array.shape[-1], 0, y2, 0, (y1 - y2) / array.shape[-2]) dataset.SetGeoTransform(geotransform) if crs is not None: dataset.SetProjection(projections.get_wkt(crs)) return dataset
def get_data_for_polygon(self, wkb, crs, size): """ Return a numpy array for the data. """ # Quick out if polygon bounds match polygon geometry = vectors.Geometry(wkb) envelope = geometry.envelope extent = geometry.extent nodatavalue = self.manager.no_data_value datatype = self.manager.data_type # Initialize resulting array to nodatavalue dtype = gdal_array.flip_code(datatype) array = np.ones( (1, size[1], size[0]), dtype=dtype, ) * dtype(nodatavalue) # Create dataset and use it to retrieve data from the store array_dict = dict( array=array, no_data_value=nodatavalue, projection=projections.get_wkt(crs), geo_transform=rasters.get_geotransform( extent=extent, width=size[0], height=size[1], ), ) dataset = rasters.dict2dataset(array_dict) self.warpinto(dataset) dataset.FlushCache() # Cut when necessary if not envelope.Equals(wkb): source = OGR_MEM_DRIVER.CreateDataSource('') sr = projections.get_spatial_reference(crs) layer = source.CreateLayer(b'', sr) defn = layer.GetLayerDefn() feature = ogr.Feature(defn) feature.SetGeometry(envelope.Difference(wkb)) layer.CreateFeature(feature) gdal.RasterizeLayer(dataset, (1,), layer, burn_values=(nodatavalue,)) dataset.FlushCache() return np.ma.masked_equal(array, nodatavalue, copy=False)
def new_dataset(self, tile, info): """ Return gdal dataset. """ path = os.path.join(self.path, self.TILES, tile.path) try: os.makedirs(os.path.dirname(path)) except OSError: pass # It existed. create_options = self.get_options(info['blocksize']) dataset = GTIFF.Create(path, tile.size[0], tile.size[1], 1, info['datatype'], create_options) dataset.SetProjection(projections.get_wkt(info['projection'])) dataset.SetGeoTransform(tile.geotransform) dataset.GetRasterBand(1).SetNoDataValue(info['nodatavalue']) return dataset
def create(self, tile): """ Create a new dataset. """ # prepare path = self.tile2path(tile) try: os.makedirs(os.path.dirname(path)) except OSError: pass # directory already exists # create dataset = GDAL_DRIVER_GTIFF.Create(path, self.raster_size[0], self.raster_size[1], self.raster_count, self.data_type, get_options(self.block_size)) # config dataset.SetProjection(projections.get_wkt(self.projection)) dataset.SetGeoTransform(self.tile2geotransform(tile)) for i in range(self.raster_count): dataset.GetRasterBand(i + 1).SetNoDataValue(self.no_data_value)
def get_bathymetry_srs(filename): """Return srs from bathymetry, None if not set.""" ds = gdal.Open(filename) return projections.get_wkt(ds.GetProjection())