Imagico.de

blog

May 1, 2026
by chris
1 Comment

Follow-up on FOSSGIS

English version based on an automatic translation with deepl.

Following the discussion about my post on FOSSGIS membership fees, it has become clear to me that my account – and especially the suggestions I made – are somewhat incomplete.

I have quite clearly criticized the fact that, since becoming a local representative of OpenStreetMap in Germany in 2017, the FOSSGIS association has failed to resolve the latent conflict between its role as an advocate for professional developers and users of free and open-source software in the GIS sector and its role as a representative of the German hobbyist mapping community. And I have made suggestions regarding membership fees and the association’s cultural openness to address this problem. However, these too – as should be clear to most – would not truly resolve the conflict.

Therefore, I would like to outline here, as a supplement, how the conflict could be addressed at the strategic level and, hopefully, resolved in a sustainable manner.

The problem with the association’s current organizational structure is that opening it up substantially to the hobby mapper community will only work if a large number of hobby mappers join the association and become active within it – bringing with them their own ideas about working methods and their culture of cooperation. The result would be a takeover of the association by the OSM community. Compared to the current situation, the problem would essentially just be reversed. The reason for this lies in the association’s structure, which is centralized at both the board and member levels and based on majority decisions.

The obvious solution would be to split FOSSGIS into two associations. And if FOSSGIS were actually taken over by the OSM community (which – as already indicated – would be hardly realistic due to the widespread lack of interest in the German hobby-mapping community, even under favorable conditions), this would be the most likely outcome, as FOSS developers and users would then presumably organize themselves elsewhere.

However, this solution would undermine the opportunities and synergies mentioned in the previous post, which exist precisely in the connection between Free and Open Source Software and OpenStreetMap.

A federal structure would be the strategy for sustainably balancing professional advocacy and representation with the organization of the hobbyist mapping community within an association. The two major segments in the association’s goals and its operations would largely coexist autonomously, could utilize shared structures, but would not be required to do so. Members could freely participate in the systematic pursuit of the respective goals of the two autonomous parts of the association, based on their own distinct formal and informal rules, without having to submit to the rules of the other segment.

It is important that this (internal) autonomy is actually formalized – in other words, that we don’t just say: “Yes, you can act freely in your working group, but in case of doubt, the board or the general assembly can shut you down at any time by a simple majority vote”.

To ensure that the whole thing remains an association not only formally but also de facto, a supervisory body would need to be created to mediate between the autonomous structures and the necessary and sensible central decisions (for example, regarding budget issues). This body would need to be composed of equal representation, ensuring that one part of the association does not dominate the other.

This type of structure is nothing new; it already exists, for example, in associations that manage individual large FOSS projects. In such cases, there is usually a supervisory board composed of an equal number of developers and users.

I realize that the chances of the FOSSGIS association actually undergoing such a fundamental restructuring (i.e., the general assembly securing the necessary 3/4 majority) are significantly lower than the chances of my ideas regarding membership fees being implemented. My point is to make it clear that this is a problem that can be practically solved if the collective will is there, and not an unsolvable dilemma that we simply have to live with.

April 17, 2026
by chris
3 Comments

The Saga of FOSSGIS Membership Fees

English version based on an automatic translation with deepl.

I had actually already decided not to write this blog post – but recent developments have led me to reconsider that decision. However, I’d like to start from the beginning so everyone can follow along, including those who aren’t FOSSGIS members and therefore likely haven’t heard much about these issues until now.

Background

Historically, the FOSSGIS association essentially began as an advocacy group for professional developers and users of free and open-source software in the GIS sector. However, the association’s goals were defined much more broadly from the start, and during my time there, FOSSGIS has generally always demonstrated an openness to activities outside this core area, which I have always viewed as very positive. In the end, however, this only applied as long as the dominance of professional interests was not called into question. In other words: While the generally significant role of development and use in the non-professional, private sector within the FOSS field was accepted and acknowledged, it was clearly positioned within the association as subordinate to the professional sector – something that is not generally the case in the global FOSS community.

At the end of 2017, the FOSSGIS association became the local representative for OpenStreetMap in Germany. This immediately called into question the dominance of professional interests within the association, and there was actually an opportunity for the German OSM mapping community to take over the association. This did not happen, primarily for three reasons:

  • OpenStreetMap was already an important topic within the association, particularly among professional developers and users. So it wasn’t as though OpenStreetMap was completely new to the association and OSM activists found an untapped field there; rather, the topic was already established and integrated into the association’s professionally oriented structures.
  • The German mapping community was and remains – despite being one of the largest and most active local communities worldwide – highly individualistic and very loosely organized. The overwhelming majority of mappers in Germany are content to map on their own and, beyond occasional local meetups, feel no need to organize or get involved – especially not where there are no existing structures and something has to be built from scratch.
  • The hurdles for formal membership in the association were quite high, especially in early 2017 to 2018; one had to submit a written membership application (on paper) and pay a membership fee of EUR 30 per year, which was double the OSMF membership fee. As a result, the number of hobby mappers who joined the association in the early years due to FOSSGIS’s new role was likely significantly lower than the number of existing professional members with ties to OSM. In addition, having a say in the association’s formal decisions was (and still is) de facto tied to physical attendance at the annual general meeting. Online participation is not provided for (with the exception of the COVID years due to a special provision by law), and the delegation of votes is only possible to a very limited extent (a member present can only have one vote delegated to them).

Thus, not only was a takeover of the association by the OSM community practically ruled out, but de facto, hobby mappers have virtually no influence within the association.

In 2020, the general meeting decided to increase the membership fee for individuals from EUR 30 to EUR 40. At the same time, the membership fee for corporate members was doubled from EUR 100 to EUR 200, and a decision was made to create a permanent paid (part-time) position within the association for administrative work. I was not at the meeting at the time, so I cannot report on the discussion there beyond what is in the minutes (For those who remember: that was the legendary FOSSGIS conference held virtually on the eve of the first pandemic lockdown).

The paid positions within the association, which had previously been limited to internal administrative roles, were expanded in 2023 to include a so-called OSM Advisory Office (see here – the details of the job description appear to have been removed in the meantime). This, along with the ideas behind it and their practical development, would be a topic for a separate post; I’ll omit it here for the sake of brevity. Along with the announcement a month ago of the creation of another position for the development of OpenStreetMap training courses within the framework of FOSSGIS, it can be said that the association is increasingly active in the area of OpenStreetMap services, and is primarily focusing on paid work. Attempts to raise funds for this seem to have had mixed results – the idea of a funding program presented at the 2025 general meeting (I wrote about it here) does not seem to be going particularly well – instead, there appears to be a growing effort to seek public funding. This is particularly noteworthy given the wide range of unpaid consulting and lobbying work that has been carried out for many years by the hobby-mapping community, and which now, of course, stands in contrast to the paid activities within FOSSGIS.

It is interesting to note in this context that FOSSGIS is increasingly presenting itself as OpenStreetMap Germany, thereby implying a claim to represent the German OSM community. On the one hand, this is also emphasized in the association’s public communications, where it speaks of us, the community, but at the same time distances itself from the community and presents the association as a link to the community.

The Membership Fee

So much for the background. Prior to this year’s general meeting, the board sent a proposal to the members to increase the membership fee once again, this time to EUR 60 – meaning, combined with the previous increase, a doubling within seven years, which would position FOSSGIS at the very top among OSMF local chapters in terms of membership fees. I didn’t attend the FOSSGIS conference this year either, so I wasn’t at the general meeting, but apparently there was a discussion and the board’s proposal was not accepted; instead, the board was tasked with initiating an online general meeting to discuss the issue and reach a decision.

After the initial announcement and the anticipated approval by the general meeting, I had already decided to use this as an opportunity to terminate my membership in FOSSGIS, but I was pleasantly surprised to find that not only was there a critical discussion of the proposal, but that it was also decided to discuss the matter as broadly as possible, at least within the association. And with this post, I would like to try to open this discussion to the OSM community outside the association as well. Whether this will ultimately be heard, of course, remains to be seen. In internal association discussions over the past few years, active members of the association, including those on the board, have repeatedly made it clear that they want the association’s decisions to be made exclusively within the association – uninfluenced by outside discussions.

To put the membership fee amounts into context: The standard FOSSGIS membership fee, currently EUR 40 (proposed to be EUR 60 in the future), applies to working members. For non-working members, there is a reduced fee of currently EUR 10 (proposed to be EUR 15 in the future). The association does not define working member; it is entirely a self-declaration. This distinction, especially in Germany with its current demographics, is quite a slap in the face for people who have to work to make a living, while people who do not have to work due to substantial non-work income pay less – regardless of whether this income is higher or lower than the work income of those who are doing paid work.

If we compare the annual membership fee to other professional associations and interest groups in Germany, even EUR 60 isn’t particularly high. A more interesting comparison is within the OSM community. Here are the annual membership fees for individuals for various organizations:

  • OSMF: GBP 15, free for active OSM contributors
  • OSM France: EUR 20
  • OSM Switzerland: CHF 20
  • OSM Austria: free
  • OSM UK: GBP 5
  • OSM US: USD 20
  • OSGeo Oceania: free
  • OSM Belgium: free
  • Wikimedia Italia: EUR 25
  • Stowarzyszenie OpenStreetMap Polska: PLN 50 (EUR 12)
  • Asociación de Cartografía Colaborativa de Colombia: COP 350 (EUR 82), COP 175 (EUR 41) for active OSM contributors

In short: Even at the current rate of EUR 40, FOSSGIS is among the absolute top tier in the OSM sector; at EUR 60, it would be the most expensive OSMF local chapter for active OSM contributors. Among western countries with larger mapping communities, the gap would be enormous.

The most common argument I hear in favor of high individual membership fees is that the association does not want to become dependent on funding from external sources. However, this argument only holds water if an association makes a serious effort to manage its budget prudently, using only the limited contributions that individual members are able and willing to provide. This is clearly not the case with FOSSGIS. Even with a membership fee of EUR 60, the projected individual membership fees for FOSSGIS total less than EUR 20k. This is not even enough to finance the administrative position created in 2020. Personally, I find the idea of an OpenStreetMap Germany association that is financed by individual contributions and is not dependent on external interests for funding regular expenses quite appealing. But for that, it would be necessary to build the association almost entirely on volunteer work. FOSSGIS clearly decided against this many years ago, by 2020 at the latest. To now suggest that the membership fee increase somehow ensures financial independence does not align with the association’s economic reality.

What is always at stake in this whole issue is the tension described in the background section regarding FOSSGIS: the conflict between representing the professional interests of FOSS users and developers – including those related to OSM – and the claim to represent the German community of hobbyist mappers. A high membership fee results – whether intended or not – in the number of members without professional interests in the association remaining low. While the association may indeed have the sincere intention of also representing the interests of the German OSM community, this is clearly not a case of democratic representation by representatives from within the community itself, but rather by individuals with their own professional interests, which do not necessarily align with the collective interests of the community, but at best act as benevolent trustees (but with inevitable conflicts of interest).

My Proposal

I think the FOSSGIS association is at a crossroads here. The underlying conflict – which began in late 2017 when FOSSGIS formally became the local representative for OpenStreetMap in Germany, and which the association did not really resolve for over eight years – could definitely come to a head here. Will the association substantially open itself up to the hobby mapper community in Germany – in the sense that mappers are not only welcome to assimilate into the existing association culture, but also in the sense that they actually expand and reshape the association with their own culture? Or will the association continue to fly the OpenStreetMap Germany banner, but exclusively as a label for its own professional activities and those of its members?

I have already mentioned that this question does not depend solely on decisions made within FOSSGIS, but also on whether the mapping community in Germany manages to organize itself sustainably, independent of professional interests. But FOSSGIS is making things too easy for itself when it claims to be open to anyone who wants to get involved. Because, as I said, that’s only true for those who are willing to adapt extensively to the existing association culture.

Against this backdrop, my proposal for membership fees would be:

  • Eliminate the distinction between employed and unemployed members.
  • Lower the standard membership fee, thereby sending a clear signal that the association is explicitly open to FOSS users/developers and mappers without commercial interests. Proposal: EUR 30.
  • Set a significantly reduced fee for active OSM contributors (the OSMF’s definitions could be adopted here). Proposal: EUR 10.
  • Create a support membership fee for individual members, intended for anyone who derives substantial income from FOSS development, FOSS use, or the use of OSM data, but also open to all members on a voluntary basis. Proposal: EUR 90.
  • Corporate memberships tiered according to number of employees/revenue. The proposal from the general meeting seems reasonable here, with the exception of the idea for solo self-employed individuals. The idea that an employee with a FOSS/OSM connection should generally pay a lower membership fee than self-employed individuals does not seem objectively justifiable to me. Nor does the alternative interpretation that solo self-employed individuals can or should have an independent corporate membership in addition to an individual membership. A supporting membership for all members with a professional connection to FOSS/OSM therefore seems more sensible to me.

In addition – and this is actually more important than membership dues – it would be of fundamental importance for FOSSGIS to be able to present itself credibly as the representative of OpenStreetMap in Germany that all of the association’s activities related to OSM be open to broad participation by the German OSM community, and not closed and reserved solely for association members. I consider this very important, but I also realize that this idea is likely to be very unpopular within the association. The way communication has often been handled in the past – treating things as internal association matters where outsiders have no say – speaks volumes. But truly substantial changes simply don’t happen without conflict.

In Conclusion

I hope that these remarks provide OSM activists in Germany who are not members of FOSSGIS with insight into the latest developments within the association, which also presents itself as their representative. And that, against this backdrop, my suggestions might find support or at least a positive response, encouraging others – especially hobby mappers – to articulate their own ideas.

Perhaps the fact that I’m discussing this publicly here will even generate some international interest. I’ve already outlined the unique position FOSSGIS would occupy within the global OSM community with an annual membership fee of 60 euros for regular mappers.

What I’d also like to note is that – and I’ve emphasized this several times in the past – I view the culture of open discussion within the FOSSGIS association as something very positive. However, so far it has been almost entirely limited to in-person events. If the association manages to open up this culture to digital channels and beyond the boundaries of its membership, this would have enormous potential for productive cooperation with the OSM community, especially beyond Germany. It is in this spirit that I would like this post to be understood – while I do see the conflicts as I have highlighted them here, I also see the enormous potential of this connection – provided there is a collective will within the association to adapt and open up, and to accept and support a truly new diversity within the association.

Update: Changed a formulation above based on comment – see the discussion of the German version.

April 10, 2026
by chris
4 Comments

The ways of the water in OpenStreetMap

Mapping of surface water is evidently a huge part of recording the physical geography in OpenStreetMap. Water covers two thirds of the planet and is one of the most important resources for human life.

I have written quite a bit about mapping practice of the edge of the ocean in OpenStreetMap. Here i now want to discuss a bit the mapping of flowing water using – in OpenStreetMap terminology – waterways.

The purpose of waterways in OpenStreetMap is to map the flow of surface water as well as – in some cases – the routes for human navigation on those waterways using ships or boats. There are five tags widely used for this purpose and all five of them originate from the very early days of OpenStreetMap. They were tags of the first hour so to speak and were never supplemented by any new tags that come close to these five regarding the scope of use.

Of course, this choice of primary classification of waterways was heavily shaped by the UK geography and could not easily be applied in other parts of the world – hence the meaning of these tags changed quite a bit as the scope of OpenStreetMap widened. This change and what the five waterway tags are de facto used for these days is what i want to discuss here.

Use of different waterway tags in mapping around Yakutsk, Russia.  This is fairly patchy regarding smaller watercourses, which is quite typical for many parts of the world.

Use of different waterway tags in mapping around Yakutsk, Russia. This is fairly patchy regarding smaller watercourses, which is quite typical for many parts of the world.

The local mapping of waterways

What the waterway tags have all in common is that they are meant to be used and are used to map flowing water locally. That means the mapper sees a body of flowing water on the ground and maps it with a waterway, tagging the local characteristics. This then, of course, connects to the waterway equally mapped locally by the next mapper in the next village. But the tagging of these can be completely different based on different locally observable properties in the two places. The name, for example, might differ – or even the primary waterway tag. This paradigm of local mapping is important to keep in mind in this analysis and when practically mapping waterways. In practical conversation about watercourses in everyday life people often view, for example, a river less as a local element of geography and more as a feature of possibly thousands of kilometers size extending across several countries. There are attempts at mapping this paradigm of watercourses in OpenStreetMap as well- using waterway relations, but this has severe issues with verifiability and has therefore not gained much traction. In this discussion i am focusing fully on the local mapping using individual waterway ways.

The legacy waterway tags

These are the five waterway tags and their approximate original meaning based on the UK understanding of geography.

  • waterway=stream represents smaller naturally formed watercourses.
  • waterway=river represents larger naturally formed watercourses. A large river in the UK is, of course, quite puny by global standards.
  • waterway=canal represents artificial watercourses built for the purpose of transportation, waterpower or irrigation. In the UK this practically mostly means transportation. The UK has a fairly large network of canals originally built for commercial transportation, which are relatively small compared to many canals in other countries and which are today often mainly used for recreational purposes.
  • waterway=ditch represents an artificial ditch dug for draining of adjacent land through either surface waterflow, percolation of water in the soil or through drainage pipes ending in the ditch.
  • waterway=drain represents an artificially constructed watercourse with a lined surface for transporting away excess surface water or wastewater.

The delineation between waterway=stream and waterway=river is interesting. The original idea apparently was that the really wide rivers (which, in the UK, are essentially only the estuarial sections of large rivers like the Thames) are to be mapped exclusively with polygons, the medium width watercourses with a linear way tagged waterway=river and the most narrow natural watercourses with waterway=stream. And since, in the UK, fast flowing larger rivers are rare and most watercourses of the waterway=river class occur in relatively flat terrain with moderate to slow flow rates, the width of the river is a fairly good proxy for the size of a river in terms of water volume per time transported. And – in the same fashion – it is rare for a river in the UK to substantially widen first and then become more narrow again, unless there is a lake – so the situation that a waterway=river would in downstream direction connect to a waterway=stream based on a width based delineation is rare. As a result in the UK this tagging practice directly represented the traditional cartographic paradigm of single line depiction (waterway=stream), double line depiction (waterway=river) and depiction of actual surface water extent (polygon mapping) in moderate to large scale maps.

Water features in the legend of Ordnance Survey map 1:50k

Water features in the legend of Ordnance Survey map 1:50k

The artificial waterway classes have no explicit size constraints, their actual range in watercourse sizes derives from the practical sizes these features have in reality – originally in the UK and later worldwide. I will discuss this more in detail later.

So essentially – the five waterway tags as originally devised can be alternatively classified by two binary delineations: natural vs. artificial and narrow vs. wide. How the five tags map to these can be seen in the following table:

narrow wide
natural waterway=stream waterway=river
artificial waterway=canal
waterway=ditch
waterway=drain

Together these tags are currently used more than 35 million times in OpenStreetMap – which makes it one of the top feature classes in OSM – after buildings, roads, addresses and landcovers.

The meaning of waterway tags today

Of course, this classification has developed since it was originally devised. Even within the geographic context of the UK there were gaps in this classification system and more so in other parts of the world.

But let’s first cover what stayed mostly as originally devised. The classification into natural and artificial waterways remains unchanged to this date. But it is important to understand that natural waterway does not mean it is in a pristine natural state. It essentially only means that the water flow represented by the waterway is of natural origin. The Rhine in the upper Rhine valley at the border between France and Germany, for example, has been extensively modified by humans, yet it remains classified as a natural=river, because the water drainage at large is not modified by the human intervention. An artificial canal, on the other hand, might divert water from a river along the side of a valley where water naturally would not flow.

Plan of the historic straightening of the Rhine in the 19th century

Plan of the historic straightening of the Rhine in the 19th century

Strictly speaking, the classification into natural and artificial waterways is not a local characteristic, looking at a watercourse locally will not always allow you to make that distinction reliably. Still, this classification has been applied fairly diligently and consistently by mappers and the idea that canal/ditch/drain are artificial and stream/river are natural in origin, though not necessarily in their current shape, is not widely challenged.

What has become more of an issue is the distinction among the artificial – and to some extent also the natural waterway types. It is already visible in the original definition of the five classes above that the system for artificial waterways is incomplete. waterway=canal is narrowly defined regarding function (transportation, waterpower, irrigation) while both waterway=ditch and waterway=drain are both even more narrowly meant to represent specific role in drainage of excess water in a temperate and humid environment.

While originally, none of the artificial waterway types had an explicit size restriction in the UK context, they were all customarily limited in the scope of sizes and also depicted in maps accordingly, which further re-affirmed the established size constraints even outside the UK. Since transportation use is dominant in the early use of waterway=canal, this was, in early years, understood to be a large waterway, at least the size of a waterway=river, often even larger (a smaller waterway=river are usually not navigable). And due to the function of drainage of adjacent land, waterway=ditch tended to be used nearly exclusively for very small waterways, sometimes located in a fairly deep ditch, but the waterway itself rarely more than 1.5m wide. waterway=drain – since meant primarily for lined watercourses – also tends to apply primarily to relatively small watercourses in the UK context.

But these size constraints, of course, clashed with the geographic reality in many parts of the world, for example:

  • In less universally humid climates artificial watercourses for irrigation and general water supply exist in all sizes. For these, mappers saw themselves confronted with the choice of either using waterway=canal and this way clashing with the size expectations of data users for those, or extending the use of waterway=ditch/waterway=drain to freshwater infrastructure. Both practically take place. For example, the qanats in North Africa and the Middle East are often mapped with waterway=canal while the levadas on Madeira and galerías on the Canary Islands are usually tagged with waterway=ditch/waterway=drain.
  • In regions prone to extreme rainfall events there are often lined artificial drains in urban environments of substantial size, exceeding, by far, the dimensions waterway=drain is traditionally used for.
Levada on Madeira - does not fit into the traditional waterway classification system in OpenStreetMap, Image by JOEXX - CC-BY-SA

Levada on Madeira – does not fit into the traditional waterway classification system in OpenStreetMap, Image by JOEXX – CC-BY-SA

For natural watercourses the main developments have been that

  • waterway=river mapping has been extended to also include very large rivers, which originally were envisioned to be mapped only with polygons. That happened because mappers realized that with only polygon mapping important information on the direction of waterflow is lost.
  • The classification into river/stream is usually made in a way that enforces that a river will not turn into a stream in downstream direction, even if it narrows substantially along its course. Abiding by this principle is, by most mappers, put above applying a consistent width classification.

The issue of width

So what are de facto the size ranges the different waterway tags are used for? We don’t know for sure, but we can try to analyze those waterways that have a width explicitly tagged. These are not necessarily representative for all waterways in general and the percentage of waterways with a width tag is small. Still it will give us some idea.

Mappers have the tendency to estimate and round width values so there is no continuous coverage of the number range, but peaks at rounded values. This is strongly visible in the histograms i show in the following.

Distribution of tagged width values of waterway=stream ways

Distribution of tagged width values of waterway=stream ways

waterway=stream is expected to be limited in the range of width values because it is clearly understood to be used only for smaller natural waterways. And the distribution of width values mostly reflects that. Values less than 2.5 meters exceed those above by a factor of more than ten. There are still quite a few much larger values tagged in substantial numbers, which has a number of reasons:

  • Mappers preferring to tag a waterway as stream to achieve a more desirable result in rendering, especially for smaller rivers and sidearms next to a big river, or to ensure the above mentioned principle that a waterway=river does not connect downstream to a waterway=stream.
  • Local naming conventions indicating a smaller type of waterway (like Bach in German) leading mappers to base their classification on this rather than physical characteristics.
  • Waterways with highly variable water levels being width tagged according to the river bed width but classified according to lower water levels that don’t fill the river bed.
  • Mis-tagging of width expecting a different default unit than meters.
Distribution of tagged width values of waterway=river ways

Distribution of tagged width values of waterway=river ways

waterway=river mirrors this – rivers with a width less than two meters tagged are just a few percent of all the width tagged waterway=river. But only above four meters the number of width tagged waterway=river exceed those of width tagged waterway=stream. So the bottom line for the two natural waterway classes is: They are quite clearly mostly used as a width distinction although the transit between them is quite a bit higher than the established rule of thumb of the OSM community (if it is practically feasible to jump over it, it is a stream) would indicate. Practically, jumping across a two meter wide watercourse is already a stretch even for a fit person on flat terrain.

Distribution of tagged width values of waterway=canal ways

Distribution of tagged width values of waterway=canal ways

With waterway=canal we can observe the problem that i already described above. The majority of features with a width tag have a width of at least 3m – which is about the smallest width of canals build for the purpose of transportation. But there is also a substantial volume of features (>10 percent) with a width of just one meter or less specified – In Europe, width=1 is even the most commonly tagged single value of width for waterway=canal.

Distribution of tagged width values of waterway=ditch ways

Distribution of tagged width values of waterway=ditch ways

waterway=ditch is very similar in the distribution of values to waterway=stream – including the long tail of high width values. An additional reason for this for waterway=ditch could be that width tagging sometimes measures the ditch as a topography feature and not the actual water cover in the ditch.

width values of less than 1m are somewhat more common, relatively speaking, for waterway=ditch than for waterway=stream. But this is likely at least partly due to a general mapping bias. Ditches in their real world distribution are concentrated in relatively densely populated and hence relatively well mapped areas while small natural watercourses exist everywhere. Hence the latter are probably more severely under-mapped for small sizes than the former.

Distribution of tagged width values of waterway=drain ways

Distribution of tagged width values of waterway=drain ways

waterway=drain has a stronger weight of both the very small and the very large values in the distribution of width values. It also features a larger number of values with units other than meters specified than the other waterway types. That makes it likely that at least some of the very large values are mis-tagged assuming a different default unit. The strong dominance of very small values could, at least to some extent, result from this being the preferred tag for lined artificial watercourses – but clearly meanwhile also for such carrying fresh water for irrigation or other purposes (usage=irrigation has 3200 uses on waterway=drain). But the tag is clearly not limited to lined features. There are many areas where it is practically used interchangeably with waterway=ditch. The original idea of delineation between waterway=ditch and waterway=drain was for the former to be for features to collect excess water and the latter for carrying away excess water. This is not very consistently followed these days any more.

Other waterway types

There is the obvious question, of course, if there are any new waterway types in addition to the traditional five than have been introduced since then. Apart from waterway values that do not represent watercourses (waterway=dam, waterway=weir etc.) there are a number of specialty values that have gained some adoption and also some failed attempts at separating out things from the traditional five tags. Here a quick summary:

  • waterway=tidal_channel has been introduced in 2019 as a means to map the water flow at a tidal coast, especially in vegetated settings (salt marches, mangrove). This differs from the tidal sections of rivers/streams, because here the water flow fully reverses with the tides, while in a tidal river, the water level changes with tides while there is a continuous downstream water flow. It has gained some adoption but with 29k uses it is still very far away from becoming one of the main waterway tags.
  • waterway=pressurized has been introduced in 2018 and was originally intended as a blanket tag for any enclosed conduits of water that are fully filled with water, either pipelines or underground tunnels, and both natural and artificial. Practically, the tag is almost exclusively used for pipelines and artificial underground tunnels carrying water, >90 percent of these are double tagged with man_made=pipeline. 12k uses.
  • waterway=flowline is a recent introduction from 2024 as a tag for mapping the drainage network within waterbodies mapped as standing water (lakes, reservoirs). This has traditionally been done using the main waterway tags – and it still is. However, there has long been disagreement among mappers if this kind of mapping is desirable, i.e. if a river ends where it enters a lake and begins again at the other side or if the river goes through the lake. This tag is an attempt to resolve that disagreement. It does, however, have the disadvantage that it does not differentiate between the different waterway types – those you would need to infer from the other waterways it connects to. 47k uses.
  • waterway=wadi has – for some time – been an attempt to expand the idea of the original five waterway classes as climate and region specific classifications to arid and semi-arid parts of the world. This has not been successful though and the tag never developed a well defined meaning globally, largely because it was widely applied independent of the verifiable presence of water flow. It is now hardly used in active mapping any more and has just above 3000 remaining uses.
  • waterway=drystream is a rather odd idea for a waterway type that gained some limited popularity from 2015 on. In essence, it is an attempt to map relief structures that seem like to have originated from waterflow without verifiable waterflow being a condition for using the tag as waterway. But, in contrast to tags explicitly mapping relief structures like natural=gully and natural=earth_bank, an actual relief form is not considered a defining element for this type of waterway either. So, in essence, this is a tag for something that a mapper considered to have originated from waterflow but that does not qualify either as an actual waterway or a relief form. The tag currently has 17k uses, mostly in Russia.
  • waterway=derelict_canal has actually been around for about as long as the five main waterway tags so you could consider it a sixth legacy waterway type. It is used for what today would most likely be tagged with disused:waterway=canal or abandoned:waterway=canal. It has minimal use with just about 2600 applications, but is more established than the lifecycle prefixes in this case.
  • waterway=fish_pass is a tag for a very specific and narrow use case with just 3200 uses, but is quite well established for that specific purpose.
  • waterway=link is an outlier in the waterway tags because it is not used to map a watercourse, but for connecting boating infrastructure at the edge of a waterbody to the waterway line. It essentially constitutes preemptive mapping for the router, it is based on the assumption that this kind of data is necessary for routers to route for navigation on waterways. Since it is almost exclusively used in cases where the water covered area is mapped with polygons, it does not actually convey any additional information in most cases. 12k uses, most in the US and central Europe.
  • waterway=artificial is essentially an imports-only tag that has been introduced for importing waterway data where the import source differentiates natural and artificial waterways, but does not provide enough information to classify into the three established artificial waterway tags in OpenStreetMap. It has not been in active use for many years and more than half of the features originally imported with that tag have meanwhile either been re-tagged or removed. About 14k features are remaining.
  • waterway=brook was an attempt to separate out the very small watercourses from the traditional waterway tags. This endeavor did not succeed though, and there are only 1600 uses of the tag now. The tag notably did not maintain the distinction into natural and artificial waterways in primary tagging, it was meant to be used for both of these. And it lacked a clear criterion to delineate it from the established waterway tags.

None of these tags comes anywhere near the big five in terms of numbers in use though.

Conclusions

I hope my analysis made it a bit clearer how watercourses are mapped in OpenStreetMap and how this system of mapping came to be the way it is.

Many readers are probably going to think that this system of classification is not very good and some might outright suggest to replace it with a different system. That is not likely to happen of course. But the question, none the less, is: Did the free form tagging system of OpenStreetMap work well here or did it fail – and in case of the latter: why did it.

As i like to say: The tagging system in OpenStreetMap is like the geographic reality: Organically grown, full of weirdness and inconsistencies – yet largely functional. And i think this mostly applies to the waterway classification as well. The fact that we have not abolished or substantially modified any of the five main original waterway classes does not mean OpenStreetMap is limited to those to characterize waterways. We have plenty of secondary tags that provide additional information. I mentioned just a few of them here (width, usage).

But waterways also demonstrate in my opinion what i see as a substantial deficit in the way tagging consensus is developed these days – that the community largely shies away from discussing clear delineations of tags. In the large and diverse OpenStreetMap community of today views on supposed tag delineation unavoidably differ. But instead of facing these differences, engaging in discussion and arguments and working towards consensus, people often choose the superficially easier way to leave such things unresolved and to deliberately stay vague in delineation of tags. The waterway=stream/waterway=river delineation is a good example here. For more than a decade this has been tied to the deliberately vague idea of the jump test (if you can jump over it, it is a stream). That is not bad as a rule of thumb, for example for a mapper crossing the watercourse in a car and casually assessing the size from the window. But it would have been of much benefit for both data quality and the ease of mapping if this rule of thumb had been concretized with a numerical value at some point.

Small watercourse in forest

Northern Greenland in Musaicum Greenland

April 1, 2026
by chris
1 Comment

The Musaicum Greenland

There is another extension available for my Musaicum satellite image product – covering the island of Greenland.

The Musaicum Greenland

Greenland has been in the political news quite a bit in recent months, so it is probably a fitting time to introduce the new image.

As long time readers of my blog know, Greenland is also – contrary to marketing claims – not fully covered by Sentinel-2 image data. Creating a Musaicum extension for all of Greenland, therefore, required changing the Musaicum process to allow use of Landsat image data. Some subtle color differences between the Sentinel-2 and Landsat based parts of the mosaic are inevitable due to the different characteristics of the sensors, but it still is in essence a seamless transit. This also makes the Musaicum Greenland the first visual color image at this resolution class that is produced to a common quality standard for the whole area of Greenland.

Ilulissat Icefjord

Ilulissat Icefjord

The Musaicum Greenland replaces my previous regional image product of Greenland from 2015 – the Landsat mosaic of Greenland. A bit more than 10 years ago this was a milestone in high quality mosaics of more remote regions, and to this date it remains the most uniformly consistent image product of Greenland at higher resolution available – with exception of the Musaicum image introduced here now.

For better comparison i produced samples of many of the same spots where i also showed samples of the Landsat mosaic – in different projections though.

I also offer the option to provide the image with local contrast adjustment – a method i originally introduced for my Antarctic mosaic and that is useful in areas with strong brightness contrast – like in Greenland with the bright ice sheet and glaciers and dark bare ground on the other hand.

Comparison of normal tone mapping with local contrast enhancement – larger: normal, local contrast enhanced

I have not updated the Mercator image tiles yet, that should follow in the near future. – See below for update.

If you are interested in using this new image product you should have a look at the product page.

Rivers at the coast in Hagen Fjord, Northern Greenland

Rivers at the coast in Hagen Fjord, Northern Greenland


Eastern Greenland glaciers

Eastern Greenland glaciers


Sermilik Fjord, Eastern Greenland

Sermilik Fjord, Eastern Greenland

Update: The Mercator map is now also updated with the Greenland tiles.

January 29, 2026
by chris
0 comments

Digital Ecosystems and Lobbying

There has been quite a bit of fuss in recent days and weeks about a public consultation of the European Commission regarding an initiative called Towards European open digital ecosystems.

While the title does not in any way point towards this being specifically about software development – or even about technology in general, the annotating texts clearly show that this is intended to be about software development, and that the initiative is about both funding and policy.

Hence substantial parts of the FOSS community these days seem to be essentially drooling over the perspective of a rain of money and there have been already more than a thousand comments made on the consultation to date.

What i found remarkable (and the main reason why i am writing this here) is that a common direction of many community comments seems to go towards a European version of the German Sovereign Tech Fund. The STF to me is notable, in particular, because it is the only open public funding program i know of that explicitly codifies the Matthew principle. One of the core criteria of the STF is Prevalence – essentially meaning that it is only meant to fund projects that already have achieved some level of market dominance. Substantially widening FOSS funding under that premise could have a devastating effect on the Open Source software landscape. One of the big practical advantages of Open Source software is the diversity of different solutions that are available to both users and developers and the resulting resilience. The economic dynamics of Open Source development are normally much less prone to the formation of monopolies and oligopolies. But massive funding specifically of the market leaders and decidedly not of the most innovative projects could well change that.

Now i don’t want to over-exaggerate that problem, because many other ways of funding of Open Source software development – both private and public – de facto also favor the market leaders. But rubbing it is everyone’s face that you use tax money to essentially protect already successful and influential projects from upcoming competition is noteworthy. Even more so if there is widespread applause for that approach from the developer community.

Also: What i found mostly missing in discussions and comments i saw so far are serious discussions of the policy aspect. There is plenty of legislation in Europe that poses substantial hurdles towards open source software and open technology in general. Like the anti-circumvention laws for technological measures put into place to prevent people to control the technology they legally own. These things are much more important for open digital ecosystems than a short term infusion of money.

If this initiative is indicative for an actual serious move towards a more open digital world in Europe or if it is essentially just an attempt to source cheap work from the FOSS community for specific fields of interest for influential stakeholders through some scraps in the form of a short term grant program is unsure. A serious move will require substantial policy changes. If it is just maybe some hundred millions in grants and subsidies then it is probably not serious.

Bottom line: If you want to provide feedback to that European Commission initiative i suggest to focus on the following ideas:

  • EU policies should be adjusted to support rather than create obtacles for small and independent actors in the field and to protect openness of both technology and knowledge – like by repealing anti-circumvention legislation.
  • Public funding should be provided to support innovation and, in particular, for work at stages before the development of concrete products. This will do much more good for sustainably improving European digital abilities and resilience than short term subsidies to already successful projects.
  • Ultimately, the sustained success of open digital ecosystems will depend on there being a long term economical and social basis for work of citizens that contributes to these ecosystems. That basis cannot be produced through public subsidies, it needs to come from our society at large. Politics, however, can help, for example by setting positive examples and requiring public and publicly financed institutions to universally and fully become part of these open digital ecosystems – as active contributors and as consumers alike, and without opportunistic cherry-picking. Politics can also create more favorable economic conditions for work on open knowledge and open technology – like by reducing taxation of such work.
Musaicum image tiles

January 16, 2026
by chris
1 Comment

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
1 Comment

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