-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.js
94 lines (84 loc) · 2.68 KB
/
build.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
'use strict'
const Flatbush = require('flatbush')
const merged = require('merged-vbb-stations')
const computeDistance = require('gps-distance')
const berlin = require('german-states-bbox').BE
const queryOverpass = require('@derhuerst/query-overpass')
const {writeFileSync} = require('fs')
const {join} = require('path')
let stations = require('vbb-stations/full.json')
stations = Object.values(stations).filter((s) => {
// filter child stations
const shouldMerge = s.id !== merged[s.id]
if (shouldMerge) console.warn('ignoring', s.id, s.name)
return !shouldMerge
})
const index = new Flatbush(stations.length);
for (const s of stations) {
const loc = s.location
index.add(loc.longitude, loc.latitude, loc.longitude, loc.latitude)
}
index.finish()
const nearby = (latitude, longitude, distance = .2) => {
return index.search(
longitude - distance / 100, // minX
latitude - distance / 100, // minY
longitude + distance / 100, // maxX
latitude + distance / 100 // maxY
)
.map((i) => {
const s = Object.assign({}, stations[i])
const loc = s.location
s.distance = computeDistance(latitude, longitude, loc.latitude, loc.longitude)
return s
})
.sort((a, b) => a.distance - b.distance)
}
const bbox = [
berlin.minLat, // south
berlin.minLon, // west
berlin.maxLat, // north
berlin.maxLon // east
]
queryOverpass(`
[out:json][timeout:60][bbox:${bbox.join(',')}];
node[amenity=bicycle_parking];
out body;
`)
.then((parkingRacks) => {
// station ID -> [[rack ID, rack capacity], ...]
const simple = Object.create(null)
// station ID -> [[rack ID, rack tags], ...]
const full = Object.create(null)
for (let rack of parkingRacks) {
let capacity = null
if ('capacity' in rack.tags) {
rack.tags.capacity = parseInt(rack.tags.capacity)
if (Number.isNaN(rack.tags.capacity)) {
console.warn(rack.id + '', 'has an invalid capacity')
continue
}
}
const close = nearby(rack.lat, rack.lon, .5)
if (close.length === 0) {
console.warn(rack.id + '', 'has no stations within .5km')
continue
}
const closest = close[0]
const secondClosest = close[1]
if (secondClosest && closest.distance / secondClosest.distance > .7) {
console.warn(rack.id + '', 'has two very similarly close stations')
continue
}
const sId = closest.id
if (simple[sId]) simple[sId].push([rack.id, rack.tags.capacity])
else simple[sId] = [[rack.id, rack.tags.capacity]]
if (full[sId]) full[sId].push([rack.id, rack.tags])
else full[sId] = [[rack.id, rack.tags]]
}
console.info('writing index.json')
writeFileSync(join(__dirname, 'index.json'), JSON.stringify(simple))
console.info('writing full.json')
writeFileSync(join(__dirname, 'full.json'), JSON.stringify(full))
})
.catch(console.error)