improve inserted_ways handling

compare destination tables for each way instead of only comparing
if the tags are similar
master
Oliver Tonnhofer 2013-12-12 17:12:05 +01:00
parent b7144dd0d8
commit 3affe43808
7 changed files with 82 additions and 11 deletions

5
cache/ways.go vendored
View File

@ -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()

View File

@ -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

View File

@ -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 {

View File

@ -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")

View File

@ -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)

View File

@ -363,6 +363,7 @@
<nd ref="9004"/>
<nd ref="9001"/>
<tag k="landuse" v="park"/>
<tag k="ref" v="42"/> <!-- unrelated tag -->
</way>
<relation id="9001" version="1" timestamp="2011-11-11T00:11:11Z">
<member type="way" ref="9009" role="outer"/>
@ -371,6 +372,40 @@
<tag k="type" v="multipolygon"/>
</relation>
<!-- test multipolygon way was _not_ inserted, but hole is -->
<node id="9101" version="1" timestamp="2011-11-11T00:11:11Z" lat="47" lon="80"/>
<node id="9102" version="1" timestamp="2011-11-11T00:11:11Z" lat="47" lon="82"/>
<node id="9103" version="1" timestamp="2011-11-11T00:11:11Z" lat="49" lon="82"/>
<node id="9104" version="1" timestamp="2011-11-11T00:11:11Z" lat="49" lon="80"/>
<node id="9111" version="1" timestamp="2011-11-11T00:11:11Z" lat="47.1" lon="80.1"/>
<node id="9112" version="1" timestamp="2011-11-11T00:11:11Z" lat="47.1" lon="80.9"/>
<node id="9113" version="1" timestamp="2011-11-11T00:11:11Z" lat="48.9" lon="80.9"/>
<node id="9114" version="1" timestamp="2011-11-11T00:11:11Z" lat="48.9" lon="80.1"/>
<way id="9109" version="1" timestamp="2011-11-11T00:11:11Z">
<nd ref="9101"/>
<nd ref="9102"/>
<nd ref="9103"/>
<nd ref="9104"/>
<nd ref="9101"/>
<tag k="landuse" v="park"/>
<tag k="ref" v="42"/> <!-- unrelated tag -->
</way>
<way id="9110" version="1" timestamp="2011-11-11T00:11:11Z">
<nd ref="9111"/>
<nd ref="9112"/>
<nd ref="9113"/>
<nd ref="9114"/>
<nd ref="9111"/>
<tag k="natural" v="scrub"/>
</way>
<relation id="9101" version="1" timestamp="2011-11-11T00:11:11Z">
<member type="way" ref="9109" role="outer"/>
<member type="way" ref="9110" role="outer"/>
<tag k="name" v="rel 9101"/>
<tag k="landuse" v="park"/>
<tag k="type" v="multipolygon"/>
</relation>
<!-- test multipolygon way was inserted -->
<node id="8001" version="1" timestamp="2011-11-11T00:11:11Z" lat="47" lon="80"/>
<node id="8002" version="1" timestamp="2011-11-11T00:11:11Z" lat="47" lon="82"/>

View File

@ -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)