validate polygons from ways

master
Oliver Tonnhofer 2015-11-21 18:10:20 +01:00
parent b3110b3bb5
commit 7f1a5cb999
4 changed files with 26 additions and 11 deletions

View File

@ -13,9 +13,11 @@ extern void initGEOS_debug();
import "C" import "C"
import ( import (
"github.com/omniscale/imposm3/logging" "errors"
"runtime" "runtime"
"unsafe" "unsafe"
"github.com/omniscale/imposm3/logging"
) )
var log = logging.NewLogger("GEOS") var log = logging.NewLogger("GEOS")
@ -268,6 +270,19 @@ func (this *Geos) Equals(a, b *Geom) bool {
return false return false
} }
func (g *Geos) MakeValid(geom *Geom) (*Geom, error) {
if g.IsValid(geom) {
return geom, nil
}
fixed := g.Buffer(geom, 0)
if fixed == nil {
return nil, errors.New("Error while fixing geom with buffer(0)")
}
g.Destroy(geom)
return fixed, nil
}
func (this *Geom) Area() float64 { func (this *Geom) Area() float64 {
var area C.double var area C.double
if ret := C.GEOSArea(this.v, &area); ret == 1 { if ret := C.GEOSArea(this.v, &area); ret == 1 {

View File

@ -196,13 +196,10 @@ func buildRelGeometry(g *geos.Geos, rel *element.Relation, rings []*ring) (*geos
return nil, errors.New("Error while building multi-polygon.") return nil, errors.New("Error while building multi-polygon.")
} }
} }
if !g.IsValid(result) { var err error
buffered := g.Buffer(result, 0) result, err = g.MakeValid(result)
if buffered == nil { if err != nil {
return nil, errors.New("Error while fixing geom with buffer(0)") return nil, err
}
g.Destroy(result)
result = buffered
} }
g.DestroyLater(result) g.DestroyLater(result)

View File

@ -252,10 +252,10 @@ def test_duplicate_ids():
def test_generalized_banana_polygon_is_valid(): def test_generalized_banana_polygon_is_valid():
"""Generalized polygons are valid.""" """Generalized polygons are valid."""
park = t.query_row(t.db_conf, 'osm_landusages', 7101) park = t.query_row(t.db_conf, 'osm_landusages', 7101)
# geometry is not valid # geometry is valid
assert not park['geometry'].is_valid, park assert park['geometry'].is_valid, park
park = t.query_row(t.db_conf, 'osm_landusages_gen0', 7101) park = t.query_row(t.db_conf, 'osm_landusages_gen0', 7101)
# but simplified geometies are valid # simplified geometies are valid too
assert park['geometry'].is_valid, park assert park['geometry'].is_valid, park
park = t.query_row(t.db_conf, 'osm_landusages_gen1', 7101) park = t.query_row(t.db_conf, 'osm_landusages_gen1', 7101)
assert park['geometry'].is_valid, park assert park['geometry'].is_valid, park

View File

@ -129,6 +129,9 @@ func (ww *WayWriter) buildAndInsert(g *geos.Geos, w *element.Way, matches []mapp
if isPolygon { if isPolygon {
geosgeom, err = geomp.Polygon(g, way.Nodes) geosgeom, err = geomp.Polygon(g, way.Nodes)
if err == nil {
geosgeom, err = g.MakeValid(geosgeom)
}
} else { } else {
geosgeom, err = geomp.LineString(g, way.Nodes) geosgeom, err = geomp.LineString(g, way.Nodes)
} }