add first simple tag filtering

master
Oliver Tonnhofer 2013-05-07 10:13:09 +02:00
parent 79db75e51a
commit 768d04ad56
4 changed files with 400 additions and 1 deletions

2
cache/db.go vendored
View File

@ -248,7 +248,7 @@ func (p *NodesCache) PutNodes(nodes []element.Node) (int, error) {
keyBuf := make([]byte, 8)
var n int
for _, node := range nodes {
if node.Tags == nil {
if len(node.Tags) == 0 {
continue
}
bin.PutVarint(keyBuf, int64(node.Id))

View File

@ -5,6 +5,7 @@ import (
"fmt"
"goposm/cache"
"goposm/element"
"goposm/mapping"
"goposm/parser"
"goposm/stats"
"log"
@ -46,6 +47,9 @@ func parse(cache *cache.OSMCache, progress *stats.Statistics, filename string) {
waitCounter.Add(1)
go func() {
for ws := range ways {
for _, w := range ws {
mapping.WayTags.Filter(w.Tags)
}
cache.Ways.PutWays(ws)
progress.AddWays(len(ws))
}
@ -56,6 +60,9 @@ func parse(cache *cache.OSMCache, progress *stats.Statistics, filename string) {
waitCounter.Add(1)
go func() {
for rels := range relations {
for _, r := range rels {
mapping.RelationTags.Filter(r.Tags)
}
cache.Relations.PutRelations(rels)
progress.AddRelations(len(rels))
}
@ -76,6 +83,12 @@ func parse(cache *cache.OSMCache, progress *stats.Statistics, filename string) {
waitCounter.Add(1)
go func() {
for nds := range nodes {
for _, nd := range nds {
ok := mapping.PointTags.Filter(nd.Tags)
if !ok {
nd.Tags = nil
}
}
n, _ := cache.Nodes.PutNodes(nds)
progress.AddNodes(n)
}

320
mapping/filter.go Normal file
View File

@ -0,0 +1,320 @@
package mapping
import (
"goposm/element"
)
type TagMap map[string]map[string]bool
var PointTags TagMap
var WayTags TagMap
var RelationTags TagMap
type TagFilter interface {
Filter(element.Tags) bool
}
func (m TagMap) Filter(tags element.Tags) bool {
for k, v := range tags {
values, ok := m[k]
if !ok {
delete(tags, k)
} else {
if _, ok := values["__any__"]; ok {
continue
} else if _, ok := values[v]; ok {
continue
} else {
delete(tags, k)
}
}
}
if _, ok := tags["name"]; ok && len(tags) == 1 {
delete(tags, "name")
}
if len(tags) > 0 {
return true
} else {
return false
}
}
// default mapping created from imposm defaultmapping.py
// TODO make configurable
func init() {
PointTags = TagMap{
"aeroway": map[string]bool{
"aerodome": true,
"gate": true,
"helipad": true,
"terminal": true,
},
"amenity": map[string]bool{
"fire_station": true,
"fuel": true,
"hospital": true,
"library": true,
"police": true,
"school": true,
"townhall": true,
"university": true,
},
"highway": map[string]bool{
"bus_stop": true,
"motorway_junction": true,
"turning_circle": true,
},
"name": map[string]bool{
"__any__": true,
},
"place": map[string]bool{
"city": true,
"country": true,
"county": true,
"hamlet": true,
"locality": true,
"region": true,
"state": true,
"suburb": true,
"town": true,
"village": true,
},
"population": map[string]bool{
"__any__": true,
},
"railway": map[string]bool{
"crossing": true,
"halt": true,
"level_crossing": true,
"station": true,
"subway_entrance": true,
"tram_stop": true,
},
"ref": map[string]bool{
"__any__": true,
},
}
WayTags = map[string]map[string]bool{
"admin_level": map[string]bool{
"__any__": true,
},
"aeroway": map[string]bool{
"aerodrome": true,
"apron": true,
"helipad": true,
"runway": true,
"taxiway": true,
"terminal": true,
},
"amenity": map[string]bool{
"cinema": true,
"college": true,
"fuel": true,
"hospital": true,
"library": true,
"parking": true,
"place_of_worship": true,
"school": true,
"theatre": true,
"university": true,
},
"area": map[string]bool{
"__any__": true,
},
"boundary": map[string]bool{
"administrative": true,
},
"bridge": map[string]bool{
"__any__": true,
},
"building": map[string]bool{
"__any__": true,
},
"highway": map[string]bool{
"bridleway": true,
"cycleway": true,
"footway": true,
"living_street": true,
"motorway": true,
"motorway_link": true,
"path": true,
"pedestrian": true,
"primary": true,
"primary_link": true,
"residential": true,
"road": true,
"secondary": true,
"secondary_link": true,
"service": true,
"steps": true,
"tertiary": true,
"track": true,
"trunk": true,
"trunk_link": true,
"unclassified": true,
},
"landuse": map[string]bool{
"allotments": true,
"basin": true,
"cemetery": true,
"commercial": true,
"farm": true,
"farmland": true,
"farmyard": true,
"forest": true,
"grass": true,
"industrial": true,
"meadow": true,
"park": true,
"quarry": true,
"railway": true,
"recreation_ground": true,
"reservoir": true,
"residential": true,
"retail": true,
"village_green": true,
"wood": true,
},
"leisure": map[string]bool{
"common": true,
"garden": true,
"golf_course": true,
"nature_reserve": true,
"park": true,
"pitch": true,
"playground": true,
"sports_centre": true,
"stadium": true,
},
"name": map[string]bool{
"__any__": true,
},
"natural": map[string]bool{
"land": true,
"scrub": true,
"water": true,
"wood": true,
},
"oneway": map[string]bool{
"__any__": true,
},
"railway": map[string]bool{
"funicular": true,
"light_rail": true,
"monorail": true,
"narrow_gauge": true,
"preserved": true,
"rail": true,
"station": true,
"subway": true,
"tram": true,
},
"ref": map[string]bool{
"__any__": true,
},
"tunnel": map[string]bool{
"__any__": true,
},
"waterway": map[string]bool{
"canal": true,
"drain": true,
"river": true,
"riverbank": true,
"stream": true,
}}
RelationTags = map[string]map[string]bool{
"admin_level": map[string]bool{
"__any__": true,
},
"aeroway": map[string]bool{
"aerodrome": true,
"apron": true,
"helipad": true,
"runway": true,
"taxiway": true,
"terminal": true,
},
"amenity": map[string]bool{
"cinema": true,
"college": true,
"fuel": true,
"hospital": true,
"library": true,
"parking": true,
"place_of_worship": true,
"school": true,
"theatre": true,
"university": true,
},
"area": map[string]bool{
"__any__": true,
},
"boundary": map[string]bool{
"administrative": true,
},
"bridge": map[string]bool{
"__any__": true,
},
"building": map[string]bool{
"__any__": true,
},
"highway": map[string]bool{
"bridleway": true,
"cycleway": true,
"footway": true,
"living_street": true,
"motorway": true,
"motorway_link": true,
"path": true,
"pedestrian": true,
"primary": true,
"primary_link": true,
"residential": true,
"road": true,
"secondary": true,
"secondary_link": true,
"service": true,
"steps": true,
"tertiary": true,
"track": true,
"trunk": true,
"trunk_link": true,
"unclassified": true,
},
"landuse": map[string]bool{
"allotments": true,
"basin": true,
"cemetery": true,
"commercial": true,
"farm": true,
"farmland": true,
"farmyard": true,
"forest": true,
"grass": true,
"industrial": true,
"meadow": true,
"park": true,
"quarry": true,
"railway": true,
"recreation_ground": true,
"reservoir": true,
"residential": true,
"retail": true,
"village_green": true,
"wood": true,
},
"leisure": map[string]bool{
"common": true,
"garden": true,
"golf_course": true,
"nature_reserve": true,
"park": true,
"pitch": true,
"playground": true,
"sports_centre": true,
"stadium": true,
},
}
}

66
mapping/filter_test.go Normal file
View File

@ -0,0 +1,66 @@
package mapping
import (
"goposm/element"
"testing"
)
func TestFilterNodes(t *testing.T) {
var tags element.Tags
// test name only
tags = make(element.Tags)
tags["name"] = "foo"
if PointTags.Filter(tags) != false {
t.Fatal("Filter result not false")
}
if len(tags) != 0 {
t.Fatal("Filter result not empty")
}
// test name + unmapped tags
tags = make(element.Tags)
tags["name"] = "foo"
tags["boring"] = "true"
if PointTags.Filter(tags) != false {
t.Fatal("Filter result not false")
}
if len(tags) != 0 {
t.Fatal("Filter result not empty")
}
// test __any__
tags = make(element.Tags)
tags["population"] = "0"
tags["name"] = "foo"
tags["boring"] = "true"
if PointTags.Filter(tags) != true {
t.Fatal("Filter result true", tags)
}
if len(tags) != 2 && tags["population"] == "0" && tags["name"] == "foo" {
t.Fatal("Filter result not expected", tags)
}
}
func BenchmarkFilterNodes(b *testing.B) {
var tags element.Tags
for i := 0; i < b.N; i++ {
// test __any__
tags = make(element.Tags)
tags["population"] = "0"
tags["name"] = "foo"
tags["boring"] = "true"
if PointTags.Filter(tags) != true {
b.Fatal("Filter result true", tags)
}
if len(tags) != 2 && tags["population"] == "0" && tags["name"] == "foo" {
b.Fatal("Filter result not expected", tags)
}
}
}