1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
package main
import (
"context"
"log"
"os"
"github.com/paulmach/osm"
"github.com/paulmach/osm/osmpbf"
)
func read(ctx context.Context, file string, nodesCh chan Node, waysCh chan Way, relationsCh chan Relation, concurrency int, layers []string) error {
f, err := os.Open(file)
if err != nil {
return err
}
defer f.Close()
scanner := osmpbf.New(context.Background(), f, concurrency)
defer scanner.Close()
layersToImport := map[string]bool{
"ways": false,
"nodes": false,
"relations": false,
}
for _, l := range layers {
layersToImport[l] = true
}
for scanner.Scan() {
if ctx.Err() != nil {
return ctx.Err()
}
o := scanner.Object()
switch o := o.(type) {
case *osm.Way:
if !layersToImport["ways"] {
continue
}
nodes := make([]int64, 0, len(o.Nodes))
for _, v := range o.Nodes {
nodes = append(nodes, int64(v.ID))
}
w := Way{
OsmID: int64(o.ID),
Tags: convertTags(o.Tags),
Nodes: nodes,
Timestamp: o.Timestamp,
Version: o.Version,
Visible: o.Visible,
}
waysCh <- w
case *osm.Node:
if !layersToImport["nodes"] {
continue
}
n := Node{
OsmID: int64(o.ID),
Location: Coords{
Type: "Point",
Coordinates: []float64{
o.Lon,
o.Lat,
}},
Tags: convertTags(o.Tags),
Version: o.Version,
Timestamp: o.Timestamp,
Visible: o.Visible,
}
nodesCh <- n
case *osm.Relation:
if !layersToImport["relations"] {
continue
}
members := make([]Member, 0, len(o.Members))
for _, v := range o.Members {
var location *Coords
if v.Lat != 0.0 && v.Lon != 0.0 {
location = &Coords{
Type: "Point",
Coordinates: []float64{
v.Lon,
v.Lat,
}}
}
members = append(members, Member{
Type: v.Type,
Version: v.Version,
Orientation: v.Orientation,
Ref: v.Ref,
Role: v.Role,
Location: location,
})
}
r := Relation{
OsmID: int64(o.ID),
Tags: convertTags(o.Tags),
Version: o.Version,
Timestamp: o.Timestamp,
Visible: o.Visible,
Members: members,
}
relationsCh <- r
}
}
log.Println("Read done")
scanErr := scanner.Err()
if scanErr != nil {
return scanErr
}
return nil
}
|