Merge pull request #669 from lonvia/address-part-on-intersect

Add all intersecting boundaries to address list for roads
This commit is contained in:
Sarah Hoffmann
2017-03-19 21:50:45 +01:00
committed by GitHub
4 changed files with 63 additions and 7 deletions

View File

@@ -1679,7 +1679,12 @@ BEGIN
-- added ourself as address already
address_havelevel[NEW.rank_address] := true;
-- RAISE WARNING ' getNearFeatures(%,''%'',%,''%'')',NEW.partition, place_centroid, search_maxrank, isin_tokens;
FOR location IN SELECT * from getNearFeatures(NEW.partition, place_centroid, search_maxrank, isin_tokens) LOOP
FOR location IN
SELECT * from getNearFeatures(NEW.partition,
CASE WHEN NEW.rank_search >= 26 THEN NEW.geometry
ELSE place_centroid END,
search_maxrank, isin_tokens)
LOOP
--RAISE WARNING ' AREA: %',location;

View File

@@ -1,4 +1,4 @@
create or replace function getNearFeatures(in_partition INTEGER, point GEOMETRY, maxrank INTEGER, isin_tokens INT[]) RETURNS setof nearfeaturecentr AS $$
create or replace function getNearFeatures(in_partition INTEGER, feature GEOMETRY, maxrank INTEGER, isin_tokens INT[]) RETURNS setof nearfeaturecentr AS $$
DECLARE
r nearfeaturecentr%rowtype;
BEGIN
@@ -6,14 +6,14 @@ BEGIN
-- start
IF in_partition = -partition- THEN
FOR r IN
SELECT place_id, keywords, rank_address, rank_search, min(ST_Distance(point, centroid)) as distance, isguess, centroid FROM (
SELECT * FROM location_area_large_-partition- WHERE ST_Contains(geometry, point) and rank_search < maxrank
SELECT place_id, keywords, rank_address, rank_search, min(ST_Distance(feature, centroid)) as distance, isguess, centroid FROM (
SELECT * FROM location_area_large_-partition- WHERE ST_Intersects(geometry, feature) and rank_search < maxrank
UNION ALL
SELECT * FROM location_area_country WHERE ST_Contains(geometry, point) and rank_search < maxrank
SELECT * FROM location_area_country WHERE ST_Intersects(geometry, feature) and rank_search < maxrank
) as location_area
GROUP BY place_id, keywords, rank_address, rank_search, isguess, centroid
ORDER BY rank_address, isin_tokens && keywords desc, isguess asc,
ST_Distance(point, centroid) *
ST_Distance(feature, centroid) *
CASE
WHEN rank_address = 16 AND rank_search = 15 THEN 0.2 -- capital city
WHEN rank_address = 16 AND rank_search = 16 THEN 0.25 -- city

View File

@@ -0,0 +1,22 @@
@DB
Feature: Address computation
Tests for filling of place_addressline
# github #121
Scenario: Roads crossing boundaries should contain both states
Given the grid
| 1 | | | 2 | | 3 |
| | 7 | | 8 | | |
| 4 | | | 5 | | 6 |
And the named places
| osm | class | type | geometry |
| W1 | highway | road | 7, 8 |
And the named places
| osm | class | type | admin | geometry |
| W10 | boundary | administrative | 5 | (1, 2, 5, 4, 1) |
| W11 | boundary | administrative | 5 | (2, 3, 6, 5, 2) |
When importing
Then place_addressline contains
| object | address | cached_rank_address |
| W1 | W10 | 10 |
| W1 | W11 | 10 |

View File

@@ -93,6 +93,12 @@ class NominatimID:
self.oid = m.group('id')
self.cls = m.group('cls')
def __str__(self):
if self.cls is None:
return self.typ + self.oid
return '%s%d:%s' % (self.typ, self.oid, self.cls)
def table_select(self):
""" Return where clause and parameter list to select the object
from a Nominatim table.
@@ -109,7 +115,9 @@ class NominatimID:
def get_place_id(self, cur):
where, params = self.table_select()
cur.execute("SELECT place_id FROM placex WHERE %s" % where, params)
eq_(1, cur.rowcount, "Expected exactly 1 entry in placex found %s" % cur.rowcount)
eq_(1, cur.rowcount,
"Expected exactly 1 entry in placex for %s found %s"
% (str(self), cur.rowcount))
return cur.fetchone()[0]
@@ -386,6 +394,27 @@ def check_search_name_contents(context):
context.db.commit()
@then("place_addressline contains")
def check_place_addressline(context):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor)
for row in context.table:
pid = NominatimID(row['object']).get_place_id(cur)
apid = NominatimID(row['address']).get_place_id(cur)
cur.execute(""" SELECT * FROM place_addressline
WHERE place_id = %s AND address_place_id = %s""",
(pid, apid))
assert_less(0, cur.rowcount,
"No rows found for place %s and address %s"
% (row['object'], row['address']))
for res in cur:
for h in row.headings:
if h not in ('address', 'object'):
assert_db_column(res, h, row[h], context)
context.db.commit()
@then("(?P<oid>\w+) expands to(?P<neg> no)? interpolation")
def check_location_property_osmline(context, oid, neg):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor)