FragmentedPath = {
const FragmentedPath = function(stopInfos, stops){
const distTot = stopInfos[stopInfos.length-1].dist
this.nodes = _.map(stopInfos, (si) => {
return {
stop: stops[si.stopId],
dist: si.dist,
distRatio: si.dist/distTot
}
})
this.dist = distTot
}
yield FragmentedPath
FragmentedPath.prototype.stopBracket = function(ratio){
const self = this;
if(ratio <=0){
return [undefined, self.nodes[0]]
}
const iMax = self.nodes.length-1
if(ratio >= 1){
return [self.nodes[iMax], undefined]
}
const dist=ratio*self.dist
return _.chain(_.take(self.nodes, iMax))
.zip(_.tail(self.nodes))
.find((p)=> dist <= p[1].dist)
.value()
}
FragmentedPath.prototype.interpolatePosition = function(ratio){
const self = this;
const seg = self.stopBracket(ratio)
if(seg[0] === undefined){
return seg[1].stop.coords
}
if(seg[1] === undefined){
return seg[0].stop.coords
}
const r = (ratio-seg[0].distRatio)/(seg[1].distRatio-seg[0].distRatio)
return {
lat: seg[0].stop.coords.lat + r*(seg[1].stop.coords.lat-seg[0].stop.coords.lat),
lon: seg[0].stop.coords.lon + r*(seg[1].stop.coords.lon-seg[0].stop.coords.lon),
}
}
FragmentedPath.prototype.interpolatePartial = function(ratio0, ratio1){
const self = this;
const dist0 = ratio0*self.dist
const dist1 = ratio1*self.dist
const intraNodes = _.chain(self.nodes)
.dropWhile((n)=> n.dist < dist0 )
.tail()
.takeWhile((n)=> dist1 > n.dist)
.map((n)=>n.stop.coords)
.value()
return _.concat(
self.interpolatePosition(ratio0),
intraNodes,
self.interpolatePosition(ratio1)
)
}
}