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 {
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 {
@ -82,12 +87,17 @@ func ConnectionType(param string) string {
type NullDb struct{}
func (n *NullDb) Init() error { return nil }
func (n *NullDb) Begin() error { return nil }
func (n *NullDb) End() error { return nil }
func (n *NullDb) Close() error { return nil }
func (n *NullDb) Abort() error { return nil }
func (n *NullDb) Insert(element.OSMElem, mapping.Match) {}
func (n *NullDb) Init() error { return nil }
func (n *NullDb) Begin() error { return nil }
func (n *NullDb) End() error { return nil }
func (n *NullDb) Close() error { return nil }
func (n *NullDb) Abort() error { return nil }
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) {
return &NullDb{}, nil

View File

@ -404,15 +404,18 @@ func clusterTable(pg *PostGIS, tableName string, srid int, columns []ColumnSpec)
}
type PostGIS struct {
Db *sql.DB
Params string
Schema string
BackupSchema string
Config database.Config
Tables map[string]*TableSpec
GeneralizedTables map[string]*GeneralizedTableSpec
Prefix string
txRouter *TxRouter
Db *sql.DB
Params string
Schema string
BackupSchema string
Config database.Config
Tables map[string]*TableSpec
GeneralizedTables map[string]*GeneralizedTableSpec
Prefix string
txRouter *TxRouter
pointTagMatcher *mapping.TagMatcher
lineStringTagMatcher *mapping.TagMatcher
polygonTagMatcher *mapping.TagMatcher
}
func (pg *PostGIS) Open() error {
@ -430,9 +433,52 @@ func (pg *PostGIS) Open() error {
return nil
}
func (pg *PostGIS) Insert(elem element.OSMElem, match mapping.Match) {
row := match.Row(&elem)
pg.txRouter.Insert(match.Table.Name, row)
func (pg *PostGIS) InsertPoint(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) 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 {
@ -609,6 +655,10 @@ func New(conf database.Config, m *mapping.Mapping) (database.DB, error) {
}
db.prepareGeneralizedTableSources()
db.pointTagMatcher = m.PointMatcher()
db.lineStringTagMatcher = m.LineStringMatcher()
db.polygonTagMatcher = m.PolygonMatcher()
db.Params = params
err = db.Open()
if err != nil {

View File

@ -44,7 +44,7 @@ func (nw *NodeWriter) loop() {
for n := range nw.nodes {
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)
if nw.expireTiles != nil {
nw.expireTiles.ExpireFromNodes([]element.Node{*n})
@ -73,10 +73,10 @@ func (nw *NodeWriter) loop() {
continue
}
if len(parts) >= 1 {
nw.insertMatches(&n.OSMElem, matches)
nw.inserter.InsertPoint(n.OSMElem, matches)
}
} 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
matches := rw.tagMatcher.Match(&r.Tags)
if len(matches) == 0 {
ok, matches := rw.inserter.ProbePolygon(r.OSMElem)
if !ok {
continue NextRel
}
@ -116,10 +116,10 @@ NextRel:
for _, g := range parts {
rel := element.Relation(*r)
rel.Geom = &element.Geometry{g, geos.AsEwkbHex(g)}
rw.insertMatches(&rel.OSMElem, matches)
rw.inserter.InsertPolygon(rel.OSMElem, matches)
}
} else {
rw.insertMatches(&r.OSMElem, matches)
rw.inserter.InsertPolygon(r.OSMElem, matches)
}
err = rw.osmCache.InsertedWays.PutMembers(r.Members)
if err != nil {

View File

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