]> git.openstreetmap.org Git - nominatim.git/commitdiff
fix address interpolation for self-intersecting ways
authorSarah Hoffmann <lonvia@denofr.de>
Mon, 3 Nov 2014 21:41:12 +0000 (22:41 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Mon, 3 Nov 2014 21:42:34 +0000 (22:42 +0100)
sql/functions.sql
tests/features/db/import/interpolation.feature
tests/features/osm2pgsql/import/broken.feature [new file with mode: 0644]
tests/steps/db_results.py

index 48ac80b54ac24aad0edeeb31f724b2858a0b7dbe..da9223adda8bfa8963c59e173f31d79ae398a612 100644 (file)
@@ -846,15 +846,13 @@ BEGIN
     IF search_place_id IS NOT NULL THEN
       select * from placex where place_id = search_place_id INTO nextnode;
 
-        IF nodeidpos < array_upper(waynodes, 1) THEN
+        IF nodeidpos > 1 and nodeidpos < array_upper(waynodes, 1) THEN
           -- Make sure that the point is actually on the line. That might
           -- be a bit paranoid but ensures that the algorithm still works
           -- should osm2pgsql attempt to repair geometries.
           splitline := split_line_on_node(linegeo, nextnode.geometry);
           sectiongeo := ST_GeometryN(splitline, 1);
-          IF ST_GeometryType(ST_GeometryN(splitline, 2)) = 'ST_LineString' THEN
-            linegeo := ST_GeometryN(splitline, 2);
-          END IF;
+          linegeo := ST_GeometryN(splitline, 2);
         ELSE
           sectiongeo = linegeo;
         END IF;
@@ -862,7 +860,7 @@ BEGIN
 
         IF startnumber IS NOT NULL AND endnumber IS NOT NULL
            AND @(startnumber - endnumber) < 1000 AND startnumber != endnumber
-           AND ST_GeometryType(linegeo) = 'ST_LineString' THEN
+           AND ST_GeometryType(sectiongeo) = 'ST_LineString' THEN
 
           IF (startnumber > endnumber) THEN
             housenum := endnumber;
@@ -897,6 +895,12 @@ BEGIN
           END LOOP;
         END IF;
 
+        -- early break if we are out of line string,
+        -- might happen when a line string loops back on itself
+        IF ST_GeometryType(linegeo) != 'ST_LineString' THEN
+            RETURN newpoints;
+        END IF;
+
         startnumber := substring(nextnode.housenumber,'[0-9]+')::integer;
         prevnode := nextnode;
     END IF;
index 9a4856f2d329efb6c11d02b8278682ab989beeb7..ad4bdf851875c4b25b7d73d1d4c42502cbde8c41 100644 (file)
@@ -326,4 +326,50 @@ Feature: Import of address interpolations
           | housenumber | centroid
           | 8           | 1.001,1.001
 
+    Scenario: Interpolation on self-intersecting way
+        Given the place nodes
+          | osm_id | class | type  | housenumber | geometry
+          | 1      | place | house | 2           | 0 0
+          | 2      | place | house | 6           | 0 0.001
+          | 3      | place | house | 10          | 0 0.002
+        And the place ways
+          | osm_id | class | type   | housenumber | geometry
+          | 1      | place | houses | even        | 0 0, 0 0.001, 0 0.002, 0 0.001
+        And the ways
+          | id | nodes
+          | 1  | 1,2,3,2
+        When importing
+        Then node 1 expands to housenumbers
+          | housenumber | centroid
+          | 2           | 0,0
+          | 4           | 0,0.0005
+        Then node 2 expands to housenumbers
+          | housenumber | centroid
+          | 6           | 0,0.001
+          | 8           | 0,0.0015
+        Then node 3 expands to housenumbers
+          | housenumber | centroid
+          | 10          | 0,0.002
+          | 8           | 0,0.0015
+
+    Scenario: Interpolation on self-intersecting way II
+        Given the place nodes
+          | osm_id | class | type  | housenumber | geometry
+          | 1      | place | house | 2           | 0 0
+          | 2      | place | house | 6           | 0 0.001
+        And the place ways
+          | osm_id | class | type   | housenumber | geometry
+          | 1      | place | houses | even        | 0 0, 0 0.001, 0 0.002, 0 0.001
+        And the ways
+          | id | nodes
+          | 1  | 1,2,3,2
+        When importing
+        Then node 1 expands to housenumbers
+          | housenumber | centroid
+          | 2           | 0,0
+          | 4           | 0,0.0005
+        Then node 2 expands to housenumbers
+          | housenumber | centroid
+          | 6           | 0,0.001
+
 
diff --git a/tests/features/osm2pgsql/import/broken.feature b/tests/features/osm2pgsql/import/broken.feature
new file mode 100644 (file)
index 0000000..58a45f9
--- /dev/null
@@ -0,0 +1,37 @@
+@DB
+Feature: Import of objects with broken geometries by osm2pgsql
+
+    @Fail
+    Scenario: Import way with double nodes
+        Given the osm nodes:
+          | id  | geometry
+          | 100 | 0 0
+          | 101 | 0 0.1
+          | 102 | 0.1 0.2
+        And the osm ways:
+          | id | tags                  | nodes
+          | 1  | 'highway' : 'primary' | 100 101 101 102
+        When loading osm data
+        Then table place contains
+          | object | class   | type    | geometry
+          | W1     | highway | primary | (0 0, 0 0.1, 0.1 0.2)
+
+    Scenario: Import of ballon areas
+        Given the osm nodes:
+          | id  | geometry
+          | 1   | 0 0
+          | 2   | 0 0.0001
+          | 3   | 0.00001 0.0001
+          | 4   | 0.00001 0
+          | 5   | -0.00001 0
+        And the osm ways:
+          | id | tags                       | nodes
+          | 1  | 'highway' : 'unclassified' | 1 2 3 4 1 5
+          | 2  | 'highway' : 'unclassified' | 1 2 3 4 1
+          | 3  | 'highway' : 'unclassified' | 1 2 3 4 3
+        When loading osm data
+        Then table place contains
+          | object | geometrytype
+          | W1     | ST_LineString
+          | W2     | ST_Polygon
+          | W3     | ST_LineString
index 2b44215e7e0aa328f421421559c2b60b186dbf44..f65e992462366373143519d03e1adeb7bf2a11ec 100644 (file)
@@ -49,6 +49,7 @@ def check_placex_content(step, tablename):
         q = 'SELECT *'
         if tablename == 'placex':
             q = q + ", ST_X(centroid) as clat, ST_Y(centroid) as clon"
+        q = q + ", ST_GeometryType(geometry) as geometrytype"
         q = q + ' FROM %s where osm_type = %%s and osm_id = %%s' % (tablename,)
         if cls is None:
             params = (osmtype, osmid)