move tag matching into database package

master
Oliver Tonnhofer 2013-10-28 11:28:56 +01:00
parent 24372771a4
commit 748354ba18
6 changed files with 111 additions and 47 deletions

View File

@ -27,7 +27,12 @@ type BulkBeginner interface {
} }
type Inserter interface { type Inserter interface {
Insert(element.OSMElem, mapping.Match) ProbePoint(element.OSMElem) (bool, interface{})
ProbeLineString(element.OSMElem) (bool, interface{})
ProbePolygon(element.OSMElem) (bool, interface{})
InsertPoint(element.OSMElem, interface{})
InsertLineString(element.OSMElem, interface{})
InsertPolygon(element.OSMElem, interface{})
} }
type Deployer interface { type Deployer interface {
@ -82,12 +87,17 @@ func ConnectionType(param string) string {
type NullDb struct{} type NullDb struct{}
func (n *NullDb) Init() error { return nil } func (n *NullDb) Init() error { return nil }
func (n *NullDb) Begin() error { return nil } func (n *NullDb) Begin() error { return nil }
func (n *NullDb) End() error { return nil } func (n *NullDb) End() error { return nil }
func (n *NullDb) Close() error { return nil } func (n *NullDb) Close() error { return nil }
func (n *NullDb) Abort() error { return nil } func (n *NullDb) Abort() error { return nil }
func (n *NullDb) Insert(element.OSMElem, mapping.Match) {} 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 NewNullDb(conf Config, m *mapping.Mapping) (DB, error) { func NewNullDb(conf Config, m *mapping.Mapping) (DB, error) {
return &NullDb{}, nil return &NullDb{}, nil

View File

@ -404,15 +404,18 @@ func clusterTable(pg *PostGIS, tableName string, srid int, columns []ColumnSpec)
} }
type PostGIS struct { type PostGIS struct {
Db *sql.DB Db *sql.DB
Params string Params string
Schema string Schema string
BackupSchema string BackupSchema string
Config database.Config Config database.Config
Tables map[string]*TableSpec Tables map[string]*TableSpec
GeneralizedTables map[string]*GeneralizedTableSpec GeneralizedTables map[string]*GeneralizedTableSpec
Prefix string Prefix string
txRouter *TxRouter txRouter *TxRouter
pointTagMatcher *mapping.TagMatcher
lineStringTagMatcher *mapping.TagMatcher
polygonTagMatcher *mapping.TagMatcher
} }
func (pg *PostGIS) Open() error { func (pg *PostGIS) Open() error {
@ -430,9 +433,52 @@ func (pg *PostGIS) Open() error {
return nil return nil
} }
func (pg *PostGIS) Insert(elem element.OSMElem, match mapping.Match) { func (pg *PostGIS) InsertPoint(elem element.OSMElem, matches interface{}) {
row := match.Row(&elem) if matches, ok := matches.([]mapping.Match); ok {
pg.txRouter.Insert(match.Table.Name, row) for _, match := range matches {
row := match.Row(&elem)
pg.txRouter.Insert(match.Table.Name, row)
}
}
}
func (pg *PostGIS) InsertLineString(elem element.OSMElem, matches interface{}) {
if matches, ok := matches.([]mapping.Match); ok {
for _, match := range matches {
row := match.Row(&elem)
pg.txRouter.Insert(match.Table.Name, row)
}
}
}
func (pg *PostGIS) InsertPolygon(elem element.OSMElem, matches interface{}) {
if matches, ok := matches.([]mapping.Match); ok {
for _, match := range matches {
row := match.Row(&elem)
pg.txRouter.Insert(match.Table.Name, row)
}
}
}
func (pg *PostGIS) ProbePoint(elem element.OSMElem) (bool, interface{}) {
if matches := pg.pointTagMatcher.Match(&elem.Tags); len(matches) > 0 {
return true, matches
}
return false, nil
}
func (pg *PostGIS) ProbeLineString(elem element.OSMElem) (bool, interface{}) {
if matches := pg.lineStringTagMatcher.Match(&elem.Tags); len(matches) > 0 {
return true, matches
}
return false, nil
}
func (pg *PostGIS) ProbePolygon(elem element.OSMElem) (bool, interface{}) {
if matches := pg.polygonTagMatcher.Match(&elem.Tags); len(matches) > 0 {
return true, matches
}
return false, nil
} }
func (pg *PostGIS) Delete(table string, id int64) error { func (pg *PostGIS) Delete(table string, id int64) error {
@ -609,6 +655,10 @@ func New(conf database.Config, m *mapping.Mapping) (database.DB, error) {
} }
db.prepareGeneralizedTableSources() db.prepareGeneralizedTableSources()
db.pointTagMatcher = m.PointMatcher()
db.lineStringTagMatcher = m.LineStringMatcher()
db.polygonTagMatcher = m.PolygonMatcher()
db.Params = params db.Params = params
err = db.Open() err = db.Open()
if err != nil { if err != nil {

View File

@ -44,7 +44,7 @@ func (nw *NodeWriter) loop() {
for n := range nw.nodes { for n := range nw.nodes {
nw.progress.AddNodes(1) nw.progress.AddNodes(1)
if matches := nw.tagMatcher.Match(&n.Tags); len(matches) > 0 { if ok, matches := nw.inserter.ProbePoint(n.OSMElem); ok {
proj.NodeToMerc(n) proj.NodeToMerc(n)
if nw.expireTiles != nil { if nw.expireTiles != nil {
nw.expireTiles.ExpireFromNodes([]element.Node{*n}) nw.expireTiles.ExpireFromNodes([]element.Node{*n})
@ -73,10 +73,10 @@ func (nw *NodeWriter) loop() {
continue continue
} }
if len(parts) >= 1 { if len(parts) >= 1 {
nw.insertMatches(&n.OSMElem, matches) nw.inserter.InsertPoint(n.OSMElem, matches)
} }
} else { } else {
nw.insertMatches(&n.OSMElem, matches) nw.inserter.InsertPoint(n.OSMElem, matches)
} }
} }

View File

@ -86,8 +86,8 @@ NextRel:
} }
// check for matches befor building the geometry // check for matches befor building the geometry
matches := rw.tagMatcher.Match(&r.Tags) ok, matches := rw.inserter.ProbePolygon(r.OSMElem)
if len(matches) == 0 { if !ok {
continue NextRel continue NextRel
} }
@ -116,10 +116,10 @@ NextRel:
for _, g := range parts { for _, g := range parts {
rel := element.Relation(*r) rel := element.Relation(*r)
rel.Geom = &element.Geometry{g, geos.AsEwkbHex(g)} rel.Geom = &element.Geometry{g, geos.AsEwkbHex(g)}
rw.insertMatches(&rel.OSMElem, matches) rw.inserter.InsertPolygon(rel.OSMElem, matches)
} }
} else { } else {
rw.insertMatches(&r.OSMElem, matches) rw.inserter.InsertPolygon(r.OSMElem, matches)
} }
err = rw.osmCache.InsertedWays.PutMembers(r.Members) err = rw.osmCache.InsertedWays.PutMembers(r.Members)
if err != nil { if err != nil {

View File

@ -65,13 +65,13 @@ func (ww *WayWriter) loop() {
proj.NodesToMerc(w.Nodes) proj.NodesToMerc(w.Nodes)
inserted = false inserted = false
if matches := ww.lineStringTagMatcher.Match(&w.Tags); len(matches) > 0 { if ok, matches := ww.inserter.ProbeLineString(w.OSMElem); ok {
ww.buildAndInsert(geos, w, matches, geom.LineString) ww.buildAndInsert(geos, w, matches, false)
inserted = true inserted = true
} }
if w.IsClosed() { if w.IsClosed() {
if matches := ww.polygonTagMatcher.Match(&w.Tags); len(matches) > 0 { if ok, matches := ww.inserter.ProbePolygon(w.OSMElem); ok {
ww.buildAndInsert(geos, w, matches, geom.Polygon) ww.buildAndInsert(geos, w, matches, true)
inserted = true inserted = true
} }
} }
@ -86,13 +86,17 @@ func (ww *WayWriter) loop() {
ww.wg.Done() ww.wg.Done()
} }
type geomBuilder func(*geos.Geos, []element.Node) (*geos.Geom, error) func (ww *WayWriter) buildAndInsert(g *geos.Geos, w *element.Way, matches interface{}, isPolygon bool) {
func (ww *WayWriter) buildAndInsert(geos *geos.Geos, w *element.Way, matches []mapping.Match, builder geomBuilder) {
var err error var err error
var geosgeom *geos.Geom
// make copy to avoid interference with polygon/linestring matches // make copy to avoid interference with polygon/linestring matches
way := element.Way(*w) way := element.Way(*w)
geosgeom, err := builder(geos, way.Nodes)
if isPolygon {
geosgeom, err = geom.Polygon(g, way.Nodes)
} else {
geosgeom, err = geom.LineString(g, way.Nodes)
}
if err != nil { if err != nil {
if err, ok := err.(ErrorLevel); ok { if err, ok := err.(ErrorLevel); ok {
if err.Level() <= 0 { if err.Level() <= 0 {
@ -103,7 +107,7 @@ func (ww *WayWriter) buildAndInsert(geos *geos.Geos, w *element.Way, matches []m
return return
} }
way.Geom, err = geom.AsGeomElement(geos, geosgeom) way.Geom, err = geom.AsGeomElement(g, geosgeom)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
return return
@ -115,12 +119,20 @@ func (ww *WayWriter) buildAndInsert(geos *geos.Geos, w *element.Way, matches []m
log.Println(err) log.Println(err)
return return
} }
for _, g := range parts { for _, p := range parts {
way := element.Way(*w) way := element.Way(*w)
way.Geom = &element.Geometry{g, geos.AsEwkbHex(g)} way.Geom = &element.Geometry{p, g.AsEwkbHex(p)}
ww.insertMatches(&way.OSMElem, matches) if isPolygon {
ww.inserter.InsertPolygon(way.OSMElem, matches)
} else {
ww.inserter.InsertLineString(way.OSMElem, matches)
}
} }
} else { } else {
ww.insertMatches(&way.OSMElem, matches) if isPolygon {
ww.inserter.InsertPolygon(way.OSMElem, matches)
} else {
ww.inserter.InsertLineString(way.OSMElem, matches)
}
} }
} }

View File

@ -3,10 +3,8 @@ package writer
import ( import (
"imposm3/cache" "imposm3/cache"
"imposm3/database" "imposm3/database"
"imposm3/element"
"imposm3/expire" "imposm3/expire"
"imposm3/geom/limit" "imposm3/geom/limit"
"imposm3/mapping"
"imposm3/stats" "imposm3/stats"
"runtime" "runtime"
"sync" "sync"
@ -50,9 +48,3 @@ func (writer *OsmElemWriter) SetExpireTiles(expireTiles *expire.Tiles) {
func (writer *OsmElemWriter) Close() { func (writer *OsmElemWriter) Close() {
writer.wg.Wait() writer.wg.Wait()
} }
func (writer *OsmElemWriter) insertMatches(elem *element.OSMElem, matches []mapping.Match) {
for _, match := range matches {
writer.inserter.Insert(*elem, match)
}
}