Real-Time Intelligence Meets Location: How Maps in Microsoft Fabric Transform Your Analytics

Description

Learn how Microsoft Fabric brings real-time and location intelligence together. Stream and transform live data with Real-Time Intelligence, visualize it instantly with Maps in Fabric, and then use Power BI to build interactive, rich geospatial analytics. In this demo-heavy session, we'll build the end-to-end solutions using real life data sources and examples.

Key Takeaways

My Notes

Action Items

Slides

Real-Time Intelligence
Meets Location :
How Maps in Microsoft
Fabric Transform your
Analytics
James Dales
James Dales
james.dales@icon-map.com
linkedin.com/in/jamesdales
Objectives
Using real data, build a real-time solution to show
location data on a map.
Include current locations, and recent history.
Detect when vehicles enter a location.
Add additional context to the map with reference layers.
Mapping in Fabric
Geospatial Processing
Display & Analytics
Data Engineering
▪ Notebooks with open source or ArcGIS
Data Engineering
▪ Notebooks with open source or ArcGIS
Databases
▪ Fabric SQL
▪ Data Warehouse
▪ Cosmos DB
▪ Snowflake
Power BI
▪ Azure Maps
▪ ArcGIS for Power BI
▪ Custom visuals such as Icon Map
Real-time Intelligence
▪ KQL Database
Real-time Intelligence
▪ Maps in Fabric
▪ Real-time Dashboard
Third-party workloads
▪ ArcGIS Maps for Fabric
Mapping in Fabric
Geospatial Processing
Display & Analytics
Data Engineering
▪ Notebooks with open source or ArcGIS
Data Engineering
▪ Notebooks with open source or ArcGIS
Databases
▪ Fabric SQL
▪ Data Warehouse
▪ Cosmos DB
▪ Snowflake
Power BI
▪ Azure Maps
▪ ArcGIS for Power BI
▪ Custom visuals such as Icon Map
Real-time Intelligence
▪ KQL Database
Real-time Intelligence
▪ Maps in Fabric
▪ Real-time Dashboard
Third-party workloads
▪ ArcGIS Maps for Fabric
Image courtesy of Han Zeng
High Level Requirements
Data Source
MARTA is the public transit system in Atlanta
GTFS is a standard data format for sharing routes, stops
schedules and live locations for transit information.
{"header":{"gtfs_realtime_version":"2.0","incrementality":0,"timestamp":1772618198},"entity":[{"id":"1601","is_deleted":false,"trip_update":null,"vehicle":{"trip":
{"trip_id":"10928497","start_time":"","start_date":"20260304","schedule_relationship":0,"route_id":"32","direction_id":5},"position":{"latitude":33.65011,"longitud
e":84.32144,"bearing":140,"odometer":0,"speed":22.352},"current_stop_sequence":0,"current_status":2,"timestamp":1772618185,"congestion_level":0,"stop_id":
"","vehicle":{"id":"2301","label":"1601","license_plate":""},"occupancy_status":0,"occupancy_percentage":0,"multi_carriage_details":[]},"alert":null,"shape":null,"
trip":null,"route":null,"stop":null},{"id":"1602","is_deleted":false,"trip_update":null,"vehicle":{"trip":{"trip_id":"10959571","start_time":"","start_date":"20260304","
schedule_relationship":0,"route_id":"86","direction_id":11},"position":{"latitude":33.71438,"longitude":84.22454,"bearing":260,"odometer":0,"speed":0.44704},"current_stop_sequence":0,"current_status":2,"timestamp":1772618186,"congestion_level":0,"stop_id"
:"","vehicle":{"id":"2302","label":"1602","license_plate":""},"occupancy_status":0,"occupancy_percentage":0,"multi_carriage_details":[]},"alert":null,"shape":null,
"trip":null,"route":null,"stop":null},{"id":"1603","is_deleted":false,"trip_update":null,"vehicle":{"trip":{"trip_id":"10972953","start_time":"","start_date":"20260304",
"schedule_relationship":0,"route_id":"114","direction_id":5},"position":{"latitude":33.7722,"longitude":84.25526,"bearing":132,"odometer":0,"speed":17.8816},"current_stop_sequence":0,"current_status":2,"timestamp":1772618183,"congestion_level":0,"stop_id"
:"","vehicle":{"id":"2303","label":"1603","license_plate":""},"occupancy_status":0,"occupancy_percentage":0,"multi_carriage_details":[]},"alert":null,"shape":null,
"trip":null,"route":null,"stop":null},{"id":"1606","is_deleted":false,"trip_update":null,"vehicle":{"trip":{"trip_id":"10983691","start_time":"","start_date":"20260304",
"schedule_relationship":0,"route_id":"126","direction_id":11},"position":{"latitude":33.84544,"longitude":84.25107,"bearing":88,"odometer":0,"speed":0},"current_stop_sequence":0,"current_status":2,"timestamp":1772618189,"congestion_level":0,"stop_id":"","vehi
https://gtfs-rt.itsmarta.com/TMGTFSRealTimeWebService/vehicle/vehiclepositions.json
Data Source
Header
"header": {
"gtfs_realtime_version": "2.0",
"incrementality": 0,
"timestamp": 1772618198
},
Data Source
Entity (Array)
{
"id": "1601",
"is_deleted": false,
"trip_update": null,
"vehicle": {
"trip": {
"trip_id": "10928497",
"start_time": "",
"start_date": "20260304",
"schedule_relationship": 0,
"route_id": "32",
"direction_id": 5
},
"position": {
"latitude": 33.65011,
"longitude": -84.32144,
"bearing": 140,
"odometer": 0,
"speed": 22.352
},
"current_stop_sequence": 0,
"current_status": 2,
"timestamp": 1772618185,
"congestion_level": 0,
"stop_id": "",
}
"vehicle": {
"id": "2301",
"label": "1601",
"license_plate": ""
},
"occupancy_status": 0,
"occupancy_percentage": 0,
"multi_carriage_details": []
Data Source
Entity (Array)
{
"id": "1601",
"is_deleted": false,
"trip_update": null,
"vehicle": {
"trip": {
"trip_id": "10928497",
"start_time": "",
"start_date": "20260304",
"schedule_relationship": 0,
"route_id": "32",
"direction_id": 5
},
"position": {
"latitude": 33.65011,
"longitude": -84.32144,
"bearing": 140,
"odometer": 0,
"speed": 22.352
},
"current_stop_sequence": 0,
"current_status": 2,
"timestamp": 1772618185,
"congestion_level": 0,
"stop_id": "",
}
"vehicle": {
"id": "2301",
"label": "1601",
"license_plate": ""
},
"occupancy_status": 0,
"occupancy_percentage": 0,
"multi_carriage_details": []
Ingestion Architecture
Microsoft Fabric
Real-time Intelligence
Event Stream
MARTA GTFS
REST API
Event House
HTTP Source
KQL Database
Expand Entities into
multiple rows
Create the Event Stream and Event House
Query the latest bus positions
let base =
BusPositions
| extend e = todynamic(ArrayValue_entity)
| extend vehicle_ts_epoch = tolong(e.vehicle.timestamp);
let last_feed_ts_epoch = toscalar(base | summarize max(vehicle_ts_epoch));
let window_start = last_feed_ts_epoch - 120;
base
| where vehicle_ts_epoch between (window_start .. last_feed_ts_epoch)
| extend
vehicle_id = tostring(e.vehicle.vehicle.id),
trip_id
= tostring(e.vehicle.trip.trip_id),
route_id
= tostring(e.vehicle.trip.route_id),
latitude
= todouble(e.vehicle.position.latitude),
longitude = todouble(e.vehicle.position.longitude),
speed_mps = todouble(e.vehicle.position.speed),
bearing
= todouble(e.vehicle.position.bearing),
occupancy_percentage = toint(e.vehicle.occupancy_percentage),
vehicle_ts = unixtime_seconds_todatetime(vehicle_ts_epoch)
| where isnotempty(vehicle_id) and isnotnull(latitude) and isnotnull(longitude)
| summarize arg_max(vehicle_ts_epoch, *) by vehicle_id
| project vehicle_id, latitude, longitude, speed_mps, bearing, route_id, trip_id, occupancy_percentage, vehicle_ts
| order by route_id asc, vehicle_id asc
Create the query
Ready to view on a map
Show recent history as a linestring
Add additional context to the map
Detect Neighborhoods
Surface in Power BI
Use Custom Visuals for Additional Capabilities
Sound off.
The mic is all yours.
Influence the product roadmap.
Join the Fabric User Panel
Join the SQL User Panel
Share your feedback directly with our
Fabric product group and researchers.
Influence our SQL roadmap and ensure
it meets your real-life needs
https://aka.ms/JoinFabricUserPanel
https://aka.ms/JoinSQLUserPanel