From 748354ba18c001d52409ac7794ecb6c8eb72930b Mon Sep 17 00:00:00 2001 From: Oliver Tonnhofer Date: Mon, 28 Oct 2013 11:28:56 +0100 Subject: [PATCH] move tag matching into database package --- database/database.go | 24 ++++++++---- database/postgis/postgis.go | 74 +++++++++++++++++++++++++++++++------ writer/nodes.go | 6 +-- writer/relations.go | 8 ++-- writer/ways.go | 38 ++++++++++++------- writer/writer.go | 8 ---- 6 files changed, 111 insertions(+), 47 deletions(-) diff --git a/database/database.go b/database/database.go index 8990979..6da4321 100644 --- a/database/database.go +++ b/database/database.go @@ -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 diff --git a/database/postgis/postgis.go b/database/postgis/postgis.go index f0b06ee..b7905cc 100644 --- a/database/postgis/postgis.go +++ b/database/postgis/postgis.go @@ -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 { diff --git a/writer/nodes.go b/writer/nodes.go index a69f91e..065c725 100644 --- a/writer/nodes.go +++ b/writer/nodes.go @@ -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) } } diff --git a/writer/relations.go b/writer/relations.go index b7b5a60..41f673c 100644 --- a/writer/relations.go +++ b/writer/relations.go @@ -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 { diff --git a/writer/ways.go b/writer/ways.go index 5f2af83..ac4f2ca 100644 --- a/writer/ways.go +++ b/writer/ways.go @@ -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) + } } } diff --git a/writer/writer.go b/writer/writer.go index bc1a4f2..4dd9bbb 100644 --- a/writer/writer.go +++ b/writer/writer.go @@ -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) - } -}