Building road geometry from osm way centerlines


I’m working on a 3d renderer for libosmscout [1]:

One of the things I’m trying to improve on is generating proper geometry for roads using way centerlines. Right now the method I’m using just offsets each edge of a given centerline along its normals and then I stitch everything together as one large triangle strip. This is very efficient, but creates overlapping triangles where way segments join. The result looks especially poor if the geometry has any transparency:

I was wondering if anyone here had a better method of creating road geometry (ie, converting a centerline into a ‘ribbon’). I haven’t found many straightforward/promising methods and wanted some input. I’m concerned with performance – hopefully this lib will work on mobile platforms at some point.



Hello Preet,
good job.
I worked with 6 years before. Please contact me.


might be interesting
Also I could provide you some (german language) information about the method we’re currently using for our system ( to generate street networks and crossings. But this requires some preprocessing on OSM data stored in a PostGIS db.

I don’t see a reason to hide information. Please place information or links here

I started a special topic dedicated to algorithms.
rajo, Marek:
Please place description or links to your algorithms there

This is not the question of hide. It is the question of too little time: Preet should concretely say what makes problems, or in which direction he believes to find solution. Maybe I can help, maybe not. I was a few years ago diploma thesis advisor. The thesis has had exactly this topic but is intelectual property of my company.

I read the inria article – unfortunately it’s not what I’m looking for (but its an interesting read, thanks for the link!). I’m basically just looking for an algorithm to convert a single way into a polygon without any overlap. I’m not too sure about the method with the PostGIS database – I’d be implementing this method with C++ and I need to build geometry on-the-fly.


If you need just a single way on a flat surface, here is my implementation in javascript:

You need to take a look at the makeRoad function (line 117-201)
coords defined at the line 118 is an array of coordinates that define the way

I haven’t yet announced it here, at the forum.
The goal is to generate photorealistical images from OSM data and external models with POV-Ray

Much beater result for roads you can get easily by using bisection of angles between roads segments. But it steel don’t work if road segment is shorter then road width. In this case you need to generate “edge events” like described in Skeleton method [1].

rajo: this article looks really nice.

[1] - Straight Skeleton Implementation, Petr Felkel and Stepan Obdrzalek


Thank you all for the valuable input. Single ways now render as expected – see the attached screenshot. vvoovv your code example was very instructive. Instead of bisection however, I chose to reposition vertices of the inner edges that would otherwise form an overlap to be coincident at their point of intersection (which looks like it does the same thing). It seems to be working well, I hope I haven’t overlooked something :slight_smile:

Hello preetdesai,
all street have the same width. Do You think about implementation of street width as a function of lane numbers? Use heuristic: 1 lane =2,50m

When you have segments with changing of lane numbers use heuristic: Lenght of the konic part of the street = 50m



I’m developer a game in Lua language and a need do render ways (2D). I have a question in your javascript code. What’s stripe[0] and stripe[1] in :

if (kwArgs.stripes) {
array.forEach(kwArgs.stripes, function(stripe){
var stripeHalfWidth = stripe[1]/2,
leftEndAbs = stripe[0] - stripeHalfWidth,
leftEndRel = Math.abs(leftEndAbs/halfWidth),
rightEndAbs = stripe[0] + stripeHalfWidth,
rightEndRel = Math.abs(rightEndAbs/halfWidth),
stripePoints = []

thank’s, Léo.

The array stripes indicates where stripes are places on the road and what width each stripe has
Example from here

stripes: [[-4.4, 0.3], [4.4, 0.3], [0, 0.3]],
width: 10

In that example the first stripe with width=0.3 is placed 0.6 meters from the left border of the road,
the second stripe with width=0.3 is placed in the middle of the road,
the third stripe with width=0.3 is placed 0.6 meters from the right border of the road

Thanks vvoovv, your code is very good !!!