imposm3/mapping/filter.go

157 lines
3.4 KiB
Go
Raw Normal View History

2013-05-07 12:13:09 +04:00
package mapping
2013-05-17 18:28:16 +04:00
import (
2014-08-04 17:19:35 +04:00
"github.com/omniscale/imposm3/element"
2013-05-17 18:28:16 +04:00
)
2014-06-18 19:18:44 +04:00
func (m *Mapping) NodeTagFilter() TagFilterer {
if m.Tags.LoadAll {
return newExcludeFilter(m.Tags.Exclude)
2014-06-18 19:18:44 +04:00
}
2014-04-30 18:33:07 +04:00
mappings := make(map[Key]map[Value][]DestTable)
2013-05-17 17:44:50 +04:00
m.mappings("point", mappings)
2014-04-30 18:33:07 +04:00
tags := make(map[Key]bool)
2013-05-17 17:44:50 +04:00
m.extraTags("point", tags)
return &TagFilter{mappings, tags}
}
2013-05-07 12:13:09 +04:00
2014-06-18 19:18:44 +04:00
func (m *Mapping) WayTagFilter() TagFilterer {
if m.Tags.LoadAll {
return newExcludeFilter(m.Tags.Exclude)
2014-06-18 19:18:44 +04:00
}
2014-04-30 18:33:07 +04:00
mappings := make(map[Key]map[Value][]DestTable)
2013-05-17 17:44:50 +04:00
m.mappings("linestring", mappings)
m.mappings("polygon", mappings)
2014-04-30 18:33:07 +04:00
tags := make(map[Key]bool)
2013-05-17 17:44:50 +04:00
m.extraTags("linestring", tags)
m.extraTags("polygon", tags)
return &TagFilter{mappings, tags}
}
2013-05-07 12:13:09 +04:00
2014-06-18 19:18:44 +04:00
func (m *Mapping) RelationTagFilter() TagFilterer {
if m.Tags.LoadAll {
return newExcludeFilter(m.Tags.Exclude)
2014-06-18 19:18:44 +04:00
}
2014-04-30 18:33:07 +04:00
mappings := make(map[Key]map[Value][]DestTable)
2013-05-17 17:44:50 +04:00
m.mappings("linestring", mappings)
m.mappings("polygon", mappings)
2014-04-30 18:33:07 +04:00
tags := make(map[Key]bool)
2013-05-17 17:44:50 +04:00
m.extraTags("linestring", tags)
m.extraTags("polygon", tags)
// do not filter out type tag
2014-04-30 18:33:07 +04:00
mappings["type"] = map[Value][]DestTable{
2013-05-27 13:24:22 +04:00
"multipolygon": []DestTable{},
"boundary": []DestTable{},
"land_area": []DestTable{},
}
2013-05-17 17:44:50 +04:00
return &RelationTagFilter{TagFilter{mappings, tags}}
}
type TagFilter struct {
2014-04-30 18:33:07 +04:00
mappings map[Key]map[Value][]DestTable
extraTags map[Key]bool
2013-05-17 17:44:50 +04:00
}
2013-05-07 12:13:09 +04:00
2013-05-17 17:44:50 +04:00
type RelationTagFilter struct {
TagFilter
}
type ExcludeFilter struct {
exclude map[Key]struct{}
}
func newExcludeFilter(tags []Key) *ExcludeFilter {
f := ExcludeFilter{make(map[Key]struct{}, len(tags))}
for _, tag := range tags {
f.exclude[tag] = struct{}{}
}
return &f
}
2014-06-18 19:18:44 +04:00
func (f *ExcludeFilter) Filter(tags *element.Tags) bool {
for k, _ := range *tags {
if _, ok := f.exclude[Key(k)]; ok {
delete(*tags, k)
}
}
2014-06-18 19:18:44 +04:00
return true
}
type TagFilterer interface {
Filter(tags *element.Tags) bool
}
2013-05-17 18:28:16 +04:00
func (f *TagFilter) Filter(tags *element.Tags) bool {
if tags == nil {
return false
}
2013-05-17 17:44:50 +04:00
foundMapping := false
2013-05-17 18:28:16 +04:00
for k, v := range *tags {
2014-04-30 18:33:07 +04:00
values, ok := f.mappings[Key(k)]
2013-05-17 17:44:50 +04:00
if ok {
if _, ok := values["__any__"]; ok {
foundMapping = true
continue
2014-04-30 18:33:07 +04:00
} else if _, ok := values[Value(v)]; ok {
2013-05-17 17:44:50 +04:00
foundMapping = true
continue
2014-04-30 18:33:07 +04:00
} else if _, ok := f.extraTags[Key(k)]; !ok {
2013-05-17 18:28:16 +04:00
delete(*tags, k)
2013-05-17 17:44:50 +04:00
}
2014-04-30 18:33:07 +04:00
} else if _, ok := f.extraTags[Key(k)]; !ok {
2013-05-17 18:28:16 +04:00
delete(*tags, k)
2013-05-17 17:44:50 +04:00
}
}
if foundMapping {
return true
} else {
2013-05-17 18:28:16 +04:00
*tags = nil
2013-05-17 17:44:50 +04:00
return false
}
}
2013-05-07 12:13:09 +04:00
2013-05-17 18:28:16 +04:00
func (f *RelationTagFilter) Filter(tags *element.Tags) bool {
if tags == nil {
return false
}
if t, ok := (*tags)["type"]; ok {
2013-05-17 17:44:50 +04:00
if t != "multipolygon" && t != "boundary" && t != "land_area" {
2013-05-17 18:28:16 +04:00
*tags = nil
2013-05-17 17:44:50 +04:00
return false
}
if t == "boundary" {
if _, ok := (*tags)["boundary"]; !ok {
// a lot of the boundary relations are not multipolygon
// only import with boundary tags (e.g. boundary=administrative)
*tags = nil
return false
}
}
2013-05-17 17:44:50 +04:00
} else {
2013-05-17 18:28:16 +04:00
*tags = nil
2013-05-17 17:44:50 +04:00
return false
2013-05-07 12:13:09 +04:00
}
tagCount := len(*tags)
2013-05-17 17:44:50 +04:00
f.TagFilter.Filter(tags)
// we removed tags...
if len(*tags) < tagCount {
expectedTags := 0
if _, ok := (*tags)["name"]; ok {
expectedTags += 1
}
if _, ok := (*tags)["type"]; ok {
expectedTags += 1
}
if len(*tags) == expectedTags {
// but no tags except name and type are left
// remove all, otherwise tags from longest
// way/ring would be used during MP building
*tags = nil
return false
}
}
2013-05-17 17:44:50 +04:00
// always return true here since we found a matching type
return true
2013-05-07 12:13:09 +04:00
}