mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-26 11:08:13 +00:00
Merge pull request #2745 from lonvia/city-in-city-fix
Improve hierarchy computation for place areas
This commit is contained in:
@@ -864,29 +864,55 @@ BEGIN
|
|||||||
|
|
||||||
IF NEW.rank_address > 9 THEN
|
IF NEW.rank_address > 9 THEN
|
||||||
-- Second check that the boundary is not completely contained in a
|
-- Second check that the boundary is not completely contained in a
|
||||||
-- place area with a higher address rank
|
-- place area with a equal or higher address rank.
|
||||||
FOR location IN
|
FOR location IN
|
||||||
SELECT rank_address FROM placex
|
SELECT rank_address
|
||||||
|
FROM placex,
|
||||||
|
LATERAL compute_place_rank(country_code, 'A', class, type,
|
||||||
|
admin_level, False, null) prank
|
||||||
WHERE class = 'place' and rank_address < 24
|
WHERE class = 'place' and rank_address < 24
|
||||||
and rank_address > NEW.rank_address
|
and prank.address_rank >= NEW.rank_address
|
||||||
and geometry && NEW.geometry
|
and geometry && NEW.geometry
|
||||||
and geometry ~ NEW.geometry -- needed because ST_Relate does not do bbox cover test
|
and geometry ~ NEW.geometry -- needed because ST_Relate does not do bbox cover test
|
||||||
and ST_Relate(geometry, NEW.geometry, 'T*T***FF*') -- contains but not equal
|
and ST_Relate(geometry, NEW.geometry, 'T*T***FF*') -- contains but not equal
|
||||||
ORDER BY rank_address desc LIMIT 1
|
ORDER BY prank.address_rank desc LIMIT 1
|
||||||
LOOP
|
LOOP
|
||||||
NEW.rank_address := location.rank_address + 2;
|
NEW.rank_address := location.rank_address + 2;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END IF;
|
END IF;
|
||||||
ELSEIF NEW.class = 'place' and NEW.osm_type = 'N'
|
ELSEIF NEW.class = 'place'
|
||||||
and NEW.rank_address between 16 and 23
|
and ST_GeometryType(NEW.geometry) in ('ST_Polygon', 'ST_MultiPolygon')
|
||||||
|
and NEW.rank_address between 16 and 23
|
||||||
THEN
|
THEN
|
||||||
-- If a place node is contained in a admin boundary with the same address level
|
-- For place areas make sure they are not completely contained in an area
|
||||||
-- and has not been linked, then make the node a subpart by increasing the
|
-- with a equal or higher address rank.
|
||||||
-- address rank (city level and above).
|
|
||||||
FOR location IN
|
FOR location IN
|
||||||
SELECT rank_address FROM placex
|
SELECT rank_address
|
||||||
WHERE osm_type = 'R' and class = 'boundary' and type = 'administrative'
|
FROM placex,
|
||||||
and rank_address = NEW.rank_address
|
LATERAL compute_place_rank(country_code, 'A', class, type,
|
||||||
|
admin_level, False, null) prank
|
||||||
|
WHERE prank.address_rank < 24
|
||||||
|
and prank.address_rank >= NEW.rank_address
|
||||||
|
and geometry && NEW.geometry
|
||||||
|
and geometry ~ NEW.geometry -- needed because ST_Relate does not do bbox cover test
|
||||||
|
and ST_Relate(geometry, NEW.geometry, 'T*T***FF*') -- contains but not equal
|
||||||
|
ORDER BY prank.address_rank desc LIMIT 1
|
||||||
|
LOOP
|
||||||
|
NEW.rank_address := location.rank_address + 2;
|
||||||
|
END LOOP;
|
||||||
|
ELSEIF NEW.class = 'place' and NEW.osm_type = 'N'
|
||||||
|
and NEW.rank_address between 16 and 23
|
||||||
|
THEN
|
||||||
|
-- If a place node is contained in an admin or place boundary with the same
|
||||||
|
-- address level and has not been linked, then make the node a subpart
|
||||||
|
-- by increasing the address rank (city level and above).
|
||||||
|
FOR location IN
|
||||||
|
SELECT rank_address
|
||||||
|
FROM placex,
|
||||||
|
LATERAL compute_place_rank(country_code, 'A', class, type,
|
||||||
|
admin_level, False, null) prank
|
||||||
|
WHERE osm_type = 'R'
|
||||||
|
and prank.address_rank = NEW.rank_address
|
||||||
and geometry && NEW.centroid and _ST_Covers(geometry, NEW.centroid)
|
and geometry && NEW.centroid and _ST_Covers(geometry, NEW.centroid)
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
LOOP
|
LOOP
|
||||||
|
|||||||
@@ -74,20 +74,22 @@ Feature: Address computation
|
|||||||
|
|
||||||
Scenario: boundary areas are preferred over place nodes in the address
|
Scenario: boundary areas are preferred over place nodes in the address
|
||||||
Given the grid
|
Given the grid
|
||||||
| 1 | | | | | | 3 |
|
| 1 | | | | 10 | | 3 |
|
||||||
| | 5 | | | | | |
|
| | 5 | | | | | |
|
||||||
| | 6 | | | | | |
|
| | 6 | | | | | |
|
||||||
| 2 | | | | | | 4 |
|
| 2 | | | | 11 | | 4 |
|
||||||
And the named places
|
And the named places
|
||||||
| osm | class | type | admin | geometry |
|
| osm | class | type | admin | geometry |
|
||||||
| N1 | place | square | 15 | 5 |
|
| N1 | place | square | 15 | 5 |
|
||||||
| N2 | place | city | 15 | 6 |
|
| N2 | place | city | 15 | 6 |
|
||||||
| R1 | place | city | 8 | (1,2,4,3,1) |
|
| R1 | place | city | 8 | (1,2,4,3,1) |
|
||||||
|
| R2 | boundary | administrative | 9 | (1,10,11,2,1) |
|
||||||
When importing
|
When importing
|
||||||
Then place_addressline contains
|
Then place_addressline contains
|
||||||
| object | address | isaddress | cached_rank_address |
|
| object | address | isaddress | cached_rank_address |
|
||||||
| N1 | R1 | True | 16 |
|
| N1 | R1 | True | 16 |
|
||||||
| N1 | N2 | False | 16 |
|
| N1 | R2 | True | 18 |
|
||||||
|
| N1 | N2 | False | 18 |
|
||||||
|
|
||||||
Scenario: place nodes outside a smaller ranked area are ignored
|
Scenario: place nodes outside a smaller ranked area are ignored
|
||||||
Given the grid
|
Given the grid
|
||||||
|
|||||||
@@ -197,3 +197,61 @@ Feature: Rank assignment
|
|||||||
| N20 | R22 | 16 |
|
| N20 | R22 | 16 |
|
||||||
| N20 | R21 | 18 |
|
| N20 | R21 | 18 |
|
||||||
|
|
||||||
|
Scenario: Mixes of admin boundaries and place areas I
|
||||||
|
Given the grid
|
||||||
|
| 1 | | 10 | | | 2 |
|
||||||
|
| | 9 | | | | |
|
||||||
|
| 20| | 21 | | | |
|
||||||
|
| 4 | | 11 | | | 3 |
|
||||||
|
And the places
|
||||||
|
| osm | class | type | admin | name | geometry |
|
||||||
|
| R1 | boundary | administrative | 5 | Greater London | (1,2,3,4,1) |
|
||||||
|
| R2 | boundary | administrative | 8 | Kensington | (1,10,11,4,1) |
|
||||||
|
And the places
|
||||||
|
| osm | class | type | name | geometry |
|
||||||
|
| R10 | place | city | London | (1,2,3,4,1) |
|
||||||
|
| N9 | place | town | Fulham | 9 |
|
||||||
|
| W1 | highway | residential | Lots Grove | 20,21 |
|
||||||
|
When importing
|
||||||
|
Then placex contains
|
||||||
|
| object | rank_search | rank_address |
|
||||||
|
| R1 | 10 | 10 |
|
||||||
|
| R10 | 16 | 16 |
|
||||||
|
| R2 | 16 | 18 |
|
||||||
|
| N9 | 18 | 18 |
|
||||||
|
And place_addressline contains
|
||||||
|
| object | address | isaddress | cached_rank_address |
|
||||||
|
| W1 | R1 | True | 10 |
|
||||||
|
| W1 | R10 | True | 16 |
|
||||||
|
| W1 | R2 | True | 18 |
|
||||||
|
| W1 | N9 | False | 18 |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Mixes of admin boundaries and place areas II
|
||||||
|
Given the grid
|
||||||
|
| 1 | | 10 | | 5 | 2 |
|
||||||
|
| | 9 | | | | |
|
||||||
|
| 20| | 21 | | | |
|
||||||
|
| 4 | | 11 | | 6 | 3 |
|
||||||
|
And the places
|
||||||
|
| osm | class | type | admin | name | geometry |
|
||||||
|
| R1 | boundary | administrative | 5 | Greater London | (1,2,3,4,1) |
|
||||||
|
| R2 | boundary | administrative | 8 | London | (1,5,6,4,1) |
|
||||||
|
And the places
|
||||||
|
| osm | class | type | name | geometry |
|
||||||
|
| R10 | place | city | Westminster | (1,10,11,4,1) |
|
||||||
|
| N9 | place | town | Fulham | 9 |
|
||||||
|
| W1 | highway | residential | Lots Grove | 20,21 |
|
||||||
|
When importing
|
||||||
|
Then placex contains
|
||||||
|
| object | rank_search | rank_address |
|
||||||
|
| R1 | 10 | 10 |
|
||||||
|
| R2 | 16 | 16 |
|
||||||
|
| R10 | 16 | 18 |
|
||||||
|
| N9 | 18 | 18 |
|
||||||
|
And place_addressline contains
|
||||||
|
| object | address | isaddress | cached_rank_address |
|
||||||
|
| W1 | R1 | True | 10 |
|
||||||
|
| W1 | R10 | True | 18 |
|
||||||
|
| W1 | R2 | True | 16 |
|
||||||
|
| W1 | N9 | False | 18 |
|
||||||
|
|||||||
Reference in New Issue
Block a user