https://github.com/geotrellis/geotrellis-server
Tools for building raster processing and display services
https://github.com/geotrellis/geotrellis-server
geotrellis geotrellis-server maml map-algebra ogc tms wcs wms wmts
Last synced: about 2 months ago
JSON representation
Tools for building raster processing and display services
- Host: GitHub
- URL: https://github.com/geotrellis/geotrellis-server
- Owner: geotrellis
- License: apache-2.0
- Created: 2017-11-22T16:47:51.000Z (almost 8 years ago)
- Default Branch: main
- Last Pushed: 2024-05-14T12:39:46.000Z (over 1 year ago)
- Last Synced: 2025-05-14T11:51:01.757Z (5 months ago)
- Topics: geotrellis, geotrellis-server, maml, map-algebra, ogc, tms, wcs, wms, wmts
- Language: Scala
- Homepage:
- Size: 2.52 MB
- Stars: 74
- Watchers: 9
- Forks: 24
- Open Issues: 28
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# GeoTrellis Server
[](https://github.com/geotrellis/geotrellis-server/actions/workflows/ci.yml) [](http://search.maven.org/#search%7Cga%7C1%7com.azavea.geotrellis) [](https://oss.sonatype.org/content/repositories/snapshots/com/azavea/geotrellis/geotrellis-server-core_2.12/)
GeoTrellis Server is a set of components designed to simplify
viewing, processing, and serving raster data from arbitrary sources
with an emphasis on doing so in a functional style. It aims to ease
the pains related to constructing complex raster processing workflows
which result in TMS-based (z, x, y) and extent-based products.In addition to providing a story about how sources of imagery can be displayed
or returned, this project aims to simplify the creation of dynamic,
responsive layers whose transformations can be described in MAML
([Map Algebra Modeling Language](https://github.com/geotrellis/maml/)).### Getting Started with GeoTrellis Server
GeoTrellis Server is currently available for Scala 2.13 and 2.12.
To get started with SBT, simply add the following to your build.sbt file:
```scala
libraryDependencies += "com.azavea.geotrellis" %% "geotrellis-server-core" % ""
```### High level concepts
Imagine you've got a simple case class which is sufficient to identify
layers of imagery for an application you're working on.```scala
import java.net.URIcase class ImageryLayer(location: URI)
```Imagine further that you'd like to enable your application to compose these
layers together via map algebra to produce derived layers and that the
combinations can't be known at compile-time (users will be deciding
which - if any - map algebra to run). This is a job that GeoTrellis
server can radically simplify. Because we're dealing with behavior
specified at runtime, we need to evaluate program descriptions rather
than simple, first-order parameters - the task for which
[MAML](https://github.com/geotrellis/maml/) was written.```scala
// This node describes a `LocalAdd` on the values eventually
// bound to `RasterVar("test1")` and `RasterVar("test2")
val simpleAdd = Addition(List(RasterVar("test1"), RasterVar("test2")))// This describes incrementing every value in the eventually bound raster by 1
val plusOne = Addition(List(RasterVar("additionRaster1"), IntLit(1)))
```Because MAML encodes map alagebra transformations in data, actually
executing a MAML program for practical purposes can be difficult and
unintuitive. GeoTrellis server bridges this gap by providing a
typeclass-based means of extending source types in client applications
with the behaviors necessary to actually evaluate a MAML AST.The following example demonstrates what is required to generate
functions which produce extents provided MAML program descriptions. For
a more complete example, check out
[CogNode](example/src/main/scala/geotrellis/server/example/cog/CogNode.scala).
```scala
import io.circe._
import io.circe.syntax._
import io.circe.generic.semiauto._
import cats._
import cats.effect._
import com.azavea.maml.ast._
import com.azavea.maml.eval.BufferingInterpreter
import geotrellis.server._// This class points to a COG and specifies a band of interest
case class RasterRef(uri: URI, band: Int)// We need to provide some implicit evidence. Most applications can do this within companion objects
object RasterRef {
// reification means 'thingification', and that's what we're proving we can do here
implicit val rasterRefExtentReification: ExtentReification[RasterRef] = new ExtentReification[RasterRef] {
def extentReification(self: CogNode, buffer: Int)(implicit contextShift: ContextShift[IO]): (Extent, CellSize) => IO[Literal] = ???
}
// We can lean on circe's automatic derivation to provide an encoder
implicit val rasterRefEncoding: Encoder[RasterRef] = deriveEncoder[RasterRef]
}// A source from which MAML evaluation will be able to derive necessary artifacts
val reference = RasterRef("http://some.url.com", 1)// We need to key provided references based on the ID of the Var they'll replace
val parameters = Map("additionRaster1" -> reference)// This is an interpeter GT Server will use to roll up the tree + params to some result
val interpreter = BufferingInterpreter.DEFAULT// Not yet a result: we can use the result here to produce artifacts for different extent inputs
val tileEval = LayerExtent.apply(IO.pure(plusOne), IO.pure(parameters), interpreter)val targetExtent: Extent = ??? // Where should the tile come from?
val targetCellSize: CellSize = ??? // What resolution should the tile be?// Branch on Valid/Invalid and print some info about which branch we're on
tileEval(targetExtent, targetCellSize) map {
case Valid(tile) =>
println("we did it, a tile: (rows: ${tile.rows}, cols: ${tile.cols})")
case Invalid(err) =>
println("Ran into an error (${err.asJson}) during MAML evaluation of AST (${plusOne.asJson}) with params (${params.asJson})")
}
````LayerExtent` is joined by two other objects which organize evaluation
strategies for different products:- `LayerExtent`: Constructs functions that produce a `cats.data.Validated` instance
containing a `Tile` (given an extent) or else `MamlError`s. Requires
`ExtentReification` and `Encoder` evidence- `LayerTms`: Constructs functions that produce a `cats.data.Validated` instance
containing a `Tile` (given the tms Z, X, Y coordinates) or else
`MamlError`s. Requires `TmsReification` and `Encoder` evidence- `LayerHistogram`: Constructs functions that produce a `cats.data.Validated` instance
containing a `Histogram` or else `MamlError`s. Requires
`ExtentReification`, `Encoder`, and `HasRasterExtents` evidenceEach of these objects is a response to distinct needs encountered when
writing raster-based applications. Included in each object are methods
which encode several strategies for evaluating their products. The strategies
currently available are:
- `apply`: Takes parameters, a MAML AST, and a MAML `Interpreter` and evaluates accordingly- `generateExpression`: parameters, a function which will generate an AST based on the
parameters, and a MAML `Interpreter`- `curried`: Takes an AST and a MAML `Interpreter` (this method produces an
intermediate, curried, function which expects a parameter map to
evaluate)- `identity`: Evaluates a proven source without any MAML evaluation (useful for
quickly defining a static layer viewer or debugging implicit evidence behavior### Running an example
Three example servers are available which can be run through the provided
makefile. These examples have been implemented via [http4s](https://http4s.org/),
which has a pleasant, clean API and plays nicely with the
[cats](https://typelevel.org/cats/) and [cats-effect](https://typelevel.org/cats-effect/)
libraries.1. A server and simple UI that evaluates weighted overlays between
arbitrary COGs. This demo includes a simple UI, available at http://localhost:9000/ for a
```bash
./scripts/server --overlay
```2. Integrates GTServer components with application-specific persistence needs.
```bash
./scripts/server --persistence
```3. Illustrates GTServer evaluating a remote-sensing classic, the NDVI.
```bash
./scripts/server --ndvi
```