forked from hans/Nominatim
Merge pull request #2038 from lonvia/addresses-for-large-areas
Improve addresses for large areas
This commit is contained in:
@@ -64,7 +64,15 @@
|
|||||||
"peak" : [18, 0],
|
"peak" : [18, 0],
|
||||||
"volcano" : [18, 0],
|
"volcano" : [18, 0],
|
||||||
"mountain_range" : [18, 0],
|
"mountain_range" : [18, 0],
|
||||||
"sea" : [4, 0]
|
"sea" : [4, 0],
|
||||||
|
"tree" : 30,
|
||||||
|
"spring" : 30,
|
||||||
|
"cave_entrance" : 30,
|
||||||
|
"geyser" : 30,
|
||||||
|
"hot_spring" : 30,
|
||||||
|
"rock" : 30,
|
||||||
|
"stone" : 30,
|
||||||
|
"" : [22, 0]
|
||||||
},
|
},
|
||||||
"waterway" : {
|
"waterway" : {
|
||||||
"river" : [19, 0],
|
"river" : [19, 0],
|
||||||
|
|||||||
@@ -509,6 +509,8 @@ DECLARE
|
|||||||
addr_street TEXT;
|
addr_street TEXT;
|
||||||
addr_place TEXT;
|
addr_place TEXT;
|
||||||
|
|
||||||
|
max_rank SMALLINT;
|
||||||
|
|
||||||
name_vector INTEGER[];
|
name_vector INTEGER[];
|
||||||
nameaddress_vector INTEGER[];
|
nameaddress_vector INTEGER[];
|
||||||
addr_nameaddress_vector INTEGER[];
|
addr_nameaddress_vector INTEGER[];
|
||||||
@@ -906,14 +908,19 @@ BEGIN
|
|||||||
--DEBUG: RAISE WARNING 'Country names updated';
|
--DEBUG: RAISE WARNING 'Country names updated';
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
SELECT * FROM insert_addresslines(NEW.place_id, NEW.partition,
|
IF NEW.rank_address = 0 THEN
|
||||||
CASE WHEN NEW.rank_address = 0 THEN NEW.rank_search
|
max_rank := geometry_to_rank(NEW.rank_search, NEW.geometry, NEW.country_code);
|
||||||
WHEN NEW.rank_address > 25 THEN 25::smallint
|
ELSEIF NEW.rank_address > 25 THEN
|
||||||
ELSE NEW.rank_address END,
|
max_rank := 25;
|
||||||
|
ELSE
|
||||||
|
max_rank = NEW.rank_address;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SELECT * FROM insert_addresslines(NEW.place_id, NEW.partition, max_rank,
|
||||||
NEW.address,
|
NEW.address,
|
||||||
CASE WHEN NEW.rank_search >= 26
|
CASE WHEN (NEW.rank_address = 0 or
|
||||||
AND NEW.rank_search < 30
|
NEW.rank_search between 26 and 29)
|
||||||
THEN NEW.geometry ELSE NEW.centroid END)
|
THEN NEW.geometry ELSE NEW.centroid END)
|
||||||
INTO NEW.parent_place_id, NEW.postcode, nameaddress_vector;
|
INTO NEW.parent_place_id, NEW.postcode, nameaddress_vector;
|
||||||
|
|
||||||
--DEBUG: RAISE WARNING 'RETURN insert_addresslines: %, %, %', NEW.parent_place_id, NEW.postcode, nameaddress_vector;
|
--DEBUG: RAISE WARNING 'RETURN insert_addresslines: %, %, %', NEW.parent_place_id, NEW.postcode, nameaddress_vector;
|
||||||
|
|||||||
@@ -55,6 +55,53 @@ END;
|
|||||||
$$
|
$$
|
||||||
LANGUAGE plpgsql IMMUTABLE;
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
|
|
||||||
|
-- Compute a base address rank from the extent of the given geometry.
|
||||||
|
--
|
||||||
|
-- This is all simple guess work. We don't need particularly good estimates
|
||||||
|
-- here. This just avoids to have very high ranked address parts in features
|
||||||
|
-- that span very large areas (or vice versa).
|
||||||
|
CREATE OR REPLACE FUNCTION geometry_to_rank(search_rank SMALLINT, geometry GEOMETRY, country_code TEXT)
|
||||||
|
RETURNS SMALLINT
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
area FLOAT;
|
||||||
|
BEGIN
|
||||||
|
IF ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') THEN
|
||||||
|
area := ST_Area(geometry);
|
||||||
|
ELSIF ST_GeometryType(geometry) in ('ST_LineString','ST_MultiLineString') THEN
|
||||||
|
area := (ST_Length(geometry)^2) * 0.1;
|
||||||
|
ELSE
|
||||||
|
RETURN search_rank;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- adjust for the fact that countries come in different sizes
|
||||||
|
IF country_code IN ('ca', 'au', 'ru') THEN
|
||||||
|
area := area / 5;
|
||||||
|
ELSIF country_code IN ('br', 'kz', 'cn', 'us', 'ne', 'gb', 'za', 'sa', 'id', 'eh', 'ml', 'tm') THEN
|
||||||
|
area := area / 3;
|
||||||
|
ELSIF country_code IN ('bo', 'ar', 'sd', 'mn', 'in', 'et', 'cd', 'mz', 'ly', 'cl', 'zm') THEN
|
||||||
|
area := area / 2;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF area > 1 THEN
|
||||||
|
RETURN 7;
|
||||||
|
ELSIF area > 0.1 THEN
|
||||||
|
RETURN 9;
|
||||||
|
ELSIF area > 0.01 THEN
|
||||||
|
RETURN 13;
|
||||||
|
ELSIF area > 0.001 THEN
|
||||||
|
RETURN 17;
|
||||||
|
ELSIF area > 0.0001 THEN
|
||||||
|
RETURN 19;
|
||||||
|
ELSIF area > 0.000005 THEN
|
||||||
|
RETURN 21;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN 23;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
|
|
||||||
|
|
||||||
-- Guess a ranking for postcodes from country and postcode format.
|
-- Guess a ranking for postcodes from country and postcode format.
|
||||||
CREATE OR REPLACE FUNCTION get_postcode_rank(country_code VARCHAR(2), postcode TEXT,
|
CREATE OR REPLACE FUNCTION get_postcode_rank(country_code VARCHAR(2), postcode TEXT,
|
||||||
|
|||||||
@@ -216,13 +216,13 @@ Feature: Import into placex
|
|||||||
| object | rank_search | rank_address |
|
| object | rank_search | rank_address |
|
||||||
| N2 | 18 | 0 |
|
| N2 | 18 | 0 |
|
||||||
| N4 | 18 | 0 |
|
| N4 | 18 | 0 |
|
||||||
| N5 | 30 | 30 |
|
| N5 | 22 | 0 |
|
||||||
| W2 | 18 | 0 |
|
| W2 | 18 | 0 |
|
||||||
| R3 | 18 | 0 |
|
| R3 | 18 | 0 |
|
||||||
| R4 | 30 | 30 |
|
| R4 | 22 | 0 |
|
||||||
| R5 | 4 | 0 |
|
| R5 | 4 | 0 |
|
||||||
| R6 | 4 | 0 |
|
| R6 | 4 | 0 |
|
||||||
| W3 | 30 | 30 |
|
| W3 | 22 | 0 |
|
||||||
|
|
||||||
Scenario: boundary ways for countries and states are ignored
|
Scenario: boundary ways for countries and states are ignored
|
||||||
Given the named places
|
Given the named places
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Feature: Update of simple objects
|
|||||||
When importing
|
When importing
|
||||||
Then placex contains
|
Then placex contains
|
||||||
| object | rank_address |
|
| object | rank_address |
|
||||||
| R1 | 30 |
|
| R1 | 0 |
|
||||||
| R2 | 26 |
|
| R2 | 26 |
|
||||||
| W1 | 30 |
|
| W1 | 30 |
|
||||||
When marking for delete R1,R2,W1
|
When marking for delete R1,R2,W1
|
||||||
|
|||||||
Reference in New Issue
Block a user