GeoTrellis

GeoTrellis

    ›Raster

    Getting Started

    • Getting Started
    • Reading Scala

    Vector

    • Vectors
    • Extents
    • Projection

    Raster

    • Rasters
    • Tiles
    • RasterSource
    • Rendering Images

    Layer

    • Layer Model

    Spark

    • Basics
    • Tile Layer RDD
    • Indexed Layers

    RasterSource

    RasterSource interface is fundamental raster input interface in GeoTrellis. It abstracts over file format, access schema, and reader implementation.

    As of GeoTrellis 3.0 implementations exist for:

    • GeoTiffRasterSource: GeoTrellis GeoTiff Reader
    • GeoTrellisRasterSource: GeoTrellis Indexed Layers
    • GDALRasterSource: GDAL through gdal-warp-bindings

    Metadata

    RasterSources are lazy, performing minimum I/O on instantiation. Raster metadata is read on demand and implementations are expected to cache it for repeated access through available fields.

    import geotrellis.raster.geotiff.GeoTiffRasterSource
    
    val source = GeoTiffRasterSource("https://geotrellis-demo.s3.amazonaws.com/data/aspect.tif")
    // source: GeoTiffRasterSource = geotrellis.raster.geotiff.GeoTiffRasterSource@1ff59a11
    
    source.extent
    // res0: geotrellis.vector.Extent = Extent(
    //   630000.0,
    //   215000.0,
    //   645000.0,
    //   228500.0
    // )
    source.crs
    // res1: geotrellis.proj4.CRS = lcc-CS
    source.cellType
    // res2: geotrellis.raster.package.CellType = FloatUserDefinedNoDataCellType(
    //   -9999.0F
    // )
    source.dimensions
    // res3: geotrellis.raster.Dimensions[Long] = Dimensions(1500L, 1350L)
    source.metadata.attributes
    // res4: Map[String, String] = Map("AREA_OR_POINT" -> "AREA")
    

    Windows

    GeoTrellis is designed around the assumption that rasters may be large and need to be split for parallel processed. Therefore the primary way to read with RasterSource is through windows into the source raster. When the file format supports it, like Cloud Optimized GeoTiff, these reads can be very efficient.

    • Result of a window read is an Option[Raster[MultibandTile]]
    • When the query extent does not intersect the source raster None will be returned
    • Reads will be snapped to the pixel grid of the source raster, that may differ from the query extent
    • Reads are not buffered when query extent partially covers the source raster
    import geotrellis.raster._
    
    val bbox = source.extent.buffer(-source.extent.width/4,  -source.extent.height/4)
    // bbox: geotrellis.vector.Extent = Extent(
    //   633750.0,
    //   218375.0,
    //   641250.0,
    //   225125.0
    // )
    val centerWindow = source.read(bbox)
    // centerWindow: Option[Raster[MultibandTile]] = Some(
    //   Raster(
    //     geotrellis.raster.ArrayMultibandTile@62c48c77,
    //     Extent(633750.0, 218370.0, 641250.0, 225130.0)
    //   )
    // )
    centerWindow.get.dimensions
    // res5: Dimensions[Int] = Dimensions(750, 676)
    
    val leftCorner = source.read(GridBounds(0L, 0L, 255L, 255L))
    // leftCorner: Option[Raster[MultibandTile]] = Some(
    //   Raster(
    //     geotrellis.raster.ArrayMultibandTile@1e78bde4,
    //     Extent(630000.0, 225940.0, 632560.0, 228500.0)
    //   )
    // )
    leftCorner.get.dimensions
    // res6: Dimensions[Int] = Dimensions(256, 256)
    

    Additional read methods readExtents and readBounds are provided for reading multiple windows at once. This allows the RasterSource implementation to perform optimizations for the read sequence. For instance GeoTiffRasterSource ensures that each GeoTiff segment is read only once, even if it contributes to multiple windows. This optimization is not guaranteed for all implementations of RasterSource.

    Views

    RasterSource provides a way to perform a lazy resampling and reprojection. These operations produce a new RasterSource instance which is a lazy view of the source raster. Both metadata and results of read function are consistent with this the view. This feature is similar to GDAL VRT, indeed GDALRasterSource is backed by GDAL VRT.

    import geotrellis.proj4._
    import geotrellis.vector._
    import geotrellis.raster.resample.{ NearestNeighbor }
    
    val wgs84Source = source.reproject(LatLng, method = NearestNeighbor)
    // wgs84Source: RasterSource = geotrellis.raster.geotiff.GeoTiffReprojectRasterSource@23e609ac
    wgs84Source.extent
    // res7: Extent = Extent(
    //   -78.7746204948163,
    //   35.687534170395224,
    //   -78.60827512493357,
    //   35.80960938344992
    // )
    
    val w1 = wgs84Source.read(Extent(-78.68, 35.76, -78.65, 35.78))
    // w1: Option[Raster[MultibandTile]] = Some(
    //   Raster(
    //     geotrellis.raster.ArrayMultibandTile@2da5fc4d,
    //     Extent(
    //       -78.68004798889035,
    //       35.759920477633685,
    //       -78.64998926808794,
    //       35.78006186538224
    //     )
    //   )
    // )
    
    w1.get.dimensions
    // res8: Dimensions[Int] = Dimensions(294, 197)
    

    Often the view may need to be matched to a specific resolution and pixel offset. This is a requirement to be able to combine two rasters in a map algebra operation.

    val minuteGrid = GridExtent(Extent(-180, -90, 180, 90), cols = 360*60, rows = 180*60)
    // minuteGrid: GridExtent[Int] = GridExtent(Extent(-180.0, -90.0, 180.0, 90.0),CellSize(0.016666666666666666,0.016666666666666666),21600x10800)
    
    val w2 = source.reprojectToGrid(LatLng, minuteGrid.toGridType[Long], NearestNeighbor)
    // w2: RasterSource = geotrellis.raster.geotiff.GeoTiffReprojectRasterSource@6b446aba
    
    w2.dimensions
    // res9: Dimensions[Long] = Dimensions(11L, 8L)
    

    Read Tiles

    When a raster needs to be read by tile keys from a known layout LayoutTileSource can be used. LayoutTileSource imposes tile layout of LayoutDefinition (see layer model) on an instance of RasterSource.

    Lets read our raster as a web tiler would, using tile grid for TMS zoom level 14:

    import geotrellis.layer._
    
    val scheme = ZoomedLayoutScheme(WebMercator, 256)
    // scheme: ZoomedLayoutScheme = geotrellis.layer.ZoomedLayoutScheme@30886dab
    val level = scheme.levelForZoom(14)
    // level: LayoutLevel = LayoutLevel(
    //   14,
    //   LayoutDefinition(
    //     Extent(
    //       -2.0037508342789244E7,
    //       -2.0037508342789244E7,
    //       2.0037508342789244E7,
    //       2.0037508342789244E7
    //     ),
    //     TileLayout(16384, 16384, 256, 256)
    //   )
    // )
    
    val tileSource = LayoutTileSource.spatial(
      source = source.reprojectToGrid(WebMercator, level.layout),
      layout = level.layout)
    // tileSource: LayoutTileSource[SpatialKey] = geotrellis.layer.LayoutTileSource@23b0a97f
    
    tileSource.keys.take(3)
    // res10: Set[SpatialKey] = Set(
    //   SpatialKey(4609, 6448),
    //   SpatialKey(4609, 6444),
    //   SpatialKey(4607, 6449)
    // )
    
    tileSource.read(SpatialKey(4609, 6448))
    // res11: Option[MultibandTile] = Some(
    //   geotrellis.raster.ArrayMultibandTile@21f56ed0
    // )
    
    ← TilesRendering Images →
    • Metadata
    • Windows
    • Views
    • Read Tiles
    GeoTrellis
    Community
    User ShowcaseGitter.im
    More
    BlogStar
    Copyright © 2020 Azavea