GeoGeometry is a set of algorithms and functions for manipulating geo hashes and geometric shapes with geo coordinates.
GeoGeometry started out as a simple side project while I was building a startup in 2012. The key feature I needed at time was a list of geohashes that cover a particular geo shape. This is a nice thing to be able to do if you want to build search engine functionality and want to implement geospatial search. Over time, I added algorithms to solve various geometric problems. Mostly these are well known & documented algorithms of course. But it is nice to have some simple library of implementations for these things. I still maintain this library; especially since I became CTO of FORMATION where we use it with our indoor maps for things like geofences, geo-referencing coordinates from various location providers, etc.
I initially used Java for this and over time added several implementations of common geometry algorithms. In 2019, after not touching this project for years, I ported the entire code base to Kotlin.
This is a Kotlin multi-platform distribution with packages for -jvm
and -js
(currently) and several other platforms. Currently,
multi-platform and multi-module does not work with jitpack.io
. You can get this library via them but if that doesn't work,
you can also try to pull from my website as described below. There's an open bug for this.
As a workaround, I currently distribute jars via our own maven repo:
repositories {
mavenCentral()
maven { url = uri("https://maven.tryformation.com/releases") }
}
and then add the dependency :
implementation("com.github.jillesvangurp:geogeometry:<VERSION>")
You can find the latest version in the releases section.
For a few of the algorithms in this code base, I've adapted / been inspired by code from others. This work would not be possible without that and I try to credit any such sources in the code base.
GeoGeometry class with lots of functions that allow you to:
GeoHashUtils class with methods that allow you to:
Geojson classes are provided that allow you to easily work with GeoJson, which just like this library uses arrays of doubles as the core primitive. We use kotlinx.serialization for parsing and serializing this so this works across platforms as well!
I put quite a bit of effort in doing code archeology to combine bits and pieces of various old Java implementations for this. Lots of edge cases and "you just have to know why" bits of code. As a consequence, I have some nice robust tests around this and all seems to work.
I used this amazing Coordinates converter to verify my converters. Also, I use randomized points to ensure round trip conversions end up being close to where they should be. Feedback and pull requests to improve this further are welcome
A geo hash is a representation of a coordinate that interleaves the bit representations of the latitude and longitude and base32 encodes the result. This string representation has a very useful property: geo hashes of nearby coordinates will have the same prefix. As is observed in this blog post: http://blog.notdot.net/2009/11/Damn-Cool-Algorithms-Spatial-indexing-with-Quadtrees-and-Hilbert-Curves, geo hashes effectively encode the path to a leaf in a quad tree.
Geohashes are super useful if you are building e.g. search engines. Though if you are, there are better data structures such as Quad Trees or BKD Trees that Elasticsearch uses in more recent versions.
Here's a simple example of the hashes for a concave polygon of Berlin rendered on a map (courtesy of geojson.io). These hashes are calculated with the algorithm in GeoHashUtils
. You could put these hashes into a database or search engine to implement polygon search.
[longitude,latitude]
order in geojson arrays vs. the latitude, longitude order when not using arrays. This is based on the (unfortunate) geojson convention of specifying longitude before latitude in arrays. When not using arrays, I use latitude followed by longitude, just like everyone else.It's a gradle project. So, checking it out and doing a gradle build
should do the trick.
Note. this is a kotlin multi-platform build, and currently it produces a JavaScript build as well as a jvm jar. Adding IOS native and other platforms should be straightforward as well. The project has no run time dependencies beyond the standard kotlin library.
Like all my other projects, this project is licensed under the so-called MIT license.
However, GeoHashUtils
was copied and adapted from Apache Lucene (a long time ago) and I have retained the Apache License for that file, as required in that license. The rest of this repository is MIT licensed. Both licenses are compatible and should also pose no issues when used with software under most other OSS licenses.
For more details see the LICENSE file