--- /dev/null
+@DB
+Feature: Import into placex
+ Tests that data in placex is completed correctly.
+
+ Scenario: No country code tag is available
+ Given the named places
+ | osm | class | type | geometry |
+ | N1 | highway | primary | country:us |
+ When importing
+ Then placex contains
+ | object | country_code | calculated_country_code |
+ | N1 | None | us |
+
+ Scenario: Location overwrites country code tag
+ Given the named places
+ | osm | class | type | country | geometry |
+ | N1 | highway | primary | de | country:us |
+ When importing
+ Then placex contains
+ | object | country_code | calculated_country_code |
+ | N1 | de | us |
+
+ Scenario: Country code tag overwrites location for countries
+ Given the named places
+ | osm | class | type | admin | country | geometry |
+ | R1 | boundary | administrative | 2 | de | (-100 40, -101 40, -101 41, -100 41, -100 40) |
+ When importing
+ Then placex contains
+ | object | country_code | calculated_country_code |
+ | R1 | de | de |
+
+ Scenario: Illegal country code tag for countries is ignored
+ Given the named places
+ | osm | class | type | admin | country | geometry |
+ | R1 | boundary | administrative | 2 | xx | (-100 40, -101 40, -101 41, -100 41, -100 40) |
+ When importing
+ Then placex contains
+ | object | country_code | calculated_country_code |
+ | R1 | xx | us |
+
+ Scenario: admin level is copied over
+ Given the named places
+ | osm | class | type | admin |
+ | N1 | place | state | 3 |
+ When importing
+ Then placex contains
+ | object | admin_level |
+ | N1 | 3 |
+
+ Scenario: admin level is default 15
+ Given the named places
+ | osm | class | type |
+ | N1 | amenity | prison |
+ When importing
+ Then placex contains
+ | object | admin_level |
+ | N1 | 15 |
+
+ Scenario: admin level is never larger than 15
+ Given the named places
+ | osm | class | type | admin |
+ | N1 | amenity | prison | 16 |
+ When importing
+ Then placex contains
+ | object | admin_level |
+ | N1 | 15 |
+
+ Scenario: postcode node without postcode is dropped
+ Given the places
+ | osm | class | type | name+ref |
+ | N1 | place | postcode | 12334 |
+ When importing
+ Then placex has no entry for N1
+
+ Scenario: postcode boundary without postcode is dropped
+ Given the places
+ | osm | class | type | name+ref | geometry |
+ | R1 | boundary | postal_code | 554476 | poly-area:0.1 |
+ When importing
+ Then placex has no entry for R1
+
+ Scenario: search and address ranks for GB post codes correctly assigned
+ Given the places
+ | osm | class | type | postcode | geometry |
+ | N1 | place | postcode | E45 2CD | country:gb |
+ | N2 | place | postcode | E45 2 | country:gb |
+ | N3 | place | postcode | Y45 | country:gb |
+ When importing
+ Then placex contains
+ | object | postcode | calculated_country_code | rank_search | rank_address |
+ | N1 | E45 2CD | gb | 25 | 5 |
+ | N2 | E45 2 | gb | 23 | 5 |
+ | N3 | Y45 | gb | 21 | 5 |
+
+ Scenario: wrongly formatted GB postcodes are down-ranked
+ Given the places
+ | osm | class | type | postcode | geometry |
+ | N1 | place | postcode | EA452CD | country:gb |
+ | N2 | place | postcode | E45 23 | country:gb |
+ | N3 | place | postcode | y45 | country:gb |
+ When importing
+ Then placex contains
+ | object | calculated_country_code | rank_search | rank_address |
+ | N1 | gb | 30 | 30 |
+ | N2 | gb | 30 | 30 |
+ | N3 | gb | 30 | 30 |
+
+ Scenario: search and address rank for DE postcodes correctly assigned
+ Given the places
+ | osm | class | type | postcode | geometry |
+ | N1 | place | postcode | 56427 | country:de |
+ | N2 | place | postcode | 5642 | country:de |
+ | N3 | place | postcode | 5642A | country:de |
+ | N4 | place | postcode | 564276 | country:de |
+ When importing
+ Then placex contains
+ | object | calculated_country_code | rank_search | rank_address |
+ | N1 | de | 21 | 11 |
+ | N2 | de | 30 | 30 |
+ | N3 | de | 30 | 30 |
+ | N4 | de | 30 | 30 |
+
+ Scenario: search and address rank for other postcodes are correctly assigned
+ Given the places
+ | osm | class | type | postcode | geometry |
+ | N1 | place | postcode | 1 | country:ca |
+ | N2 | place | postcode | X3 | country:ca |
+ | N3 | place | postcode | 543 | country:ca |
+ | N4 | place | postcode | 54dc | country:ca |
+ | N5 | place | postcode | 12345 | country:ca |
+ | N6 | place | postcode | 55TT667 | country:ca |
+ | N7 | place | postcode | 123-65 | country:ca |
+ | N8 | place | postcode | 12 445 4 | country:ca |
+ | N9 | place | postcode | A1:bc10 | country:ca |
+ When importing
+ Then placex contains
+ | object | calculated_country_code | rank_search | rank_address |
+ | N1 | ca | 21 | 11 |
+ | N2 | ca | 21 | 11 |
+ | N3 | ca | 21 | 11 |
+ | N4 | ca | 21 | 11 |
+ | N5 | ca | 21 | 11 |
+ | N6 | ca | 21 | 11 |
+ | N7 | ca | 25 | 11 |
+ | N8 | ca | 25 | 11 |
+ | N9 | ca | 25 | 11 |
+
+ Scenario: search and address ranks for places are correctly assigned
+ Given the named places
+ | osm | class | type |
+ | N1 | foo | bar |
+ | N11 | place | Continent |
+ | N12 | place | continent |
+ | N13 | place | sea |
+ | N14 | place | country |
+ | N15 | place | state |
+ | N16 | place | region |
+ | N17 | place | county |
+ | N18 | place | city |
+ | N19 | place | island |
+ | N20 | place | town |
+ | N21 | place | village |
+ | N22 | place | hamlet |
+ | N23 | place | municipality |
+ | N24 | place | district |
+ | N25 | place | unincorporated_area |
+ | N26 | place | borough |
+ | N27 | place | suburb |
+ | N28 | place | croft |
+ | N29 | place | subdivision |
+ | N30 | place | isolated_dwelling |
+ | N31 | place | farm |
+ | N32 | place | locality |
+ | N33 | place | islet |
+ | N34 | place | mountain_pass |
+ | N35 | place | neighbourhood |
+ | N36 | place | house |
+ | N37 | place | building |
+ | N38 | place | houses |
+ And the named places
+ | osm | class | type | extra+locality |
+ | N100 | place | locality | townland |
+ And the named places
+ | osm | class | type | extra+capital |
+ | N101 | place | city | yes |
+ When importing
+ Then placex contains
+ | object | rank_search | rank_address |
+ | N1 | 30 | 30 |
+ | N11 | 30 | 30 |
+ | N12 | 2 | 2 |
+ | N13 | 2 | 0 |
+ | N14 | 4 | 4 |
+ | N15 | 8 | 8 |
+ | N16 | 18 | 0 |
+ | N17 | 12 | 12 |
+ | N18 | 16 | 16 |
+ | N19 | 17 | 0 |
+ | N20 | 18 | 16 |
+ | N21 | 19 | 16 |
+ | N22 | 19 | 16 |
+ | N23 | 19 | 16 |
+ | N24 | 19 | 16 |
+ | N25 | 19 | 16 |
+ | N26 | 19 | 16 |
+ | N27 | 20 | 20 |
+ | N28 | 20 | 20 |
+ | N29 | 20 | 20 |
+ | N30 | 20 | 20 |
+ | N31 | 20 | 0 |
+ | N32 | 20 | 0 |
+ | N33 | 20 | 0 |
+ | N34 | 20 | 0 |
+ | N100 | 20 | 20 |
+ | N101 | 15 | 16 |
+ | N35 | 22 | 22 |
+ | N36 | 30 | 30 |
+ | N37 | 30 | 30 |
+ | N38 | 28 | 0 |
+
+ Scenario: search and address ranks for boundaries are correctly assigned
+ Given the named places
+ | osm | class | type |
+ | N1 | boundary | administrative |
+ And the named places
+ | osm | class | type | geometry |
+ | W10 | boundary | administrative | 10 10, 11 11 |
+ And the named places
+ | osm | class | type | admin | geometry |
+ | R20 | boundary | administrative | 2 | (1 1, 2 2, 1 2, 1 1) |
+ | R21 | boundary | administrative | 32 | (3 3, 4 4, 3 4, 3 3) |
+ | R22 | boundary | nature_park | 6 | (0 0, 1 0, 0 1, 0 0) |
+ | R23 | boundary | natural_reserve| 10 | (0 0, 1 1, 1 0, 0 0) |
+ When importing
+ Then placex has no entry for N1
+ And placex has no entry for W10
+ And placex contains
+ | object | rank_search | rank_address |
+ | R20 | 4 | 4 |
+ | R21 | 30 | 30 |
+ | R22 | 12 | 0 |
+ | R23 | 20 | 0 |
+
+ Scenario: search and address ranks for highways correctly assigned
+ Given the scene roads-with-pois
+ And the places
+ | osm | class | type |
+ | N1 | highway | bus_stop |
+ And the places
+ | osm | class | type | geometry |
+ | W1 | highway | primary | :w-south |
+ | W2 | highway | secondary | :w-south |
+ | W3 | highway | tertiary | :w-south |
+ | W4 | highway | residential | :w-north |
+ | W5 | highway | unclassified | :w-north |
+ | W6 | highway | something | :w-north |
+ When importing
+ Then placex contains
+ | object | rank_search | rank_address |
+ | N1 | 30 | 30 |
+ | W1 | 26 | 26 |
+ | W2 | 26 | 26 |
+ | W3 | 26 | 26 |
+ | W4 | 26 | 26 |
+ | W5 | 26 | 26 |
+ | W6 | 26 | 26 |
+
+ Scenario: rank and inclusion of landuses
+ Given the named places
+ | osm | class | type |
+ | N2 | landuse | residential |
+ And the named places
+ | osm | class | type | geometry |
+ | W2 | landuse | residential | 1 1, 1 1.1 |
+ | W4 | landuse | residential | poly-area:0.1 |
+ | R2 | landuse | residential | poly-area:0.05 |
+ | R3 | landuse | forrest | poly-area:0.5 |
+ When importing
+ Then placex contains
+ | object | rank_search | rank_address |
+ | N2 | 30 | 30 |
+ | W2 | 30 | 30 |
+ | W4 | 22 | 22 |
+ | R2 | 22 | 22 |
+ | R3 | 22 | 0 |
+
+ Scenario: rank and inclusion of naturals
+ Given the named places
+ | osm | class | type |
+ | N2 | natural | peak |
+ | N4 | natural | volcano |
+ | N5 | natural | foobar |
+ And the named places
+ | osm | class | type | geometry |
+ | W2 | natural | mountain_range | 12 12,11 11 |
+ | W3 | natural | foobar | 13 13,13.1 13 |
+ | R3 | natural | volcano | poly-area:0.1 |
+ | R4 | natural | foobar | poly-area:0.5 |
+ | R5 | natural | sea | poly-area:5.0 |
+ | R6 | natural | sea | poly-area:0.01 |
+ When importing
+ Then placex contains
+ | object | rank_search | rank_address |
+ | N2 | 18 | 0 |
+ | N4 | 18 | 0 |
+ | N5 | 30 | 30 |
+ | W2 | 18 | 0 |
+ | R3 | 18 | 0 |
+ | R4 | 22 | 0 |
+ | R5 | 4 | 4 |
+ | R6 | 4 | 4 |
+ | W3 | 30 | 30 |
+
import psycopg2
import psycopg2.extras
import subprocess
+from nose.tools import * # for assert functions
from sys import version_info as python_version
logger = logging.getLogger(__name__)
self.scene_cache = {}
def parse_geometry(self, geom, scene):
- if geom[0].find(':') >= 0:
- out = self.get_scene_geometry(scene, geom[1:])
- if geom.find(',') < 0:
- out = 'POINT(%s)' % geom
+ if geom.find(':') >= 0:
+ out = self.get_scene_geometry(scene, geom)
+ elif geom.find(',') < 0:
+ out = "'POINT(%s)'::geometry" % geom
elif geom.find('(') < 0:
- out = 'LINESTRING(%s)' % geom
+ out = "'LINESTRING(%s)'::geometry" % geom
else:
- out = 'POLYGON(%s)' % geom
+ out = "'POLYGON(%s)'::geometry" % geom
- # TODO parse precision
- return out, 0
+ return "ST_SetSRID(%s, 4326)" % out
def get_scene_geometry(self, default_scene, name):
geoms = []
- defscene = self.load_scene(default_scene)
for obj in name.split('+'):
oname = obj.strip()
if oname.startswith(':'):
+ assert_is_not_none(default_scene, "You need to set a scene")
+ defscene = self.load_scene(default_scene)
wkt = defscene[oname[1:]]
else:
scene, obj = oname.split(':', 2)
- scene_geoms = world.load_scene(scene)
+ scene_geoms = self.load_scene(scene)
wkt = scene_geoms[obj]
geoms.append("'%s'::geometry" % wkt)
class PlaceColumn:
def __init__(self, context, force_name):
- self.columns = {}
+ self.columns = { 'admin_level' : 100}
self.force_name = force_name
self.context = context
self.geometry = None
def set_key_housenr(self, value):
self.columns['housenumber'] = value
- def set_key_cc(self, value):
- ok_(len(value) == 2)
+ def set_key_country(self, value):
self.columns['country_code'] = value
def set_key_geometry(self, value):
- geom, precision = self.context.osm.parse_geometry(value, self.context.scene)
- assert_is_not_none(geom)
- self.geometry = "ST_SetSRID('%s'::geometry, 4326)" % geom
+ self.geometry = self.context.osm.parse_geometry(value, self.context.scene)
+ assert_is_not_none(self.geometry)
def add_hstore(self, column, key, value):
if column in self.columns:
return where, params
+@given(u'the scene (?P<scene>.+)')
+def set_default_scene(context, scene):
+ context.scene = scene
@given("the (?P<named>named )?places")
def add_data_to_place_table(context, named):
assert_almost_equal(float(x) * fac, res['cx'])
assert_almost_equal(float(y) * fac, res['cy'])
else:
- eq_(row[h], str(res[h]))
+ eq_(row[h], str(res[h]),
+ "Row '%s': expected: %s, got: %s" % (h, row[h], str(res[h])))
+ context.db.commit()
+
+@then("placex has no entry for (?P<oid>.*)")
+def check_placex_has_entry(context, oid):
+ cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor)
+ nid = NominatimID(oid)
+ where, params = nid.table_select()
+ cur.execute("""SELECT *, ST_AsText(geometry) as geomtxt,
+ ST_X(centroid) as cx, ST_Y(centroid) as cy
+ FROM placex where %s""" % where,
+ params)
+ eq_(0, cur.rowcount)
context.db.commit()