imposm3/mapping/config.go

298 lines
6.4 KiB
Go
Raw Normal View History

package mapping
2013-05-13 15:58:44 +04:00
import (
"encoding/json"
"flag"
2013-05-14 18:15:35 +04:00
"goposm/element"
2013-05-13 15:58:44 +04:00
"log"
"os"
)
type Field struct {
Key string `json:"key"`
Type string `json:"type"`
}
type Table struct {
2013-05-14 18:15:35 +04:00
Name string
2013-05-13 15:58:44 +04:00
Type string `json:"type"`
Mapping map[string][]string `json:"mapping"`
Fields map[string]*Field `json:"fields"`
}
2013-05-14 18:15:35 +04:00
type Tables map[string]*Table
2013-05-13 15:58:44 +04:00
type Mapping struct {
Tables Tables `json:"tables"`
}
func (t *Table) FillFieldKeys() {
for key, field := range t.Fields {
if field.Key == "" {
field.Key = key
}
}
}
func (t *Table) Mappings() map[string][]string {
return t.Mapping
}
func (t *Table) ExtraTags() map[string]bool {
tags := make(map[string]bool)
for _, field := range t.Fields {
tags[field.Key] = true
}
return tags
}
2013-05-14 18:15:35 +04:00
func (m *Mapping) prepare() {
for name, t := range m.Tables {
2013-05-13 15:58:44 +04:00
t.FillFieldKeys()
2013-05-14 18:15:35 +04:00
t.Name = name
2013-05-13 15:58:44 +04:00
}
}
func (m *Mapping) mappings(tableType string, mappings map[string]map[string][]string) {
for name, t := range m.Tables {
if t.Type != tableType {
continue
}
for key, vals := range t.Mappings() {
for _, v := range vals {
vals, ok := mappings[key]
if ok {
vals[v] = append(vals[v], name)
} else {
mappings[key] = make(map[string][]string)
mappings[key][v] = append(mappings[key][v], name)
}
}
}
}
}
2013-05-14 18:15:35 +04:00
func (m *Mapping) tables(tableType string) map[string]*TableFields {
result := make(map[string]*TableFields)
for name, t := range m.Tables {
if t.Type == tableType {
result[name] = t.TableFields()
}
}
return result
}
2013-05-13 15:58:44 +04:00
func (m *Mapping) extraTags(tableType string, tags map[string]bool) {
for _, t := range m.Tables {
if t.Type != tableType {
continue
}
for key, _ := range t.ExtraTags() {
tags[key] = true
}
}
}
func (m *Mapping) NodeTagFilter() *TagFilter {
mappings := make(map[string]map[string][]string)
m.mappings("point", mappings)
tags := make(map[string]bool)
m.extraTags("point", tags)
return &TagFilter{mappings, tags}
}
func (m *Mapping) WayTagFilter() *TagFilter {
mappings := make(map[string]map[string][]string)
m.mappings("linestring", mappings)
m.mappings("polygon", mappings)
tags := make(map[string]bool)
m.extraTags("linestring", tags)
m.extraTags("polygon", tags)
return &TagFilter{mappings, tags}
}
func (m *Mapping) RelationTagFilter() *TagFilter {
mappings := make(map[string]map[string][]string)
m.mappings("linestring", mappings)
m.mappings("polygon", mappings)
tags := make(map[string]bool)
m.extraTags("linestring", tags)
m.extraTags("polygon", tags)
return &TagFilter{mappings, tags}
}
2013-05-14 18:15:35 +04:00
func (m *Mapping) PointMatcher() *TagMatcher {
mappings := make(map[string]map[string][]string)
m.mappings("point", mappings)
2013-05-14 18:15:35 +04:00
return &TagMatcher{mappings, m.tables("point")}
}
2013-05-14 18:15:35 +04:00
func (m *Mapping) LineStringMatcher() *TagMatcher {
mappings := make(map[string]map[string][]string)
m.mappings("linestring", mappings)
2013-05-14 18:15:35 +04:00
return &TagMatcher{mappings, m.tables("linestring")}
}
2013-05-14 18:15:35 +04:00
func (m *Mapping) PolygonMatcher() *TagMatcher {
mappings := make(map[string]map[string][]string)
m.mappings("polygon", mappings)
2013-05-14 18:15:35 +04:00
return &TagMatcher{mappings, m.tables("polygon")}
}
2013-05-13 15:58:44 +04:00
type TagFilter struct {
mappings map[string]map[string][]string
extraTags map[string]bool
}
type RelationTagFilter struct {
TagFilter
}
func (f *TagFilter) Filter(tags map[string]string) bool {
foundMapping := false
for k, v := range tags {
values, ok := f.mappings[k]
if ok {
if _, ok := values["__any__"]; ok {
foundMapping = true
continue
} else if _, ok := values[v]; ok {
foundMapping = true
continue
} else {
delete(tags, k)
}
} else if _, ok := f.extraTags[k]; !ok {
delete(tags, k)
}
}
if foundMapping {
return true
} else {
return false
}
}
func (f *RelationTagFilter) Filter(tags map[string]string) bool {
if t, ok := tags["type"]; ok {
if t != "multipolygon" || t != "boundary" || t != "land_area" {
return false
}
} else {
return false
}
return f.TagFilter.Filter(tags)
}
2013-05-14 18:15:35 +04:00
type TagMatcher struct {
mappings map[string]map[string][]string
tables map[string]*TableFields
}
2013-05-13 15:58:44 +04:00
2013-05-14 18:15:35 +04:00
type Match struct {
Key string
Value string
Table string
tableFields *TableFields
}
func (m *Match) Row(elem *element.OSMElem) []interface{} {
return m.tableFields.MakeRow(elem, *m)
}
func (tagMatcher *TagMatcher) Match(elem element.OSMElem) []Match {
tables := make(map[string]Match)
for k, v := range elem.Tags {
values, ok := tagMatcher.mappings[k]
2013-05-13 15:58:44 +04:00
if ok {
if tbls, ok := values["__any__"]; ok {
for _, t := range tbls {
2013-05-14 18:15:35 +04:00
tables[t] = Match{k, v, t, tagMatcher.tables[t]}
2013-05-13 15:58:44 +04:00
}
continue
} else if tbls, ok := values[v]; ok {
for _, t := range tbls {
2013-05-14 18:15:35 +04:00
tables[t] = Match{k, v, t, tagMatcher.tables[t]}
2013-05-13 15:58:44 +04:00
}
continue
}
}
}
2013-05-14 18:15:35 +04:00
var matches []Match
for _, match := range tables {
matches = append(matches, match)
2013-05-13 15:58:44 +04:00
}
2013-05-14 18:15:35 +04:00
return matches
2013-05-13 15:58:44 +04:00
}
func NewMapping(filename string) (*Mapping, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
decoder := json.NewDecoder(f)
mapping := Mapping{}
err = decoder.Decode(&mapping)
if err != nil {
return nil, err
}
2013-05-14 18:15:35 +04:00
mapping.prepare()
2013-05-13 15:58:44 +04:00
return &mapping, nil
}
func main() {
// data := `
// {
// "tables": {
// "roads": {
// "mapping": {
// "highway": [
// "motorway",
// "motorway_link",
// "trunk",
// "trunk_link"
// ]
// },
// "fields": {
// "tunnel": {"type": "bool", "key": "tunnel"},
// "bridge": {"type": "bool"},
// "oneway": {"type": "direction"},
// "ref": {"type": "string"},
// "z_order": {"type": "wayzorder", "key": "NONE"}
// }
// }
// }
// }
// `
// t := Table{map[string][]string{"highway": {"motorway", "trunk"}}}
// b, err := json.Marshal(t)
// if err != nil {
// log.Fatal(err)
// }
// log.Println(string(b))
flag.Parse()
mapping, err := NewMapping(flag.Arg(0))
if err != nil {
log.Fatal(err)
}
// log.Println(mapping.Mappings("point"))
// log.Println(mapping.ExtraTags("point"))
log.Println(mapping.NodeTagFilter())
log.Println(mapping.WayTagFilter())
log.Println(mapping.RelationTagFilter())
// log.Println(mapping)
// b, err := json.MarshalIndent(mapping, "", " ")
// if err != nil {
// log.Fatal(err)
// }
// log.Println(string(b))
}