sharedstreets
Version:
SharedStreets, a 'digital commons' for the street
387 lines (386 loc) • 18.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.WeeklySharedStreetsLinearBins = exports.PeriodSize = exports.generateBinId = exports.getBinPositionFromLocation = exports.getBinLength = exports.getBinCountFromLength = void 0;
const linearProto = require('./proto/linear.js');
var fs = require('fs');
const tileHierarchy = 6;
const tileSource = 'osm';
const tileBuild = 'planet-180430';
function getBinCountFromLength(referenceLength, binSize) {
var numBins = Math.floor(referenceLength / binSize) + 1;
return numBins;
}
exports.getBinCountFromLength = getBinCountFromLength;
function getBinLength(referenceLength, binSize) {
return referenceLength / getBinCountFromLength(referenceLength, binSize);
}
exports.getBinLength = getBinLength;
function getBinPositionFromLocation(referenceLength, binSize, location) {
var bin = Math.floor(location / getBinLength(referenceLength, binSize)) + 1;
return bin;
}
exports.getBinPositionFromLocation = getBinPositionFromLocation;
function generateBinId(referenceId, binCount, binPosition) {
var binId = referenceId + "{" + binCount;
if (binPosition)
binId = binId + ":" + binPosition;
return binId;
}
exports.generateBinId = generateBinId;
var PeriodSize;
(function (PeriodSize) {
PeriodSize[PeriodSize["OneSecond"] = 0] = "OneSecond";
PeriodSize[PeriodSize["FiveSeconds"] = 1] = "FiveSeconds";
PeriodSize[PeriodSize["TenSeconds"] = 2] = "TenSeconds";
PeriodSize[PeriodSize["FifteenSeconds"] = 3] = "FifteenSeconds";
PeriodSize[PeriodSize["ThirtySeconds"] = 4] = "ThirtySeconds";
PeriodSize[PeriodSize["OneMinute"] = 5] = "OneMinute";
PeriodSize[PeriodSize["FiveMinutes"] = 6] = "FiveMinutes";
PeriodSize[PeriodSize["TenMinutes"] = 7] = "TenMinutes";
PeriodSize[PeriodSize["FifteenMinutes"] = 8] = "FifteenMinutes";
PeriodSize[PeriodSize["ThirtyMinutes"] = 9] = "ThirtyMinutes";
PeriodSize[PeriodSize["OneHour"] = 10] = "OneHour";
PeriodSize[PeriodSize["OneDay"] = 11] = "OneDay";
PeriodSize[PeriodSize["OneWeek"] = 12] = "OneWeek";
PeriodSize[PeriodSize["OneMonth"] = 13] = "OneMonth";
PeriodSize[PeriodSize["OneYear"] = 14] = "OneYear";
})(PeriodSize = exports.PeriodSize || (exports.PeriodSize = {}));
class SharedStreetsBin {
}
class SharedStreetsLinearBins {
constructor(referenceId, referenceLength, numberOfBins) {
this.referenceId = referenceId;
this.referenceLength = referenceLength;
this.numberOfBins = numberOfBins; // defaults to one bin
this.bins = {};
}
getId() {
return generateBinId(this.referenceId, this.numberOfBins, null);
}
addBin(binPosition, type, count, value) {
var bin = new SharedStreetsBin();
bin.type = type;
bin.count = count;
bin.value = value;
this.bins[binPosition] = bin;
}
}
class WeeklySharedStreetsLinearBins extends SharedStreetsLinearBins {
constructor(referenceId, referenceLength, numberOfBins, periodSize) {
super(referenceId, referenceLength, numberOfBins);
this.periodSize = periodSize;
}
addPeriodBin(binPosition, period, type, count, value) {
var bin = new SharedStreetsBin();
bin.type = type;
bin.count = count;
bin.value = value;
if (!this.bins[binPosition]) {
this.bins[binPosition] = {};
}
this.bins[binPosition][period] = bin;
}
getFilteredBins(binPosition, typeFilter, periodFilter) {
var filteredBins = [];
if (this.bins[binPosition]) {
for (var period of Object.keys(this.bins[binPosition])) {
if (periodFilter) {
if (parseInt(period) < periodFilter[0] || parseInt(period) > periodFilter[1])
continue;
}
if (typeFilter) {
if (typeFilter !== this.bins[binPosition][period].type)
continue;
}
filteredBins.push(this.bins[binPosition][period]);
}
}
return filteredBins;
}
getHourOfDaySummary(typeFilter) {
var filteredBins = new Map();
for (var binPosition of Object.keys(this.bins)) {
for (var period of Object.keys(this.bins[binPosition])) {
var hourOfDay = (parseInt(period) % 23);
if (hourOfDay > 23)
hourOfDay = hourOfDay - 23;
if (hourOfDay <= 0)
hourOfDay = hourOfDay + 23;
if (typeFilter) {
if (typeFilter !== this.bins[binPosition][period].type)
continue;
}
if (!filteredBins[hourOfDay])
filteredBins[hourOfDay] = [];
filteredBins[hourOfDay].push(this.bins[binPosition][period]);
}
}
return filteredBins;
}
getValueForBin(binPosition, typeFilter, periodFilter) {
var sum = 0;
var filteredBins = this.getFilteredBins(binPosition, typeFilter, periodFilter);
for (var bin of filteredBins) {
sum = sum + bin.value;
}
return sum;
}
getCountForHoursOfDay(typeFilter) {
var summary = this.getHourOfDaySummary(typeFilter);
var hourOfDayCount = {};
for (var hourOfDay of Object.keys(summary)) {
hourOfDayCount[hourOfDay] = 0;
for (var bin of summary[hourOfDay]) {
hourOfDayCount[hourOfDay] = hourOfDayCount[hourOfDay] + bin.count;
}
}
return hourOfDayCount;
}
getCountForBin(binPosition, typeFilter, periodFilter) {
var sum = 0;
var filteredBins = this.getFilteredBins(binPosition, typeFilter, periodFilter);
for (var bin of filteredBins) {
sum = sum + bin.count;
}
return sum;
}
getCountForEdge(typeFilter, periodFilter) {
var sum = 0;
for (var binPosition = 0; binPosition < this.numberOfBins; binPosition++) {
var filteredBins = this.getFilteredBins(binPosition, typeFilter, periodFilter);
for (var bin of filteredBins) {
sum = sum + bin.count;
}
}
return sum;
}
}
exports.WeeklySharedStreetsLinearBins = WeeklySharedStreetsLinearBins;
function processTile(reader) {
var tileData = [];
while (reader.pos < reader.len) {
try {
var result = linearProto.SharedStreetsWeeklyBinnedLinearReferences.decodeDelimited(reader).toJSON();
var linearBins = new WeeklySharedStreetsLinearBins(result.referenceId, result.referenceLength, result.numberOfBins, PeriodSize.OneHour);
for (var i = 0; i < result.binPosition.length; i++) {
var binPosition = result.binPosition[i];
for (var j = 0; j < result.binnedPeriodicData[i].bins.length; j++) {
var period = result.binnedPeriodicData[i].periodOffset[j];
var bin = result.binnedPeriodicData[i].bins[j];
for (var h in bin.dataType) {
linearBins.addPeriodBin(binPosition, period, bin.dataType[h], parseInt(bin.count[h]), parseInt(bin.value[h]));
}
}
}
tileData.push(linearBins);
}
catch (e) {
console.log(e);
}
}
return tileData;
}
class BinReferenceData {
}
//export async function query(event, cache:LocalCache, callback) {
// var sourceTest = new RegExp("[a-z]{1,10}");
// var source = undefined;
// if(sourceTest.test(event.pathParameters.source)) {
// source = event.pathParameters.source;
// if(source === "dc_pudo" && event.queryStringParameters.authKey != "c890c855-b968-4952-8c0a-64cc2ca446c3") {
// callback(401, "Not authorized");
// return;
// }
// }
// var weekTest = new RegExp("([12]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01]))");
// var week = undefined;
// if(event.pathParameters.week === '2017-09-11' || weekTest.test(event.pathParameters.week))
// week = event.pathParameters.week;
// var tileKeyTest = new RegExp("^[0-9\-]*$");
// var tileKeys = undefined;
// if(tileKeyTest.test(event.pathParameters.tileKey)) {
// tileKeys = [];
// tileKeys.push(event.pathParameters.tileKey);
// }
// var typeFilter = null;
// if(event.queryStringParameters.typeFilter) {
// typeFilter = event.queryStringParameters.typeFilter;
// }
// var offset = 4;
// if(event.queryStringParameters.offset) {
// offset = parseInt(event.queryStringParameters.offset);
// }
// var normalizeByLength = false;
// if(event.queryStringParameters.normalizeByLength) {
// normalizeByLength = JSON.parse(event.queryStringParameters.normalizeByLength);
// }
// var periodFilter = null;
// if(event.queryStringParameters.periodFilter) {
// var periodFilterParts = event.queryStringParameters.periodFilter.split('-');
// periodFilter = [];
// periodFilter[0] = parseInt(periodFilterParts[0]);
// periodFilter[1] = parseInt(periodFilterParts[1]);
// }
// var bboxPolygon = undefined;
// if(event.queryStringParameters && event.queryStringParameters.bounds) {
// var bboxString = event.queryStringParameters.bounds;
// var bboxParts = bboxString.split(",").map((s) => {return Number.parseFloat(s)});
// if(bboxParts.length == 4) {
// var line = turfHelpers.lineString([[bboxParts[0],bboxParts[1]],[bboxParts[2],bboxParts[3]]]);
// var bbox = turfBbox(line);
// bboxPolygon = turfBboxPolygon(bbox);
// }
// tileKeys = getTileIdsForPolygon(bboxPolygon);
// }
// if(!source || !week || (!tileKeys && !bbox)) {
// callback(400, "Invalid request");
// return;
// }
// var indexedGeoms = undefined;
// var referenceIds = new Set<string>();
// var resultType = "bin";
// if(event.queryStringParameters && event.queryStringParameters.resultType) {
// if(event.queryStringParameters.resultType === "bin")
// resultType = "bin";
// else if(event.queryStringParameters.resultType === "summary")
// resultType = "summary";
// else if(event.queryStringParameters.resultType === "rank")
// resultType = "rank";
// else {
// callback(400, "Invalid request");
// return;
// }
// }
// if(event.queryStringParameters && event.queryStringParameters.referenceIds) {
// var referenceIdStrings = event.queryStringParameters.referenceIds.split(",");
// for(var referenceId of referenceIdStrings) {
// referenceIds.add(referenceId);
// }
// }
// else if(bboxPolygon) {
// var geometries = await cache.within('geometries', bboxPolygon,true, tileSource, tileBuild, tileHierarchy);
// for(var geometry of geometries) {
// var geomData = cache.idIndex[geometry.properties.id];
// referenceIds.add(geomData.forwardReferenceId);
// if(geomData.backReferenceId)
// referenceIds.add(geomData.backReferenceId);
// }
// }
// try {
// var results;
// if(resultType === "bin") {
// results = {type:"FeatureCollection", features:[]};
// var selectedCount = 0;
// for(var tileKey of tileKeys ) {
// var data:Uint8Array = await downloadPath(source + '/b/' + week + '/' + tileKey + '.events.pbf');
// var reader = new probuf_minimal.Reader(data)
// var tileData = processTile(reader);
// for(var linearBin of tileData) {
// if(!referenceIds.has(linearBin.referenceId))
// continue;
// var refData = cache.idIndex[linearBin.referenceId];
// var geomData = cache.idIndex[refData.geometryId];
// var refLength = getReferenceLength(refData);
// var binLength = refLength / linearBin.numberOfBins;
// var direction = ReferenceDirection.FORWARD;
// if(linearBin.referenceId === geomData.backReferenceId)
// direction = ReferenceDirection.BACKWARD;
// var binPoints = geometryToBins(geomData.feature,
// linearBin.referenceId,
// refLength,
// linearBin.numberOfBins,
// offset,
// direction,
// ReferenceSideOfStreet.RIGHT);
// for(var binPoint of binPoints) {
// var binPosition = binPoint.properties.bin;
// if(typeFilter)
// binPoint.properties['type'] = typeFilter;
// var periodRange = periodFilter[1] - periodFilter[0];
// var value = linearBin.getValueForBin(binPosition, typeFilter, periodFilter);
// var binCount = linearBin.getCountForBin(binPosition, typeFilter, periodFilter);
// var binCountByLength = binCount / binLength;
// var periodAverageCount = binCount / periodRange;
// binPoint.properties['binLength'] = Math.round(binLength * 100) / 100;
// binPoint.properties['periodAverageCount'] = Math.round(periodAverageCount * 100) / 100;
// if(binCount > 10)
// results.features.push(binPoint);
// }
// }
// }
// }
// else if(resultType === "rank") {
// results = {type:"FeatureCollection", features:[]};
// var unfilteredResults = {type:"FeatureCollection", features:[]};
// var edgeCounts:number[] = [];
// var selectedCount = 0;
// for(var tileKey of tileKeys ) {
// var data:Uint8Array = await downloadPath(source + '/b/' + week + '/' + tileKey + '.events.pbf');
// var reader = new probuf_minimal.Reader(data)
// var tileData = processTile(reader);
// for(var linearBin of tileData) {
// if(!referenceIds.has(linearBin.referenceId))
// continue;
// var refData = cache.idIndex[linearBin.referenceId];
// var geomData = cache.idIndex[refData.geometryId];
// var refLength = getReferenceLength(refData);
// var direction = ReferenceDirection.FORWARD;
// if(linearBin.referenceId === geomData.backReferenceId)
// direction = ReferenceDirection.BACKWARD;
// var edgeTotal = linearBin.getCountForEdge(typeFilter, periodFilter);
// if(normalizeByLength)
// edgeTotal = edgeTotal / refLength;
// edgeCounts.push(edgeTotal);
// if(edgeTotal > 0) {
// var curbGeom;
// if(direction === ReferenceDirection.FORWARD)
// curbGeom = lineOffset(geomData.feature, offset, {units: 'meters'});
// else {
// var reverseGeom = geomUtils.reverseLineString(geomData.feature);
// curbGeom = lineOffset(reverseGeom, offset, {units: 'meters'});
// }
// curbGeom.properties.edgeTotal = edgeTotal;
// unfilteredResults.features.push(curbGeom);
// }
// }
// }
// var sortedEdgeCounts = edgeCounts.sort();
// for(var edge of unfilteredResults.features) {
// var rank:number = quantileRankSorted(sortedEdgeCounts, edge.properties.edgeTotal);
// edge.properties['rank'] = Math.round(rank * 100) / 100;
// delete edge.properties['edgeTotal'];
// if(edge.properties['rank'] > 0.5) {
// results.features.push(edge);
// }
// }
// }
// else if(resultType === "summary") {
// results = {};
// var selectedCount = 0;
// for(var tileKey of tileKeys ) {
// var data:Uint8Array = await downloadPath(source + '/b/' + week + '/' + tileKey + '.events.pbf');
// var reader = new probuf_minimal.Reader(data)
// var tileData = processTile(reader);
// for(var linearBin of Object.values(tileData)) {
// if(!referenceIds.has(linearBin.referenceId))
// continue;
// var hourOfDayCount = linearBin.getCountForHoursOfDay(typeFilter);
// for(var hourOfDay of Object.keys(hourOfDayCount)) {
// if(!results[hourOfDay])
// results[hourOfDay] = 0;
// results[hourOfDay] = results[hourOfDay] + hourOfDayCount[hourOfDay];
// }
// }
// }
// for(var hourOfDay of Object.keys(results)) {
// results[hourOfDay] = results[hourOfDay] / 8000;
// }
// }
// callback(null, results);
// }
// catch(e) {
// console.log(e)
// callback(400, "Invalid request");
// return;
// }
// }