forked from anvaka/extract-osm-roads
-
Notifications
You must be signed in to change notification settings - Fork 0
/
extract.js
126 lines (102 loc) · 2.77 KB
/
extract.js
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
115
116
117
118
119
120
121
122
123
124
125
126
var fs = require('fs');
var inFileName = process.argv[2];
var outFileName = process.argv[3]
var osmread = require('osm-read');
var graph = require('ngraph.graph')();
var nodes = new Map();
var BBox = require('./bbox.js');
var bbox = new BBox();
osmread.parse({
filePath: inFileName,
endDocument: saveResults,
node: processOSMNode,
way: processOSMWay,
error: processOSMError
});
function processOSMWay(way) {
if (way.tags && way.tags.highway) {
var nodes = way.nodeRefs;
if (!nodes) {
console.log('no nodes', way)
return;
}
for (var i = 1; i < nodes.length; ++i) {
let from = nodes[i];
let to = nodes[i - 1];
graph.addLink(from, to);
}
}
}
function processOSMError() {
console.log('error');
}
function processOSMNode(node) {
bbox.addPoint(node.lon, node.lat);
nodes.set(node.id, {
lon: node.lon,
lat: node.lat
});
}
function saveResults() {
console.log('end');
var phi0 = Math.cos(bbox.cy);
var r = 6371393; // radius of earth in meters
var xyBBox = new BBox();
graph.forEachNode(node => {
let data = nodes.get(node.id);
if (!data) throw new Error('missing data for ' + node.id);
node.data = {
x: -Math.round(r * data.lon * phi0),
y: -Math.round(r * data.lat),
};
xyBBox.addPoint(node.data.x, node.data.y);
});
moveCoordinatesToZero();
writeGraph(outFileName, graph);
console.log(xyBBox);
function moveCoordinatesToZero() {
let dx = xyBBox.cx
let dy = xyBBox.cy;
let movedBbox = new BBox();
graph.forEachNode(node => {
node.data.x = Math.round(node.data.x - dx);
node.data.y = Math.round(node.data.y - dy);
movedBbox.addPoint(node.data.x, node.data.y);
});
console.log('moved bbox', movedBbox);
}
}
function writeGraph(fileName, graph) {
let nodeIdMap = new Map();
saveNodes(fileName + '.co.bin', graph, nodeIdMap);
saveLinks(fileName + '.gr.bin', graph, nodeIdMap);
}
function saveNodes(fileName, graph, nodeIdMap) {
var nodeCount = graph.getNodesCount();
var buf = new Buffer(nodeCount * 4 * 2);
var idx = 0;
graph.forEachNode(p => {
nodeIdMap.set(p.id, 1 + idx / 8);
buf.writeInt32LE(p.data.x, idx);
idx += 4;
buf.writeInt32LE(p.data.y, idx);
idx += 4;
});
fs.writeFileSync(fileName , buf);
console.log('Nodes saved to ', fileName);
}
function saveLinks(fileName, graph, nodeIdMap) {
var buf = new Buffer(graph.getLinksCount() * 4 * 2);
var idx = 0;
graph.forEachLink(l => {
let fromId = nodeIdMap.get(l.fromId);
let toId = nodeIdMap.get(l.toId);
if (!fromId || !toId) throw new Error('missing id')
buf.writeInt32LE(fromId, idx);
idx += 4;
buf.writeInt32LE(toId, idx);
idx += 4;
})
fs.writeFileSync(fileName, buf);
console.log('links saved to ', fileName);
}