Reverse-geocoder microservice

Related tags

Geospatial geocoder
Overview

Docker GitHub Workflow Status Docker Image Version (latest semver)

Reverse Geocoder

This is a simple and very lightweight reverse geocoder for offline use. It's implemented in Rust and uses a k-d-tree to find the closest cities for a given coordinate. The recommended data set from GeoNames contains ~200,000 cities with a population of at least 500, but smaller datasets work fine if you require less accuracy.

Development is sponsored by Treestack GmbH.

How to use the docker image

Prerequisites

The image only contains a demo data set of a few cities. We chose not to include the full data file in the docker image, so both can be updated independently.

Download a cities500.zip from GeoNames and unpack it. You should now have a cities500.txt. If you require less accuracy and/or have limited resources, you can download any other citiesN.txt instead.

Run from command line:

$ docker run \
    -p 5353:5353 \
    -v $(pwd)/cities500.txt:/cities.txt \
    -e GEOCODER_BIND_ADDRESS=0.0.0.0:5353 \
    ghcr.io/treestack/geocoder:master

Run with Docker compose

docker-compose.yml:

version: "3.9"

services:
  geocoder:
    image: ghcr.io/treestack/geocoder:master
    ports:
      - "5353:5353"
    environment:
      GEOCODER_BIND_ADDRESS: 0.0.0.0:5353
    volumes:
      - "./cities500.txt:/cities.txt"

Run with Kubernetes (experimental)

There's a helm chart in the deploy directory, but it's haphazardly stitched together. Please feel free to create a PR if you have any suggestions.

helm install <name> deploy 

Configuration

You can configure the application with the following environment variables:

Parameter Description Default
GEOCODER_BIND_ADDRESS Bind address 127.0.0.1:5353
GEOCODER_LOGLEVEL Log level INFO
GEOCODER_DATA_FILE Data file name ./cities.txt
GEOCODER_WATCH_FOR_CHANGES Reload geocoder when data file changes* true
GEOCODER_ALLOW_ORIGIN CORS Access-Control-Allow-Origin header *

* Incredibly unreliable when the datafile is mounted as a docker volume.

Usage

Example call

curl "http://localhost:5353?lat=-48.875486&lng=-123.392519&results=1&details=true"

Request parameters

The microservice listens to all GET requests and supports the following query parameters:

Parameter Description Required Example
lat Latitude (WGS84, decimal) Yes -48.875
lng Longitude (WGS84, decimal) Yes -123.392
results Number of results, integer, defaults to 1 No 10
details Include details in response, boolean, defaults to false No true

Response

The response is a valid GeoJSON FeatureCollection. The feature's id is added as foreign members. The additional properties always includes the 'title' and distance to the given coordinates. Optionally you can add most columns from the geonames dataset by setting the details parameter to true:

Property Description
title The city's name
distanceToQuery Approx. distance to given coordinates in kilometres (assuming earth radius of exactly 6371 km).
admin1Code
admin2Code
admin3Code
admin4Code
countryCode ISO-3166 2-letter country code
cc2 alternative country codes
dem digital elevation model, srtm3 or gtopo30
elevation elevation in metres
featureCode Feature code. For a complete list, check here.
modificationDate Last modification date
population Population
timezone IANA timezone id

Example

{
	"type": "FeatureCollection",
	"features": [
		{
			"geometry": {
				"coordinates": [
					78.25628662109375,
					28.95911979675293
				],
				"type": "Point"
			},
			"id": 1272983,
			"properties": {
				"distanceToQuery": 6,
				"title": "Dhanaura"
			},
			"type": "Feature"
		},
		{
			"geometry": {
				"coordinates": [
					78.23455810546875,
					28.92694091796875
				],
				"type": "Point"
			},
			"id": 1278036,
			"properties": {
				"distanceToQuery": 8,
				"title": "Bachhraon"
			},
			"type": "Feature"
		}
	]
}

Resource use and Performance

The final docker image has a size of only 8 MB, memory usage depends on the used data set:

Dataset Cities Approx. mem. usage
cities500.txt 199,606 ~160 MiB
cities5000.txt 53,268 ~45 MiB
cities15000.txt 26,457 ~25 MiB

With cities500.txt, response time is consistently < 10 ms, measured on a M1 mac:

$ hyperfine --warmup 3 'curl "http://localhost:5353?lat=-48.875486&lng=-123.392519&results=1"'
Benchmark 1: curl "http://localhost:5353?lat=-48.875486&lng=-123.392519&results=1&details=true"
Time (mean ± σ):       5.8 ms ±   0.9 ms    [User: 1.5 ms, System: 1.9 ms]
Range (min … max):     4.1 ms …   9.3 ms    374 runs

Development

Run locally

$ cargo run web

Build local docker image

docker build -t treestack/geocoder:0 .
You might also like...
Cloud-Based Microservice Performance Profiling Tool

Revelio Systems Revelio Systems is a student startup sponsored by UT Austin's Inventors Program in partnership with Trend Micro. Team: Tejas Saboo, So

Playing with web dev in Rust. This is a sample Rust microservice that can be deployed on Kubernetes.

Playing with web dev in Rust. This is a sample Rust microservice that can be deployed on Kubernetes.

Small microservice to render Lottie animation files via an http REST API.

Lottie Renderer Service Small microservice to render Lottie animation files via an http REST API. Run via docker docker run -p 8080:8080 ghcr.io/mikbo

Microservice written in Rust from scratch.

Simple-ms This Repo This repository contains code for a microservice written in Rust using the Tokio Axum framework. This code is used in MongoDB's wo

A template project for building a database-driven microservice in Rust and run it in the WasmEdge sandbox.

Secure & lightweight microservice with a database backend In this repo, we demonstrate a microservice written in Rust, and connected to a MySQL databa

µFUZZ: Redesign of Parallel Fuzzing using Microservice Architecture

mufuzz, a parallel fuzzing framework TODO: Add reference Build Install cargo and protoc curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Simple Event-Driven Microservice Architecture in Rust

Simple Event-Driven Microservice Architecture in Rust is an open-source project showcasing the simplicity and efficiency of building microservices in Rust. This minimalistic project demonstrates an e-commerce backend system, featuring just two microservices: Catalog and Order.

Sōzu HTTP reverse proxy, configurable at runtime, fast and safe, built in Rust. It is awesome! Ping us on gitter to know more

Sōzu · Sōzu is a lightweight, fast, always-up reverse proxy server. Why use Sōzu? Hot configurable: Sozu can receive configuration changes at runtime

Utility for working with reverse DNS

RDNS RDNS is a small Rust CLI utility for performing single and bulk reverse DNS (PTR) lookups. Usage RDNS 0.1.0 Joe Banks [email protected] Utilities for

 RedLizard - A Rust TCP Reverse Shell with SSL
RedLizard - A Rust TCP Reverse Shell with SSL

RedLizard - A Rust TCP Reverse Shell with SSL RedLizard Rust TCP Reverse Shell Server/Client This is a reverse shell in Rust called RedLizard, basical

A rust implementation of the reverse-engineered Glorious mouse protocol

gloryctl This project is an implementation of the vendor-specific HID protocol in use by Glorious mice used to configure parameters such as DPI profil

A high performence Socks5 proxy server with bind/reverse support implementation by Rust.

rsocx A high performence Socks5 proxy server with bind/reverse support implementation by Rust Features Async-std No unsafe code Single executable Linu

Interactive bind/reverse PTY shell with Windows&Linux support implementation by Rust.
Interactive bind/reverse PTY shell with Windows&Linux support implementation by Rust.

Cliws Lightweight interactive bind/reverse PTY shell with Windows&Linux support implementation by Rust. Features WebSocket Full pty support: VIM, SSH,

A firewall reverse proxy for preventing Log4J (Log4Shell aka CVE-2021-44228) attacks.
A firewall reverse proxy for preventing Log4J (Log4Shell aka CVE-2021-44228) attacks.

log4jail 🛡️ A fast firewall reverse proxy with TLS (HTTPS) and swarm support for preventing Log4J (Log4Shell aka CVE-2021-44228) attacks. 📖 Table of

A fast and stable reverse proxy for NAT traversal, written in Rust
A fast and stable reverse proxy for NAT traversal, written in Rust

rathole A fast and stable reverse proxy for NAT traversal, written in Rust rathole, like frp, can help to expose the service on the device behind the

This article is about the unsound api which I found in owning_ref. Owning_ref is a library that has 11 million all-time downloads and 60 reverse dependencies.

Unsoundness in owning_ref This article is about the unsound api which I found in owning_ref. Owning_ref is a library that has 11 million all-time down

Eldrow: Wordle in Reverse

Eldrow: Wordle in Reverse Setup First you are gonna have to get Rust at rust-lang.org. Then, you will need to have nodejs installed. For the WebAssemb

A lightweight Rust reverse proxy.

Brachyura A reverse proxy, which I am primarily using as a Rust / Hyper learning project. I utilize Nginx as part of my home lab providing reverse pro

Reverse proxy for HTTP microservices and STDIO. Openfass watchdog which can run webassembly with wasmer-gpu written in rust.

The of-watchdog implements an HTTP server listening on port 8080, and acts as a reverse proxy for running functions and microservices. It can be used independently, or as the entrypoint for a container with OpenFaaS.

Releases(v0.2.0)
  • v0.2.0(Apr 25, 2023)

    Changes

    • Response is now a FeatureCollection This adds very little overhead and makes using the response a bit easier.
    • Response contains proper CORS header, content is configurable.
    • Removed quota configuration again. Seemed like a good idea, but definitely out-of-scope here. Rate limiting should be done in a load balancer.
    • Docker build uses cargo-chef now to better cache dependencies.
    • .env file is not loaded anymore.
    • Response contains a version header now.
    • The initial load will fail now for an invalid data file, not skip the invalid entry silently.
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Apr 24, 2023)

Owner
Treestack GmbH
Treestack GmbH
A fast, offline, reverse geocoder

Rust Reverse Geocoder A fast reverse geocoder in Rust. Inspired by Python reverse-geocoder. Links Crate Changelog Latest Docs v2.0 Docs v1.0 Docs Desc

Grant Miner 82 Dec 3, 2022
A set of tools for generating isochrones and reverse isochrones from geographic coordinates

This library provides a set of tools for generating isochrones and reverse isochrones from geographic coordinates. It leverages OpenStreetMap data to construct road networks and calculate areas accessible within specified time limits.

null 3 Feb 22, 2024
An fast, offline reverse geocoder (>1,000 HTTP requests per second) in Rust.

Rust Reverse Geocoder A fast reverse geocoder in Rust. Inspired by Python reverse-geocoder. Links Crate 2.0.0 Docs 1.0.1 Docs Description rrgeo takes

Grant Miner 91 Dec 29, 2022
A fast, offline reverse geocoder in Python

Reverse Geocoder A Python library for offline reverse geocoding. It improves on an existing library called reverse_geocode developed by Richard Penman

Ajay Thampi 1.8k Dec 26, 2022
A fast, offline, reverse geocoder

Rust Reverse Geocoder A fast reverse geocoder in Rust. Inspired by Python reverse-geocoder. Links Crate Changelog Latest Docs v2.0 Docs v1.0 Docs Desc

Grant Miner 82 Dec 3, 2022
rpcx microservice framework in Rust

rpcx-rs Rust library for rpcx rpc/microservice framework. Use the simplest style to explore Rust function as cross-platform rpc services. If you can w

smallnest 105 Dec 19, 2022
A super-lightweight Lua microservice (toy) framework.

Hive A super-lightweight microservice (toy) framework written in Rust. It uses Lua as interface to provide simple, fun developing experience and fast

Eric Long 39 Aug 14, 2022
Autumn is the microservice responsible for storing files and attachments.

Autumn Description Autumn is the microservice responsible for storing files and attachments. Features: Save files locally or on S3. Support for differ

Revolt 30 Dec 26, 2022
💫 Small microservice to handle state changes of Kubernetes pods and post them to Instatus or Statuspages

?? Kanata Small microservice to handle state changes of Kubernetes pods and post to Instatus ?? Why? I don't really want to implement and repeat code

Noel ʕ •ᴥ•ʔ 4 Mar 4, 2022
HTTP microservice using Axum and Reqwest to request the Google Translate TTS endpoint without rate limits

HTTP microservice using Axum and Reqwest to request the Google Translate TTS endpoint without rate limits

Gnome! 5 Oct 5, 2022