Split ways between linestrings / polygons correctly (so one object cannot be a linestring and a polygon at the same time)
parent
013e395f5c
commit
8e1da67b3d
|
@ -275,7 +275,7 @@ type elementFilter func(tags element.Tags, key Key, closed bool) bool
|
||||||
|
|
||||||
type tableElementFilters map[string][]elementFilter
|
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 areaTags map[Key]struct{}
|
||||||
var linearTags map[Key]struct{}
|
var linearTags map[Key]struct{}
|
||||||
if m.Conf.Areas.AreaTags != nil {
|
if m.Conf.Areas.AreaTags != nil {
|
||||||
|
@ -290,42 +290,7 @@ func (m *Mapping) addTypedFilters(tableType TableType, filters tableElementFilte
|
||||||
linearTags[Key(tag)] = struct{}{}
|
linearTags[Key(tag)] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return areaTags, linearTags
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mapping) addRelationFilters(tableType TableType, filters tableElementFilters) {
|
func (m *Mapping) addRelationFilters(tableType TableType, filters tableElementFilters) {
|
||||||
|
|
|
@ -10,13 +10,11 @@ func (m *Mapping) pointMatcher() (NodeMatcher, error) {
|
||||||
m.mappings(PointTable, mappings)
|
m.mappings(PointTable, mappings)
|
||||||
filters := make(tableElementFilters)
|
filters := make(tableElementFilters)
|
||||||
m.addFilters(filters)
|
m.addFilters(filters)
|
||||||
m.addTypedFilters(PointTable, filters)
|
|
||||||
tables, err := m.tables(PointTable)
|
tables, err := m.tables(PointTable)
|
||||||
return &tagMatcher{
|
return &tagMatcher{
|
||||||
mappings: mappings,
|
mappings: mappings,
|
||||||
filters: filters,
|
filters: filters,
|
||||||
tables: tables,
|
tables: tables,
|
||||||
matchAreas: false,
|
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +23,15 @@ func (m *Mapping) lineStringMatcher() (WayMatcher, error) {
|
||||||
m.mappings(LineStringTable, mappings)
|
m.mappings(LineStringTable, mappings)
|
||||||
filters := make(tableElementFilters)
|
filters := make(tableElementFilters)
|
||||||
m.addFilters(filters)
|
m.addFilters(filters)
|
||||||
m.addTypedFilters(LineStringTable, filters)
|
areaTags, linearTags := m.getAreaTags()
|
||||||
tables, err := m.tables(LineStringTable)
|
tables, err := m.tables(LineStringTable)
|
||||||
return &tagMatcher{
|
return &tagMatcher{
|
||||||
mappings: mappings,
|
mappings: mappings,
|
||||||
filters: filters,
|
filters: filters,
|
||||||
tables: tables,
|
tables: tables,
|
||||||
|
areaTags: areaTags,
|
||||||
|
linearTags: linearTags,
|
||||||
|
matchLines: true,
|
||||||
matchAreas: false,
|
matchAreas: false,
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
@ -40,7 +41,7 @@ func (m *Mapping) polygonMatcher() (RelWayMatcher, error) {
|
||||||
m.mappings(PolygonTable, mappings)
|
m.mappings(PolygonTable, mappings)
|
||||||
filters := make(tableElementFilters)
|
filters := make(tableElementFilters)
|
||||||
m.addFilters(filters)
|
m.addFilters(filters)
|
||||||
m.addTypedFilters(PolygonTable, filters)
|
areaTags, linearTags := m.getAreaTags()
|
||||||
relFilters := make(tableElementFilters)
|
relFilters := make(tableElementFilters)
|
||||||
m.addRelationFilters(PolygonTable, relFilters)
|
m.addRelationFilters(PolygonTable, relFilters)
|
||||||
tables, err := m.tables(PolygonTable)
|
tables, err := m.tables(PolygonTable)
|
||||||
|
@ -49,6 +50,9 @@ func (m *Mapping) polygonMatcher() (RelWayMatcher, error) {
|
||||||
filters: filters,
|
filters: filters,
|
||||||
tables: tables,
|
tables: tables,
|
||||||
relFilters: relFilters,
|
relFilters: relFilters,
|
||||||
|
areaTags: areaTags,
|
||||||
|
linearTags: linearTags,
|
||||||
|
matchLines: false,
|
||||||
matchAreas: true,
|
matchAreas: true,
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
@ -58,8 +62,6 @@ func (m *Mapping) relationMatcher() (RelationMatcher, error) {
|
||||||
m.mappings(RelationTable, mappings)
|
m.mappings(RelationTable, mappings)
|
||||||
filters := make(tableElementFilters)
|
filters := make(tableElementFilters)
|
||||||
m.addFilters(filters)
|
m.addFilters(filters)
|
||||||
m.addTypedFilters(PolygonTable, filters)
|
|
||||||
m.addTypedFilters(RelationTable, filters)
|
|
||||||
relFilters := make(tableElementFilters)
|
relFilters := make(tableElementFilters)
|
||||||
m.addRelationFilters(RelationTable, relFilters)
|
m.addRelationFilters(RelationTable, relFilters)
|
||||||
tables, err := m.tables(RelationTable)
|
tables, err := m.tables(RelationTable)
|
||||||
|
@ -68,7 +70,6 @@ func (m *Mapping) relationMatcher() (RelationMatcher, error) {
|
||||||
filters: filters,
|
filters: filters,
|
||||||
tables: tables,
|
tables: tables,
|
||||||
relFilters: relFilters,
|
relFilters: relFilters,
|
||||||
matchAreas: true,
|
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +78,6 @@ func (m *Mapping) relationMemberMatcher() (RelationMatcher, error) {
|
||||||
m.mappings(RelationMemberTable, mappings)
|
m.mappings(RelationMemberTable, mappings)
|
||||||
filters := make(tableElementFilters)
|
filters := make(tableElementFilters)
|
||||||
m.addFilters(filters)
|
m.addFilters(filters)
|
||||||
m.addTypedFilters(RelationMemberTable, filters)
|
|
||||||
relFilters := make(tableElementFilters)
|
relFilters := make(tableElementFilters)
|
||||||
m.addRelationFilters(RelationMemberTable, relFilters)
|
m.addRelationFilters(RelationMemberTable, relFilters)
|
||||||
tables, err := m.tables(RelationMemberTable)
|
tables, err := m.tables(RelationMemberTable)
|
||||||
|
@ -86,7 +86,6 @@ func (m *Mapping) relationMemberMatcher() (RelationMatcher, error) {
|
||||||
filters: filters,
|
filters: filters,
|
||||||
tables: tables,
|
tables: tables,
|
||||||
relFilters: relFilters,
|
relFilters: relFilters,
|
||||||
matchAreas: true,
|
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +126,9 @@ type tagMatcher struct {
|
||||||
tables map[string]*rowBuilder
|
tables map[string]*rowBuilder
|
||||||
filters tableElementFilters
|
filters tableElementFilters
|
||||||
relFilters tableElementFilters
|
relFilters tableElementFilters
|
||||||
|
areaTags map[Key]struct{}
|
||||||
|
linearTags map[Key]struct{}
|
||||||
|
matchLines bool
|
||||||
matchAreas bool
|
matchAreas bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,23 +137,7 @@ func (tm *tagMatcher) MatchNode(node *element.Node) []Match {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tm *tagMatcher) MatchWay(way *element.Way) []Match {
|
func (tm *tagMatcher) MatchWay(way *element.Way) []Match {
|
||||||
if tm.matchAreas { // match way as polygon
|
return tm.match(way.Tags, way.IsClosed(), false)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tm *tagMatcher) MatchRelation(rel *element.Relation) []Match {
|
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 {
|
for t, match := range tables {
|
||||||
filters, ok := tm.filters[t.Name]
|
filters, ok := tm.filters[t.Name]
|
||||||
filteredOut := false
|
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 {
|
for _, filter := range filters {
|
||||||
if !filter(tags, Key(match.Key), closed) {
|
if !filter(tags, Key(match.Key), closed) {
|
||||||
filteredOut = true
|
filteredOut = true
|
||||||
|
|
Loading…
Reference in New Issue