Skip to content

Use housenumber instead of streetnumber for street addresses - #1098

Merged
lonvia merged 8 commits into
komoot:masterfrom
barasoukup:master
Jul 29, 2026
Merged

Use housenumber instead of streetnumber for street addresses#1098
lonvia merged 8 commits into
komoot:masterfrom
barasoukup:master

Conversation

@barasoukup

@barasoukup barasoukup commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

In Czechia, house numbers are commonly represented as a combination of conscription number and street number (e.g. 2531/80). Both parts are used when referring to an address on a street.
Previously, Photon indexed only the street number for street-based addresses. As a result, searches using the conscription number could fail.
This change indexes the full housenumber value instead. OpenSearch tokenizes values such as 2531/80, making it possible to find the address by:

street number (80)
conscription number (2531)
full house number (2531/80)

This approach avoids creating multiple documents for the same address while improving support for Czech address numbering.

AI assistance disclosure

Per the contribution guidelines: the code change, the added tests and parts of the discussion in this PR were drafted with AI assistance and reviewed by me.

Verification on a live installation

Verified on a running photon server with the embedded OpenSearch, not only in unit tests. A JSON dump with three addresses was imported twice, once with the current master behaviour and once with this change, and each running server was queried over HTTP.

Test addresses (the address part of each dump entry):

# tags
1 street=Kaprova, city=Praha, conscriptionnumber=2531, streetnumber=80, housenumber=2531/80
2 place=Lhota, city=Lhota, conscriptionnumber=100, housenumber=100
3 street=Hlavna, city=Bratislava, streetnumber=34 (no housenumber)
java -jar photon.jar import -import-file cz-sk-test.jsonl -data-dir <dir> -languages en,cs
java -jar photon.jar serve -data-dir <dir>

House number returned per query:

query before after
Kaprova 2531/80 80 2531/80
Kaprova 80 80 2531/80
Kaprova 2531 no result 2531/80
Lhota 100 100 100
Hlavna 34 34 34

Both imports produce three documents, so no duplicate documents are created: the combined value is indexed once and the house number analyzer splits it. The conscription number becomes searchable and the canonical 2531/80 is returned. The place-based address is unchanged, and address 3, which only carries addr:streetnumber, still resolves thanks to the fallback.

@barasoukup

Copy link
Copy Markdown
Contributor Author

Can be solved by #1099 with optional settings

Index addr:housenumber on the street address, so that the conscription number and the combined form (e.g. 100/9) stay searchable in CZ/SK. Place-based addresses keep using addr:conscriptionnumber, so the orientation number does not leak into the place-based display name.
@barasoukup barasoukup reopened this Jul 27, 2026
@barasoukup

Copy link
Copy Markdown
Contributor Author

Reopening this: following the discussion in #1099, the agreed rule is exactly this change — addr:housenumber on the street address, addr:conscriptionnumber on the place-based one, no import switch and no country condition. Updated the diff accordingly; only the one argument in the PhotonDocAddressSet constructor and the testConscriptionAddress expectation change.

@lonvia

lonvia commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

The failing test case is interesting: an addr:street with addr:streetnumber but no addr:housenumber. There are a couple of hundred cases, mostly in Slovakia. My understanding is that this is a tagging error but we might just be a bit forgiving and say if addr:street with addr:housenumber didn't yield a result, then try with addr:streetnumber.

A few hundred addresses, mostly in Slovakia, carry addr:street and addr:streetnumber but no addr:housenumber. Rather than dropping them, fall back to the street number when the house number yields no usable value.
@barasoukup

Copy link
Copy Markdown
Contributor Author

Good catch, and I agree that being forgiving is better than dropping those addresses. Implemented as you suggested: the street address now falls back to addr:streetnumber when addr:housenumber yields no usable number.

private void addStreetAddress(PhotonDoc base, Map<String, String> address) {
    if (!address.containsKey("street")) {
        return;
    }

    String[] housenumbers = splitHousenumber(address, "housenumber");

    if (housenumbers.length == 0) {
        // Be forgiving about addresses that only carry a street number. That is a tagging
        // error, but a few hundred of them exist, mostly in Slovakia.
        housenumbers = splitHousenumber(address, "streetnumber");
    }

    for (String hnr : housenumbers) {
        docs.add(new PhotonDoc(base).houseNumber(hnr));
    }
}

testObjectWithConscriptionNumber passes again with this. Note the fallback also applies when addr:housenumber is present but unusable — too long, or rejected by HOUSENUMBER_CHECK — which seems right for the same reason, but say the word if you would rather key it strictly on the absence of the tag.

@lonvia

lonvia commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

That's okay. Do you mind adding an additional test to NominatimConnectorDBTest which covers the case where all three housenumber tags are present?

Covers addr:housenumber together with addr:conscriptionnumber and addr:streetnumber: the street address gets the combined form, the place address keeps the conscription number.
@barasoukup

Copy link
Copy Markdown
Contributor Author

Added testObjectWithConscriptionNumberAndHousenumber, which tags addr:housenumber=99521/34 alongside addr:conscriptionnumber=99521 and addr:streetnumber=34 and asserts both resulting documents: 99521/34 on Main St and 99521 on Village. It also pins the document count at two, so an accidental extra document would fail the test.

@lonvia

lonvia commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Thanks, that looks good now.

There is a small chance that you see issues with ordering for results with addr:streetnumber+addr:street searches. If that is the case, then please open an issue and we'll need to have a look at adapting the houesnumber index after all.

@lonvia
lonvia merged commit 5af14ec into komoot:master Jul 29, 2026
4 checks passed
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.

2 participants