diff --git a/cache/ways.go b/cache/ways.go
index de157c1..08a4c6c 100644
--- a/cache/ways.go
+++ b/cache/ways.go
@@ -141,6 +141,11 @@ func newInsertedWaysCache(path string) (*InsertedWaysCache, error) {
return &cache, err
}
+func (p *InsertedWaysCache) PutWay(way *element.Way) error {
+ keyBuf := idToKeyBuf(way.Id)
+ return p.db.Put(p.wo, keyBuf, []byte{})
+}
+
func (p *InsertedWaysCache) PutMembers(members []element.Member) error {
batch := levigo.NewWriteBatch()
defer batch.Close()
diff --git a/database/database.go b/database/database.go
index e3ed0ba..c37cd44 100644
--- a/database/database.go
+++ b/database/database.go
@@ -40,6 +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
}
type Deployer interface {
@@ -110,6 +113,7 @@ 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 newNullDb(conf Config, m *mapping.Mapping) (DB, error) {
return &nullDb{}, nil
diff --git a/database/postgis/postgis.go b/database/postgis/postgis.go
index a6101ca..8ad912c 100644
--- a/database/postgis/postgis.go
+++ b/database/postgis/postgis.go
@@ -476,6 +476,24 @@ 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
+ }
+ for _, matchA := range matchesA {
+ for _, matchB := range matchesB {
+ if matchA.Key == matchB.Key &&
+ matchA.Value == matchB.Value &&
+ matchA.Table == matchB.Table {
+ return true
+ }
+ }
+ }
+ return false
+}
+
func (pg *PostGIS) Delete(id int64, matches interface{}) error {
if matches, ok := matches.([]mapping.Match); ok {
for _, match := range matches {
diff --git a/geom/multipolygon.go b/geom/multipolygon.go
index 7b686c4..8ad5521 100644
--- a/geom/multipolygon.go
+++ b/geom/multipolygon.go
@@ -219,14 +219,6 @@ func BuildRelGeometry(rel *element.Relation, rings []*Ring, srid int) (*geos.Geo
}
}
- var relMembers []element.Member
- for _, m := range rel.Members {
- if _, ok := insertedWays[m.Id]; ok {
- relMembers = append(relMembers, m)
- }
- }
-
- rel.Members = relMembers
wkb := g.AsEwkbHex(result)
if wkb == nil {
return nil, errors.New("unable to create WKB for relation")
diff --git a/test/imposm_system_test.py b/test/imposm_system_test.py
index fa777b2..2c74476 100644
--- a/test/imposm_system_test.py
+++ b/test/imposm_system_test.py
@@ -314,6 +314,14 @@ def test_relation_way_not_inserted():
assert park['name'] == 'rel 9001'
assert query_row(db_conf, 'osm_landusages', 9009) == None
+ park = query_row(db_conf, 'osm_landusages', -9101)
+ assert park['type'] == 'park'
+ assert park['name'] == 'rel 9101'
+ assert query_row(db_conf, 'osm_landusages', 9109) == None
+
+ scrub = query_row(db_conf, 'osm_landusages', 9110)
+ assert scrub['type'] == 'scrub'
+
def test_relation_way_inserted():
"""Part of relation was inserted twice."""
park = query_row(db_conf, 'osm_landusages', -8001)
diff --git a/test/test.osm b/test/test.osm
index eb81829..5ae1a03 100644
--- a/test/test.osm
+++ b/test/test.osm
@@ -363,6 +363,7 @@
+
@@ -371,6 +372,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/writer/relations.go b/writer/relations.go
index 4e765c1..5e4eb5a 100644
--- a/writer/relations.go
+++ b/writer/relations.go
@@ -125,9 +125,18 @@ NextRel:
rel.Id = -r.Id
rw.inserter.InsertPolygon(rel.OSMElem, matches)
}
- err = rw.osmCache.InsertedWays.PutMembers(r.Members)
- if err != nil {
- log.Warn(err)
+
+ 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)
+ }
+ }
}
if rw.diffCache != nil {
rw.diffCache.Ways.AddFromMembers(r.Id, allMembers)