imposm3/diff/deleter.go

181 lines
3.6 KiB
Go

package diff
import (
"imposm3/cache"
"imposm3/database"
"imposm3/diff/parser"
"imposm3/element"
"imposm3/expire"
"imposm3/mapping"
"imposm3/proj"
)
type Deleter struct {
delDb database.Deleter
osmCache *cache.OSMCache
diffCache *cache.DiffCache
tmPoints *mapping.TagMatcher
tmLineStrings *mapping.TagMatcher
tmPolygons *mapping.TagMatcher
expireTiles *expire.Tiles
}
func NewDeleter(db database.Deleter, osmCache *cache.OSMCache, diffCache *cache.DiffCache,
tmPoints *mapping.TagMatcher,
tmLineStrings *mapping.TagMatcher,
tmPolygons *mapping.TagMatcher,
) *Deleter {
return &Deleter{
db,
osmCache,
diffCache,
tmPoints,
tmLineStrings,
tmPolygons,
nil,
}
}
func (d *Deleter) SetExpireTiles(expireTiles *expire.Tiles) {
d.expireTiles = expireTiles
}
func (d *Deleter) deleteRelation(id int64, deleteRefs bool) {
elem, err := d.osmCache.Relations.GetRelation(id)
if err != nil {
if err == cache.NotFound {
return
}
// TODO
log.Print("rel", id, err)
return
}
if elem.Tags == nil {
return
}
deleted := false
for _, m := range d.tmPolygons.Match(&elem.Tags) {
d.delDb.Delete(m.Table.Name, elem.Id)
deleted = true
}
if deleted && deleteRefs {
for _, m := range elem.Members {
if m.Type == element.WAY {
d.diffCache.Ways.DeleteRef(m.Id, id)
}
}
}
d.osmCache.InsertedWays.DeleteMembers(elem.Members)
if deleted && d.expireTiles != nil {
for _, m := range elem.Members {
if m.Way == nil {
continue
}
err := d.osmCache.Coords.FillWay(m.Way)
if err != nil {
continue
}
proj.NodesToMerc(m.Way.Nodes)
d.expireTiles.ExpireFromNodes(m.Way.Nodes)
}
}
}
func (d *Deleter) deleteWay(id int64, deleteRefs bool) {
elem, err := d.osmCache.Ways.GetWay(id)
if err != nil {
if err == cache.NotFound {
return
}
// TODO
log.Print("way", id, err)
return
}
if elem.Tags == nil {
return
}
deleted := false
for _, m := range d.tmPolygons.Match(&elem.Tags) {
d.delDb.Delete(m.Table.Name, elem.Id)
deleted = true
}
for _, m := range d.tmLineStrings.Match(&elem.Tags) {
d.delDb.Delete(m.Table.Name, elem.Id)
deleted = true
}
if deleted && deleteRefs {
for _, n := range elem.Refs {
d.diffCache.Coords.DeleteRef(n, id)
}
}
if deleted && d.expireTiles != nil {
err := d.osmCache.Coords.FillWay(elem)
if err != nil {
return
}
d.expireTiles.ExpireFromNodes(elem.Nodes)
}
}
func (d *Deleter) deleteNode(id int64) {
elem, err := d.osmCache.Nodes.GetNode(id)
if err != nil {
if err == cache.NotFound {
return
}
// TODO
log.Print("node", id, err)
return
}
if elem.Tags == nil {
return
}
deleted := false
for _, m := range d.tmPoints.Match(&elem.Tags) {
d.delDb.Delete(m.Table.Name, elem.Id)
deleted = true
}
if deleted && d.expireTiles != nil {
d.expireTiles.ExpireFromNodes([]element.Node{*elem})
}
}
func (d *Deleter) Delete(delElem parser.DiffElem) {
if !delElem.Del {
panic("del=false")
}
if delElem.Rel != nil {
d.deleteRelation(delElem.Rel.Id, true)
} else if delElem.Way != nil {
d.deleteWay(delElem.Way.Id, true)
if delElem.Mod {
dependers := d.diffCache.Ways.Get(delElem.Way.Id)
for _, rel := range dependers {
d.deleteRelation(rel, false)
}
}
} else if delElem.Node != nil {
d.deleteNode(delElem.Node.Id)
if delElem.Mod {
dependers := d.diffCache.Coords.Get(delElem.Node.Id)
for _, way := range dependers {
d.deleteWay(way, false)
dependers := d.diffCache.Ways.Get(way)
for _, rel := range dependers {
d.deleteRelation(rel, false)
}
}
}
if !delElem.Add {
d.diffCache.Coords.Delete(delElem.Node.Id)
}
}
}