Skip to main content

What a map vertex costs

· 7 min read
Evgen Bodunov
Evgen Bodunov
CEO @ Globus Software

Here is a building in the centre of Warsaw the way our previous offline map format stored it, :

Grid step 73 cm. Corners move by up to 44 cm, 28 cm on average.

The dashed line is the outline as it was mapped in OpenStreetMap. Every vertex of a GLMap tile sits on a grid laid over the tile, and the tiles that serve street-level zooms cover about 3 km of Warsaw each. With 12 bits per axis the grid step there is 73 cm, and the orange lines show how far each corner moved to reach it. At zoom 13 nobody sees that. At zoom 17, where these buildings fill the screen, the corners visibly go astray. the step is 18 cm.

gom5, our new map format, moved to 14 bits. Those two extra bits per axis cost bytes in the file, bytes in the download and time in decoding, and we did not see all of it at once.

Faster than earcut: triangulating 3.7M map polygons in 489 ms

· 20 min read
Evgen Bodunov
Evgen Bodunov
CEO @ Globus Software

We have published the polygon triangulator of our map engine as a small library, earstrip, under the ISC license, the same one earcut uses. It is one C++ header, and a WebAssembly build on npm that takes the same arguments as earcut. In C++ it is 14% faster than earcut.hpp, in the browser 1.4 to 2.1 times as fast as earcut.js, and the comparison is near the end. This post is about how we got there.

A GPU fills triangles and nothing else. A map, on the other hand, is mostly polygons: buildings, parks, parking lots, the strip of grass between two tram tracks. Here are a few blocks of Śródmieście in Warsaw the way our renderer reads them from a map file, :

 

Before any of this gets a fill, every outline has to be cut into . Hover over a polygon, or tap it, to see what it turns into. These blocks hold 331 polygons with 5,151 vertices, and they become 4,514 triangles.

Zoom level 13 of our offline map of the Masovian Voivodeship, the region around Warsaw, has 3,740,425 polygons. On one core of an M4 Pro, the constrained Delaunay triangulator in our engine needs 2.93 seconds to cut all of them. This October I replaced it with ear clipping. To write this post I rebuilt the ear clipper one idea at a time, one commit per idea, and timed every commit on those same 3.7 million polygons, so each section below ends with a number.

GLMap for Flutter, Kotlin Multiplatform, and React Native: Now in Beta

· 6 min read
Evgen Bodunov
Evgen Bodunov
CEO @ Globus Software

GLMap for Flutter, Kotlin Multiplatform, and React Native is now available in beta. Install the packages from pub.dev, the Globus Maven repository, or npm to bring native maps, search, routing, and offline data to Android and iOS apps while writing your feature code in Dart, Kotlin, or TypeScript.

Try the demos, add GLMap to your app, and tell us what works—and what gets in the way. Your feedback will help shape the APIs, examples, and integration experience before a stable release.

Find the Place, Even When the Spelling Is Wrong

· 4 min read
Evgen Bodunov
Evgen Bodunov
CEO @ Globus Software

A traveller in Warsaw types Zlotaa 59. They mean Złota 59, and as of this release the online search finds it.

GLSearch now corrects common typos in online map search: a missing letter, an extra one, or a wrong one in the name of an address, a business or a place. The user picks the destination instead of retyping it.

How an Offline Map Knows Which Paris You Mean

· 8 min read
Evgen Bodunov
Evgen Bodunov
CEO @ Globus Software

The map is open on Warsaw, and someone types Eiffel Tower Paris France. GLMap search starts from the map center: it opens the detailed maps around it and puts the nearest results first. The Eiffel Tower is 1,370 km away, in a map file that such a search never opens.

This is what the engine does with that query now, and with the other queries from this post. Each word is coloured by the role the engine gives it:

EiffelTowerParisFrance
map centerParis
The world map resolves Paris, France; the rest, Eiffel Tower, is searched in the detailed maps around Paris. Warsaw still ranks the results.

Words with an orange border are places the engine looks up before the search itself, and a dashed border marks a place name that belongs to the name of something else. The dot marked “map center” is where the map is open, and the circle is the area where the detailed maps are searched.

GLMap 2.0

· 4 min read
Evgen Bodunov
Evgen Bodunov
CEO @ Globus Software

GLMap 2.0 is our largest SDK update in years. It adds 3D terrain, one search flow for online and offline data, new pedestrian routing profiles, Vulkan rendering on Android, and much smaller reference applications for Swift and Kotlin.

GLMap 2.0 features in the SwiftDemo reference app

Most of the new features are a property or a request type, and they work with downloaded data and the same way on iOS and Android.

How 3D Terrain Works

· 4 min read
Evgen Bodunov
Evgen Bodunov
CEO @ Globus Software

GLMap SDK 2.0 can raise the map into the shape of the ground. The same vector map, with its roads, labels, tracks and markers, lies on the terrain instead of on a flat plane. Here is Chamonix going from flat to 3D and back:

Terrain is one of the larger features of the GLMap 2.0 release. This post shows what an application changes to use it and how the renderer draws it.

Teaching Valhalla That Hiking Is Not Flat

· 9 min read
Evgen Bodunov
Evgen Bodunov
CEO @ Globus Software

From Morskie Oko, the lake under the highest peaks of the Polish Tatras, a trail climbs to Czarny Staw pod Rysami, the next lake up. It is 500 metres long and rises 180 metres. The time written for it is 30 minutes up and 20 minutes down. At Valhalla's default walking speed of 5.1 km/h, the distance alone takes six minutes.

Our routing runs on Valhalla, and its tiles already store the elevation along every edge. In June we tried to turn that elevation into hiking times that agree with the times people walk by. Here is what we compared against, the models we tried on the way, and the curve that went into the tiles.

Predicted Traffic Learns When to Trust Recent Roads

· 7 min read
Evgen Bodunov
Evgen Bodunov
CEO @ Globus Software
Update, October 2026

The adaptive selector described in the second half of this post stayed an experiment: the June export that used it was built and loaded into Valhalla tiles for testing, and production kept one 180-day half-life for every road. Local road time, the guard for empty windows and the 180-day half-life are what production traffic data uses today.

One edge of a motorway in eastern Germany was driven at about 120 km/h until March 2024. For the next twenty months the GPS traces on it ran at 85 to 95 km/h, and since December 2025 they are back above 120. By 3 June, the last day of our June observations, the edge had 1,503 of them, and their plain median was 99.9 km/h:

60801001201402023202420252026101.6
Weighted median 101.6 km/h from an effective 729 of 1,503 observations. Without weights: 99.9 km/h (dashed).

Each dot is one traversal, day and night together, faded by how much it counts. Our traffic data gives every road a day speed and a night speed for Valhalla, and for this road the plain median is wrong by more than 20 km/h. This post is about how much an old observation should count, and about the decisions that have to be right before that question even makes sense.

Making Valhalla Understand Monday Morning

· 7 min read
Evgen Bodunov
Evgen Bodunov
CEO @ Globus Software
Update, October 2026

The weekly profiles described here stayed an experiment and never became part of our production traffic data; later evaluations closed this line of work. Production routing uses a day speed and a night speed per road, computed in local road time with a 180-day freshness half-life, which the June post describes.

In our GPS data, German urban motorways run at 84% of their weekly average speed between seven and eight on Monday morning, and at 113% at the same hour on Sunday. This is the week of that road group: the faint line is every five-minute slot, the solid one the average over an hour.

MonTueWedThuFriSatSun80%100%120%
Monday 07:30: 84% of the cohort's average speed over the surrounding hour, 82% in this five-minute slot. Shaded: the night window.

Hover over the week to read it. The is slow too. Other groups have other weeks: lose speed for the whole working day.

Valhalla can take a curve like this for every edge of its graph and use it when a route has a departure time. In May we tried to give it one from our own GPS data. This post is about how much of such a curve the data could support.