-
Notifications
You must be signed in to change notification settings - Fork 2.2k
[WIP] CARTO: Add TrajectoryTileLayer #9757
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
base: master
Are you sure you want to change the base?
Conversation
d89322f
to
b3494ce
Compare
in float vTime; | ||
`, | ||
// Drop the segments outside of the time window | ||
// Drop the segments outside of the time window, unless highlighted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: don't make changes in the TripsLayer
The code here makes the autohighlighting work with the full trajectory
Screen.Recording.2025-08-29.at.16.12.59.mov
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be a cool feature for the core layer too, especially if we don't have a highlight behavior today
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! Playback is perfectly smooth when testing here.
Only issues I ran into were related to picking:
- Picking on the sample dataset takes ~20ms and introduces some visible stuttering, mostly in a call to createRenderPipeline() each time.
- If I pause playback and then start picking segments, there's some visible inconsistency with the location of the mouse vs. the highlighted segment. In the screenshot below my mouse was at the center of the circle, but the orange "L" is the highlighted path:

Not sure if that indicates a glitch in rendering, in picking the right trip, or something else!
return deg * (Math.PI / 180); | ||
} | ||
|
||
function distanceBetweenPoints([lon1, lat1, lon2, lat2]: number[]): number { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the units of the return value of distanceBetweenPoints
? Might also be a good addition to @math.gl/*
at some point.
import type {ProcessedGeometry} from './trajectory-utils'; | ||
|
||
// Helper functions for speed calculation | ||
function deg2rad(deg: number): number { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional: There's toRadians
in @math.gl/core
, but it doesn't seem to be used elsewhere in the codebase so no strong preference here.
/** | ||
* Rendering mode for trajectories. | ||
* - 'paths': Static path rendering | ||
* - 'trips': Animated trip rendering with time controls | ||
*/ | ||
renderMode?: 'paths' | 'trips'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional: I slightly prefer your static | animated
naming from the comment over paths | trips
, I think it might be clearer.
if (!trajectoryIdColumn) { | ||
throw new Error( | ||
'TrajectoryTileLayer: trajectoryIdColumn is required in data source configuration' | ||
); | ||
} | ||
if (!timestampColumn) { | ||
throw new Error( | ||
'TrajectoryTileLayer: timestampColumn is required in data source configuration' | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional - sliiightly more concise/readable with an assert() here maybe?
const maxReasonableSpeed = 50000; // Max speed to prevent UI issues | ||
const minReasonableSpeed = 10; // Min speed for very short datasets | ||
const clampedSpeed = Math.max( | ||
minReasonableSpeed, | ||
Math.min(maxReasonableSpeed, calculatedSpeed) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use @math.gl/core
here, already a dependency?
const maxReasonableSpeed = 50000; // Max speed to prevent UI issues | |
const minReasonableSpeed = 10; // Min speed for very short datasets | |
const clampedSpeed = Math.max( | |
minReasonableSpeed, | |
Math.min(maxReasonableSpeed, calculatedSpeed) | |
); | |
// Clamp min speed for short datasets, and max speed to prevent UI issues. | |
const clampedSpeed = clamp(calculatedSpeed, 10, 50000); |
|
||
// CARTO API configuration | ||
const API_CONFIG = { | ||
apiBaseUrl: 'https://gcp-us-east1-19.dev.api.carto.com', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not urgent but would be great if we could include a demo dataset in a production env when merging this!
Background
In order to visualize trajectory data, a new
TrajectoryTileLayer
is addedScreen.Recording.2025-08-29.at.15.44.59.mov
The underlying rendering is performed by
TripsLayer
with the data format being the same as that used for point data inVectorTileLayer
. It has a number of features to make it easier to work with:Change List
TrajectoryTileLayer
and supporting filesVectorTileLayer