Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add markers for pickup and dropoff for each trip #216

Merged
merged 4 commits into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,14 @@ class App extends React.Component {
},
{
id: "showTraffic",
name: "Traffic",
name: "Live Traffic",
docLink: "https://github.com/googlemaps/fleet-debugger/blob/main/README.md",
columns: [],
solutionTypes: ["ODRD", "LMFS"],
},
{
id: "showLiveJS",
name: "Start Live Journey Sharing for newest trip",
name: "Live Journey Sharing",
docLink: "https://github.com/googlemaps/fleet-debugger/blob/main/README.md",
columns: [],
solutionTypes: ["ODRD", "LMFS"],
Expand Down
93 changes: 13 additions & 80 deletions src/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import Utils, { log } from "./Utils";
import PolylineCreation from "./PolylineCreation";
import { decode } from "s2polyline-ts";
import TrafficPolyline from "./TrafficPolyline";
import { TripObjects } from "./TripObjects";
import { getColor } from "./Trip";

let minDate;
let maxDate;
let allPaths = [];
let allMarkers = [];
let map;
let apikey;
let mapId;
Expand All @@ -24,7 +24,6 @@ let panorama;
let jwt;
let projectId;
let locationProvider;
let solutionType;
let tripLogs;
let taskLogs;
let setFeaturedObject;
Expand All @@ -37,62 +36,24 @@ const render = (status) => {
};

function addTripPolys(map) {
_.forEach(allPaths, (p) => p.setMap(null));
allPaths = [];
_.forEach(allMarkers, (m) => m.setMap(null));
allMarkers = [];

const tripObjects = new TripObjects({
map,
setFeaturedObject,
setTimeRange,
});
const trips = tripLogs.getTrips();
const vehicleBounds = new window.google.maps.LatLngBounds();
let lastVehicleCoords;

_.forEach(trips, (trip) => {
tripObjects.addTripVisuals(trip, minDate, maxDate);

// Update bounds
const tripCoords = trip.getPathCoords(minDate, maxDate);
if (tripCoords.length > 0) {
lastVehicleCoords = _.last(tripCoords);
const path = new window.google.maps.Polyline({
path: tripCoords,
geodesic: true,
strokeColor: getColor(trip.tripIdx),
strokeOpacity: 0.5,
strokeWeight: 6,
});
google.maps.event.addListener(path, "mouseover", () => {
path.setOptions({
strokeOpacity: 1,
strokeWeight: 8,
});
});
google.maps.event.addListener(path, "mouseout", () => {
path.setOptions({
strokeOpacity: 0.5,
strokeWeight: 6,
});
});
google.maps.event.addListener(path, "click", () => {
const fd = trip.getFeaturedData();
setFeaturedObject(fd);
// TODO: https://github.com/googlemaps/fleet-debugger/issues/79
// this time range won't capture the createTrip logs
setTimeRange(fd.firstUpdate.getTime(), fd.lastUpdate.getTime());
});
getPolyBounds(vehicleBounds, path);
path.setMap(map);
allPaths.push(path);
tripCoords.forEach((coord) => vehicleBounds.extend(coord));
}
});
if (lastVehicleCoords) {
const urlBase = "http://maps.google.com/mapfiles/kml/shapes/";
const lastVehicleLocMark = new window.google.maps.Marker({
position: lastVehicleCoords,
map: map,
icon: {
url: urlBase + (solutionType === "LMFS" ? "truck.png" : "cabs.png"),
scaledSize: new google.maps.Size(18, 18),
},
title: "Last Location",
});
allMarkers.push(lastVehicleLocMark);
}

return vehicleBounds;
}

Expand Down Expand Up @@ -204,11 +165,6 @@ function MyMapComponent(props) {
_.get(props.selectedRow, "lastlocation.currentroutesegment");

if (routeSegment) {
log("Processing new route segment polyline:", {
rowTimestamp: props.selectedRow.timestamp,
polyline: routeSegment,
});

try {
const decodedPoints = decode(routeSegment);

Expand All @@ -218,12 +174,6 @@ function MyMapComponent(props) {
lng: point.lngDegrees(),
}));

log("Creating new polyline with", {
points: validWaypoints.length,
firstPoint: validWaypoints[0],
lastPoint: validWaypoints[validWaypoints.length - 1],
});

const trafficRendering =
_.get(props.selectedRow, "request.vehicle.currentroutesegmenttraffic.trafficrendering") ||
_.get(props.selectedRow, "lastlocation.currentroutesegmenttraffic.trafficrendering");
Expand Down Expand Up @@ -389,22 +339,6 @@ function MyMapComponent(props) {
);
}

function getPolyBounds(bounds, p) {
p.getPath().forEach((e) => {
bounds.extend(e);
});
return bounds;
}

/*
* Deterministically assign a color per trip using tripIdx
* Colors were chosen for visibility
*/
function getColor(tripIdx) {
const colors = ["#2d7dd2", "#97cc04", "#eeb902", "#f45d01", "#474647", "00aa00"];
return colors[tripIdx % colors.length];
}

function Map(props) {
tripLogs = props.logData.tripLogs;
taskLogs = props.logData.taskLogs;
Expand All @@ -415,7 +349,6 @@ function Map(props) {
mapId = urlParams.get("mapId") || props.logData.mapId;
jwt = props.logData.jwt;
projectId = props.logData.projectId;
solutionType = props.logData.solutionType;
setFeaturedObject = props.setFeaturedObject;
setTimeRange = props.setTimeRange;

Expand Down
5 changes: 0 additions & 5 deletions src/TrafficPolyline.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ export class TrafficPolyline {
},
...(trafficRendering.roadstretch || []),
];

log("Added traveled route segment:", {
lengthMeters: distanceInMeters,
segments: trafficRendering.roadstretch.length,
});
}
} catch (error) {
log("Error calculating traveled route segment:", error);
Expand Down
33 changes: 33 additions & 0 deletions src/Trip.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,38 @@ class Trip {
getPlannedPath() {
return this.plannedPath;
}

getPoint(type, path) {
return _.get(
_.find(this.logs, (log) => log["@type"] === type && _.get(log, path)),
path
);
}

getPickupPoint() {
return this.getPoint("createTrip", "request.trip.pickuppoint.point");
}

getDropoffPoint() {
return this.getPoint("createTrip", "request.trip.dropoffpoint.point");
}

getActualPickupPoint() {
return this.getPoint("updateTrip", "response.actualpickuppoint.point");
}

getActualDropoffPoint() {
return this.getPoint("updateTrip", "response.actualdropoffpoint.point");
}
}

/*
* Deterministically assign a color per trip using tripIdx
* Colors were chosen for visibility
*/
export function getColor(tripIdx) {
const colors = ["#2d7dd2", "#97cc04", "#eeb902", "#f45d01", "#474647", "00aa00"];
return colors[tripIdx % colors.length];
}

export { Trip as default };
30 changes: 25 additions & 5 deletions src/TripLogs.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,17 +446,38 @@ class TripLogs {
let tripIdx = 0;
let nonTripIdx = 0;
let lastTripStatus = "no status";
// assumes logs are already sorted
// also assumes out-of-order updates can't happen. Unclear
// if this is a good assumption, but it might be worth it to call out
// places where it happens (since that might actually be a client bug).

// First, create a map of trip IDs to their logs
const tripLogs = new Map();

// Collect all trip-related logs
_.forEach(this.rawLogs, (le) => {
if (le["@type"] === "createTrip" || le["@type"] === "updateTrip") {
const tripId = le.request?.tripid || _.get(le, "request.trip.name");
if (tripId) {
if (!tripLogs.has(tripId)) {
tripLogs.set(tripId, []);
}
tripLogs.get(tripId).push(le);
}
}
});

// Process vehicle updates and create trip segments
_.forEach(this.rawLogs, (le) => {
if (le["@type"] === "updateVehicle" || le["@type"] === "updateDeliveryVehicle") {
const newTripId = this.getSegmentID(le);
if (newTripId !== curTripId) {
curTripId = newTripId;
const tripName = newTripId ? newTripId : "non-trip-segment-" + nonTripIdx;
curTripData = new Trip(tripIdx, tripName, new Date(le.timestamp));

// If this is an actual trip (not a non-trip-segment), add its logs
if (tripLogs.has(newTripId)) {
curTripData.logs = tripLogs.get(newTripId);
log(`Added ${curTripData.logs.length} logs to trip ${newTripId}`);
}

this.trips.push(curTripData);
this.trip_ids.push(curTripData.tripName);

Expand All @@ -479,7 +500,6 @@ class TripLogs {
}
}
const tripStatus = _.get(le, "response.tripstatus");
// if the logs had a trip status, and it changed update
if (tripStatus && tripStatus !== lastTripStatus) {
this.tripStatusChanges.push({
newStatus: tripStatus,
Expand Down
Loading
Loading