diff --git a/lib/get-surface.js b/lib/get-surface.js index f25d077..1aba63e 100644 --- a/lib/get-surface.js +++ b/lib/get-surface.js @@ -10,12 +10,16 @@ import {getNonTransitTime, ITERATION_WIDTH} from './origin' */ export default function getSurface ({origin, query, stopTreeCache, which}) { const surface = new Uint8Array(query.width * query.height) + const waitTimes = new Uint8Array(query.width * query.height) + const inVehicleTravelTimes = new Uint8Array(query.width * query.height) const transitOffset = getTransitOffset(origin.data[0]) // how many departure minutes are there. skip number of stops const nMinutes = origin.data[transitOffset + 1] - const travelTimes = new Uint8Array(nMinutes) + const travelTimesForDest = new Uint8Array(nMinutes) // the total travel time per iteration to reach a particular destination + const waitTimesForDest = new Uint8Array(nMinutes) // wait time per iteration for particular destination + const inVehicleTravelTimesForDest = new Uint8Array(nMinutes) // in-vehicle travel time per destination // store the number of minutes at which each cell is reached within the given cutoff // so we can calculate accessibility with arbitrary grids later @@ -33,7 +37,9 @@ export default function getSurface ({origin, query, stopTreeCache, which}) { const nonTransitTime = getNonTransitTime(origin, {x, y}) // fill with unreachable, or the walk distance - fill(travelTimes, nonTransitTime) + fill(travelTimesForDest, nonTransitTime) + fill(waitTimesForDest, 255) + fill(inVehicleTravelTimesForDest, 255) for (let stopIdx = 0; stopIdx < nStops; stopIdx++) { // read the stop ID @@ -49,19 +55,27 @@ export default function getSurface ({origin, query, stopTreeCache, which}) { if (travelTimeToStop !== -1) { const travelTimeToPixel = travelTimeToStop + time - // no need to check that travelTimeToPixel < 255 as travelTimes[minute] is preinitialized to 255 - if (travelTimes[minute] > travelTimeToPixel) travelTimes[minute] = travelTimeToPixel + // no need to check that travelTimeToPixel < 255 as travelTimesForDest[minute] is preinitialized to the nontransit time or 255 + if (travelTimesForDest[minute] > travelTimeToPixel) { + travelTimesForDest[minute] = travelTimeToPixel + inVehicleTravelTimesForDest[minute] = origin.data[offset + 1] + waitTimesForDest[minute] = origin.data[offset + 2] + + if (origin.data[offset + 2] > 254) console.log(`data value ${origin.data[offset + 2]}`) + } } } } // compute and set value for pixel - surface[pixelIdx] = computePixelValue(which, travelTimes) + surface[pixelIdx] = computePixelValue(which, travelTimesForDest) + waitTimes[pixelIdx] = computePixelValue(which, waitTimesForDest) + inVehicleTravelTimes[pixelIdx] = computePixelValue(which, inVehicleTravelTimesForDest) // compute access values - for (let i = 0; i < travelTimes.length; i++) { + for (let i = 0; i < travelTimesForDest.length; i++) { for (let cutoffIdx = 0, cutoffTime = 5; cutoffIdx < access.length; cutoffIdx++, cutoffTime += 5) { - if (travelTimes[i] < cutoffTime) access[cutoffIdx][y * query.width + x]++ + if (travelTimesForDest[i] < cutoffTime) access[cutoffIdx][y * query.width + x]++ } } } @@ -70,6 +84,8 @@ export default function getSurface ({origin, query, stopTreeCache, which}) { return { surface, access, + waitTimes, + inVehicleTravelTimes, query, nMinutes // TODO already present in query } diff --git a/lib/get-transitive-data.js b/lib/get-transitive-data.js index dedce86..6ca5649 100644 --- a/lib/get-transitive-data.js +++ b/lib/get-transitive-data.js @@ -6,7 +6,7 @@ import fill from 'lodash.fill' import slice from 'lodash.slice' import {pixelToLat, pixelToLon} from './mercator' -import {getNonTransitTime} from './origin' +import {getNonTransitTime, ITERATION_WIDTH} from './origin' const debug = dbg('browsochrones:get-transitive-data') @@ -219,8 +219,8 @@ export function getPaths ({origin, to, stopTreeCache, query}) { // minute, stopTime and pathIdx are delta-coded _per stop_ for (let minute = 0, stopTime = 0, pathIdx = 0; minute < origin.nMinutes; minute++) { - stopTime = origin.data[originOffset + minute * 2] - pathIdx = origin.data[originOffset + minute * 2 + 1] + stopTime = origin.data[originOffset + minute * ITERATION_WIDTH] + pathIdx = origin.data[originOffset + minute * ITERATION_WIDTH + 3] // reachable at this minute if (stopTime !== -1) { @@ -247,7 +247,7 @@ export function getPath ({pathDescriptor, origin}) { const [ stop, pathIdx ] = pathDescriptor if (stop === -1) return [] // offset to the first path, skipping times and nPaths - let offset = origin.index[stop] + origin.nMinutes * 2 + 1 + let offset = origin.index[stop] + origin.nMinutes * ITERATION_WIDTH + 1 // seek forward to correct path let curIdx = 0 diff --git a/lib/origin.js b/lib/origin.js index 3abdd90..58b68a3 100644 --- a/lib/origin.js +++ b/lib/origin.js @@ -44,7 +44,6 @@ export function create (data, point) { // de delta code times and paths for (let min = 0, tvlTime = 0, inVehicleTravelTime = 0, waitTime = 0, path = 0; min < nMinutes; min++) { tvlTime += origin.data[offset + min * ITERATION_WIDTH] - // don't divide -1 (unreachable) by 60 as that will yield 0 (reachable very quickly) origin.data[offset + min * ITERATION_WIDTH] = tvlTime inVehicleTravelTime += origin.data[offset + min * ITERATION_WIDTH + 1] @@ -54,7 +53,7 @@ export function create (data, point) { origin.data[offset + min * ITERATION_WIDTH + 2] = waitTime path += origin.data[offset + min * ITERATION_WIDTH + 3] - origin.data[offset + min * ITERATION_WIDTH + 1] = path + origin.data[offset + min * ITERATION_WIDTH + 3] = path } // skip the times diff --git a/lib/worker-handlers.js b/lib/worker-handlers.js index e833eef..b1b9435 100644 --- a/lib/worker-handlers.js +++ b/lib/worker-handlers.js @@ -69,7 +69,9 @@ module.exports = createHandler({ stopTreeCache: ctx.stopTreeCache, to: point }), - travelTime: ctx.surface.surface[point.y * ctx.query.width + point.x] + travelTime: ctx.surface.surface[point.y * ctx.query.width + point.x], + waitTime: ctx.surface.waitTimes[point.y * ctx.query.width + point.x], + inVehicleTravelTime: ctx.surface.inVehicleTravelTimes[point.y * ctx.query.width + point.x] } }, generateTransitiveData (ctx, message) {