From: Sarah Hoffmann Date: Sun, 20 Nov 2016 19:03:51 +0000 (+0100) Subject: add placex import tests X-Git-Tag: v3.0.0~85^2~25 X-Git-Url: https://git.openstreetmap.org./nominatim.git/commitdiff_plain/c594644aa73db2c66577a5685390a9d7deb215b5?ds=sidebyside add placex import tests --- diff --git a/test/bdd/db/import/placex.feature b/test/bdd/db/import/placex.feature new file mode 100644 index 00000000..7cbedaa3 --- /dev/null +++ b/test/bdd/db/import/placex.feature @@ -0,0 +1,313 @@ +@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 | + diff --git a/test/bdd/db/import/search_simple.feature b/test/bdd/db/import/search_simple.feature deleted file mode 100644 index fb4071dd..00000000 --- a/test/bdd/db/import/search_simple.feature +++ /dev/null @@ -1,16 +0,0 @@ -@DB -Feature: Import of simple objects - Testing simple stuff - - @wip - Scenario: Import place node - Given the places - | osm | class | type | name | name+ref | geometry | - | N1 | place | village | Foo | 32 | 10.0 -10.0 | - And the named places - | osm | class | type | housenr | - | N2 | place | village | | - When importing - Then placex contains - | object | class | type | name | name+ref | centroid*10 | - | N1 | place | village | Foo | 32 | 1 -1 | diff --git a/test/bdd/environment.py b/test/bdd/environment.py index c878c61c..a954b253 100644 --- a/test/bdd/environment.py +++ b/test/bdd/environment.py @@ -4,6 +4,7 @@ import os 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__) @@ -143,28 +144,28 @@ class OSMDataFactory(object): 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) diff --git a/test/bdd/steps/db_ops.py b/test/bdd/steps/db_ops.py index 1bb2acaa..201bf373 100644 --- a/test/bdd/steps/db_ops.py +++ b/test/bdd/steps/db_ops.py @@ -8,7 +8,7 @@ import psycopg2.extras 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 @@ -41,14 +41,12 @@ class PlaceColumn: 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: @@ -104,6 +102,9 @@ class NominatimID: return where, params +@given(u'the scene (?P.+)') +def set_default_scene(context, scene): + context.scene = scene @given("the (?Pnamed )?places") def add_data_to_place_table(context, named): @@ -169,5 +170,18 @@ def check_placex_contents(context, exact): 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.*)") +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()