reorder parenting search for POI level

Push back the more expensive node-on-way parenting which is rather
rare anyways. Prefer assodicatedStreet relations and addr:* tags
instead.
This commit is contained in:
Sarah Hoffmann
2015-02-25 23:04:24 +01:00
parent 9d9745b378
commit 27ce2afbcf
2 changed files with 69 additions and 71 deletions

View File

@@ -1488,35 +1488,61 @@ BEGIN
NEW.parent_place_id := null;
-- to do that we have to find our parent road
-- if we have a POI and there is no address information,
-- see if we can get it from a surrounding building
IF NEW.osm_type = 'N' AND NEW.street IS NULL AND NEW.addr_place IS NULL
AND NEW.housenumber IS NULL THEN
FOR location IN select * from placex where ST_Covers(geometry, place_centroid)
and (housenumber is not null or street is not null or addr_place is not null)
and rank_search > 28 AND ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon')
limit 1
LOOP
NEW.housenumber := location.housenumber;
NEW.street := location.street;
NEW.addr_place := location.addr_place;
END LOOP;
END IF;
-- We have to find our parent road.
-- Copy data from linked items (points on ways, addr:street links, relations)
-- Note that addr:street links can only be indexed once the street itself is indexed
IF NEW.parent_place_id IS NULL AND NEW.osm_type = 'N' THEN
-- if there is no address information, see if we can get it from a surrounding building
IF NEW.street IS NULL AND NEW.addr_place IS NULL AND NEW.housenumber IS NULL THEN
FOR location IN select * from placex where ST_Covers(geometry, place_centroid) and rank_search > 28 and (housenumber is not null or street is not null or addr_place is not null) AND ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon')
LOOP
NEW.housenumber := location.housenumber;
NEW.street := location.street;
NEW.addr_place := location.addr_place;
END LOOP;
END IF;
-- Is this node part of a relation?
FOR relation IN select * from planet_osm_rels where parts @> ARRAY[NEW.osm_id] and members @> ARRAY['n'||NEW.osm_id]
-- Is this object part of a relation?
FOR relation IN select * from planet_osm_rels where parts @> ARRAY[NEW.osm_id] and members @> ARRAY[lower(NEW.osm_type)||NEW.osm_id]
LOOP
-- At the moment we only process one type of relation - associatedStreet
IF relation.tags @> ARRAY['associatedStreet'] AND array_upper(relation.members, 1) IS NOT NULL THEN
IF relation.tags @> ARRAY['associatedStreet'] THEN
FOR i IN 1..array_upper(relation.members, 1) BY 2 LOOP
IF NEW.parent_place_id IS NULL AND relation.members[i+1] = 'street' THEN
--RAISE WARNING 'node in relation %',relation;
SELECT place_id from placex where osm_type='W' and osm_id = substring(relation.members[i],2,200)::bigint
SELECT place_id from placex where osm_type = 'W'
and osm_id = substring(relation.members[i],2,200)::bigint
and rank_search = 26 and name is not null INTO NEW.parent_place_id;
END IF;
END LOOP;
END IF;
END LOOP;
END LOOP;
-- Note that addr:street links can only be indexed once the street itself is indexed
IF NEW.parent_place_id IS NULL AND NEW.street IS NOT NULL THEN
address_street_word_ids := get_name_ids(make_standard_name(NEW.street));
IF address_street_word_ids IS NOT NULL THEN
FOR location IN SELECT * from getNearestNamedRoadFeature(NEW.partition, place_centroid, address_street_word_ids) LOOP
NEW.parent_place_id := location.place_id;
END LOOP;
END IF;
END IF;
IF NEW.parent_place_id IS NULL AND NEW.addr_place IS NOT NULL THEN
address_street_word_ids := get_name_ids(make_standard_name(NEW.addr_place));
IF address_street_word_ids IS NOT NULL THEN
FOR location IN SELECT * from getNearestNamedPlaceFeature(NEW.partition, place_centroid, address_street_word_ids) LOOP
NEW.parent_place_id := location.place_id;
END LOOP;
END IF;
END IF;
IF NEW.parent_place_id IS NULL AND NEW.osm_type = 'N' THEN
--RAISE WARNING 'x1';
-- Is this node part of a way?
@@ -1531,6 +1557,11 @@ BEGIN
NEW.parent_place_id := location.place_id;
END IF;
-- If this way is a street interpolation line then it is probably as good as we are going to get
IF NEW.parent_place_id IS NULL AND location.class = 'place' and location.type='houses' THEN
NEW.parent_place_id := location.parent_place_id;
END IF;
-- Is the WAY part of a relation
IF NEW.parent_place_id IS NULL THEN
FOR relation IN select * from planet_osm_rels where parts @> ARRAY[location.osm_id] and members @> ARRAY['w'||location.osm_id]
@@ -1546,63 +1577,30 @@ BEGIN
END LOOP;
END IF;
END LOOP;
END IF;
-- If the way contains an explicit name of a street copy it
-- Slightly less strict then above because data is copied from any object.
IF NEW.street IS NULL AND NEW.addr_place IS NULL THEN
--RAISE WARNING 'node in way that has a streetname %',location;
NEW.street := location.street;
NEW.addr_place := location.addr_place;
END IF;
-- If this way is a street interpolation line then it is probably as good as we are going to get
IF NEW.parent_place_id IS NULL AND NEW.street IS NULL AND NEW.addr_place IS NULL AND location.class = 'place' and location.type='houses' THEN
NEW.parent_place_id := location.parent_place_id;
-- If the way mentions a street or place address, try that for parenting.
IF NEW.parent_place_id IS NULL AND location.street IS NOT NULL THEN
address_street_word_ids := get_name_ids(make_standard_name(location.street));
IF address_street_word_ids IS NOT NULL THEN
FOR linkedplacex IN SELECT place_id from getNearestNamedRoadFeature(NEW.partition, place_centroid, address_street_word_ids) LOOP
NEW.parent_place_id := linkedplacex.place_id;
END LOOP;
END IF;
END IF;
IF NEW.parent_place_id IS NULL AND location.addr_place IS NOT NULL THEN
address_street_word_ids := get_name_ids(make_standard_name(location.addr_place));
IF address_street_word_ids IS NOT NULL THEN
FOR linkedplacex IN SELECT place_id from getNearestNamedPlaceFeature(NEW.partition, place_centroid, address_street_word_ids) LOOP
NEW.parent_place_id := linkedplacex.place_id;
END LOOP;
END IF;
END IF;
END LOOP;
END LOOP;
END IF;
--RAISE WARNING 'x2';
IF NEW.parent_place_id IS NULL AND NEW.osm_type = 'W' THEN
-- Is this way part of a relation?
FOR relation IN select * from planet_osm_rels where parts @> ARRAY[NEW.osm_id] and members @> ARRAY['w'||NEW.osm_id]
LOOP
-- At the moment we only process one type of relation - associatedStreet
IF relation.tags @> ARRAY['associatedStreet'] AND array_upper(relation.members, 1) IS NOT NULL THEN
FOR i IN 1..array_upper(relation.members, 1) BY 2 LOOP
IF NEW.parent_place_id IS NULL AND relation.members[i+1] = 'street' THEN
--RAISE WARNING 'way that is in a relation %',relation;
SELECT place_id from placex where osm_type='W' and osm_id = substring(relation.members[i],2,200)::bigint
and rank_search = 26 and name is not null INTO NEW.parent_place_id;
END IF;
END LOOP;
END IF;
END LOOP;
END IF;
--RAISE WARNING 'x3 %',NEW.parent_place_id;
IF NEW.parent_place_id IS NULL AND NEW.street IS NOT NULL THEN
address_street_word_ids := get_name_ids(make_standard_name(NEW.street));
IF address_street_word_ids IS NOT NULL THEN
FOR location IN SELECT * from getNearestNamedRoadFeature(NEW.partition, place_centroid, address_street_word_ids) LOOP
NEW.parent_place_id := location.place_id;
END LOOP;
END IF;
END IF;
IF NEW.parent_place_id IS NULL AND NEW.addr_place IS NOT NULL THEN
address_street_word_ids := get_name_ids(make_standard_name(NEW.addr_place));
IF address_street_word_ids IS NOT NULL THEN
FOR location IN SELECT * from getNearestNamedPlaceFeature(NEW.partition, place_centroid, address_street_word_ids) LOOP
NEW.parent_place_id := location.place_id;
END LOOP;
END IF;
END IF;
--RAISE WARNING 'x4 %',NEW.parent_place_id;

View File

@@ -389,7 +389,7 @@ Feature: Parenting of objects
| N3 | W2 | None | nowhere | None
### Scenario 20
Scenario: POIs parent a road if and only if they are attached to it
Scenario: POIs parent a road if they are attached to it
Given the scene points-on-roads
And the named place nodes
| osm_id | class | type | street | geometry
@@ -408,8 +408,8 @@ Feature: Parenting of objects
When importing
Then table placex contains
| object | parent_place_id
| N1 | W2
| N2 | W1
| N1 | W1
| N2 | W2
| N3 | W1
| N4 | W2