mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-26 11:08:13 +00:00
handle associatedStreet relations with multiple streets
When a associatedStreet relation has multiple street members always take the closest one. Avoid geometry operations for the frequent case that there is only one street.
This commit is contained in:
@@ -107,12 +107,17 @@ LANGUAGE plpgsql STABLE;
|
|||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION find_associated_street(poi_osm_type CHAR(1),
|
CREATE OR REPLACE FUNCTION find_associated_street(poi_osm_type CHAR(1),
|
||||||
poi_osm_id BIGINT)
|
poi_osm_id BIGINT,
|
||||||
|
bbox GEOMETRY)
|
||||||
RETURNS BIGINT
|
RETURNS BIGINT
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
location RECORD;
|
location RECORD;
|
||||||
parent RECORD;
|
parent RECORD;
|
||||||
|
result BIGINT;
|
||||||
|
distance FLOAT;
|
||||||
|
new_distance FLOAT;
|
||||||
|
waygeom GEOMETRY;
|
||||||
BEGIN
|
BEGIN
|
||||||
FOR location IN
|
FOR location IN
|
||||||
SELECT members FROM planet_osm_rels
|
SELECT members FROM planet_osm_rels
|
||||||
@@ -123,19 +128,34 @@ BEGIN
|
|||||||
FOR i IN 1..array_upper(location.members, 1) BY 2 LOOP
|
FOR i IN 1..array_upper(location.members, 1) BY 2 LOOP
|
||||||
IF location.members[i+1] = 'street' THEN
|
IF location.members[i+1] = 'street' THEN
|
||||||
FOR parent IN
|
FOR parent IN
|
||||||
SELECT place_id from placex
|
SELECT place_id, geometry
|
||||||
|
FROM placex
|
||||||
WHERE osm_type = upper(substring(location.members[i], 1, 1))::char(1)
|
WHERE osm_type = upper(substring(location.members[i], 1, 1))::char(1)
|
||||||
and osm_id = substring(location.members[i], 2)::bigint
|
and osm_id = substring(location.members[i], 2)::bigint
|
||||||
and name is not null
|
and name is not null
|
||||||
and rank_search between 26 and 27
|
and rank_search between 26 and 27
|
||||||
LOOP
|
LOOP
|
||||||
RETURN parent.place_id;
|
-- Find the closest 'street' member.
|
||||||
|
-- Avoid distance computation for the frequent case where there is
|
||||||
|
-- only one street member.
|
||||||
|
IF waygeom is null THEN
|
||||||
|
result := parent.place_id;
|
||||||
|
waygeom := parent.geometry;
|
||||||
|
ELSE
|
||||||
|
distance := coalesce(distance, ST_Distance(waygeom, bbox));
|
||||||
|
new_distance := ST_Distance(parent.geometry, bbox);
|
||||||
|
IF new_distance < distance THEN
|
||||||
|
distance := new_distance;
|
||||||
|
result := parent.place_id;
|
||||||
|
waygeom := parent.geometry;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END IF;
|
END IF;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
RETURN NULL;
|
RETURN result;
|
||||||
END;
|
END;
|
||||||
$$
|
$$
|
||||||
LANGUAGE plpgsql STABLE;
|
LANGUAGE plpgsql STABLE;
|
||||||
@@ -162,7 +182,7 @@ BEGIN
|
|||||||
{% if debug %}RAISE WARNING 'finding street for % %', poi_osm_type, poi_osm_id;{% endif %}
|
{% if debug %}RAISE WARNING 'finding street for % %', poi_osm_type, poi_osm_id;{% endif %}
|
||||||
|
|
||||||
-- Is this object part of an associatedStreet relation?
|
-- Is this object part of an associatedStreet relation?
|
||||||
parent_place_id := find_associated_street(poi_osm_type, poi_osm_id);
|
parent_place_id := find_associated_street(poi_osm_type, poi_osm_id, bbox);
|
||||||
|
|
||||||
IF parent_place_id is null THEN
|
IF parent_place_id is null THEN
|
||||||
parent_place_id := find_parent_for_address(token_info, poi_partition, bbox);
|
parent_place_id := find_parent_for_address(token_info, poi_partition, bbox);
|
||||||
@@ -185,7 +205,7 @@ BEGIN
|
|||||||
RETURN location.place_id;
|
RETURN location.place_id;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
parent_place_id := find_associated_street('W', location.osm_id);
|
parent_place_id := find_associated_street('W', location.osm_id, bbox);
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
|||||||
@@ -437,6 +437,29 @@ Feature: Parenting of objects
|
|||||||
| object | parent_place_id |
|
| object | parent_place_id |
|
||||||
| N9 | R14 |
|
| N9 | R14 |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Choose closest street in associatedStreet relation
|
||||||
|
Given the grid
|
||||||
|
| 1 | | | | 3 |
|
||||||
|
| 10 | | 11 | | 12 |
|
||||||
|
And the places
|
||||||
|
| osm | class | type | housenr | geometry |
|
||||||
|
| N1 | place | house | 1 | 1 |
|
||||||
|
| N3 | place | house | 3 | 3 |
|
||||||
|
And the named places
|
||||||
|
| osm | class | type | geometry |
|
||||||
|
| W100 | highway | residential | 10,11 |
|
||||||
|
| W101 | highway | residential | 11,12 |
|
||||||
|
And the relations
|
||||||
|
| id | members | tags+type |
|
||||||
|
| 1 | N1:house,N3:house,W100:street,W101:street | associatedStreet |
|
||||||
|
When importing
|
||||||
|
Then placex contains
|
||||||
|
| object | parent_place_id |
|
||||||
|
| N1 | W100 |
|
||||||
|
| N3 | W101 |
|
||||||
|
|
||||||
|
|
||||||
Scenario: POIs in building inherit address
|
Scenario: POIs in building inherit address
|
||||||
Given the grid
|
Given the grid
|
||||||
| 10 | | | | | | 11 |
|
| 10 | | | | | | 11 |
|
||||||
|
|||||||
Reference in New Issue
Block a user