diff --git a/geom/ring.go b/geom/ring.go index 4c5c106..2ff9446 100644 --- a/geom/ring.go +++ b/geom/ring.go @@ -82,6 +82,9 @@ func mergeRings(rings []*Ring) []*Ring { endpoints := make(map[int64]*Ring) for _, ring := range rings { + if len(ring.refs) < 2 { + continue + } left := ring.refs[0] right := ring.refs[len(ring.refs)-1] if origRing, ok := endpoints[left]; ok { diff --git a/geom/ring_test.go b/geom/ring_test.go index 43f868e..989457f 100644 --- a/geom/ring_test.go +++ b/geom/ring_test.go @@ -41,6 +41,34 @@ func TestRingMerge(t *testing.T) { } } +func TestRingMergeMissingRefs(t *testing.T) { + // way without refs should not panic with index out of range + w1 := element.Way{} + w1.Id = 1 + w1.Refs = []int64{1, 2, 3} + w1.Nodes = []element.Node{ + element.Node{}, + element.Node{}, + element.Node{}, + } + r1 := NewRing(&w1) + + w2 := element.Way{} + w2.Id = 2 + w2.Refs = []int64{} + w2.Nodes = []element.Node{} + r2 := NewRing(&w2) + rings := []*Ring{r1, r2} + + result := mergeRings(rings) + if len(result) != 1 { + t.Fatal(result) + } + if result[0] != r1 { + t.Fatal(result[0]) + } +} + func TestRingMergeReverseEndpoints(t *testing.T) { w1 := element.Way{} w1.Id = 1 diff --git a/test/imposm_system_test.py b/test/imposm_system_test.py index 80a09ce..67b8137 100644 --- a/test/imposm_system_test.py +++ b/test/imposm_system_test.py @@ -292,6 +292,18 @@ def test_merge_outer_multipolygon_way_1(): assert_almost_equal(park_16001['geometry'].area, 12779350582, -1) assert query_row(db_conf, 'osm_roads', 16002)['type'] == 'residential' +def test_broken_multipolygon_ways(): + """MultiPolygons with broken outer ways are handled.""" + # outer way does not merge (17002 has one node) + assert query_row(db_conf, 'osm_landusages', -17001) == None + assert query_row(db_conf, 'osm_roads', 17001)['type'] == 'residential' + assert query_row(db_conf, 'osm_roads', 17002) == None + + # outer way does not merge (17102 has no nodes) + assert query_row(db_conf, 'osm_landusages', -17101) == None + assert query_row(db_conf, 'osm_roads', 17101)['type'] == 'residential' + assert query_row(db_conf, 'osm_roads', 17102) == None + def test_node_way_ref_after_delete_1(): """Nodes refereces way""" data = cache_query(nodes=[20001, 20002], deps=True) diff --git a/test/test.osm b/test/test.osm index 63f4e2f..e3d8bb9 100644 --- a/test/test.osm +++ b/test/test.osm @@ -641,6 +641,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +