My helpful screenshot

In a previous post I presented the jts-discretizer, a small project able to approximate geometries with geo-hashes. Now it’s the time to see it in action: we will work in Scala on a dataset of country borders(multi-polygons) and see how to approximate country surfaces with geo-hashes.

The original dataset

We will use borders provided by Natural Earth. A simplified version of this dataset can be found at borders_wkt.csv, having the following columns:

  • continent
  • country name
  • fips country code (-99 if not present in the Natural Earth dataset)
  • iso country code (-99 if not present in the Natural Earth dataset)
  • border multi-polygon as WKT


  "io.github.adrianulbona" % "jts-discretizer" % "0.1.0"
  "com.github.tototoshi" %% "scala-csv" % "1.3.4"

Load the dataset

case class Id(continent: String, name: String, fips: String, iso: String) {
    def toList: List[String] = List(continent, name, fipsCode, isoCode)
case class Border(id: Id, wkt: String)

def read(): List[Border] = {
    val reader = File("data/borders_wkt.csv"))
    try {
            case List(continent, name, fips, iso, wkt)
                => Border(Id(continent, name, fips, iso), wkt)
    finally reader.close()

Discretize multi-polygons

case class Surface(country: Id, geoHashes: Set[GeoHash]) {
    def toList: List[String] =
        country.toList :+",")

def discretize(precision: Int)(border: Border): Surface = {
    val geometry = new WKTReader().read(border.wkt)
    val refTime = currentTimeMillis()
    val geoHashes = new DiscretizerFactoryImpl()
        .apply(geometry, precision).asScala.toSet
    val duration = currentTimeMillis() - refTime
    println(s"Discretized ${} in $duration ms.")
    Surface(, geoHashes)

Write surface approximations

def write(discretizations: List[Surface]): Unit = {
    val writer = open(new File(s"data/countries_discretized.csv"))
    try {
    finally writer.close()

Putting all together

val precision = 5
val surfaces read()





Complete SBT project at