-
Notifications
You must be signed in to change notification settings - Fork 364
GeoTrellis 3.0 Examples
Jean-Denis Giguère edited this page Aug 6, 2020
·
2 revisions
import geotrellis.raster._
import geotrellis.vector._
import org.locationtech.jts.geom._
val s3Path = "s3://bucket/key/path/to/cog.tif"
val rasterSource = RasterSource(s3Path)
val geom: Geometry = ???
val extent = Extent(geom.getEnvelopeInternal)
val multiBandRaster: Option[Raster[MultibandTile]] =
rasterSource.read(extent)
// Do whatever with the result!
Note: If you don't have COG, the tiling of the GeoTiff may be really useful.
/* This example demonstrates how to mask tiles
* loaded from a RasterSource on S3 with a geometry
*/
import geotrellis.raster._
import geotrellis.raster.rasterize.Rasterizer
import geotrellis.vector._
val s3Path = "s3://bucket/key/to/cog.tif"
val rasterSource = RasterSource(s3Path)
val extent = rasterSource.extent
// Just get the first Tile from the RasterSource
// You could do other things here like loop each tile or
// check to ensure that the read was successful
val tile = rasterSource.read(Seq(0)).get.band(0).tile
val rasterExtent = RasterExtent(extent, tile)
// Geom can be loaded from a number of sources, out
// of scope of this example
val geom: Geometry = ???
val options: Rasterizer.Options =
Rasterizer.Options(true, PixelIsArea)
val colorMap = ColorRamps.BlueToOrange
.toColorMap(tile.histogramDouble)
// Example 1 - Mask so that only pixels intersecting
// the geometry are kept
tile
.mask(extent, geom, options)
.renderPng(colorMap)
.write("/path/to/tile.png")
// Example 2 - Inverse mask so that only pixels that
// do not intersect the geometry are kept
val geomMask =
geom.rasterizeWithValue(rasterExtent,
1,
IntConstantNoDataCellType,
options)
tile
.localMask(geomMask, 1, NODATA)
.renderPng(colorMap)
.write("/path/to/tile.png")
import geotrellis.raster._
val tile: Tile = ???
// ColorRamps define a list of color values
val colorRamp = ColorRamps.BlueToOrange
// ColorMap defines a map of tile value to bin in
// a ColorRamp.
// There are a number of different ways to generate
// a ColorMap, the simplest of which is to use
// a histogram generated from the Tile
val colorMap = colorRamp.toColorMap(tile.histogramDouble)
// Render to a Png using a ColorMap then write to disk
tile.renderPng(colorMap).write("/path/to/tile.png")
import geotrellis.layer._
import geotrellis.proj4.WebMercator
import geotrellis.raster._
import geotrellis.raster.reproject.Reproject
import geotrellis.spark._
import geotrellis.spark.pyramid._
import geotrellis.spark.store.s3._
import org.apache.spark.rdd.RDD
// There are a number of ways to generate this input
// which is out of scope of this example
val tileRdd: RDD[(SpatialKey, Tile)] = ???
// Use whichever of the overloads correspond to the
// information you know about your tileRdd
val metadata: TileLayerMetadata[SpatialKey] =
tileRdd.collectMetadata(???)
val resampleOptions = Reproject.Options.DEFAULT
// This is the layout scheme compatible with tiled slippy maps
val pyramidLayoutScheme = ZoomedLayoutScheme(WebMercator, 256)
// Convert your RDD to the correct layout/projection
val (targetZoom, tileLayerRdd) =
TileLayerRDD(tileRdd, metadata)
.reproject(pyramidLayoutScheme, resampleOptions)
// You can explicitly set the zoom levels to generate,
// or let GeoTrellis figure out the optimal zoom levels,
// as is done here.
val pyramid =
Pyramid.fromLayerRDD(tileLayerRdd, Some(targetZoom), None)
pyramid.levels.foreach {
// Write each zoom level sequentially
case (zoom, tileRdd) => {
// Feel free to generate a fancier colormap here
val colorRamp = ColorRamps.BlueToOrange
val histogram = tileRdd.histogram(colorRamp.numStops)
val colorMap = colorRamp.toColorMap(histogram)
val keyToPath = (k: SpatialKey) =>
s"s3://bucket/key/path/${zoom}/${k.col}/${k.row}.png"
tileRdd.map {
case (key, tile) => {
(key, tile.renderPng(colorMap).bytes)
}
}.saveToS3(keyToPath)
}
}