223 lines
6.8 KiB
Diff
223 lines
6.8 KiB
Diff
|
commit 8e1da67b3d4221aa16469cba53c8097ddbe78cb8
|
||
|
Author: Vitaliy Filippov <vitalif@yourcmc.ru>
|
||
|
Date: Sat Sep 29 02:47:19 2018 +0300
|
||
|
|
||
|
Split ways between linestrings / polygons correctly (so one object cannot be a linestring and a polygon at the same time)
|
||
|
|
||
|
diff --git a/mapping/mapping.go b/mapping/mapping.go
|
||
|
index 4f48658..7e58a93 100644
|
||
|
--- a/mapping/mapping.go
|
||
|
+++ b/mapping/mapping.go
|
||
|
@@ -275,7 +275,7 @@ type elementFilter func(tags element.Tags, key Key, closed bool) bool
|
||
|
|
||
|
type tableElementFilters map[string][]elementFilter
|
||
|
|
||
|
-func (m *Mapping) addTypedFilters(tableType TableType, filters tableElementFilters) {
|
||
|
+func (m *Mapping) getAreaTags() (map[Key]struct{}, map[Key]struct{}) {
|
||
|
var areaTags map[Key]struct{}
|
||
|
var linearTags map[Key]struct{}
|
||
|
if m.Conf.Areas.AreaTags != nil {
|
||
|
@@ -290,42 +290,7 @@ func (m *Mapping) addTypedFilters(tableType TableType, filters tableElementFilte
|
||
|
linearTags[Key(tag)] = struct{}{}
|
||
|
}
|
||
|
}
|
||
|
-
|
||
|
- for name, t := range m.Conf.Tables {
|
||
|
- if TableType(t.Type) != GeometryTable && TableType(t.Type) != tableType {
|
||
|
- continue
|
||
|
- }
|
||
|
- if TableType(t.Type) == LineStringTable && areaTags != nil {
|
||
|
- f := func(tags element.Tags, key Key, closed bool) bool {
|
||
|
- if closed {
|
||
|
- if tags["area"] == "yes" {
|
||
|
- return false
|
||
|
- }
|
||
|
- if tags["area"] != "no" {
|
||
|
- if _, ok := areaTags[key]; ok {
|
||
|
- return false
|
||
|
- }
|
||
|
- }
|
||
|
- }
|
||
|
- return true
|
||
|
- }
|
||
|
- filters[name] = append(filters[name], f)
|
||
|
- }
|
||
|
- if TableType(t.Type) == PolygonTable && linearTags != nil {
|
||
|
- f := func(tags element.Tags, key Key, closed bool) bool {
|
||
|
- if closed && tags["area"] == "no" {
|
||
|
- return false
|
||
|
- }
|
||
|
- if tags["area"] != "yes" {
|
||
|
- if _, ok := linearTags[key]; ok {
|
||
|
- return false
|
||
|
- }
|
||
|
- }
|
||
|
- return true
|
||
|
- }
|
||
|
- filters[name] = append(filters[name], f)
|
||
|
- }
|
||
|
- }
|
||
|
+ return areaTags, linearTags
|
||
|
}
|
||
|
|
||
|
func (m *Mapping) addRelationFilters(tableType TableType, filters tableElementFilters) {
|
||
|
diff --git a/mapping/matcher.go b/mapping/matcher.go
|
||
|
index 2c58446..346782c 100644
|
||
|
--- a/mapping/matcher.go
|
||
|
+++ b/mapping/matcher.go
|
||
|
@@ -10,13 +10,11 @@ func (m *Mapping) pointMatcher() (NodeMatcher, error) {
|
||
|
m.mappings(PointTable, mappings)
|
||
|
filters := make(tableElementFilters)
|
||
|
m.addFilters(filters)
|
||
|
- m.addTypedFilters(PointTable, filters)
|
||
|
tables, err := m.tables(PointTable)
|
||
|
return &tagMatcher{
|
||
|
mappings: mappings,
|
||
|
filters: filters,
|
||
|
tables: tables,
|
||
|
- matchAreas: false,
|
||
|
}, err
|
||
|
}
|
||
|
|
||
|
@@ -25,12 +23,15 @@ func (m *Mapping) lineStringMatcher() (WayMatcher, error) {
|
||
|
m.mappings(LineStringTable, mappings)
|
||
|
filters := make(tableElementFilters)
|
||
|
m.addFilters(filters)
|
||
|
- m.addTypedFilters(LineStringTable, filters)
|
||
|
+ areaTags, linearTags := m.getAreaTags()
|
||
|
tables, err := m.tables(LineStringTable)
|
||
|
return &tagMatcher{
|
||
|
mappings: mappings,
|
||
|
filters: filters,
|
||
|
tables: tables,
|
||
|
+ areaTags: areaTags,
|
||
|
+ linearTags: linearTags,
|
||
|
+ matchLines: true,
|
||
|
matchAreas: false,
|
||
|
}, err
|
||
|
}
|
||
|
@@ -40,7 +41,7 @@ func (m *Mapping) polygonMatcher() (RelWayMatcher, error) {
|
||
|
m.mappings(PolygonTable, mappings)
|
||
|
filters := make(tableElementFilters)
|
||
|
m.addFilters(filters)
|
||
|
- m.addTypedFilters(PolygonTable, filters)
|
||
|
+ areaTags, linearTags := m.getAreaTags()
|
||
|
relFilters := make(tableElementFilters)
|
||
|
m.addRelationFilters(PolygonTable, relFilters)
|
||
|
tables, err := m.tables(PolygonTable)
|
||
|
@@ -49,6 +50,9 @@ func (m *Mapping) polygonMatcher() (RelWayMatcher, error) {
|
||
|
filters: filters,
|
||
|
tables: tables,
|
||
|
relFilters: relFilters,
|
||
|
+ areaTags: areaTags,
|
||
|
+ linearTags: linearTags,
|
||
|
+ matchLines: false,
|
||
|
matchAreas: true,
|
||
|
}, err
|
||
|
}
|
||
|
@@ -58,8 +62,6 @@ func (m *Mapping) relationMatcher() (RelationMatcher, error) {
|
||
|
m.mappings(RelationTable, mappings)
|
||
|
filters := make(tableElementFilters)
|
||
|
m.addFilters(filters)
|
||
|
- m.addTypedFilters(PolygonTable, filters)
|
||
|
- m.addTypedFilters(RelationTable, filters)
|
||
|
relFilters := make(tableElementFilters)
|
||
|
m.addRelationFilters(RelationTable, relFilters)
|
||
|
tables, err := m.tables(RelationTable)
|
||
|
@@ -68,7 +70,6 @@ func (m *Mapping) relationMatcher() (RelationMatcher, error) {
|
||
|
filters: filters,
|
||
|
tables: tables,
|
||
|
relFilters: relFilters,
|
||
|
- matchAreas: true,
|
||
|
}, err
|
||
|
}
|
||
|
|
||
|
@@ -77,7 +78,6 @@ func (m *Mapping) relationMemberMatcher() (RelationMatcher, error) {
|
||
|
m.mappings(RelationMemberTable, mappings)
|
||
|
filters := make(tableElementFilters)
|
||
|
m.addFilters(filters)
|
||
|
- m.addTypedFilters(RelationMemberTable, filters)
|
||
|
relFilters := make(tableElementFilters)
|
||
|
m.addRelationFilters(RelationMemberTable, relFilters)
|
||
|
tables, err := m.tables(RelationMemberTable)
|
||
|
@@ -86,7 +86,6 @@ func (m *Mapping) relationMemberMatcher() (RelationMatcher, error) {
|
||
|
filters: filters,
|
||
|
tables: tables,
|
||
|
relFilters: relFilters,
|
||
|
- matchAreas: true,
|
||
|
}, err
|
||
|
}
|
||
|
|
||
|
@@ -127,6 +126,9 @@ type tagMatcher struct {
|
||
|
tables map[string]*rowBuilder
|
||
|
filters tableElementFilters
|
||
|
relFilters tableElementFilters
|
||
|
+ areaTags map[Key]struct{}
|
||
|
+ linearTags map[Key]struct{}
|
||
|
+ matchLines bool
|
||
|
matchAreas bool
|
||
|
}
|
||
|
|
||
|
@@ -135,23 +137,7 @@ func (tm *tagMatcher) MatchNode(node *element.Node) []Match {
|
||
|
}
|
||
|
|
||
|
func (tm *tagMatcher) MatchWay(way *element.Way) []Match {
|
||
|
- if tm.matchAreas { // match way as polygon
|
||
|
- if way.IsClosed() {
|
||
|
- if way.Tags["area"] == "no" {
|
||
|
- return nil
|
||
|
- }
|
||
|
- return tm.match(way.Tags, true, false)
|
||
|
- }
|
||
|
- } else { // match way as linestring
|
||
|
- if way.IsClosed() {
|
||
|
- if way.Tags["area"] == "yes" {
|
||
|
- return nil
|
||
|
- }
|
||
|
- return tm.match(way.Tags, true, false)
|
||
|
- }
|
||
|
- return tm.match(way.Tags, false, false)
|
||
|
- }
|
||
|
- return nil
|
||
|
+ return tm.match(way.Tags, way.IsClosed(), false)
|
||
|
}
|
||
|
|
||
|
func (tm *tagMatcher) MatchRelation(rel *element.Relation) []Match {
|
||
|
@@ -205,7 +191,35 @@ func (tm *tagMatcher) match(tags element.Tags, closed bool, relation bool) []Mat
|
||
|
for t, match := range tables {
|
||
|
filters, ok := tm.filters[t.Name]
|
||
|
filteredOut := false
|
||
|
- if ok {
|
||
|
+ if !relation && (tm.matchLines || tm.matchAreas) {
|
||
|
+ if !closed {
|
||
|
+ // open way is always a linestring
|
||
|
+ filteredOut = tm.matchLines == false
|
||
|
+ } else {
|
||
|
+ // allow to include closed ways as linestrings if explicitly marked
|
||
|
+ // default -> area
|
||
|
+ // area=no or linear tags -> line
|
||
|
+ // area=yes or area tags -> area
|
||
|
+ filteredOut = tm.matchAreas && tags["area"] == "no" || !tm.matchAreas && tags["area"] != "no"
|
||
|
+ for k, _ := range tm.linearTags {
|
||
|
+ if _, ok := tags[string(k)]; ok {
|
||
|
+ filteredOut = tm.matchAreas
|
||
|
+ break
|
||
|
+ }
|
||
|
+ }
|
||
|
+ // but area=yes or area tag means it shouldn't be a linestring
|
||
|
+ if tags["area"] == "yes" {
|
||
|
+ filteredOut = tm.matchAreas
|
||
|
+ }
|
||
|
+ for k, _ := range tm.areaTags {
|
||
|
+ if _, ok := tags[string(k)]; ok {
|
||
|
+ filteredOut = !tm.matchAreas
|
||
|
+ break
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if ok && !filteredOut {
|
||
|
for _, filter := range filters {
|
||
|
if !filter(tags, Key(match.Key), closed) {
|
||
|
filteredOut = true
|