get additional addresses for rank 30 objects

get_addressdata() now also checks if the place itself has entries
in the place_addressline table and merges them into the results.

Also restrict checking for address tag places to cases where the
name cannot be found in the parent's address search terms. Looking
up all address tags is just too slow.
This commit is contained in:
Sarah Hoffmann
2020-11-11 11:52:14 +01:00
parent 021f2bef4c
commit 7324431b12
3 changed files with 37 additions and 18 deletions

View File

@@ -90,7 +90,7 @@ DECLARE
for_place_id BIGINT; for_place_id BIGINT;
result TEXT[]; result TEXT[];
search TEXT[]; search TEXT[];
found INTEGER; current_rank_address INTEGER;
location RECORD; location RECORD;
countrylocation RECORD; countrylocation RECORD;
searchcountrycode varchar(2); searchcountrycode varchar(2);
@@ -103,7 +103,7 @@ DECLARE
search_unlisted_place TEXT; search_unlisted_place TEXT;
countryname HSTORE; countryname HSTORE;
BEGIN BEGIN
-- The place ein question might not have a direct entry in place_addressline. -- The place in question might not have a direct entry in place_addressline.
-- Look for the parent of such places then and save if in for_place_id. -- Look for the parent of such places then and save if in for_place_id.
postcode_isexact := false; postcode_isexact := false;
@@ -177,9 +177,8 @@ BEGIN
--RAISE WARNING '% % % %',searchcountrycode, searchhousenumber, searchpostcode; --RAISE WARNING '% % % %',searchcountrycode, searchhousenumber, searchpostcode;
found := 1000; -- the lowest rank_address included -- --- Return the record for the base entry.
-- Return the record for the base entry.
FOR location IN FOR location IN
SELECT placex.place_id, osm_type, osm_id, name, SELECT placex.place_id, osm_type, osm_id, name,
coalesce(extratags->'linked_place', extratags->'place') as place_type, coalesce(extratags->'linked_place', extratags->'place') as place_type,
@@ -206,9 +205,12 @@ BEGIN
location.admin_level, true, location.isaddress, location.admin_level, true, location.isaddress,
location.rank_address, location.distance)::addressline; location.rank_address, location.distance)::addressline;
RETURN NEXT countrylocation; RETURN NEXT countrylocation;
found := location.rank_address;
current_rank_address := location.rank_address;
END LOOP; END LOOP;
-- --- Return records for address parts.
FOR location IN FOR location IN
SELECT placex.place_id, osm_type, osm_id, name, class, type, SELECT placex.place_id, osm_type, osm_id, name, class, type,
coalesce(extratags->'linked_place', extratags->'place') as place_type, coalesce(extratags->'linked_place', extratags->'place') as place_type,
@@ -216,14 +218,15 @@ BEGIN
CASE WHEN rank_address = 11 THEN 5 ELSE rank_address END as rank_address, CASE WHEN rank_address = 11 THEN 5 ELSE rank_address END as rank_address,
distance, country_code, postcode distance, country_code, postcode
FROM place_addressline join placex on (address_place_id = placex.place_id) FROM place_addressline join placex on (address_place_id = placex.place_id)
WHERE place_addressline.place_id = for_place_id WHERE place_addressline.place_id IN (for_place_id, in_place_id)
AND linked_place_id is null AND linked_place_id is null
AND (placex.country_code IS NULL OR searchcountrycode IS NULL AND (placex.country_code IS NULL OR searchcountrycode IS NULL
OR placex.country_code = searchcountrycode) OR placex.country_code = searchcountrycode)
ORDER BY rank_address desc, isaddress desc, fromarea desc, ORDER BY rank_address desc, (place_addressline.place_id = in_place_id) desc,
isaddress desc, fromarea desc,
distance asc, rank_search desc distance asc, rank_search desc
LOOP LOOP
--RAISE WARNING '%',location; -- RAISE WARNING '%',location;
IF searchcountrycode IS NULL AND location.country_code IS NOT NULL THEN IF searchcountrycode IS NULL AND location.country_code IS NOT NULL THEN
searchcountrycode := location.country_code; searchcountrycode := location.country_code;
END IF; END IF;
@@ -243,17 +246,21 @@ BEGIN
location.name, location.class, location.type, location.name, location.class, location.type,
location.place_type, location.place_type,
location.admin_level, location.fromarea, location.admin_level, location.fromarea,
location.isaddress, location.rank_address, location.isaddress and location.rank_address != current_rank_address,
location.rank_address,
location.distance)::addressline; location.distance)::addressline;
RETURN NEXT countrylocation; RETURN NEXT countrylocation;
found := location.rank_address;
IF location.isaddress THEN
current_rank_address := location.rank_address;
END IF;
END LOOP; END LOOP;
-- If no country was included yet, add the name information from country_name. -- If no country was included yet, add the name information from country_name.
IF found > 4 THEN IF current_rank_address > 4 THEN
SELECT name FROM country_name SELECT name FROM country_name
WHERE country_code = searchcountrycode LIMIT 1 INTO countryname; WHERE country_code = searchcountrycode LIMIT 1 INTO countryname;
--RAISE WARNING '% % %',found,searchcountrycode,countryname; --RAISE WARNING '% % %',current_rank_address,searchcountrycode,countryname;
IF countryname IS NOT NULL THEN IF countryname IS NOT NULL THEN
location := ROW(null, null, null, countryname, 'place', 'country', NULL, location := ROW(null, null, null, countryname, 'place', 'country', NULL,
null, true, true, 4, 0)::addressline; null, true, true, 4, 0)::addressline;

View File

@@ -432,6 +432,7 @@ DECLARE
addr_item RECORD; addr_item RECORD;
parent_address_place_ids BIGINT[]; parent_address_place_ids BIGINT[];
filtered_address HSTORE;
BEGIN BEGIN
nameaddress_vector := '{}'::INTEGER[]; nameaddress_vector := '{}'::INTEGER[];
@@ -440,11 +441,18 @@ BEGIN
FROM search_name s FROM search_name s
WHERE s.place_id = parent_place_id; WHERE s.place_id = parent_place_id;
-- Find all address tags that don't appear in the parent search names.
SELECT hstore(array_agg(ARRAY[k, v])) INTO filtered_address
FROM (SELECT skeys(address) as k, svals(address) as v) a
WHERE not addr_ids_from_name(v) && parent_address_vector
AND k not in ('country', 'street', 'place', 'postcode',
'housenumber', 'streetnumber', 'consriptionnumber');
-- Compute all search terms from the addr: tags. -- Compute all search terms from the addr: tags.
IF address IS NOT NULL THEN IF filtered_address IS NOT NULL THEN
FOR addr_item IN FOR addr_item IN
SELECT * FROM SELECT * FROM
get_places_for_addr_tags(in_partition, geometry, address, country) get_places_for_addr_tags(in_partition, geometry, filtered_address, country)
LOOP LOOP
IF addr_item.place_id is null THEN IF addr_item.place_id is null THEN
nameaddress_vector := array_merge(nameaddress_vector, nameaddress_vector := array_merge(nameaddress_vector,

View File

@@ -331,10 +331,10 @@ Feature: Address computation
| osm | class | type | admin | name | geometry | | osm | class | type | admin | name | geometry |
| R1 | boundary | administrative | 8 | Left | (1,2,3,4,1) | | R1 | boundary | administrative | 8 | Left | (1,2,3,4,1) |
| R2 | boundary | administrative | 8 | Right | (2,3,6,5,2) | | R2 | boundary | administrative | 8 | Right | (2,3,6,5,2) |
And the named places And the places
| osm | class | type | addr+city | geometry | | osm | class | type | name | addr+city | geometry |
| W1 | highway | primary | Right | 8,9 | | W1 | highway | primary | Wonderway | Right | 8,9 |
| N1 | amenity | cafe | Left | 9 | | N1 | amenity | cafe | Bolder | Left | 9 |
When importing When importing
Then place_addressline contains Then place_addressline contains
| object | address | isaddress | | object | address | isaddress |
@@ -343,4 +343,8 @@ Feature: Address computation
And place_addressline doesn't contain And place_addressline doesn't contain
| object | address | | object | address |
| W1 | R1 | | W1 | R1 |
When searching for "Bolder"
Then results contain
| osm_type | osm_id | name |
| N | 1 | Bolder, Wonderway, Left |