import multipolygons if at least on ring was build
parent
12f92b99cc
commit
b3b388b11b
|
@ -93,23 +93,23 @@ func buildRings(rel *element.Relation, maxRingGap float64) ([]*ring, error) {
|
|||
}
|
||||
// merge incomplete rings
|
||||
mergedRings = mergeRings(incompleteRings)
|
||||
if len(completeRings)+len(mergedRings) == 0 {
|
||||
err = ErrorNoRing // for defer
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// create geometries for merged rings
|
||||
for _, ring := range mergedRings {
|
||||
if !ring.isClosed() && !ring.tryClose(maxRingGap) {
|
||||
err = ErrorNoRing // for defer
|
||||
return nil, err
|
||||
continue
|
||||
}
|
||||
ring.geom, err = Polygon(g, ring.nodes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
completeRings = append(completeRings, ring)
|
||||
}
|
||||
|
||||
completeRings = append(completeRings, mergedRings...)
|
||||
if len(completeRings) == 0 {
|
||||
err = ErrorNoRing // for defer
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// sort by area (large to small)
|
||||
for _, r := range completeRings {
|
||||
|
|
|
@ -31,7 +31,6 @@ func buildRelation(rel *element.Relation, srid int) (Geometry, error) {
|
|||
if err != nil {
|
||||
return Geometry{}, err
|
||||
}
|
||||
|
||||
return prep.Build()
|
||||
}
|
||||
|
||||
|
@ -599,3 +598,63 @@ func TestBrokenPolygonSelfIntersectTriangle(t *testing.T) {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenRing(t *testing.T) {
|
||||
w1 := makeWay(1, element.Tags{}, []coord{
|
||||
{1, 0, 0},
|
||||
{2, 10, 0},
|
||||
{3, 10, 10},
|
||||
{4, 0, 10},
|
||||
})
|
||||
|
||||
rel := element.Relation{
|
||||
OSMElem: element.OSMElem{Id: 1, Tags: element.Tags{}}}
|
||||
rel.Members = []element.Member{
|
||||
{1, element.WAY, "outer", &w1},
|
||||
}
|
||||
|
||||
_, err := buildRelation(&rel, 3857)
|
||||
if err == nil {
|
||||
t.Fatal("no error from open ring")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClosedAndOpenRing(t *testing.T) {
|
||||
w1 := makeWay(1, element.Tags{}, []coord{
|
||||
{1, 0, 0},
|
||||
{2, 10, 0},
|
||||
{3, 10, 10},
|
||||
{4, 0, 10},
|
||||
{1, 0, 0},
|
||||
})
|
||||
w2 := makeWay(2, element.Tags{}, []coord{
|
||||
{5, 0, 0},
|
||||
{6, -5, -2},
|
||||
})
|
||||
rel := element.Relation{
|
||||
OSMElem: element.OSMElem{Id: 1, Tags: element.Tags{}}}
|
||||
rel.Members = []element.Member{
|
||||
{1, element.WAY, "outer", &w1},
|
||||
{2, element.WAY, "outer", &w2},
|
||||
}
|
||||
|
||||
prep, err := PrepareRelation(&rel, 3857, 0.1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// open ring is excluded
|
||||
if len(prep.rings) != 1 {
|
||||
t.Fatal("expected single ring")
|
||||
}
|
||||
geom, err := prep.Build()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
g := geos.NewGeos()
|
||||
defer g.Finish()
|
||||
|
||||
if !g.IsValid(geom.Geom) {
|
||||
t.Fatal("geometry not valid", g.AsWkt(geom.Geom))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -386,6 +386,31 @@
|
|||
<tag k="landuse" v="park"/>
|
||||
</way>
|
||||
|
||||
<!-- relation/way with "gap" (ways overlap, but are only sharing one endpoint) -->
|
||||
<node id="7401" version="1" timestamp="2011-11-11T00:11:11Z" lat="60" lon="60"/>
|
||||
<node id="7402" version="1" timestamp="2011-11-11T00:11:11Z" lat="60" lon="62"/>
|
||||
<node id="7403" version="1" timestamp="2011-11-11T00:11:11Z" lat="62" lon="62"/>
|
||||
<node id="7404" version="1" timestamp="2011-11-11T00:11:11Z" lat="62" lon="60"/>
|
||||
<way id="7401" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="7401"/>
|
||||
<nd ref="7402"/>
|
||||
<nd ref="7403"/>
|
||||
<nd ref="7404"/>
|
||||
<nd ref="7401"/>
|
||||
</way>
|
||||
<way id="7402" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<!-- connected to other way, but not at start/end node and neither a ring on its own -->
|
||||
<nd ref="7402"/>
|
||||
<nd ref="7404"/>
|
||||
</way>
|
||||
<relation id="7401" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<member type="way" ref="7401" role="outer"/>
|
||||
<member type="way" ref="7402" role="outer"/>
|
||||
<tag k="name" v="rel 7401"/>
|
||||
<tag k="landuse" v="park"/>
|
||||
<tag k="type" v="multipolygon"/>
|
||||
</relation>
|
||||
|
||||
<!-- test that single node ways or incomplete polygons are _not_ inserted -->
|
||||
<node id="30001" version="1" timestamp="2011-11-11T00:11:11Z" lat="47" lon="80"/>
|
||||
<node id="30002" version="1" timestamp="2011-11-11T00:11:11Z" lat="47" lon="80"/>
|
||||
|
|
|
@ -284,6 +284,11 @@ def test_ring_with_gap():
|
|||
park = t.query_row(t.db_conf, 'osm_landusages', 7311)
|
||||
assert park['geometry'].is_valid, park
|
||||
|
||||
def test_multipolygon_with_open_ring():
|
||||
"""Multipolygon is inserted even if there is an open ring/member"""
|
||||
park = t.query_row(t.db_conf, 'osm_landusages', -7401)
|
||||
assert park['geometry'].is_valid, park
|
||||
|
||||
def test_updated_nodes1():
|
||||
"""Zig-Zag line is inserted."""
|
||||
road = t.query_row(t.db_conf, 'osm_roads', 60000)
|
||||
|
|
Loading…
Reference in New Issue