Purpose: Process GPS-style telemetry batches into spatial grid aggregates, speed metrics, and anomaly counts for a live-feed style GIS dashboard.
Business problem: Demonstrates how high-volume sensor or vehicle events can be reduced into map-ready summaries before they hit the UI, avoiding one-symbol-per-event rendering overload.
Technologies: .NET 10, Razor Pages, Bootstrap, vanilla JavaScript, ASP.NET Core API versioning, C++20/CMake, P/Invoke, blittable structs.
Deployment model: Runs inside the Portfolio web app on Render. The C++ library is optional; the managed fallback remains active when the native shared library is not deployed.
Frontend Architecture
Page:Pages/Projects/GeoStream/Index.cshtml provides a telemetry JSON editor, processing controls, KPI cards, and a grid-style visualization panel.
Script:wwwroot/js/GeoStream/app.js follows the existing self-contained IIFE pattern, uses apiPost, and stores only page-local state.
Visualization: The MVP renders aggregate cells as positioned markers over a GIS-styled panel. Anomaly cells receive a distinct visual treatment.
API routing:api-config.js exposes PortfolioApi.routes.spatialCompute.geostream.events so route versioning stays centralized.
Future map integration: The aggregate output is already shaped for ArcGIS JS rendering as point, grid, heatmap, or feature-layer graphics.
API Layer
Controller:GeoStreamController is versioned at /api/v1/geostream and marked [AllowAnonymous] for portfolio demo access.
Endpoint:POST /api/v1/geostream/events accepts GeoStreamBatchRequestDto with telemetry events, grid size, and anomaly threshold.
Error handling: Invalid batch shape maps to BadRequest(new { error = ... }); unexpected failures flow through the app exception middleware.
Security: The endpoint is stateless and does not accept user ownership fields or persist caller-provided identity.
Services and Business Logic
Service:GeoStreamProcessorService validates input, checks GeoStreamNativeBridge.IsAvailable, and dispatches to native or managed execution.
Managed fallback: Filters invalid latitude/longitude values, maps valid events into configurable grid cells, computes average/max speed, and counts speed anomalies.
Native bridge:GeoStreamNativeBridge maps DTOs to TelemetryEventNative, passes output buffers to the C ABI, translates status codes, and maps aggregates back to DTOs.
C++ library:native/geostream_processor exposes GeoStream_ProcessTelemetryBatch and performs the same validation and aggregation over contiguous arrays.
Why C++ here: Telemetry processing is batch-oriented, allocation-sensitive, and naturally suited to cache-local numeric loops before results are handed back to the ASP.NET Core layer.
Data Access Layer
Current MVP: No PostgreSQL persistence is used; requests are processed synchronously and returned as DTOs.
Reasoning: Keeping the MVP stateless isolates the compute path and makes native/managed parity easier to validate.
Future persistence: Entity tracks, aggregate snapshots, or anomaly events could be stored through a repository with per-user or per-feed ownership filters.
Cache evolution: Redis could hold recent aggregate windows or feed state when multiple replicas serve a live dashboard.
Infrastructure and Deployment
Native build:native/geostream_processor/CMakeLists.txt builds a shared library and copies it beside the .NET output when built locally.
Runtime behavior:NativeLibrary.TryLoad controls the fast path. Missing libraries do not break the web app.
Container behavior: The current Dockerfile can run in managed-fallback mode. A future native-enabled image would add CMake compilation before dotnet publish.
Scale-out path: Redis-backed windows, SignalR/WebSockets, or a queue-backed ingestion worker would be the next production step.
Engineering Decisions and Tradeoffs
Grid aggregation over raw event rendering: Improves map readability and reduces browser load, but loses individual-event detail unless a drill-down path is added.
Stateless MVP: Easy to demo and test, but not yet a true streaming architecture with windows, back-pressure, and durable ingestion.
Native fallback contract: Demonstrates production-safe native integration without requiring every deployment host to compile C++.
Future improvements: Add geofence indexing, sliding time windows, SignalR updates, Redis state, binary payload support, and native parsing with a library such as simdjson.
Interview Discussion Points
Where should a real system draw the boundary between ingestion, processing, caching, and rendering?
How would you prevent live-feed updates from overwhelming the browser or ArcGIS graphics layer?
Which parts of the pipeline are SIMD-friendly and which are branch-heavy?
When would this move from an in-process service to a dedicated worker or stream processor?