[HN Gopher] Show HN: Offline tiles and routing and geocoding in ...
___________________________________________________________________
Show HN: Offline tiles and routing and geocoding in one Docker
Compose stack
Hi HN, I'm building Corviont, a self-hosted offline maps appliance
(tiles + routing + search) for edge/on-prem devices. Hosted demo
(no install): https://demo.corviont.com/ Self-host (Docker Compose
repo): https://github.com/corviont/monaco-demo Docs:
https://www.corviont.com/docs What's inside: -
Vector tiles served locally (PMTiles) - Routing served
locally (Valhalla) - Offline geocoding/search + reverse
(SQLite Nominatim-based index) - MapLibre UI wired to the
local endpoints After the initial image + data pulls, it runs
fully offline (no external map/routing/geocoding API calls). Next
(if people need it): a signed on-device updater for regional
datasets (verify - atomic swap - reload). I'd love feedback: where
offline maps/routing/search matters for you, and what constraints
bite (hardware, fleet size, update windows, regions, deployment
style).
Author : packet_mover
Score : 70 points
Date : 2026-01-03 15:55 UTC (7 hours ago)
(HTM) web link (www.corviont.com)
(TXT) w3m dump (www.corviont.com)
| bikelang wrote:
| This is super cool. I've been kicking around an idea for ages
| regarding tile-based routing that I think would be excellent for
| offline routing. You could leverage the quadtree aspect of tiling
| to encapsulate faster, direct routes (ie highways) and as you go
| to deeper zoom levels you'd unlock small roads - even down to
| pathways. This keeps your in-memory graph small while traversing
| large distances (which would just be highways anyways) and once
| you eliminated most of the distance your remaining graph
| traversal on local roads would be small
| krapht wrote:
| What you suggested has been done before - you might find a
| review of the literature fun if this sort of thing interests
| you, even if academic papers are pretty dry reading normally.
| tomaskafka wrote:
| Also game engines need to do painting very fast
| packet_mover wrote:
| That's a really interesting framing - you're basically
| describing hierarchical routing / "zoom-level" graphs: do the
| long leg on a coarse network (highways), then refine locally as
| you get closer to origin/destination.
|
| FWIW, Valhalla already does a version of this: it partitions
| the routing graph into hierarchical tiles and runs with
| multiple hierarchy levels (highway / arterial / local)
| specifically to keep search + in-memory working set smaller on
| long routes: https://valhalla.github.io/valhalla/tiles/
|
| The "quadtree tile unlock" mental model is a nice way to think
| about it though - if you have a favorite paper / implementation
| that leans harder into the tiling aspect, I'd love a pointer.
| I'm currently focused on packaging + offline data consistency,
| but routing performance on constrained edge boxes is definitely
| a core constraint I care about.
| michaelt wrote:
| You might enjoy reading the papers "Highway Hierarchies Hasten
| Exact Shortest Path Queries" [1] and "Exact Routing in Large
| Road Networks using Contraction Hierarchies" [2] if you're
| interested in hierarchical approaches to shortest path routing.
|
| The algorithms _do_ divide the map up into chunks that are
| themselves divided up and so on, but not on the strict
| geographical basis a quadtree uses. You might not want to
| divide Manhattan in two for routing purposes, even if the 74th
| longitude line runs straight through it.
|
| [1]
| https://turing.iem.thm.de/routeplanning/hwy/esaHwyHierarchie...
| [2]
| https://publikationen.bibliothek.kit.edu/1000028701/14297392...
| willi59549879 wrote:
| searching with street name and number offline would be nice. In
| google maps search only works when online
| packet_mover wrote:
| Good point - house-number search isn't there yet in Corviont.
|
| Right now the offline geocoder in the demo does place/street-
| level search + reverse, but street + house number ("Main St
| 12") isn't supported yet. It's explicitly on the near-term
| roadmap: richer geocoding output with house numbers and
| (optionally) street/area geometry instead of just centerpoints.
| dennis16384 wrote:
| Why not package photon?
| packet_mover wrote:
| Photon is solid - but it comes with a very different
| operational profile than what I am aiming for.
|
| Photon is built on Elasticsearch (Java) - so it tends to
| mean a heavier index + higher RAM/CPU expectations and more
| moving parts. That's fine on a beefy server, but it is a
| rough fit for the "drop-in appliance on small edge/on-prem
| boxes (amd64/arm64) + simple ops" goal.
|
| Corviont's geocoder is intentionally "boring": a single
| SQLite file + an HTTP service, built from Nominatim-derived
| data. Fast startup, low RAM, easy to ship per-region, and
| it stays consistent with the rest of the stack.
|
| That said - if there is demand for a "server-grade geocoder
| option" for people already comfortable running Elastic, I
| am not opposed to offering it as an alternative profile.
| The default is just optimized for constrained edge hardware
| and minimal moving parts.
| dabreegster wrote:
| Quite cool to see this space being explored!
| https://github.com/headwaymaps/headway is another related
| project.
| packet_mover wrote:
| Nice - thanks for the pointer. Headway is definitely a related
| "self-hosted maps stack" project.
|
| One place Corviont is trying to differentiate is the update
| story for edge/fleet deployments: the goal is a signed,
| resumable regional dataset updater (verify manifest -> atomic
| swap -> reload/rollback) so boxes in the field can stay fresh
| without manual rebuilds or "re-download the world" updates.
| Headway (at least from a quick skim) looks more like "bring
| your own data / regenerate when needed," which is totally fine
| for servers, but fleets usually need something more automated.
|
| If you've seen Headway (or similar) handle incremental/regional
| updates well, I'd love to learn from it - updater design is the
| big missing piece I'm validating demand for.
| ikawe wrote:
| (Headway maintainer here)
|
| Indeed there is currently no incremental update in Headway,
| and deployments are largely an exercise left to the reader.
|
| For maps.earth (a Headway planet deployment), I typically
| rebuild the world, and then do a blue/green deployment.
|
| I guess the one exception is for transit routing. We have
| individual transit zones small enough to fit into memory,
| which can be deployed incrementally. There's nothing really
| built in about it - just another level of indirection via our
| "travelmux" service which redirects your routing queries to a
| different backend depending on mode and region.
| packet_mover wrote:
| Thanks for chiming in - super helpful context.
|
| I am trying to learn from real deployments as I design
| Corviont's updater for edge boxes (bandwidth caps,
| maintenance windows, unreliable WAN, atomic swap +
| rollback).
|
| When you say transit "zones" are small enough to deploy
| incrementally - what is the actual artifact per zone
| (roughly what format), and what sizes do you typically see?
|
| And when a transit zone dataset changes, how do you roll
| that out safely - do you restart/reload the backend that
| serves that zone, or do you bring up a new backend/version
| and then flip travelmux to point at it?
| leros wrote:
| Does this not require a massive database of tiles?
|
| I ask because I've been looking to self host some sort of map
| tile server and they seem to have database in the hundreds of GB.
| packet_mover wrote:
| Good question. Corviont is region-focused (you package one
| region), not "host the whole planet". Hundreds of GB is usually
| the full planet at high zoom / lots of layers.
|
| Also it's not one giant tile DB - there are 3 datasets:
| - map tiles (PMTiles) - routing tiles (Valhalla tiles)
| - geocoder index (SQLite)
|
| For Monaco all three are tiny - you can see the exact files
| here: https://github.com/corviont/monaco-demo/tree/main/data
|
| For small countries like Austria/Slovakia, each is typically
| hundreds of MB.
| tomaskafka wrote:
| I love it, thanks!
|
| If I may have a feature request, I'd like to have only some of
| the features turned on - in my case it would be just the reverse
| geocoder (so I could skip the map and routing data download and
| storage).
|
| Right now I have my own reverse geocoder for
| https://weathergraph.app which downloads OSM dumps and builds in-
| memory KD tree for lookups. Surprisingly, the whole world can fit
| in 3-4 GB of RAM, and service starts in 90 seconds on a cheap
| VPS, no database needed, but of course, having a battle tested
| solution that just works (and someone else maintains it) would
| help.
| packet_mover wrote:
| Thank you! And yes, Corviont is intentionally a stack of
| separable services behind one gateway - so "geocoder-only" is
| exactly the kind of config I want to support (skip PMTiles +
| Valhalla and ship only the SQLite index + reverse API).
|
| Re: Weathergraph - thanks for the details. Since you already
| run whole-world reverse geocoding on a single server, that's a
| bit different from Corviont's current regional/fleet packaging
| (where you ship only the area you need to each edge/on-prem
| deployment). A "world geocoder-only" pack could still make
| sense - but it's a different distribution/update story than my
| default.
|
| For your use case, do you want reverse results at the
| city/region/country level - or do you also need street/house
| number detail? That choice mostly determines how heavy a world
| geocoder-only pack needs to be.
| t0mk wrote:
| I like how you packed only the necessities - tiles for maps,
| routing, and geocoding index in in sqlite. I checked the monaco
| deployment and missed lookup with street number, as someone else
| also pointed out.
|
| Why not create a "builder" repo, where people could generate
| their own local datasets by a bounding box?
| packet_mover wrote:
| Yeah, house-number lookup is not there yet. The demo geocoder
| does place/street-level search + reverse, but house numbers
| need a richer address index - it's on the roadmap.
|
| Re: a bbox "builder" repo - it's an interesting idea. I could
| see it going two ways: (a) you want to run a bbox builder
| yourself, or (b) you want a simple way to specify a bbox so the
| dataset pack can be produced for you.
|
| I started with the "ship a known-good pack" approach because
| the build pipeline is the messy part, and I want deployed boxes
| to stay simple/reproducible.
|
| For your use case, which did you mean - run the build locally,
| or "draw/paste a bbox and get back a ready-to-run pack"? And
| would bbox be OK, or do you prefer admin boundaries
| (country/state/city)?
| onaclov2000 wrote:
| Definitely interesting, I don't see an obvious comment on
| hardware requirements, do you know what those are?
|
| I've played around with OSRM, and Nominatim, etc, but had to do
| some trickery to run on a raspberry pi.
|
| (For anyone interested in running some of these kind of things on
| a pi, I talk about it generally here, I need to post an update
| with more info at some point.
| http://blog.onaclovtech.com/2025/02/general-purpose-to-speci...)
___________________________________________________________________
(page generated 2026-01-03 23:01 UTC)