# GeoTrellis turns raster analysis into typed Scala and Spark jobs

> GeoTrellis is a Scala library and framework from LocationTech for reading, writing and operating on geospatial raster and vector data, with MapAlgebra, Spark helpers and store integrations for S3, HBase, Cassandra and Accumulo. It suits teams doing large-scale raster analysis, and it is a JVM library with a wide module surface.

**locationtech/geotrellis** — GeoTrellis is a geographic data processing engine for high performance applications.

- Repository: https://github.com/locationtech/geotrellis
- Website: http://geotrellis.io
- Stars: 1,377 · Forks: 357
- Language: Scala
- License: NOASSERTION
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/locationtech-geotrellis

## A library of typed tiles rather than a raster toolkit

GeoTrellis is a Scala library and framework that provides APIs for reading, writing and operating on geospatial raster and vector data, and it also provides helpers for these same operations in Spark and for performing MapAlgebra operations on rasters.

The concept that makes it a library rather than a toolkit is the tile. A raster in GeoTrellis is not a file handle or an image object, it is a typed value: an IntArrayTile of a specified width and height, with the no-data value as a distinguished member of the type system rather than a magic number. The README's hello raster example makes this concrete.

The example builds a tile from an array of integers with a NODATA sentinel, which prints as -2147483648:

```scala
val nd = NODATA
nd: Int = -2147483648

val input = Array[Int](
     nd, 7, 1, 1,  3, 5, 9, 8, 2,
      9, 1, 1, 2,  2, 2, 4, 3, 5,
      3, 8, 1, 3,  3, 3, 1, 2, 2,
      2, 4, 7, 1, nd, 1, 8, 4, 3)

val iat = IntArrayTile(input, 9, 4)  // 9 and 4 here specify columns and rows
```

And then it is rendered as ASCII art, which the README says is mostly useful when you are working with small tiles which can be taken in at a glance:

```scala
iat.renderAscii(AsciiArtEncoder.Palette.STIPLED)
res0: String =
∘█  ▚▜██▖
█  ▖▖▖▜▚▜
▚█ ▚▚▚ ▖▖
▖▜█ ∘ █▜▚
```

That ASCII rendering is a small thing that tells you a lot. It exists because a raster operation that is wrong in a subtle way is nearly impossible to debug from numeric output alone, and printing a tile lets you see the result. It is a debugging affordance built into the data type.

The project is released under the Apache 2 Licence, hosted under the LocationTech organisation, with the project site at geotrellis.io, documentation on ReadTheDocs, and a Gitter channel for questions.

## Focal operations take a neighbourhood value, not a magic number

The MapAlgebra half of the library is the part that distinguishes GeoTrellis from a raster I/O binding, and the example walks through it in a way that shows the API shape.

A focal operation takes a neighbourhood value, and the neighbourhood is itself a typed object with a printable form:

```scala
val focalNeighborhood = Square(1)  // a 3x3 square neighborhood
focalNeighborhood: geotrellis.raster.op.focal.Square =
 O  O  O
 O  O  O
 O  O  O

val meanTile = iat.focalMean(focalNeighborhood)
meanTile: geotrellis.raster.Tile = DoubleArrayTile([D@7e31c125,9,4)
```

The comment is worth pausing on. Square(1) is a 3x3 square, and the parameter 1 is a radius, so the neighbourhood is a value with a meaning rather than a hardcoded kernel. A kernel of a different shape is a different value, and the type prints its own shape, so a mistake in a focal operation is visible in the REPL output rather than only in the numbers.

The result of a focal operation is a different tile type, a DoubleArrayTile from an IntArrayTile, because the mean of integers is not an integer. The type change is the type system doing the work, and it propagates: a chain of operations whose types do not line up will not compile.

The README then checks the arithmetic by hand, with the corner cell whose neighbours are the no-data value, 1 and 7, giving 5.666666666666667, and the comment says it should equal (1 + 7 + 9) / 3. That is the documentation demonstrating correctness rather than asserting it.

MapAlgebra as a term comes from a lineage of raster analysis systems, and GeoTrellis's contribution is to make those operations ordinary typed method calls on tiles, so a pipeline is a chain of expressions with no external expression language to learn.

## Twenty-five published packages, and one of them is the entry point

The module list in the README is long, and it is organised around a clear idea: a core of data types, a set of store integrations, and optional bridges to the rest of the geospatial ecosystem.

The recommendation for a newcomer is to start with geotrellis-raster, which is described as raster data types and operations, including MapAlgebra. The rest of the list divides into three groups.

The store integrations come in pairs, a plain one and a Spark one, for each of four backends: geotrellis-accumulo and geotrellis-accumulo-spark for Accumulo, geotrellis-cassandra and geotrellis-cassandra-spark for Cassandra, geotrellis-hbase and geotrellis-hbase-spark for HBase, and geotrellis-s3 and geotrellis-s3-spark for Amazon S3. The pairing is the design, because the same data model should be usable on a single node and in a distributed job without rewriting the analysis.

The bridges to other geospatial software are geotrellis-geotools for conversions to and from GeoTools vector and raster data, geotrellis-gdal for GDAL bindings, geotrellis-shapefile for reading ESRI Shapefiles into GeoTrellis data types via GeoTools, and geotrellis-proj4 for coordinate reference systems and reprojection as a Scala wrapper around Proj4j.

The remaining modules fill out the framework. geotrellis-spark is described as geospatially enabling Spark and providing primitives for external data stores, and geotrellis-spark-pipeline is a DSL for geospatial ingest jobs using GeoTrellis and Spark. geotrellis-vector is vector data types and operations extending JTS, so the vector side inherits the JTS geometry model rather than inventing one. geotrellis-vectortile is experimental vector tile support, including reading and writing, and it is the one module the README explicitly labels experimental.

There are also three testkit packages, for raster, vector and spark code, plus geotrellis-layer for datatypes describing sets of rasters, geotrellis-macros for performance optimisations of GeoTrellis operations, geotrellis-store for abstract storage interfaces with local and Hadoop filesystem implementations, and geotrellis-util.

The repository layout mirrors the module list, with a directory per module and a build.sbt at the root, so the physical structure and the published artefact list are the same thing.

## Scala 2.13 and 3 on Spark 4.2.x, published with a versioned artifact

The getting started section is short and tells you what you need to know about the current state.

GeoTrellis is currently available for Scala 2.13 and 3, using Spark 4.2.x. That combination is the current line, and the version numbers move together, which is the usual arrangement for a library with a Spark dependency: the Spark version is a hard constraint rather than a soft preference.

The SBT dependency is one line:

```scala
libraryDependencies += "org.locationtech.geotrellis" %% "geotrellis-raster" % "<latest version>"
```

The %% is the Scala version cross-build operator, which is why the same coordinate resolves to the 2.13 and 3 artefacts.

To get the latest SNAPSHOT, RC or milestone build, the README says to add resolvers, and it gives two options. The first is the Maven Central snapshots repository, and the second is the Eclipse repositories for releases and snapshots:

```scala
// or eclipse snapshots
resolvers ++= Seq(
  "eclipse-releases" at "https://repo.eclipse.org/content/groups/releases",
  "eclipse-snapshots" at "https://repo.eclipse.org/content/groups/snapshots"
)
```

The Eclipse repositories are a legacy of the project's history, since the artifact coordinates are org.locationtech.geotrellis and the group moved to the LocationTech organisation, and the README keeps the older path working for people who need a pre-release.

The Maven Central badge points at geotrellis-spark for Scala 2.12, which is a stale badge rather than a stale library, and there is a separate snapshots link for the 2.13 line. Older releases are available from the locationtech-releases repository, which the README links as the complete list of packages and versions.

The project publishes to Maven Central, and the README points to a module hierarchy page in the documentation as the more complete feature list, suggesting that if you are looking for a specific feature or operation you should search there or ask on Gitter.

## A LocationTech project with a 3.8 line and an Apache licence file

The governance and packaging details are worth reading, because they tell you what kind of dependency this is.

The repository sits under the locationtech organisation on GitHub, and there is a .locationtech/ directory in the tree, so the project follows an organisation-level release and governance process rather than a single maintainer's preferences. The licence is recorded as Apache-2.0, with the LICENSE file in the repository as the authoritative text, and there is a notice.html and about.html alongside it, which are the standard Apache release artefacts. This is a licensing statement rather than legal advice.

The release record is steady. The recent versions are 3.8.1 on 2026-06-22, 3.8.0 on 2025-04-23 and 3.7.1 on 2024-01-08, and the last push was on 2026-10-10, so the repository is not archived and work continues between releases.

The gap between 3.7.1 in January 2024 and 3.8.0 in April 2025 is worth noting, because a raster library has to track its dependencies. GDAL, Proj4j, JTS and Spark all move, and a release that upgrades them is a release with a large surface for behavioural change, which is why the minor version line moves less often than the patch line.

The documentation setup is thorough. There is a ReadTheDocs badge for the latest documentation, Scaladocs for the master branch, a docs/ folder with further examples and use cases, and a separate docs-mdoc/ directory for the documentation examples, plus doc-examples/. The CHANGELOG.md at the root is the version-by-version record, and a SECURITY.md is present for reporting vulnerabilities.

Contributing is governed by a CLA, which the README mentions, and the conditions live in docs/CONTRIBUTING.rst. The project also uses CircleCI, judging from the .circleci/ directory, and has a .sbtopts and .jvmopts for the build.

The bench/ directory is a good sign for a performance-focused project. A library whose selling point is high performance applications should have a benchmark suite in the tree, and having it as a first-class module rather than an external project means the benchmarks are run against the same build the tests are.

## Conclusion

Adopt GeoTrellis if you are already on the JVM and doing raster analysis at scale, and you want typed tile operations, MapAlgebra and distributed execution over a data lake rather than a bespoke set of raster scripts. Do not adopt it for a one-off analysis of a handful of GeoTIFFs, because the module surface and the Spark dependency are heavy for that. Before you start, check the Scala and Spark versions, since the README says GeoTrellis is currently available for Scala 2.13 and 3 using Spark 4.2.x, and start with geotrellis-raster, which the README recommends for newcomers.

## FAQ

### What is GeoTrellis?

It is a Scala library and framework that provides APIs for reading, writing and operating on geospatial raster and vector data. It also provides helpers for the same operations in Spark and for performing MapAlgebra operations on rasters, and it is released under the Apache 2 License.

### How do I add GeoTrellis to an SBT build?

Add libraryDependencies += "org.locationtech.geotrellis" %% "geotrellis-raster" % "<latest version>" to your build.sbt. The %% cross-build operator is what resolves the artifact for Scala 2.13 or 3, since GeoTrellis is currently available for both using Spark 4.2.x.

### What is MapAlgebra in GeoTrellis and how are focal operations written?

MapAlgebra is the set of raster operations GeoTrellis provides. A focal operation takes a typed neighbourhood value rather than a hardcoded kernel, so Square(1) is a 3x3 square neighbourhood, and the neighbourhood value prints its own shape so mistakes are visible in the REPL. The result of a focal operation carries a different tile type, an IntArrayTile becoming a DoubleArrayTile for a mean.

### Which data stores does GeoTrellis integrate with?

There are paired packages for four stores, each with a plain and a Spark variant: geotrellis-accumulo and geotrellis-accumulo-spark, geotrellis-cassandra and geotrellis-cassandra-spark, geotrellis-hbase and geotrellis-hbase-spark, and geotrellis-s3 and geotrellis-s3-spark. There are also bridges for GDAL, GeoTools, Shapefiles and Proj4j.

### Which version of GeoTrellis should I use?

The recent releases are 3.8.1 on 2026-06-22, 3.8.0 on 2025-04-23 and 3.7.1 on 2024-01-08. The README says GeoTrellis is currently available for Scala 2.13 and 3 using Spark 4.2.x, and older releases are listed at the locationtech-releases repository.

## Sources

- [Issues](https://github.com/locationtech/geotrellis/issues)
- [locationtech/geotrellis on GitHub](https://github.com/locationtech/geotrellis)
- [Project website](http://geotrellis.io)
- [README](https://github.com/locationtech/geotrellis/blob/master/README.md)
- [Releases](https://github.com/locationtech/geotrellis/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/locationtech-geotrellis
