refactored filtering of inserted_ways
parent
3affe43808
commit
eb216b4392
|
@ -40,9 +40,9 @@ type Inserter interface {
|
|||
InsertPoint(element.OSMElem, interface{})
|
||||
InsertLineString(element.OSMElem, interface{})
|
||||
InsertPolygon(element.OSMElem, interface{})
|
||||
// MatchEquals returns true if two interface{}s from ProbeXxx
|
||||
// share the same destination.
|
||||
MatchEquals(interface{}, interface{}) bool
|
||||
// FilterRelationPolygons returns a slice of all members that are already
|
||||
// imported with a relation with tags.
|
||||
FilterRelationPolygons(element.Tags, []element.Member) []element.Member
|
||||
}
|
||||
|
||||
type Deployer interface {
|
||||
|
@ -102,18 +102,18 @@ func Open(conf Config, m *mapping.Mapping) (DB, error) {
|
|||
// nullDb is a dummy database that imports into /dev/null
|
||||
type nullDb struct{}
|
||||
|
||||
func (n *nullDb) Init() error { return nil }
|
||||
func (n *nullDb) Begin() error { return nil }
|
||||
func (n *nullDb) End() error { return nil }
|
||||
func (n *nullDb) Close() error { return nil }
|
||||
func (n *nullDb) Abort() error { return nil }
|
||||
func (n *nullDb) InsertPoint(element.OSMElem, interface{}) {}
|
||||
func (n *nullDb) InsertLineString(element.OSMElem, interface{}) {}
|
||||
func (n *nullDb) InsertPolygon(element.OSMElem, interface{}) {}
|
||||
func (n *nullDb) ProbePoint(element.OSMElem) (bool, interface{}) { return true, nil }
|
||||
func (n *nullDb) ProbeLineString(element.OSMElem) (bool, interface{}) { return true, nil }
|
||||
func (n *nullDb) ProbePolygon(element.OSMElem) (bool, interface{}) { return true, nil }
|
||||
func (n *nullDb) MatchEquals(interface{}, interface{}) bool { return false }
|
||||
func (n *nullDb) Init() error { return nil }
|
||||
func (n *nullDb) Begin() error { return nil }
|
||||
func (n *nullDb) End() error { return nil }
|
||||
func (n *nullDb) Close() error { return nil }
|
||||
func (n *nullDb) Abort() error { return nil }
|
||||
func (n *nullDb) InsertPoint(element.OSMElem, interface{}) {}
|
||||
func (n *nullDb) InsertLineString(element.OSMElem, interface{}) {}
|
||||
func (n *nullDb) InsertPolygon(element.OSMElem, interface{}) {}
|
||||
func (n *nullDb) ProbePoint(element.OSMElem) (bool, interface{}) { return true, nil }
|
||||
func (n *nullDb) ProbeLineString(element.OSMElem) (bool, interface{}) { return true, nil }
|
||||
func (n *nullDb) ProbePolygon(element.OSMElem) (bool, interface{}) { return true, nil }
|
||||
func (n *nullDb) FilterRelationPolygons(element.Tags, []element.Member) []element.Member { return nil }
|
||||
|
||||
func newNullDb(conf Config, m *mapping.Mapping) (DB, error) {
|
||||
return &nullDb{}, nil
|
||||
|
|
|
@ -476,12 +476,22 @@ func (pg *PostGIS) ProbePolygon(elem element.OSMElem) (bool, interface{}) {
|
|||
return false, nil
|
||||
}
|
||||
|
||||
func (pq *PostGIS) MatchEquals(a interface{}, b interface{}) bool {
|
||||
matchesA, okA := a.([]mapping.Match)
|
||||
matchesB, okB := b.([]mapping.Match)
|
||||
if !okA && !okB {
|
||||
return false
|
||||
func (pg *PostGIS) FilterRelationPolygons(tags element.Tags, members []element.Member) []element.Member {
|
||||
relMatches := pg.polygonTagMatcher.Match(&tags)
|
||||
result := []element.Member{}
|
||||
for _, m := range members {
|
||||
if m.Type != element.WAY {
|
||||
continue
|
||||
}
|
||||
memberMatches := pg.polygonTagMatcher.Match(&m.Way.Tags)
|
||||
if matchEquals(relMatches, memberMatches) {
|
||||
result = append(result, m)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func matchEquals(matchesA, matchesB []mapping.Match) bool {
|
||||
for _, matchA := range matchesA {
|
||||
for _, matchB := range matchesB {
|
||||
if matchA.Key == matchB.Key &&
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package postgis
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"imposm3/database"
|
||||
"imposm3/element"
|
||||
"imposm3/mapping"
|
||||
)
|
||||
|
||||
func makeMember(id int64, tags element.Tags) element.Member {
|
||||
way := &element.Way{element.OSMElem{id, tags, nil}, nil, nil}
|
||||
return element.Member{Id: id, Type: element.WAY, Role: "outer", Way: way}
|
||||
|
||||
}
|
||||
|
||||
func testDb(t *testing.T) *PostGIS {
|
||||
mapping, err := mapping.NewMapping("test_mapping.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
conf := database.Config{
|
||||
ConnectionParams: "postgis://localhost",
|
||||
Srid: 3857,
|
||||
ImportSchema: "",
|
||||
ProductionSchema: "",
|
||||
BackupSchema: "",
|
||||
}
|
||||
|
||||
db, err := New(conf, mapping)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return db.(*PostGIS)
|
||||
}
|
||||
|
||||
func TestFilterRelationPolygonsSimple(t *testing.T) {
|
||||
db := testDb(t)
|
||||
filtered := db.FilterRelationPolygons(element.Tags{"landuse": "park"},
|
||||
[]element.Member{
|
||||
makeMember(0, element.Tags{"landuse": "forest"}),
|
||||
makeMember(1, element.Tags{"landuse": "park"}),
|
||||
makeMember(2, element.Tags{"waterway": "riverbank"}),
|
||||
makeMember(4, element.Tags{"foo": "bar"}),
|
||||
})
|
||||
if len(filtered) != 1 {
|
||||
t.Fatal(filtered)
|
||||
}
|
||||
if filtered[0].Id != 1 {
|
||||
t.Fatal(filtered[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterRelationPolygonsUnrelatedTags(t *testing.T) {
|
||||
db := testDb(t)
|
||||
filtered := db.FilterRelationPolygons(element.Tags{"landuse": "park"},
|
||||
[]element.Member{
|
||||
makeMember(0, element.Tags{"landuse": "park", "layer": "2", "name": "foo"}),
|
||||
makeMember(1, element.Tags{"landuse": "forest"}),
|
||||
})
|
||||
if len(filtered) != 1 {
|
||||
t.Fatal(filtered)
|
||||
}
|
||||
if filtered[0].Id != 0 {
|
||||
t.Fatal(filtered)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterRelationPolygonsMultiple(t *testing.T) {
|
||||
db := testDb(t)
|
||||
filtered := db.FilterRelationPolygons(element.Tags{"landuse": "park"},
|
||||
[]element.Member{
|
||||
makeMember(0, element.Tags{"landuse": "park"}),
|
||||
makeMember(1, element.Tags{"natural": "forest"}),
|
||||
makeMember(2, element.Tags{"landuse": "park"}),
|
||||
makeMember(3, element.Tags{"highway": "pedestrian"}),
|
||||
makeMember(4, element.Tags{"landuse": "park", "layer": "2", "name": "foo"}),
|
||||
})
|
||||
if len(filtered) != 3 {
|
||||
t.Fatal(filtered)
|
||||
}
|
||||
if filtered[0].Id != 0 || filtered[1].Id != 2 || filtered[2].Id != 4 {
|
||||
t.Fatal(filtered)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterRelationPolygonsMultipleTags(t *testing.T) {
|
||||
db := testDb(t)
|
||||
filtered := db.FilterRelationPolygons(element.Tags{"landuse": "forest", "natural": "scrub"},
|
||||
[]element.Member{
|
||||
makeMember(0, element.Tags{"natural": "scrub"}),
|
||||
makeMember(1, element.Tags{"landuse": "forest"}),
|
||||
})
|
||||
// TODO both should be filterd out, but we only get the first one,
|
||||
// because we match only one tag per table
|
||||
if len(filtered) != 1 {
|
||||
t.Fatal(filtered)
|
||||
}
|
||||
if filtered[0].Id != 0 {
|
||||
t.Fatal(filtered)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
{
|
||||
"tables": {
|
||||
"landusages": {
|
||||
"fields": [
|
||||
{
|
||||
"type": "id",
|
||||
"name": "osm_id",
|
||||
"key": null
|
||||
},
|
||||
{
|
||||
"type": "geometry",
|
||||
"name": "geometry",
|
||||
"key": null
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "name",
|
||||
"key": "name"
|
||||
},
|
||||
{
|
||||
"type": "mapping_value",
|
||||
"name": "type",
|
||||
"key": null
|
||||
}
|
||||
],
|
||||
"type": "polygon",
|
||||
"mapping": {
|
||||
"amenity": [
|
||||
"university",
|
||||
"school",
|
||||
"college",
|
||||
"library",
|
||||
"fuel",
|
||||
"parking",
|
||||
"cinema",
|
||||
"theatre",
|
||||
"place_of_worship",
|
||||
"hospital"
|
||||
],
|
||||
"barrier": [
|
||||
"hedge"
|
||||
],
|
||||
"leisure": [
|
||||
"park",
|
||||
"garden",
|
||||
"playground",
|
||||
"golf_course",
|
||||
"sports_centre",
|
||||
"pitch",
|
||||
"stadium",
|
||||
"common",
|
||||
"nature_reserve"
|
||||
],
|
||||
"tourism": [
|
||||
"zoo"
|
||||
],
|
||||
"natural": [
|
||||
"wood",
|
||||
"land",
|
||||
"scrub",
|
||||
"wetland",
|
||||
"heath"
|
||||
],
|
||||
"man_made": [
|
||||
"pier"
|
||||
],
|
||||
"aeroway": [
|
||||
"runway",
|
||||
"taxiway"
|
||||
],
|
||||
"place": [
|
||||
"island"
|
||||
],
|
||||
"military": [
|
||||
"barracks"
|
||||
],
|
||||
"landuse": [
|
||||
"park",
|
||||
"forest",
|
||||
"residential",
|
||||
"retail",
|
||||
"commercial",
|
||||
"industrial",
|
||||
"railway",
|
||||
"cemetery",
|
||||
"grass",
|
||||
"farmyard",
|
||||
"farm",
|
||||
"farmland",
|
||||
"orchard",
|
||||
"vineyard",
|
||||
"wood",
|
||||
"meadow",
|
||||
"village_green",
|
||||
"recreation_ground",
|
||||
"allotments",
|
||||
"quarry"
|
||||
],
|
||||
"highway": [
|
||||
"pedestrian",
|
||||
"footway"
|
||||
]
|
||||
}
|
||||
},
|
||||
"waterareas": {
|
||||
"fields": [
|
||||
{
|
||||
"type": "id",
|
||||
"name": "osm_id",
|
||||
"key": null
|
||||
},
|
||||
{
|
||||
"type": "geometry",
|
||||
"name": "geometry",
|
||||
"key": null
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "name",
|
||||
"key": "name"
|
||||
},
|
||||
{
|
||||
"type": "mapping_value",
|
||||
"name": "type",
|
||||
"key": null
|
||||
},
|
||||
{
|
||||
"type": "pseudoarea",
|
||||
"name": "area",
|
||||
"key": null
|
||||
}
|
||||
],
|
||||
"type": "polygon",
|
||||
"mapping": {
|
||||
"waterway": [
|
||||
"riverbank"
|
||||
],
|
||||
"landuse": [
|
||||
"basin",
|
||||
"reservoir"
|
||||
],
|
||||
"natural": [
|
||||
"water"
|
||||
],
|
||||
"amenity": [
|
||||
"swimming_pool"
|
||||
],
|
||||
"leisure": [
|
||||
"swimming_pool"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,13 +52,6 @@ func TestSimplePolygonWithHole(t *testing.T) {
|
|||
g := geos.NewGeos()
|
||||
defer g.Finish()
|
||||
|
||||
if len(rel.Members) != 2 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
if rel.Members[0].Id != 1 || rel.Members[1].Id != 2 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
|
||||
if len(rel.Tags) != 0 {
|
||||
t.Fatal("wrong rel tags", rel.Tags)
|
||||
}
|
||||
|
@ -99,13 +92,6 @@ func TestMultiPolygonWithHoleAndRelName(t *testing.T) {
|
|||
g := geos.NewGeos()
|
||||
defer g.Finish()
|
||||
|
||||
if len(rel.Members) != 1 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
if rel.Members[0].Id != 1 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
|
||||
if len(rel.Tags) != 2 {
|
||||
t.Fatal("wrong rel tags", rel.Tags)
|
||||
}
|
||||
|
@ -157,13 +143,6 @@ func TestMultiPolygonWithMultipleHoles(t *testing.T) {
|
|||
g := geos.NewGeos()
|
||||
defer g.Finish()
|
||||
|
||||
if len(rel.Members) != 1 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
if rel.Members[0].Id != 1 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
|
||||
if len(rel.Tags) != 1 {
|
||||
t.Fatal("wrong rel tags", rel.Tags)
|
||||
}
|
||||
|
@ -230,13 +209,6 @@ func TestMultiPolygonWithNeastedHoles(t *testing.T) {
|
|||
g := geos.NewGeos()
|
||||
defer g.Finish()
|
||||
|
||||
if len(rel.Members) != 3 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
if rel.Members[0].Id != 1 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
|
||||
if len(rel.Tags) != 1 {
|
||||
t.Fatal("wrong rel tags", rel.Tags)
|
||||
}
|
||||
|
@ -279,13 +251,6 @@ func TestPolygonFromThreeWays(t *testing.T) {
|
|||
g := geos.NewGeos()
|
||||
defer g.Finish()
|
||||
|
||||
if len(rel.Members) != 2 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
if rel.Members[0].Id != 1 || rel.Members[1].Id != 3 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
|
||||
if len(rel.Tags) != 1 {
|
||||
t.Fatal("wrong rel tags", rel.Tags)
|
||||
}
|
||||
|
@ -335,14 +300,6 @@ func TestTouchingPolygonsWithHole(t *testing.T) {
|
|||
g := geos.NewGeos()
|
||||
defer g.Finish()
|
||||
|
||||
if len(rel.Members) != 2 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
|
||||
if rel.Members[0].Id != 1 || rel.Members[1].Id != 2 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
|
||||
if len(rel.Tags) != 1 {
|
||||
t.Fatal("wrong rel tags", rel.Tags)
|
||||
}
|
||||
|
@ -382,14 +339,6 @@ func TestInsertedWaysDifferentTags(t *testing.T) {
|
|||
g := geos.NewGeos()
|
||||
defer g.Finish()
|
||||
|
||||
if len(rel.Members) != 1 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
|
||||
if rel.Members[0].Id != 1 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
|
||||
if len(rel.Tags) != 1 {
|
||||
t.Fatal("wrong rel tags", rel.Tags)
|
||||
}
|
||||
|
@ -429,14 +378,6 @@ func TestInsertMultipleTags(t *testing.T) {
|
|||
g := geos.NewGeos()
|
||||
defer g.Finish()
|
||||
|
||||
if len(rel.Members) != 0 {
|
||||
t.Fatal("wrong rel members", rel.Members)
|
||||
}
|
||||
|
||||
if len(rel.Tags) != 1 {
|
||||
t.Fatal("wrong rel tags", rel.Tags)
|
||||
}
|
||||
|
||||
if rel.Tags["landusage"] != "forest" {
|
||||
t.Fatal("wrong rel tags", rel.Tags)
|
||||
}
|
||||
|
@ -486,10 +427,6 @@ func TestBrokenPolygonSelfIntersect(t *testing.T) {
|
|||
g := geos.NewGeos()
|
||||
defer g.Finish()
|
||||
|
||||
if len(rel1.Members) != 2 {
|
||||
t.Fatal("wrong rel members", rel1.Members)
|
||||
}
|
||||
|
||||
if len(rel1.Tags) != 0 {
|
||||
t.Fatal("wrong rel tags", rel1.Tags)
|
||||
}
|
||||
|
@ -532,10 +469,6 @@ func TestBrokenPolygonSelfIntersect(t *testing.T) {
|
|||
g = geos.NewGeos()
|
||||
defer g.Finish()
|
||||
|
||||
if len(rel2.Members) != 2 {
|
||||
t.Fatal("wrong rel members", rel2.Members)
|
||||
}
|
||||
|
||||
if len(rel2.Tags) != 0 {
|
||||
t.Fatal("wrong rel tags", rel2.Tags)
|
||||
}
|
||||
|
|
|
@ -126,16 +126,10 @@ NextRel:
|
|||
rw.inserter.InsertPolygon(rel.OSMElem, matches)
|
||||
}
|
||||
|
||||
for _, m := range r.Members {
|
||||
if m.Type != element.WAY {
|
||||
continue
|
||||
}
|
||||
ok, memberMatches := rw.inserter.ProbePolygon(m.Way.OSMElem)
|
||||
if ok && rw.inserter.MatchEquals(matches, memberMatches) {
|
||||
err = rw.osmCache.InsertedWays.PutWay(m.Way)
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
}
|
||||
for _, m := range rw.inserter.FilterRelationPolygons(r.Tags, r.Members) {
|
||||
err = rw.osmCache.InsertedWays.PutWay(m.Way)
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
}
|
||||
}
|
||||
if rw.diffCache != nil {
|
||||
|
|
Loading…
Reference in New Issue