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

Lookup postcode areas for postcode results #3362

Merged
merged 4 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib-sql/indices.sql
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ CREATE INDEX IF NOT EXISTS idx_placex_parent_place_id
ON placex USING BTREE (parent_place_id) {{db.tablespace.search_index}}
WHERE parent_place_id IS NOT NULL;
---
-- Used to find postcode areas after a search in location_postcode.
CREATE INDEX IF NOT EXISTS idx_placex_postcode_areas
ON placex USING BTREE (country_code, postcode) {{db.tablespace.search_index}}
WHERE osm_type = 'R' AND class = 'boundary' AND type = 'postal_code';
---
CREATE INDEX IF NOT EXISTS idx_placex_geometry ON placex
USING GIST (geometry) {{db.tablespace.search_index}};
-- Index is needed during import but can be dropped as soon as a full
Expand Down
20 changes: 17 additions & 3 deletions nominatim/api/search/db_searches.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,10 +602,24 @@ async def lookup(self, conn: SearchConnection,

results = nres.SearchResults()
for row in await conn.execute(sql, _details_to_bind_params(details)):
result = nres.create_from_postcode_row(row, nres.SearchResult)
p = conn.t.placex
placex_sql = _select_placex(p).add_columns(p.c.importance)\
.where(sa.text("""class = 'boundary'
AND type = 'postal_code'
AND osm_type = 'R'"""))\
.where(p.c.country_code == row.country_code)\
.where(p.c.postcode == row.postcode)\
.limit(1)
for prow in await conn.execute(placex_sql, _details_to_bind_params(details)):
result = nres.create_from_placex_row(prow, nres.SearchResult)
break
else:
result = nres.create_from_postcode_row(row, nres.SearchResult)

assert result
result.accuracy = row.accuracy
results.append(result)
if result.place_id not in details.excluded:
result.accuracy = row.accuracy
results.append(result)

return results

Expand Down
10 changes: 10 additions & 0 deletions nominatim/tools/migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,3 +382,13 @@ def add_improved_geometry_reverse_placenode_index(conn: Connection, **_: Any) ->
WHERE rank_address between 4 and 25 AND type != 'postcode'
AND name is not null AND linked_place_id is null AND osm_type = 'N'
""")

@_migration(4, 4, 99, 0)
def create_postcode_ara_lookup_index(conn: Connection, **_: Any) -> None:
""" Create index needed for looking up postcode areas from postocde points.
"""
with conn.cursor() as cur:
cur.execute("""CREATE INDEX IF NOT EXISTS idx_placex_postcode_areas
ON placex USING BTREE (country_code, postcode)
WHERE osm_type = 'R' AND class = 'boundary' AND type = 'postal_code'
""")
2 changes: 1 addition & 1 deletion nominatim/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def __str__(self) -> str:
return f"{self.major}.{self.minor}.{self.patch_level}-{self.db_patch_level}"


NOMINATIM_VERSION = NominatimVersion(4, 4, 0, 0)
NOMINATIM_VERSION = NominatimVersion(4, 4, 99, 0)

POSTGRESQL_REQUIRED_VERSION = (9, 6)
POSTGIS_REQUIRED_VERSION = (2, 2)
Expand Down
8 changes: 0 additions & 8 deletions test/bdd/api/details/simple.feature
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@
Feature: Object details
Check details page for correctness

Scenario: Details by place ID
When sending details query for 107077
Then the result is valid json
And results contain
| place_id |
| 107077 |


Scenario Outline: Details via OSM id
When sending details query for <type><id>
Then the result is valid json
Expand Down
18 changes: 18 additions & 0 deletions test/bdd/db/query/postcodes.feature
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,21 @@ Feature: Querying fo postcode variants
| type | display_name |
| postcode | E4 7EA, United Kingdom |


@fail-legacy
@v1-api-python-only
Scenario: Postcode areas are preferred over postcode points
Given the grid with origin DE
| 1 | 2 |
| 4 | 3 |
Given the places
| osm | class | type | postcode | geometry |
| R23 | boundary | postal_code | 12345 | (1,2,3,4,1) |
When importing
Then location_postcode contains exactly
| country | postcode |
| de | 12345 |
When sending search query "12345, de"
Then results contain
| osm |
| R23 |
Loading