← GeoAI SkillsCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to GeoAI Skills
Snapshot Sep 30, 2026 · 23:13 UTC · version 0.4.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "movement-trajectory",
"description": "Movement and trajectory analytics from GPS/GNSS tracks: cleaning, stop/trip detection, road-network map matching, speed/direction, flow aggregation, and origin-destination construction. Use for fleets, human mobility, animal tracking, AIS, or sports tracks. Trigger on GPS points, GPX, trajectories, stop detection, map matching, or timestamped positions per moving object. Also invoke for privacy, aggregation, de-identification, or release of individual trajectories. Use network-accessibility-analysis for hypothetical routes, isochrones, or static OD costs without observed tracks.",
"included_files": [
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 228
},
{
"relative_path": "references/authoritative-sources.md",
"size_in_bytes": 783
}
],
"skill_md_contents": "---\nname: movement-trajectory\ndescription: >-\n Movement and trajectory analytics from GPS/GNSS tracks: cleaning, stop/trip\n detection, road-network map matching, speed/direction, flow aggregation,\n and origin-destination construction. Use for fleets, human mobility, animal\n tracking, AIS, or sports tracks. Trigger on GPS points, GPX, trajectories,\n stop detection, map matching, or timestamped positions per moving object.\n Also invoke for privacy, aggregation, de-identification, or release of\n individual trajectories. Use network-accessibility-analysis for\n hypothetical routes, isochrones, or static OD costs without observed tracks.\nlicense: MIT\nmetadata:\n author: Muhammed Enes Duran\n---\n\n# Movement & Trajectory Analytics\n\nPurpose: turn noisy timestamped points into defensible movement facts. The\nrecurring failure modes: **speed computed through GPS noise** (teleporting\npoints → 400 km/h pedestrians), **stops invented by signal drift**, and\n**privacy-blind delivery** of individual-level traces.\n\n## Data model first\n\nA trajectory = ordered fixes per object: `(object_id, timestamp, x, y,\n[accuracy, ...])`. Before analysis, report per object: fix count, time\nspan, median sampling interval, and interval distribution — **sampling\nrate drives every method choice** (1 s vehicle traces and 1 fix/hour\nanimal tags are different problems wearing the same schema).\n\n```python\nimport movingpandas as mpd\nimport geopandas as gpd\n\ngdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.lon, df.lat),\n crs=4326).to_crs(gdf_utm_epsg)\ntc = mpd.TrajectoryCollection(gdf, \"object_id\", t=\"timestamp\")\n```\n\n### Declare CRS and time base before any threshold\n\nEvery distance radius, speed limit and dwell duration in this skill is\nmeaningless until two things are stated **in the answer, before the number is\nused**:\n\n1. **The projected CRS** all distance and speed computation runs in — a \"50 m\n stop radius\" applied to raw lon/lat degrees is not 50 m anywhere, and the\n error scales with latitude. Name the CRS (`estimate_utm_crs()` for a local\n fleet, an equal-distance projection for continental extents).\n2. **The timestamp base**, normalised to timezone-aware UTC. Fleet logs mix\n local times, DST shifts and naive strings; a dwell that straddles a DST\n boundary gains or loses an hour, and stop durations silently corrupt.\n\nState both before proposing a radius or duration, not afterwards as a caveat.\n\n**Declaring is not withholding.** An unknown CRS or timezone is never grounds to\nstop and ask instead of answering. State it as an explicit, named assumption and\ndeliver the method anyway:\n\n> Assuming a local UTM zone for distance and that timestamps are naive local time\n> needing UTC normalisation — confirm both, since they change dwell durations.\n\nThen give the cleaning steps, the parameters, and the sensitivity check. A\nresponse that asks for the CRS, the timezone, or the file *in place of* the\nmethod has failed this skill even if the question is a good one. Ask alongside\nthe answer, never instead of it. Never silently treat naive timestamps as UTC —\nbut \"silently\" is the operative word: an assumption you have labelled and\nsurfaced is exactly what is wanted.\n\n## Cleaning pipeline (in order)\n\n1. **Deduplicate** identical (object, timestamp) fixes.\n2. **Accuracy filter**: drop fixes above an HDOP/accuracy threshold if\n the column exists (report the threshold and % dropped).\n3. **Speed filter**: drop fixes implying impossible speed for the mode\n (walk > 15 km/h sustained, car > 200 km/h...); iterate — one bad fix\n creates two bad segments (`mpd.OutlierCleaner`).\n4. **Gap splitting**: split trajectories at temporal gaps (e.g., > 5×\n median interval) — interpolating across a tunnel/power-off invents\n movement.\n5. Optional smoothing (Kalman/rolling median) for jittery urban-canyon\n data — AFTER outlier removal, and never before stop detection tuning.\n\nAccounting line per step: fixes in → out.\n\n## Stops and trips\n\nStop = spatial dwell: fixes within a distance radius for a minimum\nduration (`mpd.TrajectoryStopDetector(max_diameter=50,\nmin_duration=timedelta(minutes=5))`). The two parameters ARE the result —\nreport them and run a ±50% sensitivity check; urban-canyon drift mimics\nmovement, so diameter < GPS noise level yields zero stops.\n\nTrips = segments between stops. Deliver per trip: origin, destination,\nstart/end time, duration, length, main mode guess if applicable. OD\nmatrices: aggregate trip endpoints to zones (see privacy below);\naccessibility questions on the resulting flows → `network-accessibility-analysis`.\n\n## Map matching\n\nRaw GPS does not sit on the road. For any road-referenced claim (distance\ndriven, street-level flows, speeding), match to the network first:\n\n- Tools: Valhalla (Meili), OSRM `match`, or `mappymatch`; HMM-based\n matchers are the standard.\n- Sampling interval > ~30 s degrades matching sharply — report match\n confidence and the % of unmatched points; don't silently keep unmatched\n geometry.\n- Never map-match animal tracks or off-road movement (obviously) — and\n don't compute \"distance traveled\" from raw noisy fixes either\n (noise inflates path length ~5-20%); smooth first, state the method.\n\n## Aggregate analytics\n\n- **Flow maps / desire lines**: aggregate OD pairs before plotting\n (`cartography-geoviz` for delivery); hairball avoidance = zone-level\n aggregation + minimum-flow threshold.\n- **Density**: KDE or hex-bin of fixes vs of trips — fixes overweight slow\n movement (dwell = many fixes); use trip-based or time-weighted density\n and say which.\n- **Space-time clustering** (co-location, convoys): ST-DBSCAN family;\n cluster parameters in both space and time reported together.\n- Sequence/periodicity: hour-of-day × day-of-week activity matrices per\n object class before any behavioral claims.\n\n## Privacy — non-optional\n\nIndividual trajectories are personal data almost everywhere (GDPR etc.)\nand are notoriously re-identifiable (home/work anchor pairs identify most\npeople). Defaults: aggregate before sharing (zones ≥ k objects,\nsuppress cells < k, typical k=5-10), truncate trip ends near homes,\nand never publish raw individual traces without explicit clearance.\nState the anonymization applied in every deliverable.\n\n## Verification protocol\n\n1. Speed histogram per mode after cleaning — tail must be physically\n plausible.\n2. Map 3 sample trajectories (raw vs cleaned vs matched) over a basemap.\n3. Stop-detection sensitivity: parameters ±50%, report stop-count change.\n4. OD totals reconcile with trip counts (accounting).\n\n## Pitfalls checklist\n\n- Speeds computed across gaps or through outlier fixes.\n- Distance traveled from raw (unsmoothed, unmatched) fixes.\n- Stops detected with radius below GPS noise, or drift counted as trips.\n- Mixed timezones / DST jumps creating phantom teleports.\n- Fix-density maps read as movement-density maps.\n- Individual traces shipped without aggregation/suppression.\n- Trajectories split by object but not by temporal gap.\n\n## Execution contract\n\n- **Workflow:** validate identifiers, time, and CRS; segment tracks; remove impossible fixes; infer stops or trips; optionally map-match; aggregate; apply privacy controls; verify.\n- **Decision rules:** use trajectory methods for observed timestamped movement, network analysis for possible routes or access, and point-pattern methods when sequence and identity are absent.\n- **Verification protocol:** inspect speed and gap distributions, map raw-versus-cleaned samples, perturb stop parameters, reconcile trip and OD counts, and audit disclosure risk.\n- **Failure modes:** suppress or qualify results for timezone ambiguity, long gaps, implausible speeds, poor network matching, sparse sampling, or re-identification risk.\n- **Deliverables:** cleaned trajectories or approved aggregates, segmentation rules, quality report, derived stop/trip tables, privacy treatment, maps, and limitations.\n- **Source freshness:** consult [the authoritative source registry](references/authoritative-sources.md) before using format, library, or privacy guidance and record the checked date.\n"
}SHA-256: a4d7a880a6f5dfa4891439eb0bda91b4d5a05fc5c1046b0d18747f62e662deb1