Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add house numbers layer #336

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

SiarheiFedartsou
Copy link

@SiarheiFedartsou SiarheiFedartsou commented Dec 8, 2024

Description

This is an attempt to add house numbers to base maps.

Since I am not sure in approach, I decided to create this PR with preliminary implementation first and decide on the right approach.

How it looks like now in Monaco:
Screenshot 2024-12-08 at 13 21 44

Open questions/TODO:

  1. Design (these red itailic labels is definitely not what we want + we need to decide on zoom levels etc)
  2. In OSM addr:housenumber is usually:
  • tag on separate node
  • tag on building way
  • both of above
    Current implementation handles only separate nodes for now. To handle ways as well we probably need a kind of a deduplication logic to not show the same housenumber twice (at glance we can try matching by other addr:* tags to identify duplicates)

Issue

#335

public class Housenumbers implements ForwardingProfile.LayerPostProcesser {
public void processOsm(SourceFeature sf, FeatureCollector features) {
if (sf.hasTag("addr:housenumber")) {
if (sf.isPoint()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also a lot of ways in osm have a house number: https://taginfo.openstreetmap.org/keys/addr%3Ahousenumber#overview

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I agree. As I mentioned in PR description I wanted to handle them as well, but wanted to first agree on the general approach. Do you think such implementation does have a chance to be eventually merged? 😀 Ofc after handling all the cases, adding tests etc...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is a good idea to add house numbers.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, then I'll continue working on that PR :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a great start! We should align the layer name and properties to conform with the Tilezen docs: https://tilezen.readthedocs.io/en/latest/layers/#buildings-and-addresses

so it should be points included in the buildings layer with a property called addr_housenumber

features.point(this.name())
.setId(FeatureId.create(sf))
.setAttr("housenumber", sf.getString("addr:housenumber"))
.setZoomRange(10, 17);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should limit the house numbers to exist only in the zoom 15 tiles, in order to not bloat the tile size. A visual reference we use for deciding what data goes in what zoom is http://tangrams.github.io/bubble-wrap - house numbers only appear above zoom ~18 which means we can put them in our tileset at 15 and define the style to appear > 18, etc. Is that zoom level good enough for your use case?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so :)

@SiarheiFedartsou
Copy link
Author

Hey @bdon !

Thanks for your feedback.
I moved house numbers to buildings layer as you suggested and also made some fixes related to style, zoom level etc.

Some questions:

  1. Did I understand your suggestions correctly? 😄 I mean I want to first check if I am going the right way and if it is so I could add tests and may be some other things to get it eventually merged.
  2. Do we need addr_street to be present in tiles? It is in Tilezen's spec, but I don't use it in style now, so I drop it to not bloat resulting tiles https://tilezen.readthedocs.io/en/latest/layers/#buildings-and-addresses

@@ -188,6 +191,9 @@ export const CONTRAST: Theme = {
state_label: "#777777",
state_label_halo: "#ffffff",
country_label: "#9590aa",

housenumbers_label: "#91888b",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used the same values as roads_label_minor for all themes... Looks okay on my taste...
Screenshot 2024-12-14 at 09 53 14

Copy link

sonarqubecloud bot commented Jan 1, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
5.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@@ -594,6 +594,7 @@ export function nolabels_layers(
type: "fill",
source: source,
"source-layer": "buildings",
filter: ["!=", "kind", "address"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be an opt-in instead of an opt-out, e.g. kind in building or building_part

@@ -188,6 +191,9 @@ export const CONTRAST: Theme = {
state_label: "#777777",
state_label_halo: "#ffffff",
country_label: "#9590aa",

housenumbers_label: "#91888b",
house_numbers_label_halo: "#ffffff",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe housenumbers one word instead of with _?

@bdon
Copy link
Member

bdon commented Jan 1, 2025

Do we need addr_street to be present in tiles? It is in Tilezen's spec, but I don't use it in style now, so I drop it to not bloat resulting tiles

No, we don't need it if it's not used in the default style. Removing bloat is great.

List<VectorTile.Feature> buildings = new ArrayList<>();

// deduplicate addresses
HashMap<Map<String, Object>, List<VectorTile.Feature>> groupedAddresses = new LinkedHashMap<>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to address one building that is labeled twice on the map? Is there a specific place in the world where that problem is pervasive or is it an edge case where maybe it's a data problem in OSM?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NVM, I see the issue is that it also includes POIs that have an addr:housenumber in OSM. I think for the first pass we should limit the house number displays to just those tagged on buildings and not POIs, because de-duplicating them in post-process is going to lead to non-deterministic results potentially, and ideally POIs will be labeled by an icon symbology instead of just a housenumber. What do you think? Labeling on OSM Carto seems to be focused on the building addr:housenumber too.

@do-me
Copy link

do-me commented Jan 3, 2025

Just saw this PR. A month ago, I was also digging into house numbers and used a more basic style, after @wipfli gave me some hints in #352. This is the repo to reproduce this style: https://github.com/do-me/basemap-starter.

image

I too simply used .setAttr("house_number", sf.getTag("addr:housenumber")) in basemaps but found - as I mentioned here and @wipfli pointed to here - that house number tagging across different countries is very inconsistent. Best case is house numbers attached to buildings, but in some cases it's a single point (I think it was France) or added elsewhere.

I just created a world pmtiles file based on the above config and the result is very heterogenous. I can share it if you like.

Really good in Zurich:

image

Very inconsistent in Munich:

image

For comparison, see OSM, where house numbers do exist, just not on the buildings:

image

Practically no house numbers in France:

image

So @bdon I would highly encourage to use all above mentioned tags right from the start and not only rely on buildings.

Also, there are many open discussions/issues scattered in protomaps discussions, basemaps & pmtiles repo about house numbers, so it might make sense to link these threads better for people see that development is going on here.

@bdon
Copy link
Member

bdon commented Jan 9, 2025

all above mentioned tags right from the start and not only rely on buildings.

EDIT: I agree it would be nice to have non-building addr:housenumber data, but pulling in POIs for addresses creates lots of duplicate address points and we do not have a clear way to de-duplicate them in a deterministic way.

@bdon
Copy link
Member

bdon commented Jan 9, 2025

A more complex option is performing a point-in-polygon test on every point to see if its addr:housenumber matches the building that contains it, and then throwing it away if it matches.

If the building does not have a house number, but multiple points have identical house numbers, those will still show as duplicates in the final map.

@bdon
Copy link
Member

bdon commented Jan 9, 2025

Looking at OSM as an example: https://www.openstreetmap.org/node/3046828339

what if we included point addr:housenumber only if there is no non-addr: tags? This would exclude all POIs. I will experiment with this on a new build.

@do-me
Copy link

do-me commented Jan 9, 2025

pulling in POIs for addresses creates lots of duplicate address points and we do not have a clear way to de-duplicate them in a deterministic way.

Before investing too much time for coming up with our own experimental solution, what if we looked at the way others do it before?
It's a solved problem e.g. here:

Everything in OpenStreetMap which contains a addr:housenumber tag useful for labelling housenumbers on a map. This adds significant size to z14. For buildings the centroid of the building is used as housenumber. Duplicates within a tile are dropped if they have the same street/block_number (records without name tag are prioritized for preservation).

Results seem perfect, e.g. here the example for my screenshots from Munich: https://www.maptiler.com/maps/#style=streets-v2&lang=auto&mode=2d&position=18.04/48.149875/11.637837

  • maybe there are other projects to copy the logic from? Like how is the logic for setting house numbers on raster-based tiles?

@klokan
Copy link

klokan commented Jan 9, 2025

CC-BY

@bdon
Copy link
Member

bdon commented Jan 9, 2025

FYI the PR as-is adds about ~1GB to the total planet tileset, which is reasonable. It looks like the current logic chooses the "first" one that makes it into the tileset is based on sort rank and seems deterministic, so I was wrong about that. Running it again to check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants