-
Notifications
You must be signed in to change notification settings - Fork 50
/
index.js
84 lines (78 loc) · 3.38 KB
/
index.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
var isolines = require('@turf/isolines'),
grid = require('@turf/point-grid'),
bbox = require('@turf/bbox'),
destination = require('@turf/destination'),
point = require('@turf/helpers').point,
distance = require('@turf/distance'),
featureCollection = require('@turf/helpers').featureCollection,
OSRM = require('osrm');
module.exports = function (center, time, options, done) {
if (!options) throw 'options is mandatory';
if (!options.resolution) throw 'resolution is mandatory in options';
if (!options.network) throw 'network is mandatory in options';
if (!options.maxspeed) throw 'maxspeed is mandatory in options';
var unit = options.unit || 'miles';
if (options && options.draw) {
this.draw = options.draw;
} else {
this.draw = function(destinations) {
return isolines(destinations, 'eta', options.resolution, [time]);
};
}
this.getIsochrone = function() {
var osrm = options.network instanceof OSRM ? options.network : new OSRM(options.network);
// compute bboxGrid
// bboxGrid should go out 1.4 miles in each direction for each minute
// this will account for a driver going a bit above the max safe speed
var centerPt = point(center);
var spokes = featureCollection([]);
var length = (time/3600) * options.maxspeed;
spokes.features.push(destination(centerPt, length, 180, unit));
spokes.features.push(destination(centerPt, length, 0, unit));
spokes.features.push(destination(centerPt, length, 90, unit));
spokes.features.push(destination(centerPt, length, -90, unit));
var bboxGrid = this.bboxGrid = bbox(spokes);
var sizeCellGrid = this.sizeCellGrid = distance(point([bboxGrid[0], bboxGrid[1]]), point([bboxGrid[0], bboxGrid[3]]), unit) / options.resolution;
//compute destination grid
var targets = grid(bboxGrid, sizeCellGrid, unit);
targets.features = targets.features.filter(function(feat) {
return distance(point(feat.geometry.coordinates), centerPt, unit) <= length;
});
var destinations = featureCollection([]);
var coord = targets.features.map(function(feat) {
return feat.geometry.coordinates;
});
coord.push(center);
var sources = coord.length - 1;
var tableOptions = {
coordinates: coord,
sources: [sources]
}
osrm.table(tableOptions, function(err, res) {
if (err) {
console.log(err);
return done(err);
}
res.durations[0].forEach(function(time, idx) {
var distanceMapped = distance(
point(coord[idx]),
point(res.destinations[idx].location),
unit
);
if (distanceMapped < sizeCellGrid) {
var dest = point(res.destinations[idx].location);
dest.properties = {};
dest.properties.eta = time;
destinations.features.push(dest);
}
});
var result = self.draw(destinations);
return done(null, result);
}
);
};
var self = this;
// in case module is called directly
if (this.process && this.process.title == 'node')
return getIsochrone();
}