Imagico.de

blog

Musaicum image tiles

January 16, 2026
by chris
0 comments

Musaicum image tiles

Over the past years i have produced and discussed here various regional high quality and high resolution satellite image mosaics – the Musaicum series. These are available for licensing as originally produced, in the MGRS grid of the Sentinel-2 data they are based on. Obtaining the image in the original coordinate system ensures you get most out of the data, without quality reduction as a result of re-sampling.

But many customers naturally want to use the images in interactive maps and, for convenience and less processing work on their side, ask for the image in Mercator projection, which i can provide of course.

I now went a step further and processed all available Musaicum images – plus the Comprehensive Optical Mosaic of the Antarctic – into a ready-to-use tile set for interactive web maps. Like the original mosaic, these tiles come with an alpha (transparency) channel. This allows smooth blending with a background image layer for open water and for areas so far not covered by the Musaicum. And the system used to generate the tiles allows for selective updates when a new region becomes available or an existing region should be updated in the future.

Tiles are produced up to zoom level 14 at low latitudes, making use of the full resolution of the Musaicum images. At higher latitudes z14 tiles are pointless due to the variable scale of the Mercator projection, so tile generation is limited to z13 or even lower, depending on the local scale. Also excluded are areas with no image content. Tiles are generated in AVIF format, but can be produced in other file types like WEBP or PNG as well.

The total data volume of the tiles with the current Musaicum and COMA coverage in high quality AVIF format is 350GB. Of course, you can also obtain limited coverage of just one or more regions instead of all of them.

To give an idea how this tile set looks in practical use, i have set up a demo map with tiles up to zoom level 7:

You can look at this also with the Green Marble as background:

In case you are interested in licensing the Mercator tile set, or generally the Musaicum images, for your projects, have a look at the product page and contact me through the link there.

Musaicum Mercator tiles at z14 in West Asia

Musaicum Mercator tiles at z14 in West Asia

Musaicum Mercator tiles at z14 in East Asia

Musaicum Mercator tiles at z14 in East Asia

January 15, 2026
by chris
0 comments

On non-locality in tiled rule based map rendering

I want to write here about a subject that is essentially as old as tiled digital maps but that is, none the less, at least partly ignored by map designers, map operators and software developers alike, although each of them does so in different ways.

Basic non-locality of map drawing

In rule based map design you display graphical elements on the map based on geometry data, primarily points, linestrings and polygons and their attributes and relationships. For example, you might draw a marker, a label or a pictorial symbol at the location of a point with certain attributes. Or you draw a line of a certain width for a linestring with certain attributes. In the most simple cases (which are the vast majority in practically all maps) such drawing rules are atomic and local. Atomic in the sense that it is always exactly one feature in the data set with its geometry and attributes that defines the appearance of the corresponding design elements and local in the sense that what is drawn is drawn locally near the geometry of the defining feature. But here things already start to get complicated because a marker, label, pictorial symbol or line signature all have a spatial extent on their own. In tiled rendering, therefore, features outside the tile will influence the rendering results of the tile.

For the mentioned basic design elements you would, however, still consider the drawing rules to be local because the non-locality is defined clearly by the drawing rules. A line signature with a width X means features less than X/2 away from the tile edge can influence the rendering results, but not those further away. And you could use that information to explicitly query features from within that distance from the actual tile bounds to make sure the tile is correctly rendered and everything appears continuous across neighboring tiles.

How point symbols and line signatures on features outside the tile can affect rendering within the tile

How point symbols and line signatures on features outside the tile can affect rendering within the tile

Practically, this is typically not done though because it would be a lot of work to keep track of exactly how non-local each of the design elements of the map is and adjust the queries accordingly. What is done instead is rendering all tiles with a fixed buffer around the actual tile you want to generate, to make sure this kind of very limited non-locality in design elements of the map is not causing discontinuities across tile edges. This approach is costly, a 128 pixel buffer around a 8×8 metatile, for example, means a more than 25% increase in rendered area. But it saves the work to consider the exact level of non-locality for every design element in the map.

The problem is that this is typically where considerations about non-locality of map rendering stop and everyone involved simply believes that this rendering buffer will take care of all of that. But it does not.

Blocking elements

The most well known map design element where the rendering buffer of tiled rendering does not fully solve the problem is labels. When you draw labels in maps and avoid one label overlapping the other – or similarly any kind of blocking rendering of symbols or labels – you will get non-locality across arbitrary distances. Not only can a label outside the tile, that does not extend into the tile bounds, block a label that would otherwise show up in the tile. That label fully outside the tile can itself be blocked by another element, which means the label visible within the tile needs to show up. Practically it is rare for such chains of inter-dependencies between blocking features to become very long, but the mentioned two levels of inter-dependency are not uncommon.

How changes in prioritization of labels outside the tile affect rendering within the tile

How changes in prioritization of labels outside the tile affect rendering within the tile

Practical case of labeling inconsistency across metatile edges in OSM-Carto

Practical case of labeling inconsistency across metatile edges in OSM-Carto

This fundamental problem of dealing with blocking elements in tiled rendering manifests differently in server side and client side rendering. In server side rendering, the result is inconsistencies in display of blocking elements across metatile boundaries. In client side rendering that is not a problem, because the labels and symbols are not cut off at the tile boundaries in rendering. The consequence here is that you either get labels and symbols appearing and disappearing as you navigate the map, because, for example, new labels with higher priority than those shown so far appear on tiles previously not loaded. Or – if the rendering engine tries to avoid that by prioritizing labels and symbols already shown before compared to labels and symbols newly loaded – the rendering results will depend on the navigation history and, for example, fully reloading a certain map display will then change which labels and symbols are shown.

Different symbols being displayed depending on navigation history in a client side rendered style

Different symbols being displayed depending on navigation history in a client side rendered style

One strategy occasionally employed to mitigate these problems is to universally avoid any blocking elements crossing metatile boundaries. But that is, of course, a major constraint. The other approach sometimes taken is to pre-calculate labels and do the blocking calculations not on a per-tile basis or per-viewport basis, but either globally or in some geographically defined splits.

Dashing patterns

While the basic non-locality of graphical elements in maps and the special issues with blocking elements are widely known, many other cases of non-locality are not. One of them is related to dashed line signatures. I wrote about line dashing from the design side some time ago. The way dashing is implemented in practically all map rendering frameworks is that the pattern starts at one end of the line and repeats along the line in a mechanical fashion until the end. That means, of course, that, if the line geometry is cut to the extent of the tiles, the dashing pattern will normally not be consistent along the tile boundaries. Classical map rendering frameworks like Mapnik, therefore, offer the option in styling to explicitly turn off clipping of geometries to the rendering extent, which avoids the problem. Client side rendering frameworks could do the same, but that would massively increase the data volume to be transferred. Alternatively, they could record the information necessary to start the dashing at the right phase of the pattern in the data – in other words: provide the length of the line cut away with the clipped line geometry and use that information to adjust the pattern display on the client. No rendering framework i know of provides that possibility, which means: No client side rendering currently allows consistent display of line dashing patterns across tile boundaries. This, for me, is one of the clear indicators that client side rendering is practically currently not ready for serious map design work.

Dashing inconsistencies at tile boundaries in client side rendering

Dashing inconsistencies at tile boundaries in client side rendering

Geometry data compression

One other source of non-locality in map rendering that is practically only relevant in client side rendering is lossy geometry compression. Client side rendering is inherently tied to massive lossy geometry data compression, which is typically performed through line simplification plus coordinate discretization. Practically, this leads to non-consistent results at the tile edges, which are visible at higher zoom levels.

Per-tile lossy geometry compression leading to tile edge inconsistencies

Per-tile lossy geometry compression leading to tile edge inconsistencies

This could easily be avoided, even when not using original, but already aggregated geometries, but doing so would require custom implementations of geometry compression functions instead of relying on standard library functions for that. Practically, most client side rendered maps are affected by this.

Explicit non-localities in map design

So far i have discussed sources of non-locality that more or less casually derive from the way maps are rendered in general. But, in addition to those, there are also cases where additional non-localities are explicitly introduced through the way data is processed for rendering by map designers.

A simple example to illustrate that is the practice of merging geometries on a per-tile basis. Since geometries in OpenStreetMap are frequently split in a relatively fine grained fashion to differentiate attributes locally, it is often a problem to render the individual components separately, because it disrupts the rendering. For example, when a road is rendered based on relatively short segments in mapping, dashing patterns and labeling are going to be affected by this. So it might seem a good idea to simply merge all road elements within a tile that are going to be rendered in a common styling. This will, however, lead to different geometries in different tiles and therefore dashing and labeling will be discontinuous across tile edges if you do that – unless you take further measures to avoid that.

More generally: If you do more complex geometry processing in map design, like with spatial joins, you need to be mindful of the problem of non-locality. Sometimes the issues are going to be manageable with help of the buffer that also takes care of the basic non-localities discussed above.

Updating maps

So far, the reason for discussing non-locality has been inconsistencies in rendering happening as a result of non-localities not properly dealt with. There is, however, an additional aspect of practical map production where non-locality comes in, that is if you want to update the data and, in consequence of that the map, on a regular basis.

If you make changes to the data of a rule based tiled map you can either re-render everything after every data update (which is a common strategy when you rarely make changes to the data) or you can try to only selectively re-render the map where changes have been made. This kind of selective update is called tile expiry and is commonly done in OpenStreetMap data based maps. And – as you can probably imagine – non-locality plays a significant part in this as well.

Essentially, all of the non-localities i discussed above to be potentially cause of rendering inconsistencies across metatile boundaries are also relevant for tile expiry. But there are also additional problems that cause issues for tile expiry. These are connected to non-spatial relationships between elements in the data. Those are no issue for inconsistencies between tiles in normal rendering, but they pose difficulties for tile expiry.

Non-spatial relationships

What do i mean with non-spatial relationships between elements in the data? It essentially refers to the cases where there is no complete atomicity of features in rendering, i.e. where the rendering of one feature depends on information other that the geometry and the attributes of that feature and that additional information does not derive from a spatial relationship.

Cases with a spatial relationship are, for example, when the rendering of a turning circle or of a highway crossing depends in the design on the class of the intersecting road. That is not a specific problem as long as both elements involved are rendered in the map themselves and trigger an expiry when changed.

Cases with a non-spatial relationship in OpenStreetMap are primarily where relations are used. Here things get tricky. A relation in OpenStreetMap in general documents a relationship between different individual features (the relation members). This creates a non-locality in the data, but as said, this is not an issue for tiled rendering in general, because that relationship is always the same for any tiles you render. But what about changes to the data? If the tags of a relation change, that will, of course, require updating any tiles containing any of the relation members, if the relation membership is used in rendering. But will a change of one of the members affect the rendering of the other members? It depends on the type of relation and on how things are rendered.

Map rendering based on OpenStreetMap data has, so far, essentially only established two relation types relatively clearly – that is multipolygon and route relations. And both of these are not established as relationships between features, but as features on their own. For tile expiry this means: Any changes to a multipolygon or route relation or one of its members is treated as a change to the feature representing the relation.

But these are special cases – the general case of a relation in OpenStreetMap is one where the relation documents a relationship between features that is not a feature to be rendered as such on its own. Route relations are a good example here. What is done by map rendering frameworks is treating them as features on their own. That has some use in map rendering, you might, for example, show a certain type of hiking route or bus route with a line in a certain color. But that is not the only use case of route relationships in map rendering. You might also want to differentiate the way a road as a physical structure, represented by a way with a highway=* tag in OpenStreetMap, is shown, based on what route relations it is a member of.

Interestingly, while rendering frameworks meanwhile allow making available relation memberships generically to map designers for interpretation, the tools for doing that (specifically osm2pgsql) seem to insist on maintaining the illusion of feature atomicity when it comes to tile expiry. So – if i understand the documentation correctly – if you want to use general relation membership in rendering, like i described in my route relation example, you have to create dummy tables with dummy geometries combining all the features the rendering of which is affected by a relation they are members of, and only through this additional geometry data can manage correct tile expiry.

As a final note, i want to mention that apart from relationships explicitly documented through an OpenStreetMap relation, there are also relationships implicitly derived through other mechanisms (like spatial relationships) that are similarly relevant for tile expiry. Consider, for example, a scenario where you want to render endorheic lakes differently, based on the criterion that there is no natural waterway intersecting the lake and ending outside of it. Or, more practically relevant: You want to render labels differently depending on what country the label is in. Technically, those are spatial relationships, but they are very different from the ones discussed before (like turning circles) and would need to be handled more like an explicit relation regarding tile expiry.

Conclusions

I hope it became a bit clearer from this brief discussion how non-locality in map rendering is a widely neglected issue and where you need to practically consider it.

As far as tile expiry is concerned – the way current tools treat that seems to reflect the deep commitment software developers in this domain universally appear to have to the simple features paradigm (that everything in geodata is either point, linestring or polygon or a collection of these) and to feature atomicity (that each of these features stands alone and can be dealt with independently from other features). Unfortunately, when you look at the geographic reality, that paradigm is an illusion. Mapping and cartography is all about relationships between elements – spatial or otherwise. Fortunately, OpenStreetMap acknowledges that and offers relations to document such relationships, even though there are many cases where an explicit relation is not really necessary and relationships can be derived implicitly.

In principle, the rules for correct tile expiry could often be derived from the rules and queries map designers develop to collect and interpret all the data that is taken into account for rendering. But doing so automatically is, of course, anything but easy. In light of this it is – in a way – perfectly understandable that software developers would like feature atomicity. But, unfortunately, this means that in 2026, more than 15 years after relations have been introduced in OpenStreetMap, it is still a challenge to interpret general relation membership in map rendering, at least if you want regular updates on data changes.

Peeking at peaks - importance rating of peaks in map production

January 2, 2026
by chris
0 comments

Peeking at peaks

I have written about display of various landforms and topographic features in maps previously – in particular linear elements like cliffs, ridges and gullies. But there is one terrain form that stands out as uniquely iconic in maps – that is mountain peaks.

I don’t want to cover the full cartographic history of displaying mountains and mountain peaks in maps here. That is a very interesting subject, but something for another time.

Peaks rendering had received some upgrade in my experimental map style compared to what you know from OSM-Carto previously, that is:

  • Displaying elevation labels in a styling different from the name label and either together with that or separately – depending on available space.
  • A reduced symbol size for z11 (the initial zoom level at which peaks are shown)
Peak rendering in the AC-Style so far

Peak rendering in the AC-Style so far

But these are minor improvements in light of the elephant in the room regarding peak rendering, which i want to try look into addressing here. But before i do that, let’s first take a step back and look at why we actually display peaks in maps.

The function of peak rendering in maps

The first – and most obvious function the display of mountain peaks in maps has, is that of a classical point of interest. A location marker for a certain class of feature in a map – with a classifying symbol and a name label – plus an additional property: the elevation value. This is the original and main function of peak display in OSM-Carto and other non-topographic maps.

The second function of peak rendering is as an element of displaying the earth surface topography in some form. In this function, peak rendering often works together with the display of other topographic features, in particular ridges. But also in topographic maps with a more generic and more mechanical depiction of the topography (like through hachures, contour lines or shading) peak symbols are often used to guide and support understanding of the topography by the map user.

Here are a few examples.

USGS map of Alaska 1:2.5M from 1946 - note in particular the unusual top-view peak symbol resembling hachure maps

USGS map of Alaska 1:2.5M from 1946 – note in particular the unusual top-view peak symbol resembling hachure maps

Specialkarte vom westlichen Kleinasien by H. Kiepert from 1890-1892

Specialkarte vom westlichen Kleinasien by H. Kiepert from 1890-1892

Yosemite National Park Area by Automobile Club of Southern California from 1963

Yosemite National Park Area by Automobile Club of Southern California from 1963

Map of Aden, Yemen from 1914 by the Survey of India

Map of Aden, Yemen from 1914 by the Survey of India

Soviet tourist map of the Caucasus mountains from 1991

Soviet tourist map of the Caucasus mountains from 1991 with ridges, peaks and saddles prominently displayed

Adequately serving the second function requires displaying the peaks at relatively small map scales – at scales where, by far, not all peaks can be displayed. And in that situation you need a meaningful importance rating to select which peaks to display and which not to show.

The problem of importance rating peaks

The simple idea would be to use the peak’s elevation as a measure of importance. Higher peaks are more important that lower peaks. But if you think about this a bit further it will quickly become clear that this won’t work. In high altitude mountain areas every peak will have a high elevation and therefore a high importance, while huge parts of the planet will have no peaks shown at all, since they don’t reach the threshold altitude – while possibly being as mountainous as the high altitude regions.

With that realization some people have suggested to use topographic prominence as a rating criterion. Prominence is a rating of peaks popular among mountaineers. It specifies how far you at least need to re-ascend to that mountain peak when coming from a higher peak. I am not aware of any digital rule based global map implementing that idea, which is largely because topographic prominence is fairly hard to automatically determine. But, ultimately, this is also a fairly poor measure of importance for map rendering purposes. I will try to explain why.

Here a display of all peaks with a prominence of more than 1500m world wide – that is a popular prominence cut-off, indicating an ultra-prominent peak.

World wide distribution of peaks with a topographic prominence of more than 1500m

World wide distribution of peaks with a topographic prominence of more than 1500m

As you can see, the distribution of those is very uneven over the planet, much less so than if you would choose the same number of peaks ranked by elevation (which would all be in the Himalaya/Karakoram), still not a distribution that would be any useful for practical map display. For Europe in Mercator projection it would like this:

Ultra-prominent peaks in Europe with a topographic prominence of more than 1500m in Mercator projection

Ultra-prominent peaks in Europe with a topographic prominence of more than 1500m in Mercator projection

The underlying reason why topographic prominence is not a useful importance measure for peak rendering in maps is that it has no spatial component. The prominence value depends on the elevation of the peaks and of the saddles between them, but it is completely independent of the distances between those.

That brings me to the other popular measure of cartographic importance of peaks – the topographic isolation. Topographic isolation measures how far a peak is away from the closest higher point in elevation. This measure is used practically in maps as an importance rating for peaks, most prominently in the OpenStreetMap context in OpenTopoMap.

Topographic isolation in a way is the complete opposite of topographic prominence, it is a purely spatial measure not taking the quantitative differences in elevation into account at all.

Calculating the topographic isolation is much easier than determining the topographic prominence. But to do that you need an elevation data set. Accuracy and resolution of the data is not as critical as for prominence calculation, but on a global scale there is still some heavy lifting involved.

Self contained topographic isolation estimates from OSM data alone

However, we are not in need of precise isolation values. We just need a reasonable importance measure based on which to select which peaks to show at a certain scale and which not to show. The exact cutoff value is a subjective design choice anyway, and some level of non-uniformity in importance values is acceptable. Therefore, we can think about taking a simplified approach and estimating topographic isolation based on peak elevations alone. Or in other words: We determine the topographic isolation of peaks using the elevations of all the other peaks in the OSM database as elevation data set. That does not only save us the heavy lifting with a global elevation data set, it also allows doing the topographic isolation calculation on the fly during rendering. This is how this is done (see code here)

SELECT
way <-> points_all.way AS dist
FROM
planet_osm_point others
WHERE
("natural" = 'peak') AND
(tags ? 'ele') AND
(tags->'ele' ~ '^-?\d{1,4}(\.\d+)?$') AND
(tags->'ele')::NUMERIC > (points_all.tags->'ele')::NUMERIC
ORDER BY dist
LIMIT 1

To understand what is happening here: We essentially estimate the topographic isolation, that is the distance of a peak to the closest point of the earth surface of higher elevation, by determining the distance to the closest peak with a higher elevation. This approximation will systematically over-estimate the distance of course. You could therefore try to compensate for that over-estimation based on an estimate of the slope of terrain in the relevant area. But again: Since we just want a relative rating and don’t need really quantitative results i am not going to make it more complicated.

I have not actually measured performance, but it is quite clear that this is efficient enough to do on the fly.

The results can be seen below – these are the peaks of Europe with a distance to the closest higher peak of more than 32 Mercator kilometers (all km distances in the following are going to be Mercator kilometers). This allows fairly easy comparison to the map with the prominence based cutoff above since the density of peaks in the Alps is similar in both.

Peaks based on OpenStreetMap data with an estimated topographic isolation of more than 32 kilometers in Mercator projection

Peaks based on OpenStreetMap data with an estimated topographic isolation of more than 32 kilometers in Mercator projection

You can see the drastic difference. As said: The isolation measure is completely independent of quantitative differences in elevation. So a 100m hill in the northern German plain will have an isolation of more than 32 kilometers if it is that far away from any higher peak. It can be discussed if that is desirable, especially at the scale shown here (which is, of course, not really the scale i am targeting with this).

Practical results

Practically, the isolation can be used to decide which peaks should be rendered at earlier and which at later zoom levels. I used this to extend the zoom level range for peaks from z11 down to z9 and to stagger the addition of all peaks up to z14. To integrate this isolation dependent starting zoom level i defined five variants of peaks in the symbols and labels rendering system, each setting a different cutoff for a different zoom level threshold. The labels are always shown one zoom level after the symbols – if there is sufficient space in the map. How this looks like is shown in the following. Please note these are rendered based on local extracts of OSM data – hence peaks outside the extract area are not taken into account in the isolation calculation.

Pyrenees mountains around Monte Perdido at z9

Pyrenees mountains around Monte Perdido at z10

Pyrenees mountains around Monte Perdido at z11

Pyrenees mountains around Monte Perdido at z12

Pyrenees mountains around Monte Perdido at z13

Pyrenees mountains around Monte Perdido at z14

The first example is of the Pyrenees mountains between France and Spain. At z9 two peaks are shown – Monte Perdido (3349m) is the third highest peak of the Pyrenees and regularly shown here. Pico Espadas (3328m) would normally not be shown because it is very close to Pico Posets (3369m). The latter, however is just outside the data extra extract area in the test database and is therefore not considered in calculation of isolation. Pico Posets would also define the topographic isolation of Monte Perdido – the distance between those is about 45 Mercator kilometers.

At z10 both these peaks are labeled and in addition Vignemale (3298m) and Pic Long (3192m) and shown, Vignemale is 23km from Cilindro de Marboré, which is just northwest of Monte Perdido. Pic Long has an isolation of 19km, the closest higher peak is Pico Marboré. At z11, Pic Long also gets a label (Vignemale is out of view here) and again, additional peaks are added to the map – among them Pico de la Munia (3133m) – which is 11km from Pic de Lentilla (3157m) – slightly southeast of Pic Long. At z12 the same procedure repeats, Pico de la Munia gets a label (only elevation, because the name tagging is messed up, the name tag contains a compound name the components of which can both not be found in the individual language name tags). z13 adds further peaks and at z14 all peaks are shown, the new ones again only with a symbol, the labels of those would be added at z15.

Freiburg area with Black Forest and Kaiserstuhl mountains at z9

Freiburg area with Black Forest and Kaiserstuhl mountains at z10

Freiburg area with Black Forest and Kaiserstuhl mountains at z11

Freiburg area with Black Forest and Kaiserstuhl mountains at z12

Freiburg area with Black Forest and Kaiserstuhl mountains at z13

Freiburg area with Black Forest and Kaiserstuhl mountains at z14

The second example shows the area around Freiburg in the upper Rhine valley at the German-French border and the Black Forest and the Kaiserstuhl mountains. At z9 we have a similar situation as in the Pyrenees. The Feldberg (1493m) is shown – the closest higher peak for that according to OSM data is the Gnipen in Switzerland – 145km away. The sample shows another peak on the French side – La Bloss (826m), which is just a minor peak and only shows up because the higher peaks just west of this are outside the extract area. Zooming in around Freiburg to z10 leads to three more peaks showing up: The Belchen (1414m), which is 21km west of the next higher peak, the Herzogenhorn (1416m), the Kandel (1242m), which is the highest peak in the Black Forest north of the Dreisam valley, 27km north of the closest higher peak, the Hochfahrn (1263m). And finally the Totenkopf at just 557m. The last is the highest peak in a small mountain area in the Rhine valley, the Kaiserstuhl. And despite its low height it is 26km from the closest higher peak in the Black Forest, the Schönberg (644m).

At z11 these peaks all get their labels – though the Feldberg, Kandel and Belchen are now out of view. We, in addition, get the Schauinsland (1284m), which is 10km from the Schmaleck (1287m) as the closest higher peak, and two really low elevation peaks in the Rhine valley, which are the highpoints of two smaller, but distinct geological formations in the Rhine valley – the Tuniberg (314m) and the Nimberg (253m) with isolation values of 8.8/8.9km. For further zooming in i will center on the Kaiserstuhl mountains. Here, at z12, we get seven additional peaks shown, in particular Eichelspitze, Katharinenberg and Staffelberg on the outer ridge of the Kaiserstuhl. And at z13 also two peaks in the inner Kaiserstuhl, which are lower than the outer ridge – the Badberg (417m) and Ohrberg (427m).

This should give you an impression how the staggered addition of additional peaks based on an importance rating by topographic isolation looks like.

Peaks without an elevation tag, by the way, are assumed to have zero isolation and are therefore only shown at z14 and above.

Conclusions

The main question is, of course, if the topographic isolation is a good measure for cartographic importance. It depends a bit on the purpose of the map i think. Above i already mentioned that topographic isolation in a way is the opposite extreme compared to topographic prominence, measuring purely the spatial component and completely ignoring the quantitative elevation differences. Some might remember that a long time ago i discussed a fairly similar importance rating problem with regards to populated places. There i suggested an intermediate approach which takes both differences in the local properties (there: population, here: elevation) and spatial distance into account. A similar approach could be used for peaks as well. It would, however, probably not be possible to calculate that on the fly any more.

For a map where a substantial goal is to provide mapper feedback, the topographic isolation based rating is quite a good approach i think, because it provides meaningfully differentiated feedback not only on the mapping of mountain peaks, but in particular also for the topography in less mountainous surroundings, which can be practically pretty relevant as well. And in areas where few peaks are mapped, those which are mapped are going to be shown earlier than they would with more complete mapping of peaks, which is not a problem. In most cases, of course, mappers will locally often add the higher peaks first and the lower elevation ones later.

The implementation of what i showed can be found in the Alternative Colors map style. Compared to approaches used elsewhere it is a very light weight method and can easily also be adjusted to other map styles and map rendering frameworks.

Crossing the line - rendering of pedestrian crossings of roads in maps

December 27, 2025
by chris
0 comments

Crossing the line

This third and last part of my short series with discussions of recent changes of road rendering in the Alternative-Colors map style is an actual feature addition. I added rendering of highway=crossing.

highway=crossing currently is the most widely used primary tag not rendered by OSM-Carto with over 12M uses. It is used on nodes to indicate a location where a road is meant to be crossed or is actually commonly crossed by pedestrians.

There are a number of OpenStreetMap based map styles that display this tag in some form already. But most of them showing crossings like other points of interest with a blocking symbol (which practically often competes with other symbols, in particular traffic lights).

highway=crossing in opencyclemap highway=crossing in AJT-Style highway=crossing in OSMand

highway=crossing in OpenCycleMap/AJT-Style/OSMand

The most sophisticated rendering of highway=crossing in maps so far that i am aware of is in the French OSM-Carto fork. This uses non-blocking point symbols that are rotated according to the direction of the roads intersecting the crossing – unless the directions of these differ so much that it is deemed non-feasible to determine a single direction for the symbol – then a classical blocking point symbol is used. The rotated symbol is varied depending on supplemental tags.

  
  

Different rendering variants of highway=crossing in the French style depending on secondary tags. The second symbol in blue is the static, blocking variant

The rotated symbol has the advantage that it can be well used in a non-blocking fashion, that it is fairly intuitive in its meaning and how it relates to the roads and paths around. But it depends on all the roads where crossings are rendered on to have the same drawing width at the zoom levels it is used on. And both the static and the rotated symbols suffer from the problem that they are rendered after the road layers. So, in case there are bridges above the road with the crossing, the rendering results are confusing or even misleading.

 

Wrong drawing order of crossing symbols in the French style

Showing road crossings – advanced version

Since the AC-Style uses variable drawing width for roads, both depending on road class and on explicitly tagged or estimated ground width based on secondary tags, a different solution is necessary. The full list of requirements was:

  • Contextualized rendering of crossings adjusted to the width of the road.
  • Suitability to be rendered relatively early already in a subtle fashion.
  • Works well as a non-blocking symbol.
  • Rendered within the road layer stack so crossings underneath other roads are not shown above those in a misleading way.
  • Possibility to vary the symbol depending on secondary tags.
  • Rendering works both on a node located on a single road line in the middle, as well as at the edge between two connecting road segments.
  • Rendering works both on a straight road and at a corner.
  • Rendering works together with existing variations of the road line singnature (paved/unpaved, access, lanes etc.)
  • Degrades gracefully in ambiguous corner cases like at the transit between different road classes, between normal and bridge/tunnel roads and at junctions where more than two roads meet.

That is a fairly long list of requirements and it took quite some effort and experimentation to develop a solution for this.

Here is the basic design i came up with (top: default, middle: unmarked, bottom: crossing:island=yes, double resolution versions for z16, z17, z18 and z19).

z19

z18

z17

z16

This is obviously inspired by the French style. The color used is generally the same as for the access restriction dashing, just slightly varied in some cases. So far i use three three design variations, which are all shown in the examples above: Normal, unmarked and with crossing:island=yes.

crossing symbols to different drawing widths of roads

crossing symbols to different drawing widths of roads (link goes to double resolution version)

The number of dashes depends on the drawing width of the road. The length of the crossing symbol along the road is based on a combined criterion (at least 2 pixel, at max 5 meter on the ground and 0.65 times the road width, but in any case at least 0.35 times nominal drawing width).

The symbol is drawn with a slightly enlarged background in the road’s fill color to ensure good visibility against the road with variants of the normal line signature.

Appearance of crossings on roads with different secondary tags (from left to right: normal, bridge, tunnel, unpaved, access=destination)

Appearance of crossings on roads with different secondary tags (from left to right: normal, bridge, tunnel, unpaved, access=destination)

And it looks exactly the same no matter if the road is a continuous way at the crossing node or if it is split there. When the road’s secondary tags change at the crossing this usually works without problems. When the road changes its road class only the higher z_order part is shown with a crossing.

How crossings are shown at transits between different road types and subtypes

How crossings are shown at transits between different road types and subtypes

And – most importantly – the crossing is drawn within the road layer, correctly placed in the drawing order.

Rendering of road crossings at the correct place in the layered drawing order of roads

Rendering of road crossings at the correct place in the layered drawing order of roads

When the road has a corner at the crossing node, the crossing symbol is shaped to follow that corner.

Adjustment of the crossing symbol to road corners at the crossing node

Adjustment of the crossing symbol to road corners at the crossing node

This might look a bit weird but it ensures the symbol fits into the road even for wide roads at higher zoom levels. And keep in mind that a crossing directly at a corner is unusual, so having explicit feedback on the unusual nature of such a geometric constellation is not necessarily a bad thing.

Finally, the most tricky part: Junctions. When you have a crossing node directly at a junction where more than two roads meet at their ends, the situation is inherently ambiguous. It is not quite clear which road the crossing is actually crossing here. I try to determine that by scoring the roads involved by a number of criteria. This is using a somewhat unusual SQL contruct. The query for just normal crossings would be using a simple geometric join similar to the ones used in the turning circle query, followed by an aggregate ST_LineMerge() of the roads involved to take care of the split and un-split road cases. For junction handling you need to limit the number of road lines in the join to either one or two, with the selected prioritization depending on if the roads connect to the crossing at their ends or in the middle. This is accomplished with a lateral join and a CTE within the join.

Rendering of crossings ambiguously tagged on junction nodes depending on connecting road types and their secondary tags

Rendering of crossings ambiguously tagged on junction nodes depending on connecting road types and their secondary tags

Conclusion

There is a reason why road pedestrian crossings – despite 12M cases of mapping in the OSM database – are rarely shown in maps. It is difficult to display them in a way that integrates harmonically with the rest of the style because they are essentially parts of the road network. What i show here is an advanced approach to handling this, designed to meet a number of necessities you have in a map style with sophisticated road rendering.

There are a number of extensions of this feature you could imagine as future improvements. One example would be further differentiation of the crossing symbol based on additional tags, another would be to take into account the crossing path geometry or extending the design concept to railway crossings.

As usual, the changes discussed here can be found in my experimental map style project. A few real world samples can be seen below, more can be found in the AC-Style sample gallery.

Road crossings in Bruxelles, Belgium at z19

Road crossings in Bruxelles, Belgium at z19

Road crossings in Strasbourg, France at z19

Road crossings in Strasbourg, France at z19

Road crossings in Portland, US at z19

Road crossings in Portland, US at z19

Improved road ant tunnel rendering by taking connectivity context into account

December 23, 2025
by chris
0 comments

Crossing the bridge as we get to it

In the previous post i mentioned casually that the drawing of roads with round line caps at inner junctions of the road network works also with layered display of roads, i.e. with bridges and tunnels. While that is true in principle, there are a number of limitations, which can be bothering in practical map design.

First i want to re-capitulate how layered road rendering with the traditional round line cap connections works.

The traditional method of displaying layered road networks (link goes to double resolution version)

The traditional method of displaying layered road networks (link goes to double resolution version)

The layered road rendering in OSM-Carto and other OpenStreetMap data based maps works just like the normal road layering by drawing all the road lines individually and without taking their geometric context (i.e. how they connect to other road elements) into account. There are two thing which are key to this working:

  • The tunnels are rendered before the normal roads and the bridges are rendered after them.
  • The bridge casing (in black) is rendered with flat line caps while the colored fill is rendered with round line caps. For tunnels likewise – though for those the flat line caps of the casing are not essential, they are mostly chosen so the dashing of the casing works (since in Mapnik the line caps of the dashing cannot be selected independently from the line caps of the line as a whole).

As you can see in the illustration, these drawing principles lead to the well known appearance in OpenStreetMap based maps – and, as said, all without any context dependent styling.

The bridge/tunnel problem

But you can already see from the interrupted center-line on the secondary road (which indicates a two-lane road) that things are not quite that perfect. Problems occur with this design approach in particular in two situations:

  • When there are tram lines on the road (or – in case of the AC-Style – a center-line is drawn for lane visualization or exceptions from implicit access restrictions).
  • When two bridge features (lines or, in case of the AC-Style, also polygons) connect at an angle.

These situations are shown in the following example (where the non-bridge road segments are tagged as unpaved to better show what is going on):

Test setup for problem cases with bridges/tunnels connecting at an angle and tram lines on roads with bridges or tunnels.

Test setup for problem cases with bridges/tunnels connecting at an angle and tram lines on roads with bridges or tunnels.

The cause of the first problem is the round line caps of the bridge fill. The tram lines are rendered above roads of the same layer (since they have a higher z_order value than the road classes). But, of course, a bridge road is drawn above a non-bridge tram line since, otherwise, you could not have tram lines under road bridges. So, the round line caps of the bridge road cover the tram line on the road connecting to the bridge – leading to a discontinuous display of the tram line. This problem has been known for a long time.

The cause of the second problem is the use of flat line ends on the bridge casing – leading to gaps whenever bridge roads connect at an angle.

For tunnels the situation is similar, the main difference here is that the second problem is less noticeable because the casing is dashed anyway, so gaps are less noticeable.

Different approaches in terms of drawing procedure can be followed to address these problems. But no method that does not take into account the geometric context and makes the drawing dependent on road connectivity – similar to what i do for the flat road ends discussed in the previous post – is going to address this fully.

Solutions

The method i devised for the AC-Style consists of three components:

  1. modified fill line caps for the bridge fill
  2. rendering surface roads connecting to tunnels like open ends – with a flat line cap
  3. rendering additional end point casings and fills for junctions between bridge road features of the same layer. These are rendered before the corresponding bridge lines (for casing and fill respectively) and ensure connectivity, which would otherwise, as a result of the first point, be worse than with the standard OSM-Carto rendering procedure.

The second and third point are probably quite clear in connection with the following examples. The first requires some more explanation. You might ask: Why not use a flat line cap on the fill? That would work, except it would cause a thin line across the road at the ends of bridges because the casing and fill end at exactly the same location so the AGG based rendering will always mix in a fraction of the casing color on pixels partly covered by the bridge. You need at least one pixel of overhang of the fill over the casing. So essentially you need a line end in between a flat and a round line cap. This is produced in PostGIS using two subsequent ST_Buffer() operations. There is a small residual gap in the tram line of about a pixel in size as a result of this approach, which can, however, further be mitigated by rendering the tram line with round line caps – which should be done anyway.

I have decided to not also implement the third point for tunnels because it would only affect the casing, where it is – as mentioned – less severe since it is dashed. And the dashing pattern would not be synchronized with the lines anyway.

What also remains unchanged is connections between bridges of different layers – like seen on the very left in the following picture. These are subject to the existing constraint as before (discussed more in depth here) – the two lines need to be co-linear where they meet for this to be rendered correctly.

The improved rendering of bridges and tunnels with the discussed change.

The improved rendering of bridges and tunnels with the discussed change.


Comparison for road bridges – double resolution: old, new


Comparison for road tunnels – double resolution: old, new


Comparison for other highway types – double resolution: old, new

Conclusion

I showed here a number of relatively subtle limitations of the common way of drawing layered road networks in rule based digital maps and how these can be solved by taking the geometric context and the connectivity between individual road features into account. Methods used for doing that are:

  • Custom line cap styles produced with PostGIS using two subsequent ST_Buffer() operations.
  • Use connectivity dependent line caps (as introduced in the previous post) also for tunnel entrances.
  • Classifying bridge roads by connectivity and using that to draw dedicated junction elements for connections between bridge segments as backdrop to the road lines.

You can find all these changes in my experimental map style.

Practical application of the changes discussed here in Freiburg, Germany

Practical application of the changes discussed here in Freiburg, Germany

The end of the line - Flat line ends for roads in maps

December 21, 2025
by chris
0 comments

The end of the line

This is the first post in a short series i intend to publish on recent changes in road rendering in the Alternative-Colors map style.

One of the most fundamental techniques of digital rule based map design since the beginning has been the rendering of roads with round line caps, usually with a casing and fill (the different design elements of road drawing in digital maps are explained in more detail here).

The principle of using round line caps to consistently display a road network

The principle of using round line caps to consistently display a road network

For comparison: how the same would look like with flat line caps

For comparison: how the same would look like with flat line caps

By simply rendering every linestring the road network is composed of with a round line end and, in addition, sorting the drawing order of different road classes by ascending line width, you automatically get a consistent display of the road network – at all scales and no matter where the lines of the road are split in the data. This even works with layered display of roads (bridges and tunnels) – for the most part and as long as a few constraints are taken into account – which i have discussed in a previous blog post.

Layered road display with round line ends

Layered road display with round line ends

This method of road display is used almost everywhere in the domain of automatically rendered tiled digital maps, a few examples are shown below.

Road rendering universally with round line caps in various maps (line wise from top to bottom: OpenStreetMap Carto, Mapbox, Here, Google, TomTom, Esri)

Road rendering universally with round line caps in various maps (line wise from top to bottom: OpenStreetMap Carto, Mapbox, Here, Google, TomTom, Esri)

The main side effect of using this technique is that open road ends (where a road ends without being connected to another road) are shown with a rounded line ending. While this can be considered a valid design choice – after all, the road lines in maps usually do not depict the physical extent of the road on the ground – it is a design technique essentially unknown before digital maps. So, it is clear that the ubiquitous use of rounded open ends of roads in digital maps rendered from generic geodata – like OpenStreetMap – is almost never a conscious design choice, but almost always an accepted consequence of the technique employed to easily obtain a consistent overall display of the road network.

Pre-digital display of roads with flat line ends in a 1920s map of Seoul, Korea

Pre-digital display of roads with flat line ends in a 1920s map of Seoul, Korea

Flat road ends in Swisstopo map from 1994 (Sheet number 1090 - Wohlen)

Flat road ends in Swisstopo map from 1994 (Sheet number 1090 – Wohlen)

The rounded open ends of roads are not only a dubious and not very intuitive choice of displaying open ends of roads, they also have the additional negative side effect that they tend to visually connect roads that are disconnected, especially, of course, at smaller map scales where the roads are rendered in a width wider than the ground width of the road, but sometimes also beyond that. The presence of features directly at the end of a road, like some kind of barrier (wall, railing), buildings or point features is also not accurately shown.

Incorrectly connected roads in Strasbourg, France at z16 (left) and at higher zoom levels

Incorrectly connected roads in Strasbourg, France at z16 (left) and at higher zoom levels

Incorrectly connected roads in Verona, Italy at z15 (left) and at higher zoom levels

Incorrectly connected roads in Verona, Italy at z15 (left) and at higher zoom levels

Practically producing flat line ends

To address this problem there are two possible approaches:

  1. Use flat line ends for displaying roads and explicitly process junctions to generate a consistent display of connected roads. This is quite a lot of work to set up in common map rendering frameworks, but it also offers the most flexibility in design. You could, for example, take turn restrictions at a junction into account when rounding the corners of the junction. An approach like this is also necessary to decently model a change in physical width or number of lanes between two segments of road.
  2. Use flat line ends for open ends of road segments, while continuing use of round line ends elsewhere.

What i am demonstrating here is the use of the second approach. And since no currently widely used rendering framework allows specifying different line cap styles for the start and end of a line signature, the way to implement this approach is to split every road line with an open end into one part with round line caps and a second end part with flat line caps. Doing this works as an imitation of drawing with different line caps on start and end in most situations, although there are corner cases with highly convoluted way geometries where this is not completely accurate.

What is classified as an open end of a road is a road with a wide casing + fill line signature being not connected at its end with any other road with a wide road signature. Roads with a narrow line signature (track, footway, cycleway etc.) do not get the special open end treatment and also are not considered when analyzing the other roads.

End-to-end connections of various road types

End-to-end connections of various road types (links to double resolution version)

In addition to the basic design feature of showing open end roads with a flat line cap i implemented a differentiation of the styling depending on tagging of the end node:

  • untagged end nodes are displayed with a simple casing line at the end
  • ends explicitly tagged as noexit=yes are shown with a wider casing at the end
  • ends tagged fixme=continue are showing without a casing at the end.
The different types of open ends of roads and their styling

The different types of open ends of roads and their styling

Aeroways

One part of the roads (in the wider sense) where OSM-Carto – and also other OpenStreetMap based maps – never used round line ends is airport highways and taxiways. This is, however, traditionally done simply by using flat line caps universally, which leads to the usual problems which i illustrated already above. Mapping practice in OpenStreetMap has to some extent adjusted to that by avoiding splits in mapping of taxiways at corners. In the course of moving to render open road ends with flat line caps as shown above i also integrated the runways and taxiways with the normal roads so they now get rendered with the same logic of using round line caps for inner ends while using flat line caps for open, unconnected ends.

Airport runways and taxiways in OSM-Carto

Airport runways and taxiways in the AC-Style so far

Airport runways and taxiways in the AC-Style with the new design

Conclusion

Even though the ability to use different line caps on the start and end of line signatures is absent from practically all automated map rendering frameworks, this post demonstrates that it is still possible to practically show roads with flat line caps at open ends. This would be much easier, of course, if map rendering tools offered more flexible line cap choices. That this goes beyond just allowing different line caps at start and end of a line will be discussed in a future post.

As usual the demonstrated technique is now available in my experimental map style.

The new flat open road ends in Rougemont-le-Château, France

The new flat open road ends in Rougemont-le-Château, France

Update on the Alternative-Colors map style

December 20, 2025
by chris
0 comments

Update on the Alternative-Colors map style

I have made a number of changes to the road rendering in my experimental map style in recent months, which i intend to discuss in a number of upcoming blog posts here. In addition to these changes i also made the decision to remove all administrative boundaries except admin_level 2 (i.e. national boundaries) from the style.

Administrative boundaries have been an odd aspect of mapping in OpenStreetMap all along due to their abstract nature. The boundary per se, as an abstract concept and as an explicit line is clearly non-verifiable according to the OpenStreetMap concept of verifiability. Still – it is often a prominent part of the geography in the minds of people, though in a different way than verifiable things. That has led to a number of rather interesting practical effects in OpenStreetMap:

  • Boundaries, in particular administrative ones, but to some extent also those of nature reserves or other abstract delineations of special legal status, are the only clearly non-verifiable features in OpenStreetMap where there is clear consensus that they should be in OpenStreetMap.
  • Boundaries are not only clearly non-verifiable, they are also treated as such by the OSM community. Even where the de facto boundary is formed by a physical geography feature – like a river or a mountain ridge – boundaries are deliberately not aligned to those verifiable physical features. Mappers mostly seem to treat boundaries as inherently authoritative – no matter how questionable the provenance of the boundary geometries is and sometimes even in cases where the data is evidently counterfactual (because you can see that the actual administrative reality is different).

Bottom line from the data side: Boundary data is – for the most part – neither suitable to be mapped in OSM based on the local knowledge of mappers nor is it de facto widely mapped this way. It is none the less in the OSM database (a) because – as said – it is widely part of the mental image people have of the geography and (b) because it is widely believed that it is useful to have and maintain it in a common database with the other data in OpenStreetMap (a belief that can be rightfully questioned of course).

But because boundary data is usually not part of the mapping process in OpenStreetMap, displaying it in a map meant for mapper feedback is questionable. And it is amazing how much clearer and better readable the verifiable geography is in the map if you do not show the boundaries.

I made an exception for the admin_level 2 boundaries because

  • A fairly large percentage of admin_level 2 boundaries is physically manifested in some form – with either demarcations or even continuous structures like fences or walls. Although there is an annoying number of cases where admin_level 2 boundaries are not aligned to these physical manifestations it is fairly clear consensus that they should be. Hence mapper feedback is useful here.
  • admin_level 2 boundaries have a much higher practical significance on the ground in most parts of the world than higher admin level boundaries.
  • showing admin_level 2 boundaries has much less negative effect on map readability than the higher admin levels – both because they are less common and because they are shown as solid lines rather than dashed/dotted.

You can see in the AC-Style sample gallery how much this change improves overall map readability.

Previous appearance with administrative boundaries

Previous appearance with administrative boundaries (link goes to double resolution version)

New appearance without administrative boundaries (link goes to double resolution version)

New appearance without administrative boundaries (link goes to double resolution version)

December 10, 2025
by chris
2 Comments

Styleinfo update and AC-Style in Taginfo

As indicated in my Hack weekend report i updated the Styleinfo analysis of my Alternative Colors style. This includes some changes in the style i have not yet discussed here on the blog.

Styleinfo analysis of the Alternative Colors style

Styleinfo analysis of the Alternative Colors style

What is interesting to look at is the overall numbers of the old analysis and the current one. Previously, based on the style from late 2022, the analysis contained:

  • 408 primary tags
  • 211 secondary tags
  • 1997 tag combinations
  • 14831 renderings

Now it has:

  • 473 primary tags
  • 398 secondary tags
  • 3038 tag combinations
  • 22846 renderings

While not all of this difference is actual styling changes – there have been adjustment to the analysis heuristics that allow identifying stylings that were previously missed – roughly speaking the style has grown by 50 percent in terms of the taggings it interprets. But note that most of this is secondary tags. Nearly twice as many of those are interpreted now, most of them not as synonyms to other tags, but with distinct designs. The number of primary tags interpreted has grown less than 20 percent, which is primarily new POIs for human infrastructure and barriers.

This distribution reflects my overall approach in recent years to focus on depth rather than breadth and to add subtle differentiation to common base designs to keep the map intuitively readable even with a large number of features. Think of the augmentation of parking symbols, the viewpoint rendering or the various extensions of road rendering – none of which involve any additional primary tags.

Keep in mind that the Styleinfo tagging model does not cover all the variants how tags are interpreted in a complex map style. That includes all tertiary tags (like offshore wind generators or the differentiation of bell tower symbols by roof type shown here), combinations of several secondary tags leading to a distinct design, but also things like the improvements of POI labeling or the multilingual name labeling with language dependent fonts.

And there are, of course, also plenty of changes in the style that do not turn up in the overall numbers at all, while they are documented in the rendering samples – like the differentiation of barriers previously rendered in a uniform design.

With this update the Alternative Colors style is now also available in Taginfo.

In addition to the Alternative Colors style update i also updated the Styleinfo analysis of OSM-Carto – which indirectly likewise updates the Taginfo data that has been available since November.

Summary of the Styleinfo analysis of the AC-Style (all tags and all tag combinations for all feature types at all zoom levels) in the form of 16x16 pixel images.

Summary of the Styleinfo analysis of the AC-Style (all tags and all tag combinations for all feature types at all zoom levels) in the form of 16×16 pixel images.

November 25, 2025
by chris
0 comments

WeeklyOSM, volunteer appreciation and motivation

There has been an interesting remark by Ilya on Mastodon recently that i want to comment a bit about.

First the part about WeeklyOSM: Practically almost everyone in the OSM community reads it and it is a true institution in its function to disrupt the various filter bubbles in the OSM community and giving people an opportunity to widen their horizon on what goes on in and around OpenStreetMap.

At the same time it is a real role model for community projects in OpenStreetMap in its openness to contributors with diverse backgrounds. It demonstrates how this can be a true win-win-situation with low entrance hurdles for contributors and the quality of the results evidently profiting from a diverse contributor base. And this is combined with a fierce independence of the project.

So why does WeeklyOSM still struggle with recruitment? Ilya cites burn-out and lack of appreciation. The latter aligns with my recent observation on OSM community member typology, where i noted – among other things – that intrinsically motivated volunteers in the OSM community these days feel grossly under-appreciated.

WeeklyOSM editors are almost universally intrinsically motivated volunteers. They contribute to the project because they are attracted by its mission and its social function in the OSM community – and probably in most cases also by the fact that it is not guided by specific economic interests – as it is the case for many other projects within the OSM community that invite volunteers. That same thing also makes WeeklyOSM rather unattractive to contribute to for people who pursue specific economic interests in OpenStreetMap.

Ilya suggests there is a volunteers recruitment ratio between software development and communication work of 5-7 (with both terms being only vaguely defined of course, but lets ignore that for the moment). But when looking at things like that you already implicitly treat it like a pure numbers game and essentially ignore that if there is one thing turning off intrinsically motivated volunteers, it is projects where you are just a replaceable worker to burn through and replace after some time.

In terms of the actual reservoir of talent and intrinsic motivation in the OSM community (that is people who like and are fond of OpenStreetMap to a level that they – in principle – would like to get involved in their free time for that reason) i would estimate the ratio between people with non-technical skills and talent compared to technical people to be like 3:1 in the opposite direction. If that is true and the numbers from Ilya are approximately right that would mean the OSM currently demotivates non-technical volunteers 15-20 times more efficiently than technical volunteers.

What to do about it? Well, the OSM community would need to become more appreciative of non-technical and non-management work. Much more appreciative. And before you get any ideas – pretense won’t help here, i am talking about actual appreciation. I know i have said this many times in the context of intellectual work and map design in the past but it applies equally to non-managerial social tasks – including communication.

Ilya is a good example for that – he develops software but is also a talented communicator about non-technical matters. And despite being fairly extrovert, and therefore at an advantage compared to many others with social and intellectual talents and interests, it is my impression that he receives much more appreciation from the mainstream OSM community for his software development work than for communication (and even that quite sparsely – due to cultural biases and prejudices).

Normal OSM community members tend to appreciate non-technical work – like news review and aggregation as WeeklyOSM does, social and intellectual reflection and commentary, good map design etc. – as much as technical work. But people with power and influence in the OSM community almost universally have a technical, often software development background and it is my observation that an astonishing percentage of them essentially look down on people doing non-technical work. But it is even worse than that – because of the numbers i mentioned above it is a widespread belief that you can fill the undeniable needs in non-technical work cheaply and ad hoc from a near infinite pool of human capital. The problem with that view is that non-technical skills cannot be created ad hoc, in most non-technical fields, training and experience are essential for good work – as is a supportive work environment.

Which brings me to the other side of the problem: In non-technical fields it is often much harder for outsiders to distinguish between skilled and competent and unskilled/incompetent work than in technical fields. If an unskilled software developer writes bad software that is fairly clearly noticeable even by someone without a technical background, because the software sucks and that usually has immediate negative consequences even outside the technical domain. In non-technical fields, it is often much harder for a non-expert to distinguish between truly competent work and work of people who either pretend competence or who are unskilled and unaware of it. This might contribute substantially to the negative opinion many technical people have of non-technical work.

WeeklyOSM as a whole does excellent work in total, even if details (like the way individual links are framed in the text) are frequently somewhat off. But i am not too sure how many of the readers of WeeklyOSM would recognize it if WeeklyOSM was replaced by a less independent project under the influence of concrete economic interests that would more frequently report on matters in line with those interests, while silently dropping stuff that could damage those.

When i write about map design here, how many of the casual readers can actually determine if those posts provide meaningful insights into important developments in cartography or if they describe mindless and pointless playing around with toys that is of no interest for anyone serious?

And while this problem of recognizing skilled and competent work as such is more severe with non-technical work, it is not absent in technical fields. You can see truly mediocre software projects being drowned in money and praised over the moon in public communication because they fill a niche fashionable at the moment, while there are exceptionally skilled and talented developers working with a long term vision on truly innovative technologies that struggle with earning a modest living doing that.

What would be needed is a vivid, critical and independent intellectual discourse in the OSM community on both technical and non-technical matters, because that is the only way to develop true appreciation in the community for people’s contributions. Because giving everyone a pat on the shoulder – no matter how good their work is – is not really appreciation.

In societies at large it is, in particular, academic and cultural institutions that fuel and support the independent intellectual discourse on matters of importance for society. I have some hope that in the long term the OSM community might also develop some level of institutional support for this kind of work. But this is unlikely, as long as this is economically seen as a zero-sum-game (i.e. that any money invested in these things is viewed to be missing somewhere else).

OpenStreetMap Carto in Taginfo based on Styleinfo analysis

November 19, 2025
by chris
0 comments

Contemplations from the Karlsruhe Hack Weekend

Two weeks ago i participated in the OpenStreetMap Hack Weekend in Karlsruhe. I was not able to take part in many OpenStreetMap related in-person meetings in recent years due to a mixture of lack of budget and scheduling conflicts. So it was nice to meet various people there i had not seen in years. I also managed to get some actual work completed during the weekend, which i will introduce in the following. Historically, i have rarely managed to do so at hack weekends because i have mostly been working on map design – where work is frequently difficult to fit into a limited time frame. I also made progress on some map design tasks this time. These are going to require some more work though and likely will be presented at a later date.

What i managed to complete at the Hack Weekend is generating a taginfo.json file from Styleinfo data and this way get OpenStreetMap Carto into Taginfo projects. This had been on my todo list since creating Styleinfo in 2022 but so far i had never gotten around implementing that.

OSM-Carto in Taginfo

Styleinfo analyzes map styles without much a-priori information on the map style in question. It does so by systematically rendering samples of features with different tag combinations at different zoom levels and checking what the map style actually displays then. I explained this in more detail back then in a blog post. This is expensive to do, analyzing a complex map style like this can take days and it is not a hundred percent complete – some tags and tag combinations tend to be missed by the heuristics. But it produces very detailed data on how the map style actually renders things.

Taginfo includes information of data users (like map styles and various software) on how they interpret OpenStreetMap data based on structured information on the data use provided by the project through taginfo.json files.

Apart from general information on the project, that JSON file mainly contains a large array listing the tags the project interprets with optional data on how that tag is interpreted in the form of a description text, a small illustration image or a link to further information (or all of these). Originally, i had assumed that this allows for exactly one array entry per tag + feature type combination (feature type being node, linear way, polygon or relation). This would have been somewhat difficult for secondary tags like access=*, which a map style tends to interpret very differently in different contexts.

Interestingly though, Taginfo accepts an arbitrary number of entries for the same tag, documenting different interpretations of that tag. At this time i used that possibility to provide information not only on the >600 individual tags OSM-Carto interprets, but on each of the >2500 tag+feature type combinations. I could have further differentiated out the zoom levels (which would have meant ~15k different rendering variants) – but decided against it. If you want this detailed information on the map style, you should use Styleinfo.

The other interesting thing about how Taginfo deals with the projects is that it does not cache the small images illustrating the tag use, but includes them directly from the URLs specified in the taginfo.json file. That was fairly unexpected, considering nothing about this is mentioned in the privacy policy – the OSMF has some homework to do here. So, when you browse information on projects in Taginfo be aware that the images shown in the table there are directly requested by your web browser from wherever the project provides them from.

The bottom line for you as a Taginfo user is that you now have the information on what tags are interpreted by OSM-Carto, and how they are interpreted, available in Taginfo – including small rendering thumbnails and links to Styleinfo. I also provide links to the taginfo.json files for the other styles featured in Styleinfo, but i have not submitted them for integration in Taginfo. This is up to the maintainers of these projects. For my own alternative colors style i plan to do that, but first i want to update the analysis in Styleinfo since a lot of things have changed since 2022 – much more so than in OSM-Carto.

OpenStreetMap Carto in Taginfo based on Styleinfo analysis

OpenStreetMap Carto in Taginfo based on Styleinfo analysis

Why so late?

Why did it take almost three years to make this available? As mentioned, this had been on my todo list since i created Styleinfo. But my free time is limited and this did not have high priority. I developed Styleinfo for my personal education and as a strategic investment into systematic testing in map design. I made the results of this available for everyone else to study and use as reference to the map styles analyzed. But i had fairly little personal interest in also making this information available in Taginfo – hence the low priority to do this in my free time.

But don’t make the mistake to conclude now that nothing could have been done to expedite this. Because i was talking only about what i do in my free time. Paid time is a different matter. It ultimately took me about one work day to implement this. If you had asked me for an offer to do this in 2022/2023 i would probably have calculated a bit more (and to be accurate: I had already read up on the taginfo.json specs before the Hack Weekend). The bottom line is: You could have gotten this already in 2022/2023 simply by moving it from my limited free time todo list to my paid time schedule – with a rather minimal budget.

Why am i pointing this out here? Because i think it well illustrates a larger issue the OSM-Community currently struggles with. It is beyond doubt that money and economic aspects play an increasing role in OpenStreetMap. You can criticize that because you wish back the good old days when OSM was fully under control of hobbyists. Alternatively, you can dismiss that criticism as naive and backwards. But both of these perspectives miss some really important aspects.

Money is neither inherently good or bad for OpenStreetMap, it depends on how you use it. And one of the things people in positions with influence on budgeting decisions (both in private businesses and in organizations like the OSMF and FOSSGIS) seem to almost universally fail to see is that a huge part of the human potential (available time and competencies) in the OSM community exists in the form of the following two groups of people:

  1. Pure hobbyists who invest their free time into the project, but who exclusively do this out of intrinsic motivation. It is almost impossible to positively motivate those with money but very easy to de-motivate them with it. Some of these will be open to being offered economic benefits (like travel cost coverage, paid assistance), but very few will be willing to ask for such. Attempts to try to influence their decisions on how they invest their free time with money – either directly or indirectly – will usually have a highly negative effect on motivation.
  2. People who have some level of professional connection to OpenStreetMap, but who are also investing their free time into the project separately from their professional time and who – like the pure hobbyists – spend their free time in the project purely out of intrinsic motivation. For these people, time spend on OpenStreetMap can either be professional time or personal time and they separate between the two. In their decisions on how to make use of their free time, these people tend to act like the pure hobbyists, while on their professional time they adjust to market demands.

For symmetry you can define two other groups of OSM community members:

  1. People who – like the second group – spend both paid and unpaid time on the project, but who do not really separate between the two. These often come from one of two backgrounds: (1) Idealist professionals who took a job related to OSM out of idealism and who, therefore, get involved into their work beyond the time they are actually paid for and (2) Former pure hobbyists who have turned their hobby into a profession. In contrast to the second group, this group is open to adjust also their free time involvement to economic forces and tends to be much more willing to proactively ask and lobby for funding for their free time work than the second group.
  2. Pure professionals who are involved in OpenStreetMap in their paid work, but who are not involved beyond that.

You can easily see that these four groups are not inherently discrete, they form a continuous spectrum. And, as you can probably imagine, i belong into the second group.

My point here is that the vast majority of money spent in the OSM community (both by private businesses and non-profit organizations, both directly in the form of paid time and indirectly in the form of subsidies and investments) is targeted at the third group. But what people often don’t realize is that this focus on the third group is

  • interpreted by members of the first and second group as a sign of lack of appreciation for their intrinsically motivated volunteer work.
  • leading members of the second group to orient themselves professionally away from OpenStreetMap, because of the lack of demand for their work compared to that of the third group.
  • incentivizing members of the second group to change towards working more like the third group and let their free time involvement be more influenced by economic forces.
  • putting pressure on members of the fourth group to get involved in OpenStreetMap beyond their paid time.

Some of these effects might be considered desirable. But keep in mind what i said earlier: That a huge part of the human potential in the OSM community exists in the form of the first two groups. It is also my observation that the third group tends to be the most homogeneous of all four groups – most male dominated, least culturally diverse.

At the Karlsruhe Hack Weekend there are people from the first three groups present (the fourth rarely so – due to the nature of the event) and because of that it can function as a forum of exchange between these groups. But you can also feel the economic and social dominance of the third group, which sometimes makes a balanced exchange of views and ideas difficult.