func TestMatcherMappingOrder(t *testing.T) { elem := element.Relation{} polys := mapping.PolygonMatcher() /* landusages mapping has the following order, check that XxxMatcher always uses the first amenity: - university landuse: - forest leisure: - park landuse: - park */ elem.Tags = element.Tags{"landuse": "forest", "leisure": "park"} matchesEqual(t, []Match{{"landuse", "forest", DestTable{Name: "landusages"}, nil}}, polys.MatchRelation(&elem)) elem.Tags = element.Tags{"landuse": "park", "leisure": "park"} matchesEqual(t, []Match{{"leisure", "park", DestTable{Name: "landusages"}, nil}}, polys.MatchRelation(&elem)) elem.Tags = element.Tags{"landuse": "park", "leisure": "park", "amenity": "university"} matchesEqual(t, []Match{{"amenity", "university", DestTable{Name: "landusages"}, nil}}, polys.MatchRelation(&elem)) }
func TestSelectRelationPolygonsMultiple(t *testing.T) { mapping, err := NewMapping("test_mapping.json") if err != nil { t.Fatal(err) } r := element.Relation{} r.Tags = element.Tags{"landuse": "park"} r.Members = []element.Member{ makeMember(0, element.Tags{"landuse": "park"}), makeMember(1, element.Tags{"natural": "forest"}), makeMember(2, element.Tags{"landuse": "park"}), makeMember(3, element.Tags{"highway": "pedestrian"}), makeMember(4, element.Tags{"landuse": "park", "layer": "2", "name": "foo"}), } filtered := SelectRelationPolygons( mapping.PolygonMatcher(), &r, ) if len(filtered) != 3 { t.Fatal(filtered) } if filtered[0].Id != 0 || filtered[1].Id != 2 || filtered[2].Id != 4 { t.Fatal(filtered) } }
func PrepareRelation(rel *element.Relation, srid int) (*preparedRelation, error) { rings, err := BuildRings(rel) if err != nil { return nil, err } rel.Tags = relationTags(rel.Tags, rings[0].ways[0].Tags) return &preparedRelation{rings, rel, srid}, nil }
// PrepareRelation is the first step in building a (multi-)polygon of a Relation. // It builds rings from all ways and returns an error if there are unclosed rings. // It also merges the Relation.Tags with the Tags of the outer way. func PrepareRelation(rel *element.Relation, srid int, maxRingGap float64) (PreparedRelation, error) { rings, err := buildRings(rel, maxRingGap) if err != nil { return PreparedRelation{}, err } rel.Tags = relationTags(rel.Tags, rings[0].ways[0].Tags) return PreparedRelation{rings, rel, srid}, nil }
// PrepareRelation is the first step in building a (multi-)polygon of a Relation. // It builds rings from all ways and returns an error if there are unclosed rings. // It also merges the Relation.Tags with the Tags of the outer way. func PrepareRelation(rel *element.Relation, srid int, maxRingGap float64) (PreparedRelation, error) { rings, err := buildRings(rel, maxRingGap) if err != nil { return PreparedRelation{}, err } if rel.Tags["type"] == "multipolygon" && len(rel.Tags) == 1 { rel.Tags = relationTags(rel.Tags, rings[0].ways[0].Tags) //merge the Relation.Tags with the Tags of the outer way was removed } return PreparedRelation{rings, rel, srid}, nil }
func TestPolygonMatcher(t *testing.T) { elem := element.Relation{} polys := mapping.PolygonMatcher() elem.Tags = element.Tags{"unknown": "baz"} matchesEqual(t, []Match{}, polys.MatchRelation(&elem)) elem.Tags = element.Tags{"landuse": "unknowns"} matchesEqual(t, []Match{}, polys.MatchRelation(&elem)) elem.Tags = element.Tags{"building": "yes"} matchesEqual(t, []Match{{"building", "yes", DestTable{"buildings", ""}, nil}}, polys.MatchRelation(&elem)) elem.Tags = element.Tags{"building": "residential"} matchesEqual(t, []Match{{"building", "residential", DestTable{"buildings", ""}, nil}}, polys.MatchRelation(&elem)) elem.Tags = element.Tags{"building": "shop"} matchesEqual(t, []Match{ {"building", "shop", DestTable{"buildings", ""}, nil}, {"building", "shop", DestTable{"amenity_areas", ""}, nil}}, polys.MatchRelation(&elem)) elem.Tags = element.Tags{"landuse": "farm"} matchesEqual(t, []Match{{"landuse", "farm", DestTable{"landusages", ""}, nil}}, polys.MatchRelation(&elem)) elem.Tags = element.Tags{"landuse": "farm", "highway": "secondary"} matchesEqual(t, []Match{{"landuse", "farm", DestTable{"landusages", ""}, nil}}, polys.MatchRelation(&elem)) elem.Tags = element.Tags{"landuse": "farm", "aeroway": "apron"} matchesEqual(t, []Match{ {"aeroway", "apron", DestTable{"transport_areas", ""}, nil}, {"landuse", "farm", DestTable{"landusages", ""}, nil}}, polys.MatchRelation(&elem)) elem.Tags = element.Tags{"highway": "footway"} matchesEqual(t, []Match{{"highway", "footway", DestTable{"landusages", ""}, nil}}, polys.MatchRelation(&elem)) elem.Tags = element.Tags{"boundary": "administrative", "admin_level": "8"} matchesEqual(t, []Match{{"boundary", "administrative", DestTable{"admin", ""}, nil}}, polys.MatchRelation(&elem)) }
func BenchmarkTagMatch(b *testing.B) { m, err := NewMapping("matcher_test_mapping.json") if err != nil { b.Fatal(err) } matcher := m.PolygonMatcher() for i := 0; i < b.N; i++ { e := element.Relation{} e.Tags = element.Tags{"landuse": "forest", "name": "Forest", "source": "bling", "tourism": "zoo"} if m := matcher.MatchRelation(&e); len(m) != 1 { b.Fatal(m) } } }
func BuildRelation(rel *element.Relation, srid int) error { rings, err := BuildRings(rel) if err != nil { return err } rel.Tags = relationTags(rel.Tags, rings[0].ways[0].Tags) _, err = BuildRelGeometry(rel, rings, srid) if err != nil { return err } return nil }
func TestSelectRelationPolygonsMultipleTags(t *testing.T) { mapping, err := NewMapping("test_mapping.json") if err != nil { t.Fatal(err) } r := element.Relation{} r.Tags = element.Tags{"landuse": "forest", "natural": "scrub"} r.Members = []element.Member{ makeMember(0, element.Tags{"natural": "scrub"}), makeMember(1, element.Tags{"landuse": "forest"}), } filtered := SelectRelationPolygons( mapping.PolygonMatcher(), &r, ) // TODO both should be filterd out, but we only get one, // because we match only one tag per table if len(filtered) != 1 { t.Fatal(filtered) } }
func TestSelectRelationPolygonsUnrelatedTags(t *testing.T) { mapping, err := NewMapping("test_mapping.json") if err != nil { t.Fatal(err) } r := element.Relation{} r.Tags = element.Tags{"landuse": "park"} r.Members = []element.Member{ makeMember(0, element.Tags{"landuse": "park", "layer": "2", "name": "foo"}), makeMember(1, element.Tags{"landuse": "forest"}), } filtered := SelectRelationPolygons( mapping.PolygonMatcher(), &r, ) if len(filtered) != 1 { t.Fatal(filtered) } if filtered[0].Id != 0 { t.Fatal(filtered) } }
func TestSelectRelationPolygonsSimple(t *testing.T) { mapping, err := NewMapping("test_mapping.json") if err != nil { t.Fatal(err) } r := element.Relation{} r.Tags = element.Tags{"landuse": "park"} r.Members = []element.Member{ makeMember(0, element.Tags{"landuse": "forest"}), makeMember(1, element.Tags{"landuse": "park"}), makeMember(2, element.Tags{"waterway": "riverbank"}), makeMember(4, element.Tags{"foo": "bar"}), } filtered := SelectRelationPolygons( mapping.PolygonMatcher(), &r, ) if len(filtered) != 1 { t.Fatal(filtered) } if filtered[0].Id != 1 { t.Fatal(filtered[0]) } }
func TestSelectRelationPolygonsMultipleTagsOnWay(t *testing.T) { mapping, err := NewMapping("test_mapping.json") if err != nil { t.Fatal(err) } r := element.Relation{} r.Tags = element.Tags{"waterway": "riverbank"} r.Members = []element.Member{ makeMemberRole(0, element.Tags{"waterway": "riverbank", "natural": "water"}, "outer"), makeMemberRole(1, element.Tags{"natural": "water"}, "inner"), makeMemberRole(2, element.Tags{"place": "islet"}, "inner"), } filtered := SelectRelationPolygons( mapping.PolygonMatcher(), &r, ) if len(filtered) != 1 { t.Fatal(filtered) } if filtered[0].Id != 0 { t.Fatal(filtered) } }