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.
for_place_id BIGINT;
result TEXT[];
search TEXT[];
for_place_id BIGINT;
result TEXT[];
search TEXT[];
+ current_rank_address INTEGER;
location RECORD;
countrylocation RECORD;
searchcountrycode varchar(2);
location RECORD;
countrylocation RECORD;
searchcountrycode varchar(2);
search_unlisted_place TEXT;
countryname HSTORE;
BEGIN
search_unlisted_place TEXT;
countryname HSTORE;
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.
postcode_isexact := false;
-- Look for the parent of such places then and save if in for_place_id.
postcode_isexact := false;
--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
SELECT placex.place_id, osm_type, osm_id, name,
coalesce(extratags->'linked_place', extratags->'place') as place_type,
FOR location IN
SELECT placex.place_id, osm_type, osm_id, name,
coalesce(extratags->'linked_place', extratags->'place') as place_type,
location.admin_level, true, location.isaddress,
location.rank_address, location.distance)::addressline;
RETURN NEXT countrylocation;
location.admin_level, true, location.isaddress,
location.rank_address, location.distance)::addressline;
RETURN NEXT countrylocation;
- found := location.rank_address;
+
+ current_rank_address := location.rank_address;
+ -- --- Return records for address parts.
+
FOR location IN
SELECT placex.place_id, osm_type, osm_id, name, class, type,
coalesce(extratags->'linked_place', extratags->'place') as place_type,
FOR location IN
SELECT placex.place_id, osm_type, osm_id, name, class, type,
coalesce(extratags->'linked_place', extratags->'place') as place_type,
CASE WHEN rank_address = 11 THEN 5 ELSE rank_address END as rank_address,
distance, country_code, postcode
FROM place_addressline join placex on (address_place_id = placex.place_id)
CASE WHEN rank_address = 11 THEN 5 ELSE rank_address END as rank_address,
distance, country_code, postcode
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 (placex.country_code IS NULL OR searchcountrycode IS NULL
OR placex.country_code = searchcountrycode)
AND linked_place_id is null
AND (placex.country_code IS NULL OR searchcountrycode IS NULL
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
LOOP
distance asc, rank_search desc
LOOP
---RAISE WARNING '%',location;
+ -- RAISE WARNING '%',location;
IF searchcountrycode IS NULL AND location.country_code IS NOT NULL THEN
searchcountrycode := location.country_code;
END IF;
IF searchcountrycode IS NULL AND location.country_code IS NOT NULL THEN
searchcountrycode := location.country_code;
END IF;
location.name, location.class, location.type,
location.place_type,
location.admin_level, location.fromarea,
location.name, location.class, location.type,
location.place_type,
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;
RETURN NEXT countrylocation;
location.distance)::addressline;
RETURN NEXT countrylocation;
- found := location.rank_address;
+
+ IF location.isaddress THEN
+ current_rank_address := location.rank_address;
+ END IF;
END LOOP;
-- If no country was included yet, add the name information from country_name.
END LOOP;
-- If no country was included yet, add the name information from country_name.
+ IF current_rank_address > 4 THEN
SELECT name FROM country_name
WHERE country_code = searchcountrycode LIMIT 1 INTO countryname;
SELECT name FROM country_name
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
location := ROW(null, null, null, countryname, 'place', 'country', NULL,
null, true, true, 4, 0)::addressline;
IF countryname IS NOT NULL THEN
location := ROW(null, null, null, countryname, 'place', 'country', NULL,
null, true, true, 4, 0)::addressline;
addr_item RECORD;
parent_address_place_ids BIGINT[];
addr_item RECORD;
parent_address_place_ids BIGINT[];
+ filtered_address HSTORE;
BEGIN
nameaddress_vector := '{}'::INTEGER[];
BEGIN
nameaddress_vector := '{}'::INTEGER[];
FROM search_name s
WHERE s.place_id = parent_place_id;
FROM search_name s
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
SELECT * FROM
FOR addr_item IN
SELECT * FROM
- get_places_for_addr_tags(in_partition, geometry, address, country)
+ get_places_for_addr_tags(in_partition, geometry, filtered_address, country)
LOOP
IF addr_item.place_id is null THEN
nameaddress_vector := array_merge(nameaddress_vector,
LOOP
IF addr_item.place_id is null THEN
nameaddress_vector := array_merge(nameaddress_vector,
| osm | class | type | admin | name | geometry |
| R1 | boundary | administrative | 8 | Left | (1,2,3,4,1) |
| R2 | boundary | administrative | 8 | Right | (2,3,6,5,2) |
| osm | class | type | admin | name | geometry |
| R1 | boundary | administrative | 8 | Left | (1,2,3,4,1) |
| R2 | boundary | administrative | 8 | Right | (2,3,6,5,2) |
- And the named places
- | osm | class | type | addr+city | geometry |
- | W1 | highway | primary | Right | 8,9 |
- | N1 | amenity | cafe | Left | 9 |
+ And the places
+ | osm | class | type | name | addr+city | geometry |
+ | W1 | highway | primary | Wonderway | Right | 8,9 |
+ | N1 | amenity | cafe | Bolder | Left | 9 |
When importing
Then place_addressline contains
| object | address | isaddress |
When importing
Then place_addressline contains
| object | address | isaddress |
And place_addressline doesn't contain
| object | address |
| W1 | R1 |
And place_addressline doesn't contain
| object | address |
| W1 | R1 |
+ When searching for "Bolder"
+ Then results contain
+ | osm_type | osm_id | name |
+ | N | 1 | Bolder, Wonderway, Left |