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)