mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-26 11:08:13 +00:00
improve parenting for large areas with rank 30
Instead of unconditionally parenting them to a street, the larger areas get a parent area that contains them. To keep things computationally light-weight, only use the centroid and bbox to determine if an area is contained. Requires renaming of parenting functions because renaming a parameter of the function causes issues when updating the function (it requires a manual delete, which I'd like to avoid).
This commit is contained in:
@@ -46,13 +46,13 @@ LANGUAGE plpgsql IMMUTABLE;
|
|||||||
--
|
--
|
||||||
-- Copy data from linked items (POIs on ways, addr:street links, relations).
|
-- Copy data from linked items (POIs on ways, addr:street links, relations).
|
||||||
--
|
--
|
||||||
CREATE OR REPLACE FUNCTION find_parent_place_for_poi(poi_osm_type CHAR(1),
|
CREATE OR REPLACE FUNCTION find_parent_for_poi(poi_osm_type CHAR(1),
|
||||||
poi_osm_id BIGINT,
|
poi_osm_id BIGINT,
|
||||||
poi_partition SMALLINT,
|
poi_partition SMALLINT,
|
||||||
near_centroid GEOMETRY,
|
bbox GEOMETRY,
|
||||||
addr_street TEXT,
|
addr_street TEXT,
|
||||||
addr_place TEXT,
|
addr_place TEXT,
|
||||||
fallback BOOL = true)
|
fallback BOOL = true)
|
||||||
RETURNS BIGINT
|
RETURNS BIGINT
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
@@ -85,7 +85,7 @@ BEGIN
|
|||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
parent_place_id := find_parent_for_address(addr_street, addr_place,
|
parent_place_id := find_parent_for_address(addr_street, addr_place,
|
||||||
poi_partition, near_centroid);
|
poi_partition, bbox);
|
||||||
IF parent_place_id is not null THEN
|
IF parent_place_id is not null THEN
|
||||||
RETURN parent_place_id;
|
RETURN parent_place_id;
|
||||||
END IF;
|
END IF;
|
||||||
@@ -95,7 +95,7 @@ BEGIN
|
|||||||
FOR parent IN
|
FOR parent IN
|
||||||
SELECT q.parent_place_id
|
SELECT q.parent_place_id
|
||||||
FROM location_property_osmline q, planet_osm_ways x
|
FROM location_property_osmline q, planet_osm_ways x
|
||||||
WHERE q.linegeo && near_centroid and x.id = q.osm_id
|
WHERE q.linegeo && bbox and x.id = q.osm_id
|
||||||
and poi_osm_id = any(x.nodes)
|
and poi_osm_id = any(x.nodes)
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
LOOP
|
LOOP
|
||||||
@@ -109,7 +109,7 @@ BEGIN
|
|||||||
coalesce(p.centroid, ST_Centroid(p.geometry)) as centroid
|
coalesce(p.centroid, ST_Centroid(p.geometry)) as centroid
|
||||||
FROM placex p, planet_osm_ways w
|
FROM placex p, planet_osm_ways w
|
||||||
WHERE p.osm_type = 'W' and p.rank_search >= 26
|
WHERE p.osm_type = 'W' and p.rank_search >= 26
|
||||||
and p.geometry && near_centroid
|
and p.geometry && bbox
|
||||||
and w.id = p.osm_id and poi_osm_id = any(w.nodes)
|
and w.id = p.osm_id and poi_osm_id = any(w.nodes)
|
||||||
LOOP
|
LOOP
|
||||||
--DEBUG: RAISE WARNING 'Node is part of way % ', location.osm_id;
|
--DEBUG: RAISE WARNING 'Node is part of way % ', location.osm_id;
|
||||||
@@ -120,11 +120,11 @@ BEGIN
|
|||||||
return location.place_id;
|
return location.place_id;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
SELECT find_parent_place_for_poi('W', location.osm_id, poi_partition,
|
SELECT find_parent_for_poi('W', location.osm_id, poi_partition,
|
||||||
location.centroid,
|
location.centroid,
|
||||||
location.address->'street',
|
location.address->'street',
|
||||||
location.address->'place',
|
location.address->'place',
|
||||||
false)
|
false)
|
||||||
INTO parent_place_id;
|
INTO parent_place_id;
|
||||||
IF parent_place_id is not null THEN
|
IF parent_place_id is not null THEN
|
||||||
RETURN parent_place_id;
|
RETURN parent_place_id;
|
||||||
@@ -132,10 +132,24 @@ BEGIN
|
|||||||
END LOOP;
|
END LOOP;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Still nothing, just use the nearest road
|
|
||||||
IF fallback THEN
|
IF fallback THEN
|
||||||
SELECT place_id FROM getNearestRoadFeature(poi_partition, near_centroid) INTO parent_place_id;
|
IF ST_Area(bbox) < 0.01 THEN
|
||||||
--DEBUG: RAISE WARNING 'Checked for nearest way (%)', parent_place_id;
|
-- for smaller features get the nearest road
|
||||||
|
SELECT place_id FROM getNearestRoadFeature(poi_partition, bbox)
|
||||||
|
INTO parent_place_id;
|
||||||
|
--DEBUG: RAISE WARNING 'Checked for nearest way (%)', parent_place_id;
|
||||||
|
ELSE
|
||||||
|
-- for larger features simply find the area with the largest rank that
|
||||||
|
-- contains the bbox
|
||||||
|
FOR location IN
|
||||||
|
SELECT place_id FROM placex
|
||||||
|
WHERE bbox @ geometry AND _ST_Covers(geometry, ST_Centroid(bbox))
|
||||||
|
AND rank_search between 5 and 25
|
||||||
|
ORDER BY rank_search desc
|
||||||
|
LOOP
|
||||||
|
RETURN location.place_id;
|
||||||
|
END LOOP;
|
||||||
|
END IF;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
RETURN parent_place_id;
|
RETURN parent_place_id;
|
||||||
@@ -414,8 +428,6 @@ CREATE OR REPLACE FUNCTION placex_update()
|
|||||||
RETURNS TRIGGER
|
RETURNS TRIGGER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
near_centroid GEOMETRY;
|
|
||||||
|
|
||||||
search_maxdistance FLOAT[];
|
search_maxdistance FLOAT[];
|
||||||
search_mindistance FLOAT[];
|
search_mindistance FLOAT[];
|
||||||
address_havelevel BOOLEAN[];
|
address_havelevel BOOLEAN[];
|
||||||
@@ -515,7 +527,6 @@ BEGIN
|
|||||||
-- cheaper but less acurate
|
-- cheaper but less acurate
|
||||||
NEW.centroid := ST_PointOnSurface(NEW.geometry);
|
NEW.centroid := ST_PointOnSurface(NEW.geometry);
|
||||||
-- For searching near features rather use the centroid
|
-- For searching near features rather use the centroid
|
||||||
near_centroid := ST_Envelope(NEW.geometry);
|
|
||||||
NEW.postcode := null;
|
NEW.postcode := null;
|
||||||
--DEBUG: RAISE WARNING 'Computing preliminary centroid at %',ST_AsText(NEW.centroid);
|
--DEBUG: RAISE WARNING 'Computing preliminary centroid at %',ST_AsText(NEW.centroid);
|
||||||
|
|
||||||
@@ -595,10 +606,10 @@ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- We have to find our parent road.
|
-- We have to find our parent road.
|
||||||
NEW.parent_place_id := find_parent_place_for_poi(NEW.osm_type, NEW.osm_id,
|
NEW.parent_place_id := find_parent_for_poi(NEW.osm_type, NEW.osm_id,
|
||||||
NEW.partition,
|
NEW.partition,
|
||||||
near_centroid, addr_street,
|
ST_Envelope(NEW.geometry),
|
||||||
addr_place);
|
addr_street, addr_place);
|
||||||
|
|
||||||
-- If we found the road take a shortcut here.
|
-- If we found the road take a shortcut here.
|
||||||
-- Otherwise fall back to the full address getting method below.
|
-- Otherwise fall back to the full address getting method below.
|
||||||
|
|||||||
Reference in New Issue
Block a user