imposm3/mapping/matcher.go

111 lines
2.5 KiB
Go
Raw Normal View History

2013-05-17 17:44:50 +04:00
package mapping
import (
2013-08-29 17:44:15 +04:00
"imposm3/element"
2013-05-17 17:44:50 +04:00
)
func (m *Mapping) PointMatcher() *TagMatcher {
mappings := make(TagTables)
m.mappings("point", mappings)
filters := m.ElementFilters()
return &TagMatcher{mappings, m.tables("point"), filters}
}
func (m *Mapping) LineStringMatcher() *TagMatcher {
mappings := make(TagTables)
m.mappings("linestring", mappings)
filters := m.ElementFilters()
return &TagMatcher{mappings, m.tables("linestring"), filters}
}
func (m *Mapping) PolygonMatcher() *TagMatcher {
mappings := make(TagTables)
m.mappings("polygon", mappings)
filters := m.ElementFilters()
return &TagMatcher{mappings, m.tables("polygon"), filters}
}
type TagMatcher struct {
mappings TagTables
tables map[string]*TableFields
filters map[string][]ElementFilter
}
type Match struct {
Key string
Value string
2013-05-27 13:24:22 +04:00
Table DestTable
2013-05-17 17:44:50 +04:00
tableFields *TableFields
}
func (m *Match) Row(elem *element.OSMElem) []interface{} {
return m.tableFields.MakeRow(elem, *m)
}
2013-05-23 15:09:47 +04:00
func (tagMatcher *TagMatcher) Match(tags *element.Tags) []Match {
2013-05-27 13:24:22 +04:00
tables := make(map[DestTable]Match)
2013-05-17 17:44:50 +04:00
2013-05-23 15:09:47 +04:00
for k, v := range *tags {
2014-04-30 18:33:07 +04:00
values, ok := tagMatcher.mappings[Key(k)]
2013-05-17 17:44:50 +04:00
if ok {
if tbls, ok := values["__any__"]; ok {
for _, t := range tbls {
2013-05-27 13:24:22 +04:00
tables[t] = Match{k, v, t, tagMatcher.tables[t.Name]}
2013-05-17 17:44:50 +04:00
}
}
2014-04-30 18:33:07 +04:00
if tbls, ok := values[Value(v)]; ok {
2013-05-17 17:44:50 +04:00
for _, t := range tbls {
2013-05-27 13:24:22 +04:00
tables[t] = Match{k, v, t, tagMatcher.tables[t.Name]}
2013-05-17 17:44:50 +04:00
}
}
}
}
var matches []Match
for t, match := range tables {
2013-05-27 13:24:22 +04:00
filters, ok := tagMatcher.filters[t.Name]
2013-05-17 17:44:50 +04:00
filteredOut := false
if ok {
for _, filter := range filters {
2013-05-23 15:09:47 +04:00
if !filter(tags) {
2013-05-17 17:44:50 +04:00
filteredOut = true
break
}
}
}
if !filteredOut {
matches = append(matches, match)
}
}
return matches
}
// SelectRelationPolygons returns a slice of all members that are already
// imported with a relation with tags.
func SelectRelationPolygons(polygonTagMatcher *TagMatcher, tags element.Tags, members []element.Member) []element.Member {
relMatches := polygonTagMatcher.Match(&tags)
result := []element.Member{}
for _, m := range members {
if m.Type != element.WAY {
continue
}
memberMatches := polygonTagMatcher.Match(&m.Way.Tags)
if matchEquals(relMatches, memberMatches) {
result = append(result, m)
}
}
return result
}
func matchEquals(matchesA, matchesB []Match) bool {
for _, matchA := range matchesA {
for _, matchB := range matchesB {
if matchA.Key == matchB.Key &&
matchA.Value == matchB.Value &&
matchA.Table == matchB.Table {
return true
}
}
}
return false
}