function parseActivities(historyStr) {
const weCareAboutActivityType = function(type) {
return ['FLYING', 'IN_VEHICLE', 'IN_PASSENGER_VEHICLE', 'IN_TAXI'].includes(type);
}
const weCareAboutActivity = function(activitySegment) {
return activitySegment && activitySegment.distance && weCareAboutActivityType(activitySegment.activityType);
}
const activityTypeToTransportationMode = function(type) {
switch(type) {
case 'FLYING':
return 'Air';
case 'IN_TAXI':
case 'IN_PASSENGER_VEHICLE':
case 'IN_VEHICLE':
return 'Road';
default:
return type;
}
}
const preProcessActivity = function (activitySegment) {
const FLIGHT_MIN_DISTANCE_KM = 500;
const FLIGHT_MIN_AVERAGE_SPEED_KMH = 300;
const FLIGHT_MAX_AVERAGE_SPEED_KMH = 1000;
const CAR_MAX_DISTANCE_KM = 1000;
const CAR_MIN_DISTANCE_KM = 50;
const CAR_MAX_AVERAGE_SPEED_KMH = 130;
const CAR_MIN_AVERAGE_SPEED_KMH = 50;
// we need duration to compute speed.
if( !activitySegment
|| !activitySegment.duration
|| !activitySegment.duration.endTimestampMs
|| !activitySegment.duration.startTimestampMs) {
return;
}
const speedKmH = function(activitySegment) {
const km = activitySegment.distance / 1000;
const h = (activitySegment.duration.endTimestampMs - activitySegment.duration.startTimestampMs) / (1000 * 60 * 60);
return km / h;
}
if(activitySegment.distance > FLIGHT_MIN_DISTANCE_KM * 1000
&& speedKmH(activitySegment) > FLIGHT_MIN_AVERAGE_SPEED_KMH
&& speedKmH(activitySegment) < FLIGHT_MAX_AVERAGE_SPEED_KMH) {
activitySegment.activityType = 'FLYING';
return;
}
if(activitySegment.distance > CAR_MIN_DISTANCE_KM * 1000
&& activitySegment.distance < CAR_MAX_DISTANCE_KM * 1000
&& speedKmH(activitySegment) > CAR_MIN_AVERAGE_SPEED_KMH
&& speedKmH(activitySegment) < CAR_MAX_AVERAGE_SPEED_KMH) {
activitySegment.activityType = 'IN_PASSENGER_VEHICLE';
return;
}
}
const history = JSON.parse(historyStr)
if(!history.timelineObjects) { return; }
let activities = [];
history.timelineObjects.forEach(timelineObject => {
const activitySegment = timelineObject.activitySegment;
preProcessActivity(activitySegment);
if(weCareAboutActivity(activitySegment)) {
const activity = {
id: activitySegment.duration.startTimestampMs,
datetime: new Date(parseInt(activitySegment.duration.startTimestampMs, 10)),
durationHours: (activitySegment.duration.endTimestampMs - activitySegment.duration.startTimestampMs) / (1000 * 60 * 60),
distanceKilometers: activitySegment.distance / 1000,
activityType: 'ACTIVITY_TYPE_TRANSPORTATION',
transportationMode: activityTypeToTransportationMode(activitySegment.activityType),
};
activities.push(activity);
}
// For Debug only
else if(activitySegment
&& !['WALKING', 'IN_SUBWAY', 'CYCLING', 'SAILING', 'BOATING', 'IN_BUS', 'HIKING', 'IN_TRAIN'].includes(activitySegment.activityType)
&& activitySegment.distance > 100 * 1000
&& (activitySegment.duration.endTimestampMs - activitySegment.duration.startTimestampMs) > 1000 * 60 * 60
) {
console.log(activitySegment);
}
})
return activities;
}