--- /dev/null
+@DB
+Feature: Linking of places
+ Tests for correctly determining linked places
+
+ Scenario: Only address-describing places can be linked
+ Given the scene way-area-with-center
+ And the places
+ | osm | class | type | name | geometry |
+ | R13 | landuse | forest | Garbo | :area |
+ | N256 | natural | peak | Garbo | :inner-C |
+ When importing
+ Then placex contains
+ | object | linked_place_id |
+ | R13 | - |
+ | N256 | - |
+
+ Scenario: Waterways are linked when in waterway relations
+ Given the scene split-road
+ And the places
+ | osm | class | type | name | geometry |
+ | W1 | waterway | river | Rhein | :w-2 |
+ | W2 | waterway | river | Rhein | :w-3 |
+ | R13 | waterway | river | Rhein | :w-1 + :w-2 + :w-3 |
+ | R23 | waterway | river | Limmat| :w-4a |
+ And the relations
+ | id | members | tags+type |
+ | 13 | R23:tributary,W1,W2:main_stream | waterway |
+ When importing
+ Then placex contains
+ | object | linked_place_id |
+ | W1 | R13 |
+ | W2 | R13 |
+ | R13 | - |
+ | R23 | - |
+ When searching for "rhein"
+ Then results contain
+ | osm_type |
+ | R |
+
+ Scenario: Relations are not linked when in waterway relations
+ Given the scene split-road
+ And the places
+ | osm | class | type | name | geometry |
+ | W1 | waterway | river | Rhein | :w-2 |
+ | W2 | waterway | river | Rhein | :w-3 |
+ | R1 | waterway | river | Rhein | :w-1 + :w-2 + :w-3 |
+ | R2 | waterway | river | Limmat| :w-4a |
+ And the relations
+ | id | members | tags+type |
+ | 1 | R2 | waterway |
+ When importing
+ Then placex contains
+ | object | linked_place_id |
+ | W1 | - |
+ | W2 | - |
+ | R1 | - |
+ | R2 | - |
+
+ Scenario: Empty waterway relations are handled correctly
+ Given the scene split-road
+ And the places
+ | osm | class | type | name | geometry |
+ | R1 | waterway | river | Rhein | :w-1 + :w-2 + :w-3 |
+ And the relations
+ | id | members | tags+type |
+ | 1 | | waterway |
+ When importing
+ Then placex contains
+ | object | linked_place_id |
+ | R1 | - |
+
+ Scenario: Waterways are not linked when waterway types don't match
+ Given the scene split-road
+ And the places
+ | osm | class | type | name | geometry |
+ | W1 | waterway | drain | Rhein | :w-2 |
+ | R1 | waterway | river | Rhein | :w-1 + :w-2 + :w-3 |
+ And the relations
+ | id | members | tags+type |
+ | 1 | N23,N34,W1,R45 | multipolygon |
+ When importing
+ Then placex contains
+ | object | linked_place_id |
+ | W1 | - |
+ | R1 | - |
+ When searching for "rhein"
+ Then results contain
+ | ID | osm_type |
+ | 0 | R |
+ | 1 | W |
+
+ Scenario: Side streams are linked only when they have the same name
+ Given the scene split-road
+ And the places
+ | osm | class | type | name | geometry |
+ | W1 | waterway | river | Rhein2 | :w-2 |
+ | W2 | waterway | river | Rhein | :w-3 |
+ | R1 | waterway | river | Rhein | :w-1 + :w-2 + :w-3 |
+ And the relations
+ | id | members | tags+type |
+ | 1 | W1:side_stream,W2:side_stream | waterway |
+ When importing
+ Then placex contains
+ | object | linked_place_id |
+ | W1 | - |
+ | W2 | R1 |
+ When searching for "rhein2"
+ Then results contain
+ | osm_type |
+ | W |
last_node = 0
last_way = 0
parts = []
- members = []
- for m in r['members'].split(','):
- mid = NominatimID(m)
- if mid.typ == 'N':
- parts.insert(last_node, int(mid.oid))
- members.insert(2 * last_node, mid.cls)
- members.insert(2 * last_node, 'n' + mid.oid)
- last_node += 1
- last_way += 1
- elif mid.typ == 'W':
- parts.insert(last_way, int(mid.oid))
- members.insert(2 * last_way, mid.cls)
- members.insert(2 * last_way, 'w' + mid.oid)
- last_way += 1
- else:
- parts.append(int(mid.oid))
- members.extend(('r' + mid.oid, mid.cls))
+ if r['members']:
+ members = []
+ for m in r['members'].split(','):
+ mid = NominatimID(m)
+ if mid.typ == 'N':
+ parts.insert(last_node, int(mid.oid))
+ last_node += 1
+ last_way += 1
+ elif mid.typ == 'W':
+ parts.insert(last_way, int(mid.oid))
+ last_way += 1
+ else:
+ parts.append(int(mid.oid))
+
+ members.extend((mid.typ.lower() + mid.oid, mid.cls or ''))
+ else:
+ members = None
tags = []
for h in r.headings:
eq_(res['name'][name], row[h])
elif h.startswith('extratags+'):
eq_(res['extratags'][h[10:]], row[h])
- elif h == 'parent_place_id':
+ elif h in ('linked_place_id', 'parent_place_id'):
if row[h] == '0':
eq_(0, res[h])
+ elif row[h] == '-':
+ assert_is_none(res[h])
else:
eq_(NominatimID(row[h]).get_place_id(context.db.cursor()),
res[h])