Data is far more powerful when you can see and interact with it on a map.
I built Cary EV Charging Explorer—a spatial analytics pipeline and interactive map application that ingests over 20,000 public EV charging session records from the Town of Cary, NC. The architecture processes raw JSON records through a serverless AWS ETL pipeline and renders them on a dynamic browser interface.
Here is a full breakdown of how the data pipeline and frontend visualization fit together.
🏗️ AWS Pipeline Architecture
- Stage 1 (Raw Dataset): Municipal JSON records ingested into AWS.
- Stage 2 (Staging): Amazon S3 Express One Zone for low-latency directory storage.
- Stage 3 (ETL & Geocoding): AWS Lambda + Amazon Location Service for parsing and address resolution.
- Stage 4 (Processed Storage): Amazon S3 Standard for clean CSV data storage.
- Stage 5 (Analytics Catalog): AWS Glue Data Catalog + Amazon Athena running Apache Iceberg tables.
- Stage 6 (Frontend Visualization): Leaflet.js + Esri Basemaps for interactive web map rendering.
1. High-Speed Staging with Amazon S3 Express One Zone
Raw municipal charging session data (electric-vehicle-charging-stations.json) is staged in an S3 Express Directory Bucket (cary-ev-stations--apse2-az1--x-s3). Using S3 Express One Zone provides single-digit millisecond data access latencies, making high-frequency file reads seamless for downstream transformation jobs.
2. Serverless Transformation with AWS Lambda & Amazon Location Service
An AWS Lambda function (geocode-ev-stations) streams the JSON payload. It handles:
- Parsing multi-nested JSON structures into structured rows.
- Resolving missing spatial coordinates using Amazon Location Service Place Indexes (
ev-place-index). - Formatting clean CSV streams directly into an S3 Standard Bucket (
cary-ev-stations-standard-jayesh/processed-data/ev_stations.csv).
By streaming transformed output directly to S3 CSV rather than executing per-row SQL inserts inside Lambda loops, the entire 20,000+ record dataset is processed in under 2 seconds without triggering concurrency rate limits (TooManyRequestsException) or query payload limits.
3. Open Table Formatting via Apache Iceberg & Amazon Athena
The CSV file location and schema are defined within the AWS Glue Data Catalog (ev_charging_db).
Using Amazon Athena, data is inserted into an Apache Iceberg table (charging_stations). Apache Iceberg provides ACID transactions, schema evolution, and fast spatial query speeds over open-table formats stored on S3.
sql -- Querying the production Iceberg catalog in Athena SELECT station_name, street_address, longitude, latitude, kwh_consumed FROM ev_charging_db.charging_stations LIMIT 10; 🌐 Interactive Web Frontend The client-side interface is built with Leaflet.js, Leaflet MarkerCluster, and Esri World Topo/Street Map raster tiles. Key features of the web map: Marker Clustering: Groups dense station clusters dynamically, expanding on zoom to keep browser performance silky-smooth across thousands of points. Interactive Metadata: Clicking any pin displays a popup with station details, street address, active status, and total kWh consumption. 🛠️ Lessons Learned & Optimization Highlights Athena Concurrency Caps: Asynchronous INSERT INTO queries inside rapid Lambda execution loops quickly hit Athena rate limits. Staging clean CSVs in S3 and triggering bulk catalog updates in Athena proved to be the most performant, resilient design pattern. CORS & Local File Protocols: When fetching local CSV data directly over file:// URLs, browser security blocks standard fetch calls. Embedding fallback datasets or running a simple local HTTP server (python -m http.server 8000) completely resolves domain restrictions.` > ## `