From 1d43dc2a4c2c1876e40b7877bf8de8d7e8345a53 Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 8 Oct 2025 01:08:52 -0400 Subject: [PATCH 01/24] Add staging environment support to data pipeline - Update rebuild-cache.js to support staging and production modes - Add environment detection based on STAGING env var - Use staging-specific tables and buckets when STAGING=true - Skip timestamped backups in staging (cleaner staging bucket) - Update GitHub Actions workflow to handle both branches - Add staging branch trigger and environment detection - Create sync-prod-to-staging.js script for refreshing staging data - Create copy-geometries.js script for syncing geometry files - Update README with staging workflow and promotion process - Update CONTRIBUTING.md to direct PRs to staging branch --- .github/workflows/rebuild-cache.yml | 29 ++++++- CONTRIBUTING.md | 11 +++ README.md | 68 ++++++++++++++- copy-geometries.js | 109 ++++++++++++++++++++++++ rebuild-cache.js | 67 +++++++++++---- sync-prod-to-staging.js | 123 ++++++++++++++++++++++++++++ 6 files changed, 386 insertions(+), 21 deletions(-) create mode 100644 copy-geometries.js create mode 100644 sync-prod-to-staging.js diff --git a/.github/workflows/rebuild-cache.yml b/.github/workflows/rebuild-cache.yml index 2f33156..426ba5e 100644 --- a/.github/workflows/rebuild-cache.yml +++ b/.github/workflows/rebuild-cache.yml @@ -3,11 +3,21 @@ name: Rebuild Cache on: # Trigger manually from GitHub UI workflow_dispatch: + inputs: + environment: + description: 'Environment to deploy to' + required: true + default: 'staging' + type: choice + options: + - staging + - production # Trigger when events.csv or geometries are updated push: branches: - main + - staging paths: - 'events.csv' - 'geometries/**' @@ -20,6 +30,20 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Determine environment + id: env + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "STAGING=${{ github.event.inputs.environment == 'staging' && 'true' || 'false' }}" >> $GITHUB_OUTPUT + echo "ENV_NAME=${{ github.event.inputs.environment }}" >> $GITHUB_OUTPUT + elif [ "${{ github.ref }}" == "refs/heads/staging" ]; then + echo "STAGING=true" >> $GITHUB_OUTPUT + echo "ENV_NAME=staging" >> $GITHUB_OUTPUT + else + echo "STAGING=false" >> $GITHUB_OUTPUT + echo "ENV_NAME=production" >> $GITHUB_OUTPUT + fi + - name: Setup Node.js uses: actions/setup-node@v4 with: @@ -32,4 +56,7 @@ jobs: env: SUPABASE_URL: ${{ secrets.SUPABASE_URL }} SUPABASE_SERVICE_KEY: ${{ secrets.SUPABASE_SERVICE_KEY }} - run: node rebuild-cache.js + STAGING: ${{ steps.env.outputs.STAGING }} + run: | + echo "Rebuilding ${{ steps.env.outputs.ENV_NAME }} cache..." + node rebuild-cache.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6b632fb..2698ebd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,6 +2,17 @@ This dataset tracks autonomous vehicle deployments and powers [avmap.io](https://avmap.io). While currently focused on US services, we accept data from anywhere. +## ⚠️ Important: Submit PRs to `staging` branch + +**All pull requests should target the `staging` branch, not `main`.** This allows us to test your changes on the staging site before promoting to production. + +1. Fork this repository +2. Create a feature branch from `staging` +3. Make your changes +4. Submit a PR to the `staging` branch +5. Your changes will be tested on the staging environment +6. Once verified, they'll be promoted to production + ## Event sourcing basics Each row in `events.csv` represents one change to a service. Service creation events include all attributes. **Update events must include the complete new state for the field being updated** (not deltas) and always include the `company` field to identify which service is being updated. diff --git a/README.md b/README.md index 10f6c24..1c5ee9b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Open dataset tracking autonomous vehicle deployments in the United States. Power ## What's here -**events.csv** - Timeline of AV service changes since 2017 (launches, expansions, shutdowns, policy changes) +**events.csv** - Timeline of AV service changes since 2017 (launches, expansions, shutdowns, policy changes) **geometries/** - GeoJSON service area boundaries showing how coverage evolved This uses event sourcing: create events capture full service details, updates only record what changed. Every change has a source. @@ -27,12 +27,76 @@ Load the GeoJSON files into any mapping tool. Parse the CSV for historical analy ## Contributing -Add events to `events.csv`, run `python3 scripts/validate.py`, submit a PR. +**Important: Submit all PRs to the `staging` branch, not `main`.** + +1. Fork this repository +2. Create a feature branch from `staging` +3. Add events to `events.csv` or update geometries +4. Run `python3 scripts/validate.py` to verify your changes +5. Submit a PR to the `staging` branch +6. Your changes will be tested on the staging site before being promoted to production See [CONTRIBUTING.md](CONTRIBUTING.md) for the data format spec and examples. Most useful contributions: new service launches, boundary updates, fleet size changes, policy announcements. +## Staging & Production Workflow + +This repository uses a staging environment to test data updates before they go live: + +- **`staging` branch** → Deploys to staging environment (test your changes here) +- **`main` branch** → Deploys to production (avmap.io) + +### Testing Your Changes + +After submitting a PR to `staging`: +1. Wait for the GitHub Action to rebuild the staging cache +2. Check the staging site to verify your data looks correct +3. Once approved, your PR will be merged to `staging` +4. Later, staging will be promoted to `main` (production) + +## For Maintainers + +### Promoting Staging to Production + +Once staging data has been verified and looks good: + +```bash +# Create a PR from staging → main +gh pr create --base main --head staging --title "Promote staging to production" + +# Or via GitHub UI: +# 1. Go to Pull Requests → New PR +# 2. Base: main ← Compare: staging +# 3. Review changes, then merge +# 4. GitHub Action will automatically rebuild production cache +``` + +### Syncing Production Data to Staging + +To refresh staging with the latest production data: + +```bash +# Sync database tables +node sync-prod-to-staging.js + +# Copy geometry files +node copy-geometries.js + +# Rebuild staging cache +STAGING=true node rebuild-cache.js +``` + +### Manual Cache Rebuilds + +```bash +# Rebuild staging cache +STAGING=true node rebuild-cache.js + +# Rebuild production cache +node rebuild-cache.js +``` + ## License MIT - use it however you want. diff --git a/copy-geometries.js b/copy-geometries.js new file mode 100644 index 0000000..3b8eec2 --- /dev/null +++ b/copy-geometries.js @@ -0,0 +1,109 @@ +#!/usr/bin/env node + +/** + * Copy Geometry Files from Production to Staging + * + * This script copies all GeoJSON files from the production bucket to staging: + * - service-area-boundaries → staging-service-area-boundaries + * + * Run this after sync-prod-to-staging.js to ensure staging has all geometry files. + * + * Usage: node copy-geometries.js + */ + +import { createClient } from '@supabase/supabase-js' +import { config } from 'dotenv' + +// Load .env file +if (!process.env.GITHUB_ACTIONS) { + config() +} + +const supabaseUrl = process.env.SUPABASE_URL +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY || process.env.SUPABASE_ANON_KEY + +if (!supabaseUrl || !supabaseServiceKey) { + console.error('❌ Missing required environment variables!') + console.error('Please set SUPABASE_URL and SUPABASE_SERVICE_KEY in .env') + process.exit(1) +} + +const supabase = createClient(supabaseUrl, supabaseServiceKey) + +const PROD_BUCKET = 'service-area-boundaries' +const STAGING_BUCKET = 'staging-service-area-boundaries' + +async function copyGeometries() { + console.log('🔄 Copying geometry files from production to staging...\n') + + try { + // Step 1: List all files in production bucket + console.log(`📡 Listing files in ${PROD_BUCKET}...`) + const { data: files, error: listError } = await supabase.storage + .from(PROD_BUCKET) + .list('', { limit: 1000 }) + + if (listError) throw listError + + const geojsonFiles = files.filter(f => f.name.endsWith('.geojson')) + console.log(` Found ${geojsonFiles.length} geometry files\n`) + + if (geojsonFiles.length === 0) { + console.log('✅ No files to copy') + return + } + + // Step 2: Copy each file + console.log(`📥 Copying files to ${STAGING_BUCKET}...`) + let successCount = 0 + let failCount = 0 + + for (const file of geojsonFiles) { + try { + // Download from production + const { data: fileData, error: downloadError } = await supabase.storage + .from(PROD_BUCKET) + .download(file.name) + + if (downloadError) throw downloadError + + // Upload to staging + const { error: uploadError } = await supabase.storage + .from(STAGING_BUCKET) + .upload(file.name, fileData, { + contentType: 'application/json', + upsert: true // Overwrite if exists + }) + + if (uploadError) throw uploadError + + console.log(` ✅ ${file.name}`) + successCount++ + + } catch (error) { + console.error(` ❌ ${file.name}: ${error.message}`) + failCount++ + } + } + + console.log(`\n📊 Copy Summary:`) + console.log(` ✅ Successful: ${successCount}`) + console.log(` ❌ Failed: ${failCount}`) + console.log(` 📁 Total: ${geojsonFiles.length}`) + + if (failCount === 0) { + console.log('\n✅ All geometry files copied successfully!') + console.log('\n📝 Next steps:') + console.log(' Run: STAGING=true node rebuild-cache.js') + } else { + console.error('\n⚠️ Some files failed to copy. Check errors above.') + process.exit(1) + } + + } catch (error) { + console.error('❌ Copy failed:', error) + process.exit(1) + } +} + +copyGeometries() diff --git a/rebuild-cache.js b/rebuild-cache.js index f064783..2138f8c 100644 --- a/rebuild-cache.js +++ b/rebuild-cache.js @@ -1,7 +1,7 @@ #!/usr/bin/env node /** - * Production cache rebuild script + * Cache rebuild script - supports both staging and production environments * * This script: * 1. Fetches all data from Supabase database @@ -9,11 +9,16 @@ * 3. Processes service areas using timeline logic * 4. Uploads combined JSON blob to storage * + * Environment Detection: + * - STAGING=true env var → Uses staging tables/buckets + * - Default → Uses production tables/buckets + * * Run this whenever you update av_events or service_area_geometries data */ import { createClient } from '@supabase/supabase-js' import { config } from 'dotenv' +import { execSync } from 'child_process' // Load .env file for local development (GitHub Actions sets env vars directly) if (!process.env.GITHUB_ACTIONS) { @@ -34,6 +39,26 @@ if (!supabaseUrl || !supabaseServiceKey) { process.exit(1) } +// Detect environment: staging or production +const isStaging = process.env.STAGING === 'true' +const environment = isStaging ? 'staging' : 'production' + +// Environment-specific configuration +const config_env = { + eventsTable: isStaging ? 'av_events_staging' : 'av_events', + geometriesTable: isStaging ? 'service_area_geometries_staging' : 'service_area_geometries', + dataCacheBucket: isStaging ? 'staging-data-cache' : 'data-cache', + geometriesBucket: isStaging ? 'staging-service-area-boundaries' : 'service-area-boundaries' +} + +console.log(`🌍 Environment: ${environment.toUpperCase()}`) +console.log(`📋 Configuration:`) +console.log(` Events table: ${config_env.eventsTable}`) +console.log(` Geometries table: ${config_env.geometriesTable}`) +console.log(` Data cache bucket: ${config_env.dataCacheBucket}`) +console.log(` Geometries bucket: ${config_env.geometriesBucket}`) +console.log('') + const supabase = createClient(supabaseUrl, supabaseServiceKey) async function rebuildCache() { @@ -45,13 +70,13 @@ async function rebuildCache() { console.log('📡 Fetching database data...') const [eventsResult, geometriesResult] = await Promise.all([ supabase - .from('av_events') + .from(config_env.eventsTable) .select('*') .eq('aggregate_type', 'service_area') .order('event_date', { ascending: true }), supabase - .from('service_area_geometries') + .from(config_env.geometriesTable) .select('*') .order('created_at', { ascending: false }) ]) @@ -149,35 +174,41 @@ async function rebuildCache() { const jsonData = JSON.stringify(cacheData) const sizeMB = (jsonData.length / 1024 / 1024).toFixed(2) - // Use timestamped filename to avoid caching issues - const timestamp = Date.now(); - const filename = `all-data-${timestamp}.json`; + // Use timestamped filename to avoid caching issues (production only) + if (!isStaging) { + const timestamp = Date.now(); + const filename = `all-data-${timestamp}.json`; - const { error: uploadError } = await supabase.storage - .from('data-cache') - .upload(filename, jsonData, { - contentType: 'application/json', - cacheControl: 'max-age=0, no-cache' - }) + const { error: uploadError } = await supabase.storage + .from(config_env.dataCacheBucket) + .upload(filename, jsonData, { + contentType: 'application/json', + cacheControl: 'max-age=0, no-cache' + }) - if (uploadError) throw uploadError + if (uploadError) throw uploadError + console.log(` Backup saved: ${filename}`) + } - // Also upload as all-data.json for backwards compatibility - await supabase.storage.from('data-cache').remove(['all-data.json']) + // Upload as all-data.json + await supabase.storage.from(config_env.dataCacheBucket).remove(['all-data.json']) const { error: mainUploadError } = await supabase.storage - .from('data-cache') + .from(config_env.dataCacheBucket) .upload('all-data.json', jsonData, { contentType: 'application/json', cacheControl: 'max-age=0, no-cache' }) - if (uploadError) throw uploadError + if (mainUploadError) throw mainUploadError const totalTime = Date.now() - startTime + const publicUrl = `${supabaseUrl}/storage/v1/object/public/${config_env.dataCacheBucket}/all-data.json` + console.log(`🎉 Cache rebuild complete!`) + console.log(` Environment: ${environment}`) console.log(` Size: ${sizeMB}MB`) console.log(` Time: ${totalTime}ms`) - console.log(` URL: https://vbqijqcveavjycsfoszy.supabase.co/storage/v1/object/public/data-cache/all-data.json`) + console.log(` URL: ${publicUrl}`) if (failed.length > 0) { console.log(`⚠️ ${failed.length} geometries failed to load`) diff --git a/sync-prod-to-staging.js b/sync-prod-to-staging.js new file mode 100644 index 0000000..520f687 --- /dev/null +++ b/sync-prod-to-staging.js @@ -0,0 +1,123 @@ +#!/usr/bin/env node + +/** + * Sync Production Data to Staging + * + * This script copies current production data to staging tables: + * - av_events → av_events_staging + * - service_area_geometries → service_area_geometries_staging + * + * Run this when you want to refresh staging with the latest production data. + * + * Usage: node sync-prod-to-staging.js + */ + +import { createClient } from '@supabase/supabase-js' +import { config } from 'dotenv' + +// Load .env file +if (!process.env.GITHUB_ACTIONS) { + config() +} + +const supabaseUrl = process.env.SUPABASE_URL +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY || process.env.SUPABASE_ANON_KEY + +if (!supabaseUrl || !supabaseServiceKey) { + console.error('❌ Missing required environment variables!') + console.error('Please set SUPABASE_URL and SUPABASE_SERVICE_KEY in .env') + process.exit(1) +} + +const supabase = createClient(supabaseUrl, supabaseServiceKey) + +async function syncProdToStaging() { + console.log('🔄 Syncing production data to staging...\n') + + try { + // Step 1: Fetch production data + console.log('📡 Fetching production data...') + const [eventsResult, geometriesResult] = await Promise.all([ + supabase + .from('av_events') + .select('*') + .order('created_at', { ascending: true }), + + supabase + .from('service_area_geometries') + .select('*') + .order('created_at', { ascending: true }) + ]) + + if (eventsResult.error) throw eventsResult.error + if (geometriesResult.error) throw geometriesResult.error + + const prodEvents = eventsResult.data + const prodGeometries = geometriesResult.data + + console.log(` Found ${prodEvents.length} events`) + console.log(` Found ${prodGeometries.length} geometries\n`) + + // Step 2: Clear staging tables + console.log('🗑️ Clearing staging tables...') + const [deleteEventsResult, deleteGeomsResult] = await Promise.all([ + supabase.from('av_events_staging').delete().neq('id', '00000000-0000-0000-0000-000000000000'), + supabase.from('service_area_geometries_staging').delete().neq('id', '00000000-0000-0000-0000-000000000000') + ]) + + if (deleteEventsResult.error) throw deleteEventsResult.error + if (deleteGeomsResult.error) throw deleteGeomsResult.error + + console.log(' Staging tables cleared\n') + + // Step 3: Insert production data into staging + console.log('📥 Copying to staging tables...') + + // Insert events + const { error: eventsInsertError } = await supabase + .from('av_events_staging') + .insert(prodEvents) + + if (eventsInsertError) throw eventsInsertError + console.log(` ✅ Copied ${prodEvents.length} events`) + + // Insert geometries + const { error: geometriesInsertError } = await supabase + .from('service_area_geometries_staging') + .insert(prodGeometries) + + if (geometriesInsertError) throw geometriesInsertError + console.log(` ✅ Copied ${prodGeometries.length} geometries\n`) + + // Step 4: Verify counts match + console.log('🔍 Verifying sync...') + const [stagingEventsResult, stagingGeomsResult] = await Promise.all([ + supabase.from('av_events_staging').select('id', { count: 'exact', head: true }), + supabase.from('service_area_geometries_staging').select('id', { count: 'exact', head: true }) + ]) + + const stagingEventsCount = stagingEventsResult.count + const stagingGeomsCount = stagingGeomsResult.count + + console.log(` Production events: ${prodEvents.length}`) + console.log(` Staging events: ${stagingEventsCount}`) + console.log(` Production geometries: ${prodGeometries.length}`) + console.log(` Staging geometries: ${stagingGeomsCount}\n`) + + if (stagingEventsCount === prodEvents.length && stagingGeomsCount === prodGeometries.length) { + console.log('✅ Sync complete! Staging data matches production.') + console.log('\n📝 Next steps:') + console.log(' 1. Run: node copy-geometries.js (to sync geometry files)') + console.log(' 2. Run: STAGING=true node rebuild-cache.js (to rebuild staging cache)') + } else { + console.error('❌ Count mismatch! Sync may have failed.') + process.exit(1) + } + + } catch (error) { + console.error('❌ Sync failed:', error) + process.exit(1) + } +} + +syncProdToStaging() From a61f57d33f9cf743d9b70dd14c8bd023e12e0a31 Mon Sep 17 00:00:00 2001 From: jackson Date: Fri, 10 Oct 2025 22:08:54 -0700 Subject: [PATCH 02/24] adding Chandler Flex service to the map --- events.csv | 3 ++- ...handler-september-18-2025-boundary.geojson | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 geometries/waymo-chandler-september-18-2025-boundary.geojson diff --git a/events.csv b/events.csv index 5dc89c6..43356a5 100644 --- a/events.csv +++ b/events.csv @@ -34,4 +34,5 @@ date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_bookin 2025-08-26,geometry_updated,Tesla,Austin,tesla-austin-august-26-2025-boundary.geojson,,,,,,,,https://electrek.co/2025/08/27/tesla-announces-50-increase-in-austin-robotaxi-but-50-from-what/,Service area boundary update 2025-09-01,supervision_updated,Tesla,Austin,,,,,,Safety Driver,,,https://mashable.com/article/tesla-robotaxi-human-safety-monitor-drivers-seat#:~:text=Tesla%20now%20puts%20their%20robotaxi%20safety%20monitors%20in%20the%20driver%27s&text=Texas%20SB%202807%2C%20which%20went%20into%20effect%20on%20Sept.,Supervision level update 2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Safety Driver,Public,,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service -2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Autonomous,Public,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service \ No newline at end of file +2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Autonomous,Public,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service +2025-09-18,service_created,Waymo,Chandler,av-map-data/geometries/waymo-chandler-september-18-2025-boundary.geojson,Jaguar I-Pace,Chandler Flex,Yes,No,Autonomous,Public,,https://www.chandleraz.gov/news-center/city-chandler-partners-waymo-and-bring-avs-chandler-flex,Chandler Flex public transportation service with Waymo as a provider \ No newline at end of file diff --git a/geometries/waymo-chandler-september-18-2025-boundary.geojson b/geometries/waymo-chandler-september-18-2025-boundary.geojson new file mode 100644 index 0000000..ed174a6 --- /dev/null +++ b/geometries/waymo-chandler-september-18-2025-boundary.geojson @@ -0,0 +1,27 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [-111.82413240462685, 33.32070153177102], + [-111.86775815875122, 33.32063128523849], + [-111.86773925403301, 33.30638645345937], + [-111.8938924901019, 33.30621748251329], + [-111.89390342029861, 33.30560951668099], + [-111.90303254535685, 33.30540196658767], + [-111.90259816555334, 33.292425530975706], + [-111.89374064026434, 33.29262515511297], + [-111.89309796486694, 33.23249400317847], + [-111.82396905519376, 33.23331001484584], + [-111.82413240462685, 33.32070153177102] + ] + ], + "type": "Polygon" + } + } + ] +} From a07c8d0776659666c4437d4ab46ec5e1a3395ba7 Mon Sep 17 00:00:00 2001 From: jackson Date: Tue, 14 Oct 2025 11:47:08 -0700 Subject: [PATCH 03/24] Remove Chandler Flex test service --- events.csv | 1 - events.csv.tmp | 0 ...handler-september-18-2025-boundary.geojson | 27 ----- temp-add-chandler-staging.js | 111 ++++++++++++++++++ temp-delete-chandler.js | 63 ++++++++++ 5 files changed, 174 insertions(+), 28 deletions(-) create mode 100644 events.csv.tmp delete mode 100644 geometries/waymo-chandler-september-18-2025-boundary.geojson create mode 100644 temp-add-chandler-staging.js create mode 100644 temp-delete-chandler.js diff --git a/events.csv b/events.csv index 43356a5..9b6f0b7 100644 --- a/events.csv +++ b/events.csv @@ -35,4 +35,3 @@ date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_bookin 2025-09-01,supervision_updated,Tesla,Austin,,,,,,Safety Driver,,,https://mashable.com/article/tesla-robotaxi-human-safety-monitor-drivers-seat#:~:text=Tesla%20now%20puts%20their%20robotaxi%20safety%20monitors%20in%20the%20driver%27s&text=Texas%20SB%202807%2C%20which%20went%20into%20effect%20on%20Sept.,Supervision level update 2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Safety Driver,Public,,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service 2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Autonomous,Public,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service -2025-09-18,service_created,Waymo,Chandler,av-map-data/geometries/waymo-chandler-september-18-2025-boundary.geojson,Jaguar I-Pace,Chandler Flex,Yes,No,Autonomous,Public,,https://www.chandleraz.gov/news-center/city-chandler-partners-waymo-and-bring-avs-chandler-flex,Chandler Flex public transportation service with Waymo as a provider \ No newline at end of file diff --git a/events.csv.tmp b/events.csv.tmp new file mode 100644 index 0000000..e69de29 diff --git a/geometries/waymo-chandler-september-18-2025-boundary.geojson b/geometries/waymo-chandler-september-18-2025-boundary.geojson deleted file mode 100644 index ed174a6..0000000 --- a/geometries/waymo-chandler-september-18-2025-boundary.geojson +++ /dev/null @@ -1,27 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "coordinates": [ - [ - [-111.82413240462685, 33.32070153177102], - [-111.86775815875122, 33.32063128523849], - [-111.86773925403301, 33.30638645345937], - [-111.8938924901019, 33.30621748251329], - [-111.89390342029861, 33.30560951668099], - [-111.90303254535685, 33.30540196658767], - [-111.90259816555334, 33.292425530975706], - [-111.89374064026434, 33.29262515511297], - [-111.89309796486694, 33.23249400317847], - [-111.82396905519376, 33.23331001484584], - [-111.82413240462685, 33.32070153177102] - ] - ], - "type": "Polygon" - } - } - ] -} diff --git a/temp-add-chandler-staging.js b/temp-add-chandler-staging.js new file mode 100644 index 0000000..7c1a9da --- /dev/null +++ b/temp-add-chandler-staging.js @@ -0,0 +1,111 @@ +#!/usr/bin/env node + +import { createClient } from '@supabase/supabase-js' +import { config } from 'dotenv' +import { readFileSync } from 'fs' + +// Load environment variables +config() + +const supabaseUrl = process.env.SUPABASE_URL +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY + +if (!supabaseUrl || !supabaseServiceKey) { + console.error('❌ Missing SUPABASE_URL or SUPABASE_SERVICE_KEY') + process.exit(1) +} + +const supabase = createClient(supabaseUrl, supabaseServiceKey) + +async function addChandlerToStaging() { + console.log('🚀 Adding Chandler Flex service to staging...\n') + + // Step 1: Insert event into av_events_staging + const event = { + event_type: 'service_created', + aggregate_type: 'service_area', + aggregate_id: 'waymo-chandler', + event_date: '2025-09-18', + event_data: { + name: 'Chandler', + company: 'Waymo', + city: 'Chandler', + geometry_name: 'waymo-chandler-september-18-2025-boundary.geojson', + vehicle_types: 'Jaguar I-Pace', + platform: 'Chandler Flex', + fares: 'Yes', + direct_booking: 'No', + supervision: 'Autonomous', + access: 'Public' + }, + source: 'https://www.chandleraz.gov/news-center/city-chandler-partners-waymo-and-bring-avs-chandler-flex' + } + + console.log('📝 Inserting event into av_events_staging...') + const { data: eventData, error: eventError } = await supabase + .from('av_events_staging') + .insert(event) + .select() + + if (eventError) { + console.error('❌ Failed to insert event:', eventError) + return + } + + console.log('✅ Event inserted successfully!') + + // Step 2: Upload geometry file to staging storage + console.log('\n📦 Uploading geometry file to staging storage...') + + const geometryPath = 'geometries/waymo-chandler-september-18-2025-boundary.geojson' + const geometryData = readFileSync(geometryPath, 'utf8') + const geometryJson = JSON.parse(geometryData) + + const { data: uploadData, error: uploadError } = await supabase + .storage + .from('staging-service-area-boundaries') + .upload('waymo-chandler-september-18-2025-boundary.geojson', geometryData, { + contentType: 'application/json', + upsert: true + }) + + if (uploadError) { + console.error('❌ Failed to upload geometry:', uploadError) + return + } + + console.log('✅ Geometry uploaded successfully!') + + // Step 3: Add metadata to service_area_geometries_staging + console.log('\n📝 Adding geometry metadata to service_area_geometries_staging...') + + const { data: publicUrlData } = supabase + .storage + .from('staging-service-area-boundaries') + .getPublicUrl('waymo-chandler-september-18-2025-boundary.geojson') + + const geometryMeta = { + geometry_name: 'waymo-chandler-september-18-2025-boundary.geojson', + display_name: 'Waymo Chandler - September 18, 2025', + storage_url: publicUrlData.publicUrl, + file_size: Buffer.from(geometryData).length + } + + const { data: metaData, error: metaError } = await supabase + .from('service_area_geometries_staging') + .insert(geometryMeta) + .select() + + if (metaError) { + console.error('❌ Failed to insert geometry metadata:', metaError) + return + } + + console.log('✅ Geometry metadata inserted successfully!') + console.log('\n🎉 Chandler Flex service added to staging!') + console.log('\n📋 Next steps:') + console.log(' 1. Run: STAGING=true node rebuild-cache.js') + console.log(' 2. Check staging site to verify Chandler appears') +} + +addChandlerToStaging().catch(console.error) diff --git a/temp-delete-chandler.js b/temp-delete-chandler.js new file mode 100644 index 0000000..7ed79e1 --- /dev/null +++ b/temp-delete-chandler.js @@ -0,0 +1,63 @@ +#!/usr/bin/env node + +import { createClient } from '@supabase/supabase-js' +import { config } from 'dotenv' + +config() + +const supabaseUrl = process.env.SUPABASE_URL +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY + +if (!supabaseUrl || !supabaseServiceKey) { + console.error('Missing SUPABASE_URL or SUPABASE_SERVICE_KEY') + process.exit(1) +} + +const supabase = createClient(supabaseUrl, supabaseServiceKey) + +async function deleteChandler() { + console.log('Deleting Chandler Flex service from staging...\n') + + // Delete event from av_events_staging + console.log('Deleting event from av_events_staging...') + const { error: eventError } = await supabase + .from('av_events_staging') + .delete() + .eq('aggregate_id', 'waymo-chandler') + + if (eventError) { + console.error('Failed to delete event:', eventError) + } else { + console.log('Event deleted successfully') + } + + // Delete geometry metadata + console.log('\nDeleting geometry metadata...') + const { error: metaError } = await supabase + .from('service_area_geometries_staging') + .delete() + .eq('geometry_name', 'waymo-chandler-september-18-2025-boundary.geojson') + + if (metaError) { + console.error('Failed to delete metadata:', metaError) + } else { + console.log('Metadata deleted successfully') + } + + // Delete geometry file from storage + console.log('\nDeleting geometry file from storage...') + const { error: storageError } = await supabase + .storage + .from('staging-service-area-boundaries') + .remove(['waymo-chandler-september-18-2025-boundary.geojson']) + + if (storageError) { + console.error('Failed to delete geometry file:', storageError) + } else { + console.log('Geometry file deleted successfully') + } + + console.log('\nChandler Flex deleted from staging!') +} + +deleteChandler().catch(console.error) From 80e70a94a614d09dbeaa057d5c604a89ba4ba9f9 Mon Sep 17 00:00:00 2001 From: jackson Date: Tue, 14 Oct 2025 12:58:27 -0700 Subject: [PATCH 04/24] Clarify README for external contributors vs maintainers --- README.md | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 1c5ee9b..05214ba 100644 --- a/README.md +++ b/README.md @@ -27,35 +27,38 @@ Load the GeoJSON files into any mapping tool. Parse the CSV for historical analy ## Contributing -**Important: Submit all PRs to the `staging` branch, not `main`.** +We welcome contributions! To submit changes: 1. Fork this repository 2. Create a feature branch from `staging` -3. Add events to `events.csv` or update geometries -4. Run `python3 scripts/validate.py` to verify your changes -5. Submit a PR to the `staging` branch -6. Your changes will be tested on the staging site before being promoted to production +3. Make your changes to `events.csv` and/or add geometry files +4. Run validation: `python3 scripts/validate.py` +5. Submit a pull request to the `staging` branch +6. Wait for review - a maintainer will test your changes and merge if approved -See [CONTRIBUTING.md](CONTRIBUTING.md) for the data format spec and examples. +See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed format specs and examples. -Most useful contributions: new service launches, boundary updates, fleet size changes, policy announcements. +**Helpful contributions:** +- New service launches or expansions +- Service area boundary updates +- Fleet changes, policy updates +- Corrections to existing data -## Staging & Production Workflow +## Review Process -This repository uses a staging environment to test data updates before they go live: - -- **`staging` branch** → Deploys to staging environment (test your changes here) -- **`main` branch** → Deploys to production (avmap.io) +After you submit a pull request: +1. Automated tests will run to validate your data format +2. A maintainer will review and test your changes +3. If approved, your PR will be merged to `staging` +4. Changes will be promoted to production after internal testing -### Testing Your Changes +## For Maintainers Only -After submitting a PR to `staging`: -1. Wait for the GitHub Action to rebuild the staging cache -2. Check the staging site to verify your data looks correct -3. Once approved, your PR will be merged to `staging` -4. Later, staging will be promoted to `main` (production) +The following commands are for repository maintainers managing the staging → production workflow. -## For Maintainers +This repository uses a staging environment to test data updates before they go live: +- **`staging` branch** → Deploys to staging environment for testing +- **`main` branch** → Deploys to production (avmap.io) ### Promoting Staging to Production From 3b35a81fcf8a9ebd123cfcd08cf04e793c35d8d3 Mon Sep 17 00:00:00 2001 From: jackson Date: Tue, 14 Oct 2025 13:00:46 -0700 Subject: [PATCH 05/24] Remove temp files --- events.csv.tmp | 0 temp-add-chandler-staging.js | 111 ----------------------------------- temp-delete-chandler.js | 63 -------------------- 3 files changed, 174 deletions(-) delete mode 100644 events.csv.tmp delete mode 100644 temp-add-chandler-staging.js delete mode 100644 temp-delete-chandler.js diff --git a/events.csv.tmp b/events.csv.tmp deleted file mode 100644 index e69de29..0000000 diff --git a/temp-add-chandler-staging.js b/temp-add-chandler-staging.js deleted file mode 100644 index 7c1a9da..0000000 --- a/temp-add-chandler-staging.js +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env node - -import { createClient } from '@supabase/supabase-js' -import { config } from 'dotenv' -import { readFileSync } from 'fs' - -// Load environment variables -config() - -const supabaseUrl = process.env.SUPABASE_URL -const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY - -if (!supabaseUrl || !supabaseServiceKey) { - console.error('❌ Missing SUPABASE_URL or SUPABASE_SERVICE_KEY') - process.exit(1) -} - -const supabase = createClient(supabaseUrl, supabaseServiceKey) - -async function addChandlerToStaging() { - console.log('🚀 Adding Chandler Flex service to staging...\n') - - // Step 1: Insert event into av_events_staging - const event = { - event_type: 'service_created', - aggregate_type: 'service_area', - aggregate_id: 'waymo-chandler', - event_date: '2025-09-18', - event_data: { - name: 'Chandler', - company: 'Waymo', - city: 'Chandler', - geometry_name: 'waymo-chandler-september-18-2025-boundary.geojson', - vehicle_types: 'Jaguar I-Pace', - platform: 'Chandler Flex', - fares: 'Yes', - direct_booking: 'No', - supervision: 'Autonomous', - access: 'Public' - }, - source: 'https://www.chandleraz.gov/news-center/city-chandler-partners-waymo-and-bring-avs-chandler-flex' - } - - console.log('📝 Inserting event into av_events_staging...') - const { data: eventData, error: eventError } = await supabase - .from('av_events_staging') - .insert(event) - .select() - - if (eventError) { - console.error('❌ Failed to insert event:', eventError) - return - } - - console.log('✅ Event inserted successfully!') - - // Step 2: Upload geometry file to staging storage - console.log('\n📦 Uploading geometry file to staging storage...') - - const geometryPath = 'geometries/waymo-chandler-september-18-2025-boundary.geojson' - const geometryData = readFileSync(geometryPath, 'utf8') - const geometryJson = JSON.parse(geometryData) - - const { data: uploadData, error: uploadError } = await supabase - .storage - .from('staging-service-area-boundaries') - .upload('waymo-chandler-september-18-2025-boundary.geojson', geometryData, { - contentType: 'application/json', - upsert: true - }) - - if (uploadError) { - console.error('❌ Failed to upload geometry:', uploadError) - return - } - - console.log('✅ Geometry uploaded successfully!') - - // Step 3: Add metadata to service_area_geometries_staging - console.log('\n📝 Adding geometry metadata to service_area_geometries_staging...') - - const { data: publicUrlData } = supabase - .storage - .from('staging-service-area-boundaries') - .getPublicUrl('waymo-chandler-september-18-2025-boundary.geojson') - - const geometryMeta = { - geometry_name: 'waymo-chandler-september-18-2025-boundary.geojson', - display_name: 'Waymo Chandler - September 18, 2025', - storage_url: publicUrlData.publicUrl, - file_size: Buffer.from(geometryData).length - } - - const { data: metaData, error: metaError } = await supabase - .from('service_area_geometries_staging') - .insert(geometryMeta) - .select() - - if (metaError) { - console.error('❌ Failed to insert geometry metadata:', metaError) - return - } - - console.log('✅ Geometry metadata inserted successfully!') - console.log('\n🎉 Chandler Flex service added to staging!') - console.log('\n📋 Next steps:') - console.log(' 1. Run: STAGING=true node rebuild-cache.js') - console.log(' 2. Check staging site to verify Chandler appears') -} - -addChandlerToStaging().catch(console.error) diff --git a/temp-delete-chandler.js b/temp-delete-chandler.js deleted file mode 100644 index 7ed79e1..0000000 --- a/temp-delete-chandler.js +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env node - -import { createClient } from '@supabase/supabase-js' -import { config } from 'dotenv' - -config() - -const supabaseUrl = process.env.SUPABASE_URL -const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY - -if (!supabaseUrl || !supabaseServiceKey) { - console.error('Missing SUPABASE_URL or SUPABASE_SERVICE_KEY') - process.exit(1) -} - -const supabase = createClient(supabaseUrl, supabaseServiceKey) - -async function deleteChandler() { - console.log('Deleting Chandler Flex service from staging...\n') - - // Delete event from av_events_staging - console.log('Deleting event from av_events_staging...') - const { error: eventError } = await supabase - .from('av_events_staging') - .delete() - .eq('aggregate_id', 'waymo-chandler') - - if (eventError) { - console.error('Failed to delete event:', eventError) - } else { - console.log('Event deleted successfully') - } - - // Delete geometry metadata - console.log('\nDeleting geometry metadata...') - const { error: metaError } = await supabase - .from('service_area_geometries_staging') - .delete() - .eq('geometry_name', 'waymo-chandler-september-18-2025-boundary.geojson') - - if (metaError) { - console.error('Failed to delete metadata:', metaError) - } else { - console.log('Metadata deleted successfully') - } - - // Delete geometry file from storage - console.log('\nDeleting geometry file from storage...') - const { error: storageError } = await supabase - .storage - .from('staging-service-area-boundaries') - .remove(['waymo-chandler-september-18-2025-boundary.geojson']) - - if (storageError) { - console.error('Failed to delete geometry file:', storageError) - } else { - console.log('Geometry file deleted successfully') - } - - console.log('\nChandler Flex deleted from staging!') -} - -deleteChandler().catch(console.error) From 9c1d1beadefdba0d2183fbed83f2605aabca986a Mon Sep 17 00:00:00 2001 From: jackson Date: Tue, 14 Oct 2025 13:01:52 -0700 Subject: [PATCH 06/24] Update coverage timeline and companies --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 05214ba..4479da2 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,8 @@ This uses event sourcing: create events capture full service details, updates on ## Current coverage -- 2017-2025 timeline -- Waymo, Tesla, May Mobility, Zoox, Cruise, and others +- 2017 to current timeline +- Waymo, Tesla, May Mobility, Zoox, and others - Major US cities with active or historical deployments ## Quick start From 233a887d7ece50f130e52263fdeff8b4baf8ac3e Mon Sep 17 00:00:00 2001 From: jackson Date: Tue, 14 Oct 2025 13:02:32 -0700 Subject: [PATCH 07/24] Add temp files to gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index daf1dd0..60b03e3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,7 @@ node_modules/ .env *.log .DS_Store + +# Temporary files +*.tmp +temp-*.js From 50a5934afa52ac0e7e95c8fb946d92f40d7d4532 Mon Sep 17 00:00:00 2001 From: jackson Date: Tue, 14 Oct 2025 13:20:51 -0700 Subject: [PATCH 08/24] Update contributing workflow to fork from main instead of staging - Contributors now fork from main (stable) rather than staging (WIP) - PRs still target staging for testing before production - Clarified workflow in both README and CONTRIBUTING files --- CONTRIBUTING.md | 8 ++++---- README.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2698ebd..3616310 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ This dataset tracks autonomous vehicle deployments and powers [avmap.io](https:/ **All pull requests should target the `staging` branch, not `main`.** This allows us to test your changes on the staging site before promoting to production. 1. Fork this repository -2. Create a feature branch from `staging` +2. Create a feature branch from `main` (the stable production branch) 3. Make your changes 4. Submit a PR to the `staging` branch 5. Your changes will be tested on the staging environment @@ -160,10 +160,10 @@ Pull requests run tests automatically via GitHub Actions. ## Submission -1. Fork and create a feature branch -2. Make changes +1. Fork this repository and create a feature branch from `main` +2. Make your changes 3. Run tests (`pytest tests/ -v`) -4. Push and create pull request +4. Push your branch and create a pull request to the `staging` branch ## Questions? diff --git a/README.md b/README.md index 4479da2..4f10996 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,10 @@ Load the GeoJSON files into any mapping tool. Parse the CSV for historical analy We welcome contributions! To submit changes: 1. Fork this repository -2. Create a feature branch from `staging` +2. Create a feature branch from `main` 3. Make your changes to `events.csv` and/or add geometry files 4. Run validation: `python3 scripts/validate.py` -5. Submit a pull request to the `staging` branch +5. Submit a pull request to the `staging` branch (changes are tested there before production) 6. Wait for review - a maintainer will test your changes and merge if approved See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed format specs and examples. From 19d94360f634fb845c5140848f69ab6dff756625 Mon Sep 17 00:00:00 2001 From: jackson Date: Tue, 14 Oct 2025 22:56:15 -0700 Subject: [PATCH 09/24] Add flexibility field to distinguish point-to-point vs stop-to-stop services This adds a new 'flexibility' field to track whether riders can travel freely between any points in the service area (point-to-point) or only to/from predetermined stops (stop-to-stop). Changes: - Add flexibility column to events.csv after direct_booking - Populate all service_created events with flexibility values - Most services: Point-to-Point - Zoox Las Vegas: Stop-to-Stop - Update CONTRIBUTING.md with flexibility field documentation - Add flexibility_updated event type support to rebuild-cache.js - Add flexibility validation to test_validation.py Services with stop-to-stop flexibility will display with dashed borders and reduced opacity in the map UI to indicate limited service. The field is backward compatible - optional in TypeScript and handled gracefully when missing from old data. --- CONTRIBUTING.md | 16 +++++++++++++--- events.csv | 22 +++++++++++----------- rebuild-cache.js | 8 ++++++-- tests/test_validation.py | 11 ++++++++--- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3616310..44e2b63 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,7 @@ Each row in `events.csv` represents one change to a service. Service creation ev ## CSV structure -14 columns capture service attributes: +15 columns capture service attributes: | Column | Description | Example | Required? | | ---------------- | -------------------------- | -------------------------------------------- | ------------- | @@ -32,6 +32,7 @@ Each row in `events.csv` represents one change to a service. Service creation ev | `platform` | Booking app | `Robotaxi` | If applicable | | `fares` | Charges fares? | `Yes` / `No` | If applicable | | `direct_booking` | Can book AV directly? | `Yes` / `No` | If applicable | +| `flexibility` | Travel flexibility | `Point-to-Point` / `Stop-to-Stop` | If applicable | | `supervision` | Supervision level | `Autonomous` / `Safety Driver` | If applicable | | `access` | Access policy | `Public` / `Waitlist` | If applicable | | `fleet_partner` | Fleet partnerships | `Moove` | If applicable | @@ -43,10 +44,10 @@ Each row in `events.csv` represents one change to a service. Service creation ev For `service_created` events, fill in all service attributes: ```csv -2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Autonomous,Public,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service +2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Stop-to-Stop,Autonomous,Public,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service ``` -Required: `date`, `event_type`, `company`, `city`, `vehicles`, `platform`, `fares`, `direct_booking`, `supervision`, `access`, `source_url` +Required: `date`, `event_type`, `company`, `city`, `vehicles`, `platform`, `fares`, `direct_booking`, `flexibility`, `supervision`, `access`, `source_url` ## Updating a service @@ -80,6 +81,12 @@ Note: Multiple platforms separated by `;` (semicolon). This allows filtering by 2024-11-12,access_policy_changed,Waymo,Los Angeles,,,,,,,Public,,https://waymo.com/blog/2024/11/waymo-one-open-to-all-in-los-angeles,Access policy update ``` +### Flexibility change + +```csv +2026-03-15,flexibility_updated,Zoox,Las Vegas,,,,,,,Point-to-Point,,,https://example.com,Service now allows point-to-point travel +``` + ## Event types **Service lifecycle:** @@ -95,6 +102,7 @@ Note: Multiple platforms separated by `;` (semicolon). This allows filtering by - `fares_policy_changed` - Fare policy changes - `access_policy_changed` - Access changes - `supervision_updated` - Supervision level changes +- `flexibility_updated` - Travel flexibility changes - `fleet_partner_changed` - Fleet partnership changes ## Field values @@ -113,6 +121,8 @@ Add new values when documenting companies, vehicles, platforms, or policies not **Direct Booking:** `Yes` (book AV directly), `No` (may or may not get AV, like Waymo on UberX) +**Flexibility:** `Point-to-Point` (riders can travel freely between any points in the service area), `Stop-to-Stop` (riders can only travel to/from predetermined stops) + **Supervision:** `Autonomous`, `Safety Driver`, `Safety Attendant` **Access:** `Public`, `Waitlist` diff --git a/events.csv b/events.csv index 9b6f0b7..bfc8e53 100644 --- a/events.csv +++ b/events.csv @@ -1,18 +1,18 @@ -date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_booking,supervision,access,fleet_partner,source_url,notes -2017-04-25,service_created,Waymo,Phoenix,waymo-phoenix-april-25-2017-boundary.geojson,Chrysler Pacifica Hybrid,Waymo,No,Yes,Safety Driver,Waitlist,,https://www.technologyreview.com/2017/04/25/152152/waymo-has-invited-the-public-to-hop-into-its-self-driving-cars/,Waymo Phoenix service +date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_booking,flexibility,supervision,access,fleet_partner,source_url,notes +2017-04-25,service_created,Waymo,Phoenix,waymo-phoenix-april-25-2017-boundary.geojson,Chrysler Pacifica Hybrid,Waymo,No,Yes,Point-to-Point,Safety Driver,Waitlist,,https://www.technologyreview.com/2017/04/25/152152/waymo-has-invited-the-public-to-hop-into-its-self-driving-cars/,Waymo Phoenix service 2017-11-07,supervision_updated,Waymo,Phoenix,,,,,,Autonomous,,,https://waymo.com/blog/2017/11/waymos-fully-self-driving-vehicles-are-here,Supervision level update 2020-10-08,fares_policy_changed,Waymo,Phoenix,,,,Yes,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Fares policy update 2020-10-08,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace;Chrysler Pacifica Hybrid,,,,,,,https://techcrunch.com/2019/06/17/waymos-self-driving-jaguar-i-pace-vehicles-are-now-testing-on-public-roads/,Vehicle fleet expansion - adding Jaguar I-Pace 2020-10-08,access_policy_changed,Waymo,Phoenix,,,,,,,Public,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Access policy update 2020-10-08,geometry_updated,Waymo,Phoenix,waymo-phoenix-october-8-2020-boundary.geojson,,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Service area boundary update 2022-11-01,geometry_updated,Waymo,Phoenix,waymo-phoenix-november-1-2022-boundary.geojson,,,,,,,,https://techcrunch.com/2022/11/01/waymo-launches-autonomous-rides-to-phoenix-airport/,Service area boundary update -2022-12-16,service_created,Waymo,San Francisco,waymo-san-francisco-december-16-2022-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Autonomous,Waitlist,,https://waymo.com/blog/2022/12/wheels-up-for-waymo-as-we-expand,Waymo San Francisco service +2022-12-16,service_created,Waymo,San Francisco,waymo-san-francisco-december-16-2022-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Point-to-Point,Autonomous,Waitlist,,https://waymo.com/blog/2022/12/wheels-up-for-waymo-as-we-expand,Waymo San Francisco service 2023-03-30,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace,,,,,,,https://techcrunch.com/2023/03/30/waymo-retires-its-self-driving-chrysler-pacifica-minivan/,Vehicle fleet change - retiring Chrysler Pacifica Hybrid 2023-05-04,geometry_updated,Waymo,Phoenix,waymo-phoenix-may-4-2023-boundary.geojson,,,,,,,,https://waymo.com/blog/2023/05/waymo-one-doubles-service-area-in,Service area boundary update 2023-08-21,fares_policy_changed,Waymo,San Francisco,,,,Yes,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Fares policy update 2023-08-21,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-21-2023-boundary.geojson,,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Service area boundary update 2023-10-26,platform_updated,Waymo,Phoenix,,,Waymo;Uber,,,,,,https://waymo.com/blog/2023/10/the-waymo-driver-now-available-on-uber-in-phoenix,Booking platform update -2024-03-13,service_created,Waymo,Los Angeles,waymo-los-angeles-march-13-2024-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Autonomous,Waitlist,,https://waymo.com/blog/2024/03/scaling-waymo-one-safely-across-four-cities-this-year,Waymo Los Angeles service +2024-03-13,service_created,Waymo,Los Angeles,waymo-los-angeles-march-13-2024-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Point-to-Point,Autonomous,Waitlist,,https://waymo.com/blog/2024/03/scaling-waymo-one-safely-across-four-cities-this-year,Waymo Los Angeles service 2024-04-10,fares_policy_changed,Waymo,Los Angeles,,,,Yes,,,,,https://www.nbcnews.com/tech/innovation/waymo-will-launch-paid-robotaxi-service-los-angeles-wednesday-rcna147101,Fares policy update 2024-06-05,geometry_updated,Waymo,Phoenix,waymo-phoenix-june-5-2024-boundary.geojson,,,,,,,,https://waymo.com/blog/2024/06/largest-autonomous-ride-hail-territory-in-us-now-even-larger,Service area boundary update 2024-06-25,access_policy_changed,Waymo,San Francisco,,,,,,,Public,,https://waymo.com/blog/2024/06/waymo-one-is-now-open-to-everyone-in-san-francisco,Access policy update @@ -20,18 +20,18 @@ date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_bookin 2024-08-06,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-6-2024-boundary.geojson,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update 2024-11-12,access_policy_changed,Waymo,Los Angeles,,,,,,,Public,,https://waymo.com/blog/2024/11/waymo-one-open-to-all-in-los-angeles,Access policy update 2024-12-05,fleet_partner_changed,Waymo,Phoenix,,,,,,,,Moove,https://www.prnewswire.com/news-releases/moove-partners-with-waymo-to-redefine-the-future-of-urban-mobility-302324144.html,Fleet partnership with Moove established -2025-03-04,service_created,Waymo,Austin,waymo-austin-march-4-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Autonomous,Public,,https://www.cnbc.com/2025/03/04/waymo-uber-begin-offering-robotaxi-rides-in-austin-ahead-of-sxsw.html,Waymo Austin service -2025-03-11,service_created,Waymo,Silicon Valley,waymo-silicon-valley-march-11-2025-boundary.geojson,Jaguar I-Pace,Waymo,Yes,Yes,Autonomous,Public,,https://www.mercurynews.com/2025/03/11/alphabets-waymo-to-offer-self-driving-rides-in-silicon-valley/,Waymo Silicon Valley service +2025-03-04,service_created,Waymo,Austin,waymo-austin-march-4-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Point-to-Point,Autonomous,Public,,https://www.cnbc.com/2025/03/04/waymo-uber-begin-offering-robotaxi-rides-in-austin-ahead-of-sxsw.html,Waymo Austin service +2025-03-11,service_created,Waymo,Silicon Valley,waymo-silicon-valley-march-11-2025-boundary.geojson,Jaguar I-Pace,Waymo,Yes,Yes,Point-to-Point,Autonomous,Public,,https://www.mercurynews.com/2025/03/11/alphabets-waymo-to-offer-self-driving-rides-in-silicon-valley/,Waymo Silicon Valley service 2025-06-17,geometry_updated,Waymo,Silicon Valley,waymo-silicon-valley-june-17-2025-boundary.geojson,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update 2025-06-17,geometry_updated,Waymo,San Francisco,waymo-san-francisco-june-17-2025-boundary.geojson,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update 2025-06-18,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-june-18-2025-boundary.geojson,,,,,,,,https://techcrunch.com/2025/06/17/waymo-robotaxis-are-pushing-into-even-more-california-cities/,Service area boundary update -2025-06-22,service_created,Tesla,Austin,tesla-austin-june-22-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Safety Attendant,Waitlist,,https://www.cnbc.com/2025/06/20/tesla-robotaxi-launch-austin.html,Tesla Austin service -2025-06-24,service_created,Waymo,Atlanta,waymo-atlanta-june-24-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Autonomous,Public,,https://www.uber.com/newsroom/waymo-on-uber-atl/,Waymo Atlanta service +2025-06-22,service_created,Tesla,Austin,tesla-austin-june-22-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Point-to-Point,Safety Attendant,Waitlist,,https://www.cnbc.com/2025/06/20/tesla-robotaxi-launch-austin.html,Tesla Austin service +2025-06-24,service_created,Waymo,Atlanta,waymo-atlanta-june-24-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Point-to-Point,Autonomous,Public,,https://www.uber.com/newsroom/waymo-on-uber-atl/,Waymo Atlanta service 2025-07-14,geometry_updated,Tesla,Austin,tesla-austin-july-14-2025-boundary.geojson,,,,,,,,https://www.businessinsider.com/tesla-new-robotaxi-geofence-austin-shape-elon-musk-bigger-waymo-2025-7,Service area boundary update 2025-07-17,geometry_updated,Waymo,Austin,waymo-austin-july-17-2025-boundary.geojson,,,,,,,,https://www.axios.com/local/austin/2025/07/17/waymo-expands-austin-service-area,Service area boundary update -2025-07-31,service_created,Tesla,Bay Area,tesla-bay-area-july-31-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Safety Driver,Waitlist,,https://www.businessinsider.com/teslas-ride-hailing-service-live-in-san-francisco-musk-says-2025-7,Tesla Bay Area service +2025-07-31,service_created,Tesla,Bay Area,tesla-bay-area-july-31-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Point-to-Point,Safety Driver,Waitlist,,https://www.businessinsider.com/teslas-ride-hailing-service-live-in-san-francisco-musk-says-2025-7,Tesla Bay Area service 2025-08-03,geometry_updated,Tesla,Austin,tesla-austin-august-3-2025-boundary.geojson,,,,,,,,https://www.pcmag.com/news/teslas-robotaxi-coverage-expands-four-times-the-size-of-initial-austin,Service area boundary update 2025-08-26,geometry_updated,Tesla,Austin,tesla-austin-august-26-2025-boundary.geojson,,,,,,,,https://electrek.co/2025/08/27/tesla-announces-50-increase-in-austin-robotaxi-but-50-from-what/,Service area boundary update 2025-09-01,supervision_updated,Tesla,Austin,,,,,,Safety Driver,,,https://mashable.com/article/tesla-robotaxi-human-safety-monitor-drivers-seat#:~:text=Tesla%20now%20puts%20their%20robotaxi%20safety%20monitors%20in%20the%20driver%27s&text=Texas%20SB%202807%2C%20which%20went%20into%20effect%20on%20Sept.,Supervision level update -2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Safety Driver,Public,,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service -2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Autonomous,Public,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service +2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Point-to-Point,Safety Driver,Public,,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service +2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Stop-to-Stop,Autonomous,Public,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service diff --git a/rebuild-cache.js b/rebuild-cache.js index 2138f8c..33f0ded 100644 --- a/rebuild-cache.js +++ b/rebuild-cache.js @@ -290,9 +290,9 @@ function buildServiceAreasFromEvents(events) { } } - } else if (['service_updated', 'fares_policy_changed', 'access_policy_changed', 'vehicle_types_updated', 'platform_updated', 'supervision_updated', 'fleet_partner_changed'].includes(event.event_type)) { + } else if (['service_updated', 'fares_policy_changed', 'access_policy_changed', 'vehicle_types_updated', 'platform_updated', 'supervision_updated', 'flexibility_updated', 'fleet_partner_changed'].includes(event.event_type)) { if (currentState.isActive) { - const shouldCreateNewState = ['fares_policy_changed', 'access_policy_changed', 'vehicle_types_updated', 'platform_updated', 'supervision_updated', 'fleet_partner_changed'].includes(event.event_type) + const shouldCreateNewState = ['fares_policy_changed', 'access_policy_changed', 'vehicle_types_updated', 'platform_updated', 'supervision_updated', 'flexibility_updated', 'fleet_partner_changed'].includes(event.event_type) if (shouldCreateNewState) { // Check if last state has same effectiveDate - if so, update in place instead of creating new state @@ -312,6 +312,8 @@ function buildServiceAreasFromEvents(events) { lastState.platform = event.event_data.new_platform } else if (event.event_type === 'supervision_updated') { lastState.supervision = event.event_data.new_supervision + } else if (event.event_type === 'flexibility_updated') { + lastState.flexibility = event.event_data.new_flexibility } else if (event.event_type === 'fleet_partner_changed') { lastState.fleet_partner = event.event_data.new_fleet_partner } @@ -337,6 +339,8 @@ function buildServiceAreasFromEvents(events) { newState.platform = event.event_data.new_platform } else if (event.event_type === 'supervision_updated') { newState.supervision = event.event_data.new_supervision + } else if (event.event_type === 'flexibility_updated') { + newState.flexibility = event.event_data.new_flexibility } else if (event.event_type === 'fleet_partner_changed') { newState.fleet_partner = event.event_data.new_fleet_partner } diff --git a/tests/test_validation.py b/tests/test_validation.py index 1a93174..2216a38 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -40,7 +40,7 @@ def test_csv_headers(csv_file): """Test that CSV has correct headers.""" expected_headers = [ 'date', 'event_type', 'company', 'city', 'geometry_file', - 'vehicles', 'platform', 'fares', 'direct_booking', 'supervision', + 'vehicles', 'platform', 'fares', 'direct_booking', 'flexibility', 'supervision', 'access', 'fleet_partner', 'source_url', 'notes' ] @@ -87,7 +87,7 @@ def test_event_types(csv_file): valid_event_types = [ 'service_created', 'service_ended', 'geometry_updated', 'vehicle_types_updated', 'supervision_updated', 'fares_policy_changed', - 'access_policy_changed', 'platform_updated', 'fleet_partner_changed' + 'access_policy_changed', 'flexibility_updated', 'platform_updated', 'fleet_partner_changed' ] errors = [] @@ -112,7 +112,7 @@ def test_service_created_events(csv_file): for row_num, row in enumerate(reader, start=2): if row.get('event_type') == 'service_created': required_fields = ['company', 'city', 'vehicles', 'platform', 'fares', - 'direct_booking', 'supervision', 'access'] + 'direct_booking', 'flexibility', 'supervision', 'access'] for field in required_fields: if not row.get(field, '').strip(): errors.append(f"Row {row_num}: service_created event missing required field: {field}") @@ -209,6 +209,11 @@ def test_service_attribute_values(csv_file): if direct_booking and direct_booking not in ['Yes', 'No']: errors.append(f"Row {row_num}: direct_booking must be 'Yes' or 'No', got: {direct_booking}") + flexibility = row.get('flexibility', '').strip() + valid_flexibility = ['Point-to-Point', 'Stop-to-Stop'] + if flexibility and flexibility not in valid_flexibility: + errors.append(f"Row {row_num}: flexibility must be one of {valid_flexibility}, got: {flexibility}") + supervision = row.get('supervision', '').strip() valid_supervision = ['Autonomous', 'Safety Driver', 'Safety Attendant'] if supervision and supervision not in valid_supervision: From 2221d0a513c9e81c68cfd1b21fb7c38799b850f7 Mon Sep 17 00:00:00 2001 From: jackson Date: Tue, 14 Oct 2025 23:26:49 -0700 Subject: [PATCH 10/24] Add CSV import script to sync events.csv to Supabase database This adds a new import-csv.js script that reads events.csv and syncs it to the Supabase database (production or staging). The script: - Parses events.csv with proper handling of optional columns - Converts CSV rows to the database event format (event sourcing) - Maps CSV fields to event_data structure - Handles all event types (service_created, *_updated, *_changed) - Clears and repopulates the database table - Verifies import success Usage: node import-csv.js # Import to production STAGING=true node import-csv.js # Import to staging This solves the missing flexibility field issue - now when events.csv is updated, you can run this script to sync it to the database, then rebuild the cache. Changes: - Add import-csv.js script - Add csv-parse dependency to package.json - Includes flexibility field mapping --- import-csv.js | 207 ++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 7 ++ package.json | 1 + 3 files changed, 215 insertions(+) create mode 100644 import-csv.js diff --git a/import-csv.js b/import-csv.js new file mode 100644 index 0000000..b9bf917 --- /dev/null +++ b/import-csv.js @@ -0,0 +1,207 @@ +#!/usr/bin/env node + +/** + * Import CSV to Supabase + * + * This script reads events.csv and syncs it to the Supabase database. + * It will create/update events in the database based on the CSV. + * + * Usage: + * node import-csv.js # Import to production + * STAGING=true node import-csv.js # Import to staging + */ + +import { createClient } from '@supabase/supabase-js' +import { config } from 'dotenv' +import fs from 'fs' +import { parse } from 'csv-parse/sync' + +// Load .env file +if (!process.env.GITHUB_ACTIONS) { + config() +} + +const supabaseUrl = process.env.SUPABASE_URL +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY || process.env.SUPABASE_ANON_KEY + +if (!supabaseUrl || !supabaseServiceKey) { + console.error('❌ Missing required environment variables!') + console.error('Please set SUPABASE_URL and SUPABASE_SERVICE_KEY in .env') + process.exit(1) +} + +const isStaging = process.env.STAGING === 'true' +const environment = isStaging ? 'staging' : 'production' +const eventsTable = isStaging ? 'av_events_staging' : 'av_events' + +console.log(`🌍 Environment: ${environment.toUpperCase()}`) +console.log(`📋 Events table: ${eventsTable}`) +console.log('') + +const supabase = createClient(supabaseUrl, supabaseServiceKey) + +// Map CSV column names to database field names +const FIELD_MAPPING = { + 'date': 'event_date', + 'event_type': 'event_type', + 'company': 'company', + 'city': 'city', + 'geometry_file': 'geometry_name', + 'vehicles': 'vehicle_types', + 'platform': 'platform', + 'fares': 'fares', + 'direct_booking': 'direct_booking', + 'flexibility': 'flexibility', + 'supervision': 'supervision', + 'access': 'access', + 'fleet_partner': 'fleet_partner', + 'source_url': 'event_url', + 'notes': 'notes' +} + +function csvRowToEvent(row) { + const company = row.company?.trim() + const city = row.city?.trim() + const date = row.date?.trim() + + if (!company || !city || !date) { + throw new Error('Missing required fields: company, city, or date') + } + + // Create aggregate_id (unique identifier for the service) + const aggregateId = `${company.toLowerCase().replace(/\s+/g, '-')}-${city.toLowerCase().replace(/\s+/g, '-')}` + + // Build event_data object with all service attributes + const eventData = { + name: city, // city becomes "name" in event_data + company: company // company goes in event_data too + } + + // Map all CSV fields to event_data, excluding date/event_type which go in top level + Object.keys(row).forEach(csvKey => { + const value = row[csvKey]?.trim() + if (!value) return // Skip empty values + + const dbKey = FIELD_MAPPING[csvKey] + if (dbKey && !['event_date', 'event_type'].includes(dbKey)) { + // Convert geometry_file to geometry_name format (without .geojson extension) + if (csvKey === 'geometry_file') { + eventData.geometry_name = value.replace(/\.geojson$/, '') + } else { + eventData[dbKey] = value + } + } + }) + + // Parse event type specific data + if (row.event_type === 'fares_policy_changed') { + eventData.new_fares = row.fares + } else if (row.event_type === 'access_policy_changed') { + eventData.new_access = row.access + } else if (row.event_type === 'supervision_updated') { + eventData.new_supervision = row.supervision + } else if (row.event_type === 'platform_updated') { + eventData.new_platform = row.platform + } else if (row.event_type === 'vehicle_types_updated') { + eventData.new_vehicle_types = row.vehicles + } else if (row.event_type === 'fleet_partner_changed') { + eventData.new_fleet_partner = row.fleet_partner + } else if (row.event_type === 'flexibility_updated') { + eventData.new_flexibility = row.flexibility + } + + return { + aggregate_id: aggregateId, + aggregate_type: 'service_area', + event_date: date, + event_type: row.event_type, + event_data: eventData + } +} + +async function importCSV() { + console.log('📖 Reading events.csv...') + + try { + // Read CSV file + const csvContent = fs.readFileSync('./events.csv', 'utf-8') + const records = parse(csvContent, { + columns: true, + skip_empty_lines: true, + trim: true, + relax_column_count: true // Allow rows with different column counts + }) + + console.log(` Found ${records.length} events in CSV\n`) + + // Convert CSV rows to event objects + console.log('🔄 Converting CSV to event format...') + const events = records.map((row, index) => { + try { + return csvRowToEvent(row) + } catch (error) { + console.error(` ❌ Error on row ${index + 2}:`, error.message) + throw error + } + }) + console.log(` ✅ Converted ${events.length} events\n`) + + // Clear existing events in the table + console.log(`🗑️ Clearing ${eventsTable} table...`) + const { error: deleteError } = await supabase + .from(eventsTable) + .delete() + .neq('id', '00000000-0000-0000-0000-000000000000') + + if (deleteError) throw deleteError + console.log(' ✅ Table cleared\n') + + // Insert events in batches + console.log('📥 Importing events to database...') + const BATCH_SIZE = 50 + let imported = 0 + + for (let i = 0; i < events.length; i += BATCH_SIZE) { + const batch = events.slice(i, i + BATCH_SIZE) + const { error: insertError } = await supabase + .from(eventsTable) + .insert(batch) + + if (insertError) { + console.error(` ❌ Error inserting batch ${Math.floor(i/BATCH_SIZE) + 1}:`, insertError) + throw insertError + } + + imported += batch.length + console.log(` Progress: ${imported}/${events.length} events`) + } + + console.log(` ✅ Imported ${imported} events\n`) + + // Verify count + console.log('🔍 Verifying import...') + const { count, error: countError } = await supabase + .from(eventsTable) + .select('id', { count: 'exact', head: true }) + + if (countError) throw countError + + console.log(` CSV events: ${events.length}`) + console.log(` Database events: ${count}\n`) + + if (count === events.length) { + console.log('✅ Import complete! All events synced successfully.') + console.log('\n📝 Next steps:') + console.log(` Run: ${isStaging ? 'STAGING=true ' : ''}node rebuild-cache.js`) + } else { + console.error('❌ Count mismatch! Import may have failed.') + process.exit(1) + } + + } catch (error) { + console.error('❌ Import failed:', error) + process.exit(1) + } +} + +importCSV() diff --git a/package-lock.json b/package-lock.json index c5ef78b..3423b29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "": { "dependencies": { "@supabase/supabase-js": "^2.58.0", + "csv-parse": "^6.1.0", "dotenv": "^16.4.5" } }, @@ -107,6 +108,12 @@ "@types/node": "*" } }, + "node_modules/csv-parse": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-6.1.0.tgz", + "integrity": "sha512-CEE+jwpgLn+MmtCpVcPtiCZpVtB6Z2OKPTr34pycYYoL7sxdOkXDdQ4lRiw6ioC0q6BLqhc6cKweCVvral8yhw==", + "license": "MIT" + }, "node_modules/dotenv": { "version": "16.6.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", diff --git a/package.json b/package.json index 53e7f95..24b0ad6 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "type": "module", "dependencies": { "@supabase/supabase-js": "^2.58.0", + "csv-parse": "^6.1.0", "dotenv": "^16.4.5" } } From 942184a089dd286c4340dc9bfe71ab529c4face4 Mon Sep 17 00:00:00 2001 From: jackson Date: Tue, 14 Oct 2025 23:34:07 -0700 Subject: [PATCH 11/24] Fix field naming: transform snake_case to camelCase in cache The database stores fields in snake_case (direct_booking, vehicle_types, fleet_partner) but the frontend TypeScript interfaces expect camelCase (directBooking, vehicleTypes, fleetPartner). Added transformEventData() helper to convert field names during cache rebuild so the generated JSON uses camelCase throughout. This fixes the issue where Zoox showed directBooking: null instead of "Yes". --- rebuild-cache.js | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/rebuild-cache.js b/rebuild-cache.js index 33f0ded..6a952ff 100644 --- a/rebuild-cache.js +++ b/rebuild-cache.js @@ -222,6 +222,31 @@ async function rebuildCache() { } } +// Helper function to transform snake_case to camelCase for frontend compatibility +function transformEventData(eventData) { + const transformed = { ...eventData } + + // Transform snake_case fields to camelCase + if (transformed.direct_booking !== undefined) { + transformed.directBooking = transformed.direct_booking + delete transformed.direct_booking + } + if (transformed.vehicle_types !== undefined) { + transformed.vehicleTypes = transformed.vehicle_types + delete transformed.vehicle_types + } + if (transformed.fleet_partner !== undefined) { + transformed.fleetPartner = transformed.fleet_partner + delete transformed.fleet_partner + } + if (transformed.geometry_name !== undefined) { + transformed.geojsonPath = transformed.geometry_name + delete transformed.geometry_name + } + + return transformed +} + // Service area processing logic function buildServiceAreasFromEvents(events) { const currentServiceStates = new Map() @@ -237,14 +262,15 @@ function buildServiceAreasFromEvents(events) { const currentState = currentServiceStates.get(serviceId) || { isActive: false } if (event.event_type === 'service_created') { + const transformedData = transformEventData(event.event_data) const newState = { - ...event.event_data, + ...transformedData, id: `${serviceId}-${event.event_date}`, serviceId: serviceId, effectiveDate: eventDate, lastUpdated: eventDate, isActive: true, - geojsonPath: event.event_data.geometry_name + geojsonPath: transformedData.geojsonPath || event.event_data.geometry_name } currentServiceStates.set(serviceId, newState) @@ -301,13 +327,13 @@ function buildServiceAreasFromEvents(events) { const currentEventDate = eventDate.getTime() if (lastState && lastStateDate === currentEventDate) { - // Same date - update existing state in place + // Same date - update existing state in place (using camelCase for frontend) if (event.event_type === 'fares_policy_changed') { lastState.fares = event.event_data.new_fares } else if (event.event_type === 'access_policy_changed') { lastState.access = event.event_data.new_access } else if (event.event_type === 'vehicle_types_updated') { - lastState.vehicleTypes = event.event_data.new_vehicle_types + lastState.vehicleTypes = event.event_data.new_vehicle_types || event.event_data.vehicle_types } else if (event.event_type === 'platform_updated') { lastState.platform = event.event_data.new_platform } else if (event.event_type === 'supervision_updated') { @@ -315,7 +341,7 @@ function buildServiceAreasFromEvents(events) { } else if (event.event_type === 'flexibility_updated') { lastState.flexibility = event.event_data.new_flexibility } else if (event.event_type === 'fleet_partner_changed') { - lastState.fleet_partner = event.event_data.new_fleet_partner + lastState.fleetPartner = event.event_data.new_fleet_partner || event.event_data.fleet_partner } lastState.lastUpdated = eventDate currentServiceStates.set(serviceId, lastState) @@ -328,13 +354,13 @@ function buildServiceAreasFromEvents(events) { lastUpdated: eventDate } - // Apply field updates + // Apply field updates (using camelCase for frontend) if (event.event_type === 'fares_policy_changed') { newState.fares = event.event_data.new_fares } else if (event.event_type === 'access_policy_changed') { newState.access = event.event_data.new_access } else if (event.event_type === 'vehicle_types_updated') { - newState.vehicleTypes = event.event_data.new_vehicle_types + newState.vehicleTypes = event.event_data.new_vehicle_types || event.event_data.vehicle_types } else if (event.event_type === 'platform_updated') { newState.platform = event.event_data.new_platform } else if (event.event_type === 'supervision_updated') { @@ -342,7 +368,7 @@ function buildServiceAreasFromEvents(events) { } else if (event.event_type === 'flexibility_updated') { newState.flexibility = event.event_data.new_flexibility } else if (event.event_type === 'fleet_partner_changed') { - newState.fleet_partner = event.event_data.new_fleet_partner + newState.fleetPartner = event.event_data.new_fleet_partner || event.event_data.fleet_partner } if (lastState) { From dd6554529232ff077c71b2839eeda4c893d2bc4c Mon Sep 17 00:00:00 2001 From: jackson Date: Tue, 14 Oct 2025 23:57:18 -0700 Subject: [PATCH 12/24] Fix CSV column alignment for update events When the flexibility column was added, existing update events (with 14 fields) were missing the empty flexibility field, causing all subsequent columns to shift left by one. CSV changes: - Added empty flexibility field (column 10) to all rows with 14 fields - All rows now have 15 fields, properly aligned with headers Import script improvements: - For update events, only include the field being updated as new_* in event_data - Don't include the field being updated under its regular name to avoid duplication - Always include company, city, notes, and source_url for all events - For service_created, include all fields as before This fixes issues where: - fleet_partner values were appearing in the access field - source_url values were appearing in the fleet_partner field - notes values were appearing in the source_url field --- events.csv | 52 +++++++++++++++++++++++----------------------- import-csv.js | 57 ++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 73 insertions(+), 36 deletions(-) diff --git a/events.csv b/events.csv index bfc8e53..204b476 100644 --- a/events.csv +++ b/events.csv @@ -1,37 +1,37 @@ date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_booking,flexibility,supervision,access,fleet_partner,source_url,notes 2017-04-25,service_created,Waymo,Phoenix,waymo-phoenix-april-25-2017-boundary.geojson,Chrysler Pacifica Hybrid,Waymo,No,Yes,Point-to-Point,Safety Driver,Waitlist,,https://www.technologyreview.com/2017/04/25/152152/waymo-has-invited-the-public-to-hop-into-its-self-driving-cars/,Waymo Phoenix service -2017-11-07,supervision_updated,Waymo,Phoenix,,,,,,Autonomous,,,https://waymo.com/blog/2017/11/waymos-fully-self-driving-vehicles-are-here,Supervision level update -2020-10-08,fares_policy_changed,Waymo,Phoenix,,,,Yes,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Fares policy update -2020-10-08,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace;Chrysler Pacifica Hybrid,,,,,,,https://techcrunch.com/2019/06/17/waymos-self-driving-jaguar-i-pace-vehicles-are-now-testing-on-public-roads/,Vehicle fleet expansion - adding Jaguar I-Pace -2020-10-08,access_policy_changed,Waymo,Phoenix,,,,,,,Public,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Access policy update -2020-10-08,geometry_updated,Waymo,Phoenix,waymo-phoenix-october-8-2020-boundary.geojson,,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Service area boundary update -2022-11-01,geometry_updated,Waymo,Phoenix,waymo-phoenix-november-1-2022-boundary.geojson,,,,,,,,https://techcrunch.com/2022/11/01/waymo-launches-autonomous-rides-to-phoenix-airport/,Service area boundary update +2017-11-07,supervision_updated,Waymo,Phoenix,,,,,,,Autonomous,,,https://waymo.com/blog/2017/11/waymos-fully-self-driving-vehicles-are-here,Supervision level update +2020-10-08,fares_policy_changed,Waymo,Phoenix,,,,Yes,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Fares policy update +2020-10-08,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace;Chrysler Pacifica Hybrid,,,,,,,,https://techcrunch.com/2019/06/17/waymos-self-driving-jaguar-i-pace-vehicles-are-now-testing-on-public-roads/,Vehicle fleet expansion - adding Jaguar I-Pace +2020-10-08,access_policy_changed,Waymo,Phoenix,,,,,,,,Public,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Access policy update +2020-10-08,geometry_updated,Waymo,Phoenix,waymo-phoenix-october-8-2020-boundary.geojson,,,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Service area boundary update +2022-11-01,geometry_updated,Waymo,Phoenix,waymo-phoenix-november-1-2022-boundary.geojson,,,,,,,,,https://techcrunch.com/2022/11/01/waymo-launches-autonomous-rides-to-phoenix-airport/,Service area boundary update 2022-12-16,service_created,Waymo,San Francisco,waymo-san-francisco-december-16-2022-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Point-to-Point,Autonomous,Waitlist,,https://waymo.com/blog/2022/12/wheels-up-for-waymo-as-we-expand,Waymo San Francisco service -2023-03-30,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace,,,,,,,https://techcrunch.com/2023/03/30/waymo-retires-its-self-driving-chrysler-pacifica-minivan/,Vehicle fleet change - retiring Chrysler Pacifica Hybrid -2023-05-04,geometry_updated,Waymo,Phoenix,waymo-phoenix-may-4-2023-boundary.geojson,,,,,,,,https://waymo.com/blog/2023/05/waymo-one-doubles-service-area-in,Service area boundary update -2023-08-21,fares_policy_changed,Waymo,San Francisco,,,,Yes,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Fares policy update -2023-08-21,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-21-2023-boundary.geojson,,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Service area boundary update -2023-10-26,platform_updated,Waymo,Phoenix,,,Waymo;Uber,,,,,,https://waymo.com/blog/2023/10/the-waymo-driver-now-available-on-uber-in-phoenix,Booking platform update +2023-03-30,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace,,,,,,,,https://techcrunch.com/2023/03/30/waymo-retires-its-self-driving-chrysler-pacifica-minivan/,Vehicle fleet change - retiring Chrysler Pacifica Hybrid +2023-05-04,geometry_updated,Waymo,Phoenix,waymo-phoenix-may-4-2023-boundary.geojson,,,,,,,,,https://waymo.com/blog/2023/05/waymo-one-doubles-service-area-in,Service area boundary update +2023-08-21,fares_policy_changed,Waymo,San Francisco,,,,Yes,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Fares policy update +2023-08-21,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-21-2023-boundary.geojson,,,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Service area boundary update +2023-10-26,platform_updated,Waymo,Phoenix,,,Waymo;Uber,,,,,,,https://waymo.com/blog/2023/10/the-waymo-driver-now-available-on-uber-in-phoenix,Booking platform update 2024-03-13,service_created,Waymo,Los Angeles,waymo-los-angeles-march-13-2024-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Point-to-Point,Autonomous,Waitlist,,https://waymo.com/blog/2024/03/scaling-waymo-one-safely-across-four-cities-this-year,Waymo Los Angeles service -2024-04-10,fares_policy_changed,Waymo,Los Angeles,,,,Yes,,,,,https://www.nbcnews.com/tech/innovation/waymo-will-launch-paid-robotaxi-service-los-angeles-wednesday-rcna147101,Fares policy update -2024-06-05,geometry_updated,Waymo,Phoenix,waymo-phoenix-june-5-2024-boundary.geojson,,,,,,,,https://waymo.com/blog/2024/06/largest-autonomous-ride-hail-territory-in-us-now-even-larger,Service area boundary update -2024-06-25,access_policy_changed,Waymo,San Francisco,,,,,,,Public,,https://waymo.com/blog/2024/06/waymo-one-is-now-open-to-everyone-in-san-francisco,Access policy update -2024-08-06,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-august-6-2024-boundary.geojson,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update -2024-08-06,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-6-2024-boundary.geojson,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update -2024-11-12,access_policy_changed,Waymo,Los Angeles,,,,,,,Public,,https://waymo.com/blog/2024/11/waymo-one-open-to-all-in-los-angeles,Access policy update -2024-12-05,fleet_partner_changed,Waymo,Phoenix,,,,,,,,Moove,https://www.prnewswire.com/news-releases/moove-partners-with-waymo-to-redefine-the-future-of-urban-mobility-302324144.html,Fleet partnership with Moove established +2024-04-10,fares_policy_changed,Waymo,Los Angeles,,,,Yes,,,,,,https://www.nbcnews.com/tech/innovation/waymo-will-launch-paid-robotaxi-service-los-angeles-wednesday-rcna147101,Fares policy update +2024-06-05,geometry_updated,Waymo,Phoenix,waymo-phoenix-june-5-2024-boundary.geojson,,,,,,,,,https://waymo.com/blog/2024/06/largest-autonomous-ride-hail-territory-in-us-now-even-larger,Service area boundary update +2024-06-25,access_policy_changed,Waymo,San Francisco,,,,,,,,Public,,https://waymo.com/blog/2024/06/waymo-one-is-now-open-to-everyone-in-san-francisco,Access policy update +2024-08-06,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-august-6-2024-boundary.geojson,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update +2024-08-06,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-6-2024-boundary.geojson,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update +2024-11-12,access_policy_changed,Waymo,Los Angeles,,,,,,,,Public,,https://waymo.com/blog/2024/11/waymo-one-open-to-all-in-los-angeles,Access policy update +2024-12-05,fleet_partner_changed,Waymo,Phoenix,,,,,,,,,Moove,https://www.prnewswire.com/news-releases/moove-partners-with-waymo-to-redefine-the-future-of-urban-mobility-302324144.html,Fleet partnership with Moove established 2025-03-04,service_created,Waymo,Austin,waymo-austin-march-4-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Point-to-Point,Autonomous,Public,,https://www.cnbc.com/2025/03/04/waymo-uber-begin-offering-robotaxi-rides-in-austin-ahead-of-sxsw.html,Waymo Austin service 2025-03-11,service_created,Waymo,Silicon Valley,waymo-silicon-valley-march-11-2025-boundary.geojson,Jaguar I-Pace,Waymo,Yes,Yes,Point-to-Point,Autonomous,Public,,https://www.mercurynews.com/2025/03/11/alphabets-waymo-to-offer-self-driving-rides-in-silicon-valley/,Waymo Silicon Valley service -2025-06-17,geometry_updated,Waymo,Silicon Valley,waymo-silicon-valley-june-17-2025-boundary.geojson,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update -2025-06-17,geometry_updated,Waymo,San Francisco,waymo-san-francisco-june-17-2025-boundary.geojson,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update -2025-06-18,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-june-18-2025-boundary.geojson,,,,,,,,https://techcrunch.com/2025/06/17/waymo-robotaxis-are-pushing-into-even-more-california-cities/,Service area boundary update +2025-06-17,geometry_updated,Waymo,Silicon Valley,waymo-silicon-valley-june-17-2025-boundary.geojson,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update +2025-06-17,geometry_updated,Waymo,San Francisco,waymo-san-francisco-june-17-2025-boundary.geojson,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update +2025-06-18,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-june-18-2025-boundary.geojson,,,,,,,,,https://techcrunch.com/2025/06/17/waymo-robotaxis-are-pushing-into-even-more-california-cities/,Service area boundary update 2025-06-22,service_created,Tesla,Austin,tesla-austin-june-22-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Point-to-Point,Safety Attendant,Waitlist,,https://www.cnbc.com/2025/06/20/tesla-robotaxi-launch-austin.html,Tesla Austin service 2025-06-24,service_created,Waymo,Atlanta,waymo-atlanta-june-24-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Point-to-Point,Autonomous,Public,,https://www.uber.com/newsroom/waymo-on-uber-atl/,Waymo Atlanta service -2025-07-14,geometry_updated,Tesla,Austin,tesla-austin-july-14-2025-boundary.geojson,,,,,,,,https://www.businessinsider.com/tesla-new-robotaxi-geofence-austin-shape-elon-musk-bigger-waymo-2025-7,Service area boundary update -2025-07-17,geometry_updated,Waymo,Austin,waymo-austin-july-17-2025-boundary.geojson,,,,,,,,https://www.axios.com/local/austin/2025/07/17/waymo-expands-austin-service-area,Service area boundary update +2025-07-14,geometry_updated,Tesla,Austin,tesla-austin-july-14-2025-boundary.geojson,,,,,,,,,https://www.businessinsider.com/tesla-new-robotaxi-geofence-austin-shape-elon-musk-bigger-waymo-2025-7,Service area boundary update +2025-07-17,geometry_updated,Waymo,Austin,waymo-austin-july-17-2025-boundary.geojson,,,,,,,,,https://www.axios.com/local/austin/2025/07/17/waymo-expands-austin-service-area,Service area boundary update 2025-07-31,service_created,Tesla,Bay Area,tesla-bay-area-july-31-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Point-to-Point,Safety Driver,Waitlist,,https://www.businessinsider.com/teslas-ride-hailing-service-live-in-san-francisco-musk-says-2025-7,Tesla Bay Area service -2025-08-03,geometry_updated,Tesla,Austin,tesla-austin-august-3-2025-boundary.geojson,,,,,,,,https://www.pcmag.com/news/teslas-robotaxi-coverage-expands-four-times-the-size-of-initial-austin,Service area boundary update -2025-08-26,geometry_updated,Tesla,Austin,tesla-austin-august-26-2025-boundary.geojson,,,,,,,,https://electrek.co/2025/08/27/tesla-announces-50-increase-in-austin-robotaxi-but-50-from-what/,Service area boundary update -2025-09-01,supervision_updated,Tesla,Austin,,,,,,Safety Driver,,,https://mashable.com/article/tesla-robotaxi-human-safety-monitor-drivers-seat#:~:text=Tesla%20now%20puts%20their%20robotaxi%20safety%20monitors%20in%20the%20driver%27s&text=Texas%20SB%202807%2C%20which%20went%20into%20effect%20on%20Sept.,Supervision level update +2025-08-03,geometry_updated,Tesla,Austin,tesla-austin-august-3-2025-boundary.geojson,,,,,,,,,https://www.pcmag.com/news/teslas-robotaxi-coverage-expands-four-times-the-size-of-initial-austin,Service area boundary update +2025-08-26,geometry_updated,Tesla,Austin,tesla-austin-august-26-2025-boundary.geojson,,,,,,,,,https://electrek.co/2025/08/27/tesla-announces-50-increase-in-austin-robotaxi-but-50-from-what/,Service area boundary update +2025-09-01,supervision_updated,Tesla,Austin,,,,,,,Safety Driver,,,https://mashable.com/article/tesla-robotaxi-human-safety-monitor-drivers-seat#:~:text=Tesla%20now%20puts%20their%20robotaxi%20safety%20monitors%20in%20the%20driver%27s&text=Texas%20SB%202807%2C%20which%20went%20into%20effect%20on%20Sept.,Supervision level update 2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Point-to-Point,Safety Driver,Public,,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service 2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Stop-to-Stop,Autonomous,Public,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service diff --git a/import-csv.js b/import-csv.js index b9bf917..89c814f 100644 --- a/import-csv.js +++ b/import-csv.js @@ -77,7 +77,21 @@ function csvRowToEvent(row) { company: company // company goes in event_data too } - // Map all CSV fields to event_data, excluding date/event_type which go in top level + // Determine which fields to include in event_data based on event type + const isUpdateEvent = [ + 'fares_policy_changed', + 'access_policy_changed', + 'supervision_updated', + 'platform_updated', + 'vehicle_types_updated', + 'fleet_partner_changed', + 'flexibility_updated', + 'geometry_updated' + ].includes(row.event_type) + + const isServiceCreated = row.event_type === 'service_created' + + // Map all CSV fields to event_data Object.keys(row).forEach(csvKey => { const value = row[csvKey]?.trim() if (!value) return // Skip empty values @@ -87,26 +101,49 @@ function csvRowToEvent(row) { // Convert geometry_file to geometry_name format (without .geojson extension) if (csvKey === 'geometry_file') { eventData.geometry_name = value.replace(/\.geojson$/, '') - } else { + } + // For service_created, include all fields + // For update events, skip the field being updated (will be added as new_* below) + // Always include company, city, notes, and source_url + else if (isServiceCreated || + csvKey === 'company' || + csvKey === 'city' || + csvKey === 'notes' || + csvKey === 'source_url') { eventData[dbKey] = value } + // For update events, only include fields that aren't being updated + else if (isUpdateEvent) { + const isFieldBeingUpdated = + (row.event_type === 'fares_policy_changed' && csvKey === 'fares') || + (row.event_type === 'access_policy_changed' && csvKey === 'access') || + (row.event_type === 'supervision_updated' && csvKey === 'supervision') || + (row.event_type === 'platform_updated' && csvKey === 'platform') || + (row.event_type === 'vehicle_types_updated' && csvKey === 'vehicles') || + (row.event_type === 'fleet_partner_changed' && csvKey === 'fleet_partner') || + (row.event_type === 'flexibility_updated' && csvKey === 'flexibility') + + if (!isFieldBeingUpdated) { + eventData[dbKey] = value + } + } } }) - // Parse event type specific data - if (row.event_type === 'fares_policy_changed') { + // Add the new_* fields for update events + if (row.event_type === 'fares_policy_changed' && row.fares) { eventData.new_fares = row.fares - } else if (row.event_type === 'access_policy_changed') { + } else if (row.event_type === 'access_policy_changed' && row.access) { eventData.new_access = row.access - } else if (row.event_type === 'supervision_updated') { + } else if (row.event_type === 'supervision_updated' && row.supervision) { eventData.new_supervision = row.supervision - } else if (row.event_type === 'platform_updated') { + } else if (row.event_type === 'platform_updated' && row.platform) { eventData.new_platform = row.platform - } else if (row.event_type === 'vehicle_types_updated') { + } else if (row.event_type === 'vehicle_types_updated' && row.vehicles) { eventData.new_vehicle_types = row.vehicles - } else if (row.event_type === 'fleet_partner_changed') { + } else if (row.event_type === 'fleet_partner_changed' && row.fleet_partner) { eventData.new_fleet_partner = row.fleet_partner - } else if (row.event_type === 'flexibility_updated') { + } else if (row.event_type === 'flexibility_updated' && row.flexibility) { eventData.new_flexibility = row.flexibility } From 2d2369bbb22b519a5dad6f93824e77ee0ffd7cb6 Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 00:00:06 -0700 Subject: [PATCH 13/24] Add CSV import step to rebuild cache workflow The workflow now runs import-csv.js before rebuild-cache.js to ensure events.csv changes are synced to the database before rebuilding the cache. Without this, CSV changes would trigger the workflow but not actually be included in the rebuilt cache (since rebuild-cache.js reads from the database, not directly from the CSV). --- .github/workflows/rebuild-cache.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/rebuild-cache.yml b/.github/workflows/rebuild-cache.yml index 426ba5e..b559459 100644 --- a/.github/workflows/rebuild-cache.yml +++ b/.github/workflows/rebuild-cache.yml @@ -52,6 +52,15 @@ jobs: - name: Install dependencies run: npm install + - name: Import CSV to database + env: + SUPABASE_URL: ${{ secrets.SUPABASE_URL }} + SUPABASE_SERVICE_KEY: ${{ secrets.SUPABASE_SERVICE_KEY }} + STAGING: ${{ steps.env.outputs.STAGING }} + run: | + echo "Importing events.csv to ${{ steps.env.outputs.ENV_NAME }} database..." + node import-csv.js + - name: Rebuild cache env: SUPABASE_URL: ${{ secrets.SUPABASE_URL }} From a783f8a0d5220431870b36fd964725e7b239d95e Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 08:22:43 -0700 Subject: [PATCH 14/24] Add automatic area calculation from GeoJSON geometries Calculate area_square_miles automatically from GeoJSON geometry files during cache rebuild. Uses @turf/area to compute area in square meters, then converts to square miles. Area is calculated: - When a service is created (service_created events) - When geometry is updated (geometry_updated events) This ensures area is always up-to-date and resilient - when new service areas are added, their area is automatically calculated from the geometry file. --- package-lock.json | 54 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + rebuild-cache.js | 38 ++++++++++++++++++++++++++++----- 3 files changed, 88 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3423b29..b3b759d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "": { "dependencies": { "@supabase/supabase-js": "^2.58.0", + "@turf/area": "^7.2.0", "csv-parse": "^6.1.0", "dotenv": "^16.4.5" } @@ -84,6 +85,53 @@ "@supabase/storage-js": "2.12.2" } }, + "node_modules/@turf/area": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/area/-/area-7.2.0.tgz", + "integrity": "sha512-zuTTdQ4eoTI9nSSjerIy4QwgvxqwJVciQJ8tOPuMHbXJ9N/dNjI7bU8tasjhxas/Cx3NE9NxVHtNpYHL0FSzoA==", + "license": "MIT", + "dependencies": { + "@turf/helpers": "^7.2.0", + "@turf/meta": "^7.2.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/helpers": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-7.2.0.tgz", + "integrity": "sha512-cXo7bKNZoa7aC7ydLmUR02oB3IgDe7MxiPuRz3cCtYQHn+BJ6h1tihmamYDWWUlPHgSNF0i3ATc4WmDECZafKw==", + "license": "MIT", + "dependencies": { + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/meta": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-7.2.0.tgz", + "integrity": "sha512-igzTdHsQc8TV1RhPuOLVo74Px/hyPrVgVOTgjWQZzt3J9BVseCdpfY/0cJBdlSRI4S/yTmmHl7gAqjhpYH5Yaw==", + "license": "MIT", + "dependencies": { + "@turf/helpers": "^7.2.0", + "@types/geojson": "^7946.0.10" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "24.6.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.6.2.tgz", @@ -132,6 +180,12 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/undici-types": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.13.0.tgz", diff --git a/package.json b/package.json index 24b0ad6..9f8edb8 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "type": "module", "dependencies": { "@supabase/supabase-js": "^2.58.0", + "@turf/area": "^7.2.0", "csv-parse": "^6.1.0", "dotenv": "^16.4.5" } diff --git a/rebuild-cache.js b/rebuild-cache.js index 6a952ff..b193a3f 100644 --- a/rebuild-cache.js +++ b/rebuild-cache.js @@ -19,6 +19,7 @@ import { createClient } from '@supabase/supabase-js' import { config } from 'dotenv' import { execSync } from 'child_process' +import area from '@turf/area' // Load .env file for local development (GitHub Actions sets env vars directly) if (!process.env.GITHUB_ACTIONS) { @@ -141,9 +142,23 @@ async function rebuildCache() { console.log(`✅ Geometries: ${successful.length} loaded, ${failed.length} failed`) + // Create geometry lookup map with calculated areas + const geometryMap = new Map() + geometriesWithData.forEach(geo => { + if (geo.geojson_data) { + // Calculate area in square meters and convert to square miles + const areaSquareMeters = area(geo.geojson_data) + const areaSquareMiles = areaSquareMeters / 2589988.11 // 1 sq mi = 2,589,988.11 sq m + geometryMap.set(geo.geometry_name, { + geojson: geo.geojson_data, + area_square_miles: Math.round(areaSquareMiles * 100) / 100 // Round to 2 decimals + }) + } + }) + // STEP 3: Process service areas console.log('⚙️ Processing service areas...') - const serviceAreas = buildServiceAreasFromEvents(events) + const serviceAreas = buildServiceAreasFromEvents(events, geometryMap) // STEP 4: Create final data structure const cacheData = { @@ -248,7 +263,7 @@ function transformEventData(eventData) { } // Service area processing logic -function buildServiceAreasFromEvents(events) { +function buildServiceAreasFromEvents(events, geometryMap) { const currentServiceStates = new Map() const allStates = [] @@ -263,6 +278,12 @@ function buildServiceAreasFromEvents(events) { if (event.event_type === 'service_created') { const transformedData = transformEventData(event.event_data) + const geojsonPath = transformedData.geojsonPath || event.event_data.geometry_name + + // Add calculated area from geometry + const geometryData = geometryMap.get(geojsonPath) + const areaSquareMiles = geometryData?.area_square_miles || null + const newState = { ...transformedData, id: `${serviceId}-${event.event_date}`, @@ -270,7 +291,8 @@ function buildServiceAreasFromEvents(events) { effectiveDate: eventDate, lastUpdated: eventDate, isActive: true, - geojsonPath: transformedData.geojsonPath || event.event_data.geometry_name + geojsonPath: geojsonPath, + area_square_miles: areaSquareMiles } currentServiceStates.set(serviceId, newState) @@ -292,9 +314,14 @@ function buildServiceAreasFromEvents(events) { const lastStateDate = lastState ? new Date(lastState.effectiveDate).getTime() : 0 const currentEventDate = eventDate.getTime() + const newGeojsonPath = event.event_data.geometry_name || event.event_data.new_geometry_name || lastState?.geojsonPath + const geometryData = geometryMap.get(newGeojsonPath) + const areaSquareMiles = geometryData?.area_square_miles || null + if (lastState && lastStateDate === currentEventDate) { // Same date - update existing state in place - lastState.geojsonPath = event.event_data.geometry_name || event.event_data.new_geometry_name || lastState.geojsonPath + lastState.geojsonPath = newGeojsonPath + lastState.area_square_miles = areaSquareMiles lastState.lastUpdated = eventDate currentServiceStates.set(serviceId, lastState) } else { @@ -304,7 +331,8 @@ function buildServiceAreasFromEvents(events) { id: `${serviceId}-${event.event_date}`, effectiveDate: eventDate, lastUpdated: eventDate, - geojsonPath: event.event_data.geometry_name || event.event_data.new_geometry_name || currentState.geojsonPath + geojsonPath: newGeojsonPath, + area_square_miles: areaSquareMiles } if (lastState) { From 4064794a7467fe04743891d460844008ec9d09b4 Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 11:32:51 -0700 Subject: [PATCH 15/24] adding cruise service areas --- .../cruise-san-francisco-february-1-2022-boundary.geojson | 8 ++++++++ .../cruise-san-francisco-november-1-2022-boundary.geojson | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 geometries/cruise-san-francisco-february-1-2022-boundary.geojson create mode 100644 geometries/cruise-san-francisco-november-1-2022-boundary.geojson diff --git a/geometries/cruise-san-francisco-february-1-2022-boundary.geojson b/geometries/cruise-san-francisco-february-1-2022-boundary.geojson new file mode 100644 index 0000000..c2f21e9 --- /dev/null +++ b/geometries/cruise-san-francisco-february-1-2022-boundary.geojson @@ -0,0 +1,8 @@ +{ +"type": "FeatureCollection", +"name": "cruise-san-francisco-february-16-2022-boundary", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, +"features": [ +{ "type": "Feature", "properties": { "id": null }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -122.508343556090693, 37.73793792328955 ], [ -122.512269297911203, 37.764235679698452 ], [ -122.512705491446837, 37.77509694264144 ], [ -122.502345894976003, 37.775614105845655 ], [ -122.502782088511623, 37.781302662321522 ], [ -122.492858685576337, 37.781819782112471 ], [ -122.492749637192446, 37.783715857059512 ], [ -122.472466637786397, 37.784577693228456 ], [ -122.472139492634668, 37.786215154261882 ], [ -122.466032783136072, 37.786473697424327 ], [ -122.465814686368262, 37.784836242119411 ], [ -122.445749783729966, 37.787507861029027 ], [ -122.447821703024132, 37.80017519063076 ], [ -122.443786912819704, 37.798796539000811 ], [ -122.437353058169407, 37.799399702255066 ], [ -122.436371622714248, 37.796297667337626 ], [ -122.424594397252662, 37.797417861639765 ], [ -122.423831058565341, 37.798710372419578 ], [ -122.420559607048204, 37.798451872072825 ], [ -122.420123413512584, 37.796470006028166 ], [ -122.416633865227695, 37.796211497841568 ], [ -122.416197671692075, 37.795608308555003 ], [ -122.40998191380956, 37.796211497841568 ], [ -122.409545720273954, 37.79397105566575 ], [ -122.407582849363692, 37.793798711145705 ], [ -122.406928559060248, 37.790007029991763 ], [ -122.40976381704175, 37.78948996748592 ], [ -122.409327623506115, 37.786818420233914 ], [ -122.420777703816, 37.785094790105873 ], [ -122.419905316744803, 37.780699351326177 ], [ -122.422958671494101, 37.780182223696535 ], [ -122.422958671494101, 37.77845843880241 ], [ -122.430810155135148, 37.777165573752185 ], [ -122.430592058367367, 37.774665970541101 ], [ -122.436916864633773, 37.773890214429606 ], [ -122.436262574330357, 37.770097511825817 ], [ -122.435172090491321, 37.768373491785297 ], [ -122.43528113887524, 37.767080450377684 ], [ -122.437244009785459, 37.766908043148455 ], [ -122.43942497746356, 37.765959796203106 ], [ -122.441278799989917, 37.76501153709939 ], [ -122.441387848373836, 37.763804644292215 ], [ -122.44051546130261, 37.76311498241725 ], [ -122.441605945141646, 37.762597731790883 ], [ -122.441933090293347, 37.761994268154979 ], [ -122.445531686962184, 37.761304589399494 ], [ -122.446731219185111, 37.758804450004625 ], [ -122.451965541612481, 37.757942313379019 ], [ -122.453928412522757, 37.756390442133231 ], [ -122.4561093802008, 37.756390442133231 ], [ -122.457745105959361, 37.755010973697019 ], [ -122.458944638182331, 37.754924756065741 ], [ -122.460907509092593, 37.758373382947767 ], [ -122.462543234851154, 37.758545810071936 ], [ -122.46319752515457, 37.753200382340964 ], [ -122.464615154145321, 37.752338180407925 ], [ -122.464615154145321, 37.751303524826241 ], [ -122.465378492832627, 37.750355077833674 ], [ -122.465378492832627, 37.747337211071809 ], [ -122.467668508894633, 37.743284453538024 ], [ -122.47541094415179, 37.743111990847943 ], [ -122.476065234455206, 37.748199471276394 ], [ -122.493403927495862, 37.747595890188073 ], [ -122.493294879111957, 37.738369109399159 ], [ -122.493294879111957, 37.738369109399159 ], [ -122.493512975879796, 37.738282872378157 ], [ -122.498638249923275, 37.738282872378157 ], [ -122.508343556090693, 37.73793792328955 ] ] ] ] } } +] +} diff --git a/geometries/cruise-san-francisco-november-1-2022-boundary.geojson b/geometries/cruise-san-francisco-november-1-2022-boundary.geojson new file mode 100644 index 0000000..f5038f2 --- /dev/null +++ b/geometries/cruise-san-francisco-november-1-2022-boundary.geojson @@ -0,0 +1,8 @@ +{ +"type": "FeatureCollection", +"name": "cruise-san-francisco-november-1-2023-boundary", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, +"features": [ +{ "type": "Feature", "properties": { "fid": 1, "DN": 255 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -122.434677831968642, 37.707452804157235 ], [ -122.438247746517717, 37.706987163129099 ], [ -122.438247746517717, 37.710401864002129 ], [ -122.44135202003865, 37.710867505030265 ], [ -122.442904156799116, 37.712109214438641 ], [ -122.447560567080515, 37.710246650326077 ], [ -122.449423131193072, 37.708228872537468 ], [ -122.453303473094252, 37.707452804157235 ], [ -122.454079541474485, 37.708228872537468 ], [ -122.456097319263094, 37.708228872537468 ], [ -122.455942105587042, 37.710867505030265 ], [ -122.458735951755884, 37.71102271870631 ], [ -122.459822447488207, 37.712109214438641 ], [ -122.461529797924726, 37.712109214438641 ], [ -122.464478857769606, 37.710401864002129 ], [ -122.47006655010729, 37.712574855466784 ], [ -122.473170823628223, 37.712885282818874 ], [ -122.474412533036599, 37.714592633255386 ], [ -122.474257319360561, 37.718783402508649 ], [ -122.470376977459381, 37.721732462353536 ], [ -122.474102105684509, 37.722974171761912 ], [ -122.474722960388704, 37.724836735874476 ], [ -122.470842618487524, 37.72732015469122 ], [ -122.471153045839628, 37.728406650423551 ], [ -122.47627509714917, 37.730269214536108 ], [ -122.47922415699405, 37.728251436747499 ], [ -122.483570139923359, 37.729493146155875 ], [ -122.484656635655682, 37.728251436747499 ], [ -122.487140054472434, 37.727941009395408 ], [ -122.490244327993366, 37.729337932479829 ], [ -122.492572533134066, 37.727630582043318 ], [ -122.494124669894546, 37.727475368367266 ], [ -122.499246721204088, 37.729803573507972 ], [ -122.499557148556178, 37.731355710268438 ], [ -122.498781080175945, 37.73275263335286 ], [ -122.501419712668735, 37.732907847028905 ], [ -122.503437490457344, 37.734459983789371 ], [ -122.505610481922005, 37.734459983789371 ], [ -122.508714755442938, 37.73678818893007 ], [ -122.511974242639909, 37.763950582238252 ], [ -122.510577319555495, 37.765192291646628 ], [ -122.508404328090833, 37.765502718998718 ], [ -122.507938687062705, 37.766589214731049 ], [ -122.512284669992013, 37.768451778843605 ], [ -122.512905524696194, 37.77512596691362 ], [ -122.514612875132713, 37.778075026758508 ], [ -122.51445766145666, 37.779937590871064 ], [ -122.512905524696194, 37.781955368659673 ], [ -122.511042960583637, 37.781024086603395 ], [ -122.509490823823171, 37.78117930027944 ], [ -122.508404328090833, 37.782421009687816 ], [ -122.502661422077111, 37.781644941307583 ], [ -122.500798857964554, 37.783352291744094 ], [ -122.498625866499893, 37.783197078068049 ], [ -122.497384157091517, 37.782110582335719 ], [ -122.49521116562687, 37.782421009687816 ], [ -122.494900738274779, 37.783973146448282 ], [ -122.495676806655013, 37.785680496884794 ], [ -122.494745524598727, 37.786766992617125 ], [ -122.492417319458028, 37.787232633645267 ], [ -122.490709969021509, 37.788939984081779 ], [ -122.486829627120343, 37.790026479814102 ], [ -122.485277490359877, 37.791268189222478 ], [ -122.483725353599411, 37.795303744799696 ], [ -122.482173216838945, 37.796235026855975 ], [ -122.482018003162892, 37.798718445672726 ], [ -122.478603302289869, 37.802133146545749 ], [ -122.47891372964196, 37.804150924334358 ], [ -122.476430310825208, 37.808341693587622 ], [ -122.468514413346824, 37.806168702122967 ], [ -122.467738344966591, 37.805237420066689 ], [ -122.467738344966591, 37.803064428602035 ], [ -122.466651849234268, 37.801977932869704 ], [ -122.465099712473801, 37.802288360221802 ], [ -122.463702789389373, 37.803685283306223 ], [ -122.461529797924726, 37.803685283306223 ], [ -122.460443302192402, 37.802598787573892 ], [ -122.458115097051689, 37.802754001249937 ], [ -122.457028601319365, 37.801512291841561 ], [ -122.455010823530756, 37.801357078165516 ], [ -122.453924327798433, 37.801977932869704 ], [ -122.454855609854718, 37.804306138010404 ], [ -122.45345868677029, 37.804926992714591 ], [ -122.436540396081199, 37.80663434315111 ], [ -122.432660054180033, 37.805237420066689 ], [ -122.4318839857998, 37.803685283306223 ], [ -122.430797490067462, 37.803685283306223 ], [ -122.426917148166297, 37.804150924334358 ], [ -122.426606720814206, 37.806168702122967 ], [ -122.423657660969312, 37.806479129475058 ], [ -122.421795096856755, 37.807876052559479 ], [ -122.413723985702333, 37.808807334615764 ], [ -122.409378002773011, 37.808496907263667 ], [ -122.40642894292813, 37.807410411531343 ], [ -122.400686036914394, 37.803064428602035 ], [ -122.391218002675544, 37.792975539658997 ], [ -122.388113729154611, 37.788629556729688 ], [ -122.388113729154611, 37.781489727631538 ], [ -122.390907575323453, 37.777609385730365 ], [ -122.387958515478573, 37.775746821617808 ], [ -122.386872019746235, 37.770003915604079 ], [ -122.385785524013912, 37.76829656516756 ], [ -122.388113729154611, 37.763950582238252 ], [ -122.388113729154611, 37.757431607844289 ], [ -122.385940737689964, 37.751533488154514 ], [ -122.384388600929498, 37.751067847126372 ], [ -122.384388600929498, 37.750136565070093 ], [ -122.386561592394145, 37.749826137717996 ], [ -122.389045011210897, 37.747963573605439 ], [ -122.393080566788115, 37.749205283013815 ], [ -122.394477489872529, 37.748894855661717 ], [ -122.393856635168348, 37.745790582140785 ], [ -122.398047404421604, 37.743462377000085 ], [ -122.398047404421604, 37.742686308619852 ], [ -122.397271336041371, 37.741444599211476 ], [ -122.397426549717423, 37.739116394070777 ], [ -122.395253558252762, 37.738650753042634 ], [ -122.394167062520438, 37.739582035098913 ], [ -122.394787917224619, 37.741289385535431 ], [ -122.394322276196476, 37.743151949647988 ], [ -122.390597147971363, 37.74563536846474 ], [ -122.388734583858806, 37.74563536846474 ], [ -122.387027233422288, 37.744548872732409 ], [ -122.387337660774378, 37.741444599211476 ], [ -122.379732190648085, 37.739116394070777 ], [ -122.379576976972047, 37.73647776157798 ], [ -122.386251165042054, 37.733683915409138 ], [ -122.386561592394145, 37.732442206000762 ], [ -122.385940737689964, 37.731510923944484 ], [ -122.384078173577393, 37.731510923944484 ], [ -122.382836464169017, 37.730269214536108 ], [ -122.38066347270437, 37.730269214536108 ], [ -122.379421763295994, 37.729337932479829 ], [ -122.379266549619956, 37.724215881170288 ], [ -122.382215609464836, 37.723129385437957 ], [ -122.384233387253445, 37.724526308522378 ], [ -122.385630310337859, 37.724526308522378 ], [ -122.387648088126468, 37.722818958085867 ], [ -122.389200224886935, 37.722818958085867 ], [ -122.393235780464153, 37.724060667494243 ], [ -122.394011848844386, 37.724991949550521 ], [ -122.399754754858122, 37.726388872634942 ], [ -122.400375609562303, 37.724836735874476 ], [ -122.399444327506032, 37.719559470888882 ], [ -122.402238173674874, 37.718472975156558 ], [ -122.40642894292813, 37.719559470888882 ], [ -122.408136293364649, 37.721111607649348 ], [ -122.409688430125115, 37.720956393973303 ], [ -122.41139578056162, 37.719249043536792 ], [ -122.41325834467419, 37.719093829860746 ], [ -122.414655267758604, 37.720335539269115 ], [ -122.417604327603499, 37.720490752945167 ], [ -122.421795096856755, 37.722818958085867 ], [ -122.423968088321416, 37.722818958085867 ], [ -122.424433729349545, 37.720801180297258 ], [ -122.423657660969312, 37.716299983691904 ], [ -122.425520225081883, 37.715058274283528 ], [ -122.431107917419567, 37.715834342663761 ], [ -122.431263131095605, 37.714592633255386 ], [ -122.430331849039334, 37.713350923847017 ], [ -122.431107917419567, 37.711488359734453 ], [ -122.430176635363281, 37.709470581945844 ], [ -122.434677831968642, 37.707452804157235 ] ], [ [ -122.457028601319365, 37.735856906873792 ], [ -122.452837832066109, 37.735701693197747 ], [ -122.452837832066109, 37.737719470986356 ], [ -122.451440908981681, 37.739116394070777 ], [ -122.451906550009824, 37.740513317155191 ], [ -122.450199199573305, 37.741599812887522 ], [ -122.446008430320049, 37.739426821422867 ], [ -122.446474071348192, 37.736322547901935 ], [ -122.445698002967958, 37.734770411141461 ], [ -122.439799883278184, 37.733683915409138 ], [ -122.435298686672823, 37.734149556437281 ], [ -122.435298686672823, 37.736943402606123 ], [ -122.440265524306326, 37.738029898338446 ], [ -122.440265524306326, 37.742841522295898 ], [ -122.438558173869808, 37.742996735971943 ], [ -122.439489455926079, 37.743617590676131 ], [ -122.436695609757251, 37.743772804352176 ], [ -122.436540396081199, 37.747963573605439 ], [ -122.438092532841665, 37.747963573605439 ], [ -122.439489455926079, 37.749515710365905 ], [ -122.441507233714688, 37.749981351394048 ], [ -122.441817661066793, 37.753396052267071 ], [ -122.440110310630274, 37.753861693295214 ], [ -122.440110310630274, 37.755258616379635 ], [ -122.439023814897951, 37.755879471083823 ], [ -122.439179028573989, 37.757586821520334 ], [ -122.44135202003865, 37.758673317252665 ], [ -122.440110310630274, 37.759604599308943 ], [ -122.440731165334455, 37.761932804449643 ], [ -122.445542789291906, 37.760846308717319 ], [ -122.446318857672139, 37.759138958280801 ], [ -122.447405353404463, 37.758983744604755 ], [ -122.447870994432606, 37.76115673606941 ], [ -122.452682618390057, 37.761932804449643 ], [ -122.45345868677029, 37.76457143694244 ], [ -122.462150652628907, 37.762553659153831 ], [ -122.461995438952869, 37.761311949745455 ], [ -122.463081934685192, 37.760691095041274 ], [ -122.463392362037283, 37.759294171956853 ], [ -122.461840225276816, 37.757897248872432 ], [ -122.461374584248674, 37.755879471083823 ], [ -122.45997766116426, 37.756345112111966 ], [ -122.459046379107974, 37.75541383005568 ], [ -122.458115097051689, 37.75541383005568 ], [ -122.457339028671456, 37.756500325788011 ], [ -122.456252532939132, 37.756500325788011 ], [ -122.456252532939132, 37.75541383005568 ], [ -122.457804669699598, 37.753706479619169 ], [ -122.461219370572636, 37.753551265943123 ], [ -122.463547575713335, 37.758362889900567 ], [ -122.465099712473801, 37.757586821520334 ], [ -122.464478857769606, 37.753396052267071 ], [ -122.462150652628907, 37.751067847126372 ], [ -122.461529797924726, 37.748274000957529 ], [ -122.458425524403793, 37.747187505225206 ], [ -122.457028601319365, 37.745324941112642 ], [ -122.460132874840298, 37.745169727436597 ], [ -122.461685011600764, 37.743772804352176 ], [ -122.465254926149839, 37.743772804352176 ], [ -122.466496635558215, 37.739116394070777 ], [ -122.460443302192402, 37.735546479521702 ], [ -122.457028601319365, 37.735856906873792 ] ], [ [ -122.409688430125115, 37.738340325690537 ], [ -122.405497660871845, 37.739582035098913 ], [ -122.405497660871845, 37.743772804352176 ], [ -122.410309284829296, 37.743928018028221 ], [ -122.410930139533491, 37.738029898338446 ], [ -122.409688430125115, 37.738340325690537 ] ], [ [ -122.454545182502613, 37.768917419871748 ], [ -122.458425524403793, 37.768917419871748 ], [ -122.458270310727741, 37.766589214731049 ], [ -122.454079541474485, 37.766744428407094 ], [ -122.454545182502613, 37.768917419871748 ] ], [ [ -122.410774925857439, 37.779937590871064 ], [ -122.40611851557604, 37.782576223363861 ], [ -122.400375609562303, 37.778075026758508 ], [ -122.399133900153927, 37.778075026758508 ], [ -122.390597147971363, 37.784283573800373 ], [ -122.39044193429531, 37.788163915701546 ], [ -122.394787917224619, 37.791268189222478 ], [ -122.394011848844386, 37.792975539658997 ], [ -122.399133900153927, 37.796855881560163 ], [ -122.405963301899988, 37.796700667884117 ], [ -122.40642894292813, 37.798563231996674 ], [ -122.412482276293957, 37.799184086700862 ], [ -122.411240566885581, 37.791423402898523 ], [ -122.413413558350229, 37.791423402898523 ], [ -122.413413558350229, 37.789405625109922 ], [ -122.416207404519071, 37.788319129377591 ], [ -122.415431336138838, 37.783817932772237 ], [ -122.417138686575356, 37.78350750542014 ], [ -122.417759541279537, 37.785214855856658 ], [ -122.421795096856755, 37.784904428504561 ], [ -122.422571165236988, 37.78117930027944 ], [ -122.422105524208845, 37.779161522490831 ], [ -122.420553387448379, 37.778385454110598 ], [ -122.414189626730462, 37.778385454110598 ], [ -122.410774925857439, 37.779937590871064 ] ], [ [ -122.423657660969312, 37.791268189222478 ], [ -122.423347233617221, 37.790026479814102 ], [ -122.421174242152574, 37.788939984081779 ], [ -122.421019028476522, 37.787853488349448 ], [ -122.41822518230768, 37.788163915701546 ], [ -122.418069968631642, 37.789871266138057 ], [ -122.421019028476522, 37.789871266138057 ], [ -122.421639883180717, 37.791578616574576 ], [ -122.42272637891304, 37.792199471278764 ], [ -122.423812874645364, 37.792199471278764 ], [ -122.423657660969312, 37.791268189222478 ] ], [ [ -122.425209797729792, 37.788319129377591 ], [ -122.42536501140583, 37.789716052462012 ], [ -122.426606720814206, 37.789871266138057 ], [ -122.426141079786063, 37.788474343053636 ], [ -122.425209797729792, 37.788319129377591 ] ] ], [ [ [ -122.458580738079831, 37.755724257407778 ], [ -122.458115097051689, 37.756189898435913 ], [ -122.457804669699598, 37.756189898435913 ], [ -122.458425524403793, 37.755569043731725 ], [ -122.459046379107974, 37.755569043731725 ], [ -122.458580738079831, 37.755724257407778 ] ] ] ] } } +] +} From 873afa7f58bc1d6ed2df291b09141dcbae63e7be Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 15:50:24 -0700 Subject: [PATCH 16/24] updated language around flexibility --- CONTRIBUTING.md | 8 ++++---- events.csv | 20 +++++++++---------- ...artinez-september-12-2024-boundary.geojson | 8 ++++++++ import-csv.js | 10 +++++----- rebuild-cache.js | 12 +++++------ tests/test_validation.py | 14 ++++++------- 6 files changed, 40 insertions(+), 32 deletions(-) create mode 100644 geometries/may-mobility-martinez-september-12-2024-boundary.geojson diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 44e2b63..b1d136f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,7 +32,7 @@ Each row in `events.csv` represents one change to a service. Service creation ev | `platform` | Booking app | `Robotaxi` | If applicable | | `fares` | Charges fares? | `Yes` / `No` | If applicable | | `direct_booking` | Can book AV directly? | `Yes` / `No` | If applicable | -| `flexibility` | Travel flexibility | `Point-to-Point` / `Stop-to-Stop` | If applicable | +| `service_model` | Service model | `Flexible` / `Stop-to-Stop` | If applicable | | `supervision` | Supervision level | `Autonomous` / `Safety Driver` | If applicable | | `access` | Access policy | `Public` / `Waitlist` | If applicable | | `fleet_partner` | Fleet partnerships | `Moove` | If applicable | @@ -47,7 +47,7 @@ For `service_created` events, fill in all service attributes: 2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Stop-to-Stop,Autonomous,Public,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service ``` -Required: `date`, `event_type`, `company`, `city`, `vehicles`, `platform`, `fares`, `direct_booking`, `flexibility`, `supervision`, `access`, `source_url` +Required: `date`, `event_type`, `company`, `city`, `vehicles`, `platform`, `fares`, `direct_booking`, `service_model`, `supervision`, `access`, `source_url` ## Updating a service @@ -81,10 +81,10 @@ Note: Multiple platforms separated by `;` (semicolon). This allows filtering by 2024-11-12,access_policy_changed,Waymo,Los Angeles,,,,,,,Public,,https://waymo.com/blog/2024/11/waymo-one-open-to-all-in-los-angeles,Access policy update ``` -### Flexibility change +### Service model change ```csv -2026-03-15,flexibility_updated,Zoox,Las Vegas,,,,,,,Point-to-Point,,,https://example.com,Service now allows point-to-point travel +2026-03-15,service_model_updated,Zoox,Las Vegas,,,,,,,Flexible,,,https://example.com,Service now allows flexible travel ``` ## Event types diff --git a/events.csv b/events.csv index 204b476..08b3497 100644 --- a/events.csv +++ b/events.csv @@ -1,18 +1,18 @@ -date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_booking,flexibility,supervision,access,fleet_partner,source_url,notes -2017-04-25,service_created,Waymo,Phoenix,waymo-phoenix-april-25-2017-boundary.geojson,Chrysler Pacifica Hybrid,Waymo,No,Yes,Point-to-Point,Safety Driver,Waitlist,,https://www.technologyreview.com/2017/04/25/152152/waymo-has-invited-the-public-to-hop-into-its-self-driving-cars/,Waymo Phoenix service +date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_booking,service_model,supervision,access,fleet_partner,source_url,notes +2017-04-25,service_created,Waymo,Phoenix,waymo-phoenix-april-25-2017-boundary.geojson,Chrysler Pacifica Hybrid,Waymo,No,Yes,Flexible,Safety Driver,Waitlist,,https://www.technologyreview.com/2017/04/25/152152/waymo-has-invited-the-public-to-hop-into-its-self-driving-cars/,Waymo Phoenix service 2017-11-07,supervision_updated,Waymo,Phoenix,,,,,,,Autonomous,,,https://waymo.com/blog/2017/11/waymos-fully-self-driving-vehicles-are-here,Supervision level update 2020-10-08,fares_policy_changed,Waymo,Phoenix,,,,Yes,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Fares policy update 2020-10-08,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace;Chrysler Pacifica Hybrid,,,,,,,,https://techcrunch.com/2019/06/17/waymos-self-driving-jaguar-i-pace-vehicles-are-now-testing-on-public-roads/,Vehicle fleet expansion - adding Jaguar I-Pace 2020-10-08,access_policy_changed,Waymo,Phoenix,,,,,,,,Public,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Access policy update 2020-10-08,geometry_updated,Waymo,Phoenix,waymo-phoenix-october-8-2020-boundary.geojson,,,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Service area boundary update 2022-11-01,geometry_updated,Waymo,Phoenix,waymo-phoenix-november-1-2022-boundary.geojson,,,,,,,,,https://techcrunch.com/2022/11/01/waymo-launches-autonomous-rides-to-phoenix-airport/,Service area boundary update -2022-12-16,service_created,Waymo,San Francisco,waymo-san-francisco-december-16-2022-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Point-to-Point,Autonomous,Waitlist,,https://waymo.com/blog/2022/12/wheels-up-for-waymo-as-we-expand,Waymo San Francisco service +2022-12-16,service_created,Waymo,San Francisco,waymo-san-francisco-december-16-2022-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/blog/2022/12/wheels-up-for-waymo-as-we-expand,Waymo San Francisco service 2023-03-30,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace,,,,,,,,https://techcrunch.com/2023/03/30/waymo-retires-its-self-driving-chrysler-pacifica-minivan/,Vehicle fleet change - retiring Chrysler Pacifica Hybrid 2023-05-04,geometry_updated,Waymo,Phoenix,waymo-phoenix-may-4-2023-boundary.geojson,,,,,,,,,https://waymo.com/blog/2023/05/waymo-one-doubles-service-area-in,Service area boundary update 2023-08-21,fares_policy_changed,Waymo,San Francisco,,,,Yes,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Fares policy update 2023-08-21,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-21-2023-boundary.geojson,,,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Service area boundary update 2023-10-26,platform_updated,Waymo,Phoenix,,,Waymo;Uber,,,,,,,https://waymo.com/blog/2023/10/the-waymo-driver-now-available-on-uber-in-phoenix,Booking platform update -2024-03-13,service_created,Waymo,Los Angeles,waymo-los-angeles-march-13-2024-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Point-to-Point,Autonomous,Waitlist,,https://waymo.com/blog/2024/03/scaling-waymo-one-safely-across-four-cities-this-year,Waymo Los Angeles service +2024-03-13,service_created,Waymo,Los Angeles,waymo-los-angeles-march-13-2024-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/blog/2024/03/scaling-waymo-one-safely-across-four-cities-this-year,Waymo Los Angeles service 2024-04-10,fares_policy_changed,Waymo,Los Angeles,,,,Yes,,,,,,https://www.nbcnews.com/tech/innovation/waymo-will-launch-paid-robotaxi-service-los-angeles-wednesday-rcna147101,Fares policy update 2024-06-05,geometry_updated,Waymo,Phoenix,waymo-phoenix-june-5-2024-boundary.geojson,,,,,,,,,https://waymo.com/blog/2024/06/largest-autonomous-ride-hail-territory-in-us-now-even-larger,Service area boundary update 2024-06-25,access_policy_changed,Waymo,San Francisco,,,,,,,,Public,,https://waymo.com/blog/2024/06/waymo-one-is-now-open-to-everyone-in-san-francisco,Access policy update @@ -20,18 +20,18 @@ date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_bookin 2024-08-06,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-6-2024-boundary.geojson,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update 2024-11-12,access_policy_changed,Waymo,Los Angeles,,,,,,,,Public,,https://waymo.com/blog/2024/11/waymo-one-open-to-all-in-los-angeles,Access policy update 2024-12-05,fleet_partner_changed,Waymo,Phoenix,,,,,,,,,Moove,https://www.prnewswire.com/news-releases/moove-partners-with-waymo-to-redefine-the-future-of-urban-mobility-302324144.html,Fleet partnership with Moove established -2025-03-04,service_created,Waymo,Austin,waymo-austin-march-4-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Point-to-Point,Autonomous,Public,,https://www.cnbc.com/2025/03/04/waymo-uber-begin-offering-robotaxi-rides-in-austin-ahead-of-sxsw.html,Waymo Austin service -2025-03-11,service_created,Waymo,Silicon Valley,waymo-silicon-valley-march-11-2025-boundary.geojson,Jaguar I-Pace,Waymo,Yes,Yes,Point-to-Point,Autonomous,Public,,https://www.mercurynews.com/2025/03/11/alphabets-waymo-to-offer-self-driving-rides-in-silicon-valley/,Waymo Silicon Valley service +2025-03-04,service_created,Waymo,Austin,waymo-austin-march-4-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://www.cnbc.com/2025/03/04/waymo-uber-begin-offering-robotaxi-rides-in-austin-ahead-of-sxsw.html,Waymo Austin service +2025-03-11,service_created,Waymo,Silicon Valley,waymo-silicon-valley-march-11-2025-boundary.geojson,Jaguar I-Pace,Waymo,Yes,Yes,Flexible,Autonomous,Public,,https://www.mercurynews.com/2025/03/11/alphabets-waymo-to-offer-self-driving-rides-in-silicon-valley/,Waymo Silicon Valley service 2025-06-17,geometry_updated,Waymo,Silicon Valley,waymo-silicon-valley-june-17-2025-boundary.geojson,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update 2025-06-17,geometry_updated,Waymo,San Francisco,waymo-san-francisco-june-17-2025-boundary.geojson,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update 2025-06-18,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-june-18-2025-boundary.geojson,,,,,,,,,https://techcrunch.com/2025/06/17/waymo-robotaxis-are-pushing-into-even-more-california-cities/,Service area boundary update -2025-06-22,service_created,Tesla,Austin,tesla-austin-june-22-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Point-to-Point,Safety Attendant,Waitlist,,https://www.cnbc.com/2025/06/20/tesla-robotaxi-launch-austin.html,Tesla Austin service -2025-06-24,service_created,Waymo,Atlanta,waymo-atlanta-june-24-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Point-to-Point,Autonomous,Public,,https://www.uber.com/newsroom/waymo-on-uber-atl/,Waymo Atlanta service +2025-06-22,service_created,Tesla,Austin,tesla-austin-june-22-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Flexible,Safety Attendant,Waitlist,,https://www.cnbc.com/2025/06/20/tesla-robotaxi-launch-austin.html,Tesla Austin service +2025-06-24,service_created,Waymo,Atlanta,waymo-atlanta-june-24-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://www.uber.com/newsroom/waymo-on-uber-atl/,Waymo Atlanta service 2025-07-14,geometry_updated,Tesla,Austin,tesla-austin-july-14-2025-boundary.geojson,,,,,,,,,https://www.businessinsider.com/tesla-new-robotaxi-geofence-austin-shape-elon-musk-bigger-waymo-2025-7,Service area boundary update 2025-07-17,geometry_updated,Waymo,Austin,waymo-austin-july-17-2025-boundary.geojson,,,,,,,,,https://www.axios.com/local/austin/2025/07/17/waymo-expands-austin-service-area,Service area boundary update -2025-07-31,service_created,Tesla,Bay Area,tesla-bay-area-july-31-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Point-to-Point,Safety Driver,Waitlist,,https://www.businessinsider.com/teslas-ride-hailing-service-live-in-san-francisco-musk-says-2025-7,Tesla Bay Area service +2025-07-31,service_created,Tesla,Bay Area,tesla-bay-area-july-31-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Flexible,Safety Driver,Waitlist,,https://www.businessinsider.com/teslas-ride-hailing-service-live-in-san-francisco-musk-says-2025-7,Tesla Bay Area service 2025-08-03,geometry_updated,Tesla,Austin,tesla-austin-august-3-2025-boundary.geojson,,,,,,,,,https://www.pcmag.com/news/teslas-robotaxi-coverage-expands-four-times-the-size-of-initial-austin,Service area boundary update 2025-08-26,geometry_updated,Tesla,Austin,tesla-austin-august-26-2025-boundary.geojson,,,,,,,,,https://electrek.co/2025/08/27/tesla-announces-50-increase-in-austin-robotaxi-but-50-from-what/,Service area boundary update 2025-09-01,supervision_updated,Tesla,Austin,,,,,,,Safety Driver,,,https://mashable.com/article/tesla-robotaxi-human-safety-monitor-drivers-seat#:~:text=Tesla%20now%20puts%20their%20robotaxi%20safety%20monitors%20in%20the%20driver%27s&text=Texas%20SB%202807%2C%20which%20went%20into%20effect%20on%20Sept.,Supervision level update -2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Point-to-Point,Safety Driver,Public,,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service +2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Flexible,Safety Driver,Public,,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service 2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Stop-to-Stop,Autonomous,Public,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service diff --git a/geometries/may-mobility-martinez-september-12-2024-boundary.geojson b/geometries/may-mobility-martinez-september-12-2024-boundary.geojson new file mode 100644 index 0000000..c76cc55 --- /dev/null +++ b/geometries/may-mobility-martinez-september-12-2024-boundary.geojson @@ -0,0 +1,8 @@ +{ +"type": "FeatureCollection", +"name": "may-mobility-martinez-september-12-2024-boundary", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, +"features": [ +{ "type": "Feature", "properties": { "fid": 1, "DN": 191 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -122.118995600476254, 37.985521255178163 ], [ -122.119366112390381, 37.984780231349895 ], [ -122.1216262350666, 37.983816900373149 ], [ -122.122107900554965, 37.9839651051388 ], [ -122.124516227996835, 37.987003302834694 ], [ -122.123441743445852, 37.98918932312808 ], [ -122.126257633993262, 37.990597268401785 ], [ -122.129592241220465, 37.996229049496613 ], [ -122.133556718701684, 37.99574738400824 ], [ -122.135261073506697, 37.996970073324874 ], [ -122.135520431846587, 37.99989711744653 ], [ -122.134223640147127, 38.006640434283753 ], [ -122.133667872275922, 38.007381458112022 ], [ -122.133667872275922, 38.007900174791807 ], [ -122.133000950830493, 38.008492993854418 ], [ -122.141300417707072, 38.017088870262313 ], [ -122.14141157128131, 38.020460528680921 ], [ -122.138669783116725, 38.020868091786468 ], [ -122.140707598644454, 38.025462439521718 ], [ -122.137113633077362, 38.026055258584336 ], [ -122.134594152061254, 38.022127832294522 ], [ -122.129444036454814, 38.019200788172867 ], [ -122.128628910243719, 38.018274508387535 ], [ -122.128591859052307, 38.015829129754259 ], [ -122.1263687875675, 38.013494904695214 ], [ -122.130592623388623, 38.011049526061939 ], [ -122.126035326844786, 38.006455178326689 ], [ -122.124886739910963, 38.004824925904501 ], [ -122.124034562508456, 38.002638905611114 ], [ -122.117772911159605, 38.001045704380346 ], [ -122.115809198014702, 38.000008271020768 ], [ -122.116068556354605, 37.999378400766744 ], [ -122.114364201549591, 38.000045322212181 ], [ -122.109065881177486, 37.99900788885261 ], [ -122.105768325141696, 37.996377254262264 ], [ -122.109065881177486, 37.991004831507333 ], [ -122.110362672876946, 37.990300858870484 ], [ -122.120699955281268, 37.990337910061896 ], [ -122.122478412469107, 37.989708039807866 ], [ -122.118995600476254, 37.985521255178163 ] ], [ [ -122.116105607546018, 37.999378400766744 ], [ -122.116105607546018, 37.999341349575332 ], [ -122.116068556354605, 37.999341349575332 ], [ -122.116068556354605, 37.999378400766744 ], [ -122.116105607546018, 37.999378400766744 ] ] ], [ [ [ -122.129444036454814, 37.993820722054743 ], [ -122.129481087646226, 37.993820722054743 ], [ -122.129481087646226, 37.99422828516029 ], [ -122.129444036454814, 37.99422828516029 ], [ -122.129444036454814, 37.993820722054743 ] ] ] ] } } +] +} diff --git a/import-csv.js b/import-csv.js index 89c814f..ada1417 100644 --- a/import-csv.js +++ b/import-csv.js @@ -51,7 +51,7 @@ const FIELD_MAPPING = { 'platform': 'platform', 'fares': 'fares', 'direct_booking': 'direct_booking', - 'flexibility': 'flexibility', + 'service_model': 'service_model', 'supervision': 'supervision', 'access': 'access', 'fleet_partner': 'fleet_partner', @@ -85,7 +85,7 @@ function csvRowToEvent(row) { 'platform_updated', 'vehicle_types_updated', 'fleet_partner_changed', - 'flexibility_updated', + 'service_model_updated', 'geometry_updated' ].includes(row.event_type) @@ -121,7 +121,7 @@ function csvRowToEvent(row) { (row.event_type === 'platform_updated' && csvKey === 'platform') || (row.event_type === 'vehicle_types_updated' && csvKey === 'vehicles') || (row.event_type === 'fleet_partner_changed' && csvKey === 'fleet_partner') || - (row.event_type === 'flexibility_updated' && csvKey === 'flexibility') + (row.event_type === 'service_model_updated' && csvKey === 'service_model') if (!isFieldBeingUpdated) { eventData[dbKey] = value @@ -143,8 +143,8 @@ function csvRowToEvent(row) { eventData.new_vehicle_types = row.vehicles } else if (row.event_type === 'fleet_partner_changed' && row.fleet_partner) { eventData.new_fleet_partner = row.fleet_partner - } else if (row.event_type === 'flexibility_updated' && row.flexibility) { - eventData.new_flexibility = row.flexibility + } else if (row.event_type === 'service_model_updated' && row.service_model) { + eventData.new_service_model = row.service_model } return { diff --git a/rebuild-cache.js b/rebuild-cache.js index b193a3f..3c8bc9a 100644 --- a/rebuild-cache.js +++ b/rebuild-cache.js @@ -344,9 +344,9 @@ function buildServiceAreasFromEvents(events, geometryMap) { } } - } else if (['service_updated', 'fares_policy_changed', 'access_policy_changed', 'vehicle_types_updated', 'platform_updated', 'supervision_updated', 'flexibility_updated', 'fleet_partner_changed'].includes(event.event_type)) { + } else if (['service_updated', 'fares_policy_changed', 'access_policy_changed', 'vehicle_types_updated', 'platform_updated', 'supervision_updated', 'service_model_updated', 'fleet_partner_changed'].includes(event.event_type)) { if (currentState.isActive) { - const shouldCreateNewState = ['fares_policy_changed', 'access_policy_changed', 'vehicle_types_updated', 'platform_updated', 'supervision_updated', 'flexibility_updated', 'fleet_partner_changed'].includes(event.event_type) + const shouldCreateNewState = ['fares_policy_changed', 'access_policy_changed', 'vehicle_types_updated', 'platform_updated', 'supervision_updated', 'service_model_updated', 'fleet_partner_changed'].includes(event.event_type) if (shouldCreateNewState) { // Check if last state has same effectiveDate - if so, update in place instead of creating new state @@ -366,8 +366,8 @@ function buildServiceAreasFromEvents(events, geometryMap) { lastState.platform = event.event_data.new_platform } else if (event.event_type === 'supervision_updated') { lastState.supervision = event.event_data.new_supervision - } else if (event.event_type === 'flexibility_updated') { - lastState.flexibility = event.event_data.new_flexibility + } else if (event.event_type === 'service_model_updated') { + lastState.serviceModel = event.event_data.new_service_model } else if (event.event_type === 'fleet_partner_changed') { lastState.fleetPartner = event.event_data.new_fleet_partner || event.event_data.fleet_partner } @@ -393,8 +393,8 @@ function buildServiceAreasFromEvents(events, geometryMap) { newState.platform = event.event_data.new_platform } else if (event.event_type === 'supervision_updated') { newState.supervision = event.event_data.new_supervision - } else if (event.event_type === 'flexibility_updated') { - newState.flexibility = event.event_data.new_flexibility + } else if (event.event_type === 'service_model_updated') { + newState.serviceModel = event.event_data.new_service_model } else if (event.event_type === 'fleet_partner_changed') { newState.fleetPartner = event.event_data.new_fleet_partner || event.event_data.fleet_partner } diff --git a/tests/test_validation.py b/tests/test_validation.py index 2216a38..945e8c2 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -40,7 +40,7 @@ def test_csv_headers(csv_file): """Test that CSV has correct headers.""" expected_headers = [ 'date', 'event_type', 'company', 'city', 'geometry_file', - 'vehicles', 'platform', 'fares', 'direct_booking', 'flexibility', 'supervision', + 'vehicles', 'platform', 'fares', 'direct_booking', 'service_model', 'supervision', 'access', 'fleet_partner', 'source_url', 'notes' ] @@ -87,7 +87,7 @@ def test_event_types(csv_file): valid_event_types = [ 'service_created', 'service_ended', 'geometry_updated', 'vehicle_types_updated', 'supervision_updated', 'fares_policy_changed', - 'access_policy_changed', 'flexibility_updated', 'platform_updated', 'fleet_partner_changed' + 'access_policy_changed', 'service_model_updated', 'platform_updated', 'fleet_partner_changed' ] errors = [] @@ -112,7 +112,7 @@ def test_service_created_events(csv_file): for row_num, row in enumerate(reader, start=2): if row.get('event_type') == 'service_created': required_fields = ['company', 'city', 'vehicles', 'platform', 'fares', - 'direct_booking', 'flexibility', 'supervision', 'access'] + 'direct_booking', 'service_model', 'supervision', 'access'] for field in required_fields: if not row.get(field, '').strip(): errors.append(f"Row {row_num}: service_created event missing required field: {field}") @@ -209,10 +209,10 @@ def test_service_attribute_values(csv_file): if direct_booking and direct_booking not in ['Yes', 'No']: errors.append(f"Row {row_num}: direct_booking must be 'Yes' or 'No', got: {direct_booking}") - flexibility = row.get('flexibility', '').strip() - valid_flexibility = ['Point-to-Point', 'Stop-to-Stop'] - if flexibility and flexibility not in valid_flexibility: - errors.append(f"Row {row_num}: flexibility must be one of {valid_flexibility}, got: {flexibility}") + service_model = row.get('service_model', '').strip() + valid_service_model = ['Flexible', 'Stop-to-Stop'] + if service_model and service_model not in valid_service_model: + errors.append(f"Row {row_num}: service_model must be one of {valid_service_model}, got: {service_model}") supervision = row.get('supervision', '').strip() valid_supervision = ['Autonomous', 'Safety Driver', 'Safety Attendant'] From 15653f3da2a4b88cb6275c54891909f5b6780809 Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 16:03:07 -0700 Subject: [PATCH 17/24] updating flexibility to service model --- rebuild-cache.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rebuild-cache.js b/rebuild-cache.js index 3c8bc9a..e1360bc 100644 --- a/rebuild-cache.js +++ b/rebuild-cache.js @@ -258,6 +258,10 @@ function transformEventData(eventData) { transformed.geojsonPath = transformed.geometry_name delete transformed.geometry_name } + if (transformed.service_model !== undefined) { + transformed.serviceModel = transformed.service_model + delete transformed.service_model + } return transformed } From cc2d6b8247f4dd02c11c417e566dd4c89f816995 Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 19:54:31 -0700 Subject: [PATCH 18/24] Add service links to CSV data Added company_link and booking_platform_link columns to events.csv to make service links data-driven instead of hardcoded. Updated import and cache scripts to handle the new fields with proper snake_case to camelCase transformation. --- events.csv | 74 ++++++++++++++++++++++++------------------------ import-csv.js | 2 ++ rebuild-cache.js | 8 ++++++ 3 files changed, 47 insertions(+), 37 deletions(-) diff --git a/events.csv b/events.csv index 08b3497..7579b0a 100644 --- a/events.csv +++ b/events.csv @@ -1,37 +1,37 @@ -date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_booking,service_model,supervision,access,fleet_partner,source_url,notes -2017-04-25,service_created,Waymo,Phoenix,waymo-phoenix-april-25-2017-boundary.geojson,Chrysler Pacifica Hybrid,Waymo,No,Yes,Flexible,Safety Driver,Waitlist,,https://www.technologyreview.com/2017/04/25/152152/waymo-has-invited-the-public-to-hop-into-its-self-driving-cars/,Waymo Phoenix service -2017-11-07,supervision_updated,Waymo,Phoenix,,,,,,,Autonomous,,,https://waymo.com/blog/2017/11/waymos-fully-self-driving-vehicles-are-here,Supervision level update -2020-10-08,fares_policy_changed,Waymo,Phoenix,,,,Yes,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Fares policy update -2020-10-08,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace;Chrysler Pacifica Hybrid,,,,,,,,https://techcrunch.com/2019/06/17/waymos-self-driving-jaguar-i-pace-vehicles-are-now-testing-on-public-roads/,Vehicle fleet expansion - adding Jaguar I-Pace -2020-10-08,access_policy_changed,Waymo,Phoenix,,,,,,,,Public,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Access policy update -2020-10-08,geometry_updated,Waymo,Phoenix,waymo-phoenix-october-8-2020-boundary.geojson,,,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Service area boundary update -2022-11-01,geometry_updated,Waymo,Phoenix,waymo-phoenix-november-1-2022-boundary.geojson,,,,,,,,,https://techcrunch.com/2022/11/01/waymo-launches-autonomous-rides-to-phoenix-airport/,Service area boundary update -2022-12-16,service_created,Waymo,San Francisco,waymo-san-francisco-december-16-2022-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/blog/2022/12/wheels-up-for-waymo-as-we-expand,Waymo San Francisco service -2023-03-30,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace,,,,,,,,https://techcrunch.com/2023/03/30/waymo-retires-its-self-driving-chrysler-pacifica-minivan/,Vehicle fleet change - retiring Chrysler Pacifica Hybrid -2023-05-04,geometry_updated,Waymo,Phoenix,waymo-phoenix-may-4-2023-boundary.geojson,,,,,,,,,https://waymo.com/blog/2023/05/waymo-one-doubles-service-area-in,Service area boundary update -2023-08-21,fares_policy_changed,Waymo,San Francisco,,,,Yes,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Fares policy update -2023-08-21,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-21-2023-boundary.geojson,,,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Service area boundary update -2023-10-26,platform_updated,Waymo,Phoenix,,,Waymo;Uber,,,,,,,https://waymo.com/blog/2023/10/the-waymo-driver-now-available-on-uber-in-phoenix,Booking platform update -2024-03-13,service_created,Waymo,Los Angeles,waymo-los-angeles-march-13-2024-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/blog/2024/03/scaling-waymo-one-safely-across-four-cities-this-year,Waymo Los Angeles service -2024-04-10,fares_policy_changed,Waymo,Los Angeles,,,,Yes,,,,,,https://www.nbcnews.com/tech/innovation/waymo-will-launch-paid-robotaxi-service-los-angeles-wednesday-rcna147101,Fares policy update -2024-06-05,geometry_updated,Waymo,Phoenix,waymo-phoenix-june-5-2024-boundary.geojson,,,,,,,,,https://waymo.com/blog/2024/06/largest-autonomous-ride-hail-territory-in-us-now-even-larger,Service area boundary update -2024-06-25,access_policy_changed,Waymo,San Francisco,,,,,,,,Public,,https://waymo.com/blog/2024/06/waymo-one-is-now-open-to-everyone-in-san-francisco,Access policy update -2024-08-06,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-august-6-2024-boundary.geojson,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update -2024-08-06,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-6-2024-boundary.geojson,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update -2024-11-12,access_policy_changed,Waymo,Los Angeles,,,,,,,,Public,,https://waymo.com/blog/2024/11/waymo-one-open-to-all-in-los-angeles,Access policy update -2024-12-05,fleet_partner_changed,Waymo,Phoenix,,,,,,,,,Moove,https://www.prnewswire.com/news-releases/moove-partners-with-waymo-to-redefine-the-future-of-urban-mobility-302324144.html,Fleet partnership with Moove established -2025-03-04,service_created,Waymo,Austin,waymo-austin-march-4-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://www.cnbc.com/2025/03/04/waymo-uber-begin-offering-robotaxi-rides-in-austin-ahead-of-sxsw.html,Waymo Austin service -2025-03-11,service_created,Waymo,Silicon Valley,waymo-silicon-valley-march-11-2025-boundary.geojson,Jaguar I-Pace,Waymo,Yes,Yes,Flexible,Autonomous,Public,,https://www.mercurynews.com/2025/03/11/alphabets-waymo-to-offer-self-driving-rides-in-silicon-valley/,Waymo Silicon Valley service -2025-06-17,geometry_updated,Waymo,Silicon Valley,waymo-silicon-valley-june-17-2025-boundary.geojson,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update -2025-06-17,geometry_updated,Waymo,San Francisco,waymo-san-francisco-june-17-2025-boundary.geojson,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update -2025-06-18,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-june-18-2025-boundary.geojson,,,,,,,,,https://techcrunch.com/2025/06/17/waymo-robotaxis-are-pushing-into-even-more-california-cities/,Service area boundary update -2025-06-22,service_created,Tesla,Austin,tesla-austin-june-22-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Flexible,Safety Attendant,Waitlist,,https://www.cnbc.com/2025/06/20/tesla-robotaxi-launch-austin.html,Tesla Austin service -2025-06-24,service_created,Waymo,Atlanta,waymo-atlanta-june-24-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://www.uber.com/newsroom/waymo-on-uber-atl/,Waymo Atlanta service -2025-07-14,geometry_updated,Tesla,Austin,tesla-austin-july-14-2025-boundary.geojson,,,,,,,,,https://www.businessinsider.com/tesla-new-robotaxi-geofence-austin-shape-elon-musk-bigger-waymo-2025-7,Service area boundary update -2025-07-17,geometry_updated,Waymo,Austin,waymo-austin-july-17-2025-boundary.geojson,,,,,,,,,https://www.axios.com/local/austin/2025/07/17/waymo-expands-austin-service-area,Service area boundary update -2025-07-31,service_created,Tesla,Bay Area,tesla-bay-area-july-31-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Flexible,Safety Driver,Waitlist,,https://www.businessinsider.com/teslas-ride-hailing-service-live-in-san-francisco-musk-says-2025-7,Tesla Bay Area service -2025-08-03,geometry_updated,Tesla,Austin,tesla-austin-august-3-2025-boundary.geojson,,,,,,,,,https://www.pcmag.com/news/teslas-robotaxi-coverage-expands-four-times-the-size-of-initial-austin,Service area boundary update -2025-08-26,geometry_updated,Tesla,Austin,tesla-austin-august-26-2025-boundary.geojson,,,,,,,,,https://electrek.co/2025/08/27/tesla-announces-50-increase-in-austin-robotaxi-but-50-from-what/,Service area boundary update -2025-09-01,supervision_updated,Tesla,Austin,,,,,,,Safety Driver,,,https://mashable.com/article/tesla-robotaxi-human-safety-monitor-drivers-seat#:~:text=Tesla%20now%20puts%20their%20robotaxi%20safety%20monitors%20in%20the%20driver%27s&text=Texas%20SB%202807%2C%20which%20went%20into%20effect%20on%20Sept.,Supervision level update -2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Flexible,Safety Driver,Public,,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service -2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Stop-to-Stop,Autonomous,Public,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service +date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_booking,service_model,supervision,access,fleet_partner,company_link,booking_platform_link,source_url,notes +2017-04-25,service_created,Waymo,Phoenix,waymo-phoenix-april-25-2017-boundary.geojson,Chrysler Pacifica Hybrid,Waymo,No,Yes,Flexible,Safety Driver,Waitlist,,https://waymo.com/rides/phoenix/,https://www.uber.com/newsroom/waymo-on-uber/,https://www.technologyreview.com/2017/04/25/152152/waymo-has-invited-the-public-to-hop-into-its-self-driving-cars/,Waymo Phoenix service +2017-11-07,supervision_updated,Waymo,Phoenix,,,,,,,Autonomous,,,,https://waymo.com/blog/2017/11/waymos-fully-self-driving-vehicles-are-here,Supervision level update +2020-10-08,fares_policy_changed,Waymo,Phoenix,,,,Yes,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Fares policy update +2020-10-08,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace;Chrysler Pacifica Hybrid,,,,,,,,,https://techcrunch.com/2019/06/17/waymos-self-driving-jaguar-i-pace-vehicles-are-now-testing-on-public-roads/,Vehicle fleet expansion - adding Jaguar I-Pace +2020-10-08,access_policy_changed,Waymo,Phoenix,,,,,,,,Public,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Access policy update +2020-10-08,geometry_updated,Waymo,Phoenix,waymo-phoenix-october-8-2020-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Service area boundary update +2022-11-01,geometry_updated,Waymo,Phoenix,waymo-phoenix-november-1-2022-boundary.geojson,,,,,,,,,,https://techcrunch.com/2022/11/01/waymo-launches-autonomous-rides-to-phoenix-airport/,Service area boundary update +2022-12-16,service_created,Waymo,San Francisco,waymo-san-francisco-december-16-2022-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/rides/san-francisco/,,https://waymo.com/blog/2022/12/wheels-up-for-waymo-as-we-expand,Waymo San Francisco service +2023-03-30,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace,,,,,,,,,https://techcrunch.com/2023/03/30/waymo-retires-its-self-driving-chrysler-pacifica-minivan/,Vehicle fleet change - retiring Chrysler Pacifica Hybrid +2023-05-04,geometry_updated,Waymo,Phoenix,waymo-phoenix-may-4-2023-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2023/05/waymo-one-doubles-service-area-in,Service area boundary update +2023-08-21,fares_policy_changed,Waymo,San Francisco,,,,Yes,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Fares policy update +2023-08-21,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-21-2023-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Service area boundary update +2023-10-26,platform_updated,Waymo,Phoenix,,,Waymo;Uber,,,,,,,,https://waymo.com/blog/2023/10/the-waymo-driver-now-available-on-uber-in-phoenix,Booking platform update +2024-03-13,service_created,Waymo,Los Angeles,waymo-los-angeles-march-13-2024-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/rides/los-angeles/,,https://waymo.com/blog/2024/03/scaling-waymo-one-safely-across-four-cities-this-year,Waymo Los Angeles service +2024-04-10,fares_policy_changed,Waymo,Los Angeles,,,,Yes,,,,,,,https://www.nbcnews.com/tech/innovation/waymo-will-launch-paid-robotaxi-service-los-angeles-wednesday-rcna147101,Fares policy update +2024-06-05,geometry_updated,Waymo,Phoenix,waymo-phoenix-june-5-2024-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2024/06/largest-autonomous-ride-hail-territory-in-us-now-even-larger,Service area boundary update +2024-06-25,access_policy_changed,Waymo,San Francisco,,,,,,,,Public,,,https://waymo.com/blog/2024/06/waymo-one-is-now-open-to-everyone-in-san-francisco,Access policy update +2024-08-06,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-august-6-2024-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update +2024-08-06,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-6-2024-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update +2024-11-12,access_policy_changed,Waymo,Los Angeles,,,,,,,,Public,,,https://waymo.com/blog/2024/11/waymo-one-open-to-all-in-los-angeles,Access policy update +2024-12-05,fleet_partner_changed,Waymo,Phoenix,,,,,,,,,Moove,,https://www.prnewswire.com/news-releases/moove-partners-with-waymo-to-redefine-the-future-of-urban-mobility-302324144.html,Fleet partnership with Moove established +2025-03-04,service_created,Waymo,Austin,waymo-austin-march-4-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://waymo.com/waymo-on-uber/,https://www.uber.com/us/en/u/waymo-on-uber/,https://www.cnbc.com/2025/03/04/waymo-uber-begin-offering-robotaxi-rides-in-austin-ahead-of-sxsw.html,Waymo Austin service +2025-03-11,service_created,Waymo,Silicon Valley,waymo-silicon-valley-march-11-2025-boundary.geojson,Jaguar I-Pace,Waymo,Yes,Yes,Flexible,Autonomous,Public,,https://support.google.com/waymo/answer/15976820?hl=en,,https://www.mercurynews.com/2025/03/11/alphabets-waymo-to-offer-self-driving-rides-in-silicon-valley/,Waymo Silicon Valley service +2025-06-17,geometry_updated,Waymo,Silicon Valley,waymo-silicon-valley-june-17-2025-boundary.geojson,,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update +2025-06-17,geometry_updated,Waymo,San Francisco,waymo-san-francisco-june-17-2025-boundary.geojson,,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update +2025-06-18,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-june-18-2025-boundary.geojson,,,,,,,,,,https://techcrunch.com/2025/06/17/waymo-robotaxis-are-pushing-into-even-more-california-cities/,Service area boundary update +2025-06-22,service_created,Tesla,Austin,tesla-austin-june-22-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Flexible,Safety Attendant,Waitlist,,https://www.tesla.com/support/robotaxi/,,https://www.cnbc.com/2025/06/20/tesla-robotaxi-launch-austin.html,Tesla Austin service +2025-06-24,service_created,Waymo,Atlanta,waymo-atlanta-june-24-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://waymo.com/waymo-on-uber/,https://www.uber.com/us/en/u/waymo-on-uber/,https://www.uber.com/newsroom/waymo-on-uber-atl/,Waymo Atlanta service +2025-07-14,geometry_updated,Tesla,Austin,tesla-austin-july-14-2025-boundary.geojson,,,,,,,,,,https://www.businessinsider.com/tesla-new-robotaxi-geofence-austin-shape-elon-musk-bigger-waymo-2025-7,Service area boundary update +2025-07-17,geometry_updated,Waymo,Austin,waymo-austin-july-17-2025-boundary.geojson,,,,,,,,,,https://www.axios.com/local/austin/2025/07/17/waymo-expands-austin-service-area,Service area boundary update +2025-07-31,service_created,Tesla,Bay Area,tesla-bay-area-july-31-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Flexible,Safety Driver,Waitlist,,https://www.tesla.com/support/robotaxi/,,https://www.businessinsider.com/teslas-ride-hailing-service-live-in-san-francisco-musk-says-2025-7,Tesla Bay Area service +2025-08-03,geometry_updated,Tesla,Austin,tesla-austin-august-3-2025-boundary.geojson,,,,,,,,,,https://www.pcmag.com/news/teslas-robotaxi-coverage-expands-four-times-the-size-of-initial-austin,Service area boundary update +2025-08-26,geometry_updated,Tesla,Austin,tesla-austin-august-26-2025-boundary.geojson,,,,,,,,,,https://electrek.co/2025/08/27/tesla-announces-50-increase-in-austin-robotaxi-but-50-from-what/,Service area boundary update +2025-09-01,supervision_updated,Tesla,Austin,,,,,,,Safety Driver,,,,https://mashable.com/article/tesla-robotaxi-human-safety-monitor-drivers-seat#:~:text=Tesla%20now%20puts%20their%20robotaxi%20safety%20monitors%20in%20the%20driver%27s&text=Texas%20SB%202807%2C%20which%20went%20into%20effect%20on%20Sept.,Supervision level update +2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Flexible,Safety Driver,Public,,https://maymobility.com/locations/atlanta-georgia/,https://www.lyft.com/autonomous/maymobility,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service +2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Stop-to-Stop,Autonomous,Public,,https://zoox.com/las-vegas/,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service diff --git a/import-csv.js b/import-csv.js index ada1417..010022b 100644 --- a/import-csv.js +++ b/import-csv.js @@ -55,6 +55,8 @@ const FIELD_MAPPING = { 'supervision': 'supervision', 'access': 'access', 'fleet_partner': 'fleet_partner', + 'company_link': 'company_link', + 'booking_platform_link': 'booking_platform_link', 'source_url': 'event_url', 'notes': 'notes' } diff --git a/rebuild-cache.js b/rebuild-cache.js index e1360bc..b9b367a 100644 --- a/rebuild-cache.js +++ b/rebuild-cache.js @@ -262,6 +262,14 @@ function transformEventData(eventData) { transformed.serviceModel = transformed.service_model delete transformed.service_model } + if (transformed.company_link !== undefined) { + transformed.companyLink = transformed.company_link + delete transformed.company_link + } + if (transformed.booking_platform_link !== undefined) { + transformed.bookingPlatformLink = transformed.booking_platform_link + delete transformed.booking_platform_link + } return transformed } From 481663d8d6263ceed0c01f8a6655193ed6af2dbf Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 20:32:46 -0700 Subject: [PATCH 19/24] Add Cruise and May Mobility services Added historical Cruise San Francisco service (2022-2023) and May Mobility services in Grand Rapids MI/MN, Martinez CA, and Peachtree Corners GA. All events sorted chronologically. --- events.csv | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/events.csv b/events.csv index 7579b0a..ad30944 100644 --- a/events.csv +++ b/events.csv @@ -1,16 +1,25 @@ date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_booking,service_model,supervision,access,fleet_partner,company_link,booking_platform_link,source_url,notes 2017-04-25,service_created,Waymo,Phoenix,waymo-phoenix-april-25-2017-boundary.geojson,Chrysler Pacifica Hybrid,Waymo,No,Yes,Flexible,Safety Driver,Waitlist,,https://waymo.com/rides/phoenix/,https://www.uber.com/newsroom/waymo-on-uber/,https://www.technologyreview.com/2017/04/25/152152/waymo-has-invited-the-public-to-hop-into-its-self-driving-cars/,Waymo Phoenix service 2017-11-07,supervision_updated,Waymo,Phoenix,,,,,,,Autonomous,,,,https://waymo.com/blog/2017/11/waymos-fully-self-driving-vehicles-are-here,Supervision level update -2020-10-08,fares_policy_changed,Waymo,Phoenix,,,,Yes,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Fares policy update -2020-10-08,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace;Chrysler Pacifica Hybrid,,,,,,,,,https://techcrunch.com/2019/06/17/waymos-self-driving-jaguar-i-pace-vehicles-are-now-testing-on-public-roads/,Vehicle fleet expansion - adding Jaguar I-Pace +2019-07-25,service_created,May Mobility,Grand Rapids MI,may-mobility-grand-rapids-mi-25-july-2019-boundary.geojson,Polaris GEM,,No,Yes,Stop-to-Stop,Safety Driver,Public,,https://maymobility.com/locations/grand-rapids-michigan/,https://www.grandrapidsmi.gov/Government/Departments/Mobile-GR/Grand-Rapids-Autonomous-Vehicle-Initiative,https://www.michiganbusiness.org/press-releases/2019/07/public-private-partners-launch-grand-rapids-autonomous-vehicle-initiative-avgr/,Downtown Grand Rapids autonomous shuttle service 2020-10-08,access_policy_changed,Waymo,Phoenix,,,,,,,,Public,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Access policy update +2020-10-08,fares_policy_changed,Waymo,Phoenix,,,,Yes,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Fares policy update 2020-10-08,geometry_updated,Waymo,Phoenix,waymo-phoenix-october-8-2020-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Service area boundary update +2020-10-08,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace;Chrysler Pacifica Hybrid,,,,,,,,,https://techcrunch.com/2019/06/17/waymos-self-driving-jaguar-i-pace-vehicles-are-now-testing-on-public-roads/,Vehicle fleet expansion - adding Jaguar I-Pace +2021-07-26,geometry_updated,May Mobility,Grand Rapids MI,may-mobility-grand-rapids-mi-26-july-2021-boundary.geojson,,,,,,,,,,,https://www.prnewswire.com/news-releases/may-mobility-announces-on-demand-autonomous-service-in-grand-rapids-michigan-301351595.html, +2021-07-26,platform_updated,May Mobility,Grand Rapids MI,,,May Mobility,,,,,,,,,https://www.prnewswire.com/news-releases/may-mobility-announces-on-demand-autonomous-service-in-grand-rapids-michigan-301351595.html, +2021-07-26,vehicle_types_updated,May Mobility,Grand Rapids MI,,Polaris GEM;Lexus RX 450h,,,,,,,,,,https://www.prnewswire.com/news-releases/may-mobility-announces-on-demand-autonomous-service-in-grand-rapids-michigan-301351595.html, +2022-02-02,service_created,Cruise,San Francisco,cruise-san-francisco-february-1-2022-boundary.geojson,Chevrolet Bolt EV,Cruise,Yes,Yes,Flexible,Autonomous,Waitlist,,https://web.archive.org/web/20230928020703/https://getcruise.com/rides/,,https://fortune.com/2022/02/01/cruise-robotaxi-self-driving-car-san-francisco/,Cruise San Francisco commercial service launch +2022-04-29,service_ended,May Mobility,Grand Rapids MI,,,,,,,,,,,,https://www.grandrapidsmi.gov/Government/Departments/Mobile-GR/Grand-Rapids-Autonomous-Vehicle-Initiative, +2022-09-28,service_created,May Mobility,Grand Rapids MN,may-mobility-grand-rapids-mn-september-28-2022-boundary.geojson,Toyota Sienna,May Mobility,No,Yes,Stop-to-Stop,Safety Driver,Public,,https://maymobility.com/locations/grand-rapids-minnesota/,https://gomarti.com/,https://maymobility.com/posts/may-mobility-and-via-launch-first-rural-transit-program-to-use-wheelchair-accessible-ada-compliant-autonomous-vehicless/, +2022-11-01,geometry_updated,Cruise,San Francisco,cruise-san-francisco-november-1-2022-boundary.geojson,,,,,,,,,,,https://sfstandard.com/2022/11/01/self-driving-cruise-cars-are-expanding-to-most-of-sf-says-ceo/,CPUC approved public expansion and 24/7 operations 2022-11-01,geometry_updated,Waymo,Phoenix,waymo-phoenix-november-1-2022-boundary.geojson,,,,,,,,,,https://techcrunch.com/2022/11/01/waymo-launches-autonomous-rides-to-phoenix-airport/,Service area boundary update 2022-12-16,service_created,Waymo,San Francisco,waymo-san-francisco-december-16-2022-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/rides/san-francisco/,,https://waymo.com/blog/2022/12/wheels-up-for-waymo-as-we-expand,Waymo San Francisco service 2023-03-30,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace,,,,,,,,,https://techcrunch.com/2023/03/30/waymo-retires-its-self-driving-chrysler-pacifica-minivan/,Vehicle fleet change - retiring Chrysler Pacifica Hybrid 2023-05-04,geometry_updated,Waymo,Phoenix,waymo-phoenix-may-4-2023-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2023/05/waymo-one-doubles-service-area-in,Service area boundary update 2023-08-21,fares_policy_changed,Waymo,San Francisco,,,,Yes,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Fares policy update 2023-08-21,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-21-2023-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Service area boundary update +2023-10-24,service_ended,Cruise,San Francisco,,,,,,,,,,,,https://www.wired.com/story/cruise-robotaxi-self-driving-permit-revoked-california/,California DMV suspended operations due to pedestrian dragging incident 2023-10-26,platform_updated,Waymo,Phoenix,,,Waymo;Uber,,,,,,,,https://waymo.com/blog/2023/10/the-waymo-driver-now-available-on-uber-in-phoenix,Booking platform update 2024-03-13,service_created,Waymo,Los Angeles,waymo-los-angeles-march-13-2024-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/rides/los-angeles/,,https://waymo.com/blog/2024/03/scaling-waymo-one-safely-across-four-cities-this-year,Waymo Los Angeles service 2024-04-10,fares_policy_changed,Waymo,Los Angeles,,,,Yes,,,,,,,https://www.nbcnews.com/tech/innovation/waymo-will-launch-paid-robotaxi-service-los-angeles-wednesday-rcna147101,Fares policy update @@ -18,12 +27,15 @@ date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_bookin 2024-06-25,access_policy_changed,Waymo,San Francisco,,,,,,,,Public,,,https://waymo.com/blog/2024/06/waymo-one-is-now-open-to-everyone-in-san-francisco,Access policy update 2024-08-06,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-august-6-2024-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update 2024-08-06,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-6-2024-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update +2024-09-12,service_created,May Mobility,Martinez CA,may-mobility-martinez-september-12-2024-boundary.geojson,Toyota Sienna,May Mobility,No,Yes,Stop-to-Stop,Safety Driver,Public,,https://maymobility.com/locations/martinez-california/,https://ridepresto.com/martinez/,https://ccta.net/news/contra-costa-transportation-authority-and-may-mobility-launch-autonomous-vehicle-service-in-martinez-california/, +2024-10-07,service_created,May Mobility,Peachtree Corners,may-mobility-peachtree-corners-october-7-2024-boundary.geojson,Toyota Sienna,May Mobility,No,Yes,Stop-to-Stop,Safety Driver,Public,,https://maymobility.com/locations/peachtree-corners-georgia/,,"https://maymobility.com/posts/peachtree-corners-launch-autonomous-vehicle-may-mobility-t-mobile/#:~:text=Peachtree%20Corners%2C%20Ga.,Corners%20City%20Manager%20Brian%20Johnson.",Peachtree Corners autonomous shuttle service 2024-11-12,access_policy_changed,Waymo,Los Angeles,,,,,,,,Public,,,https://waymo.com/blog/2024/11/waymo-one-open-to-all-in-los-angeles,Access policy update 2024-12-05,fleet_partner_changed,Waymo,Phoenix,,,,,,,,,Moove,,https://www.prnewswire.com/news-releases/moove-partners-with-waymo-to-redefine-the-future-of-urban-mobility-302324144.html,Fleet partnership with Moove established +2025-02-16,supervision_updated,May Mobility,Peachtree Corners,,,,,,,Autonomous,,,,,https://www.iotworldtoday.com/transportation-logistics/may-mobility-launches-first-commercial-driverless-car-service, 2025-03-04,service_created,Waymo,Austin,waymo-austin-march-4-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://waymo.com/waymo-on-uber/,https://www.uber.com/us/en/u/waymo-on-uber/,https://www.cnbc.com/2025/03/04/waymo-uber-begin-offering-robotaxi-rides-in-austin-ahead-of-sxsw.html,Waymo Austin service 2025-03-11,service_created,Waymo,Silicon Valley,waymo-silicon-valley-march-11-2025-boundary.geojson,Jaguar I-Pace,Waymo,Yes,Yes,Flexible,Autonomous,Public,,https://support.google.com/waymo/answer/15976820?hl=en,,https://www.mercurynews.com/2025/03/11/alphabets-waymo-to-offer-self-driving-rides-in-silicon-valley/,Waymo Silicon Valley service -2025-06-17,geometry_updated,Waymo,Silicon Valley,waymo-silicon-valley-june-17-2025-boundary.geojson,,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update 2025-06-17,geometry_updated,Waymo,San Francisco,waymo-san-francisco-june-17-2025-boundary.geojson,,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update +2025-06-17,geometry_updated,Waymo,Silicon Valley,waymo-silicon-valley-june-17-2025-boundary.geojson,,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update 2025-06-18,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-june-18-2025-boundary.geojson,,,,,,,,,,https://techcrunch.com/2025/06/17/waymo-robotaxis-are-pushing-into-even-more-california-cities/,Service area boundary update 2025-06-22,service_created,Tesla,Austin,tesla-austin-june-22-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Flexible,Safety Attendant,Waitlist,,https://www.tesla.com/support/robotaxi/,,https://www.cnbc.com/2025/06/20/tesla-robotaxi-launch-austin.html,Tesla Austin service 2025-06-24,service_created,Waymo,Atlanta,waymo-atlanta-june-24-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://waymo.com/waymo-on-uber/,https://www.uber.com/us/en/u/waymo-on-uber/,https://www.uber.com/newsroom/waymo-on-uber-atl/,Waymo Atlanta service @@ -33,5 +45,6 @@ date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_bookin 2025-08-03,geometry_updated,Tesla,Austin,tesla-austin-august-3-2025-boundary.geojson,,,,,,,,,,https://www.pcmag.com/news/teslas-robotaxi-coverage-expands-four-times-the-size-of-initial-austin,Service area boundary update 2025-08-26,geometry_updated,Tesla,Austin,tesla-austin-august-26-2025-boundary.geojson,,,,,,,,,,https://electrek.co/2025/08/27/tesla-announces-50-increase-in-austin-robotaxi-but-50-from-what/,Service area boundary update 2025-09-01,supervision_updated,Tesla,Austin,,,,,,,Safety Driver,,,,https://mashable.com/article/tesla-robotaxi-human-safety-monitor-drivers-seat#:~:text=Tesla%20now%20puts%20their%20robotaxi%20safety%20monitors%20in%20the%20driver%27s&text=Texas%20SB%202807%2C%20which%20went%20into%20effect%20on%20Sept.,Supervision level update +2025-09-02,geometry_updated,May Mobility,Grand Rapids MN,may-mobility-grand-rapids-mn-september-2-2025-boundary.geojson,,,,,,,,,,,https://www.kaxe.org/local-news/2025-08-11/grand-rapids-autonomous-transit-expanding-to-nearby-cities-tribal-stops, 2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Flexible,Safety Driver,Public,,https://maymobility.com/locations/atlanta-georgia/,https://www.lyft.com/autonomous/maymobility,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service 2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Stop-to-Stop,Autonomous,Public,,https://zoox.com/las-vegas/,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service From 12832cf25b61541dcf347da2e03873564255f8a8 Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 20:44:27 -0700 Subject: [PATCH 20/24] Add scripts for uploading and syncing geometry files - upload-geometries.js: Uploads local geometry files to Supabase storage - sync-geometries-table.js: Syncs storage bucket with geometries database table These scripts ensure new geometry files are properly uploaded and registered in the database. --- sync-geometries-table.js | 132 +++++++++++++++++++++++++++++++++++++++ upload-geometries.js | 117 ++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 sync-geometries-table.js create mode 100644 upload-geometries.js diff --git a/sync-geometries-table.js b/sync-geometries-table.js new file mode 100644 index 0000000..55a6fc1 --- /dev/null +++ b/sync-geometries-table.js @@ -0,0 +1,132 @@ +#!/usr/bin/env node + +/** + * Sync Geometries Table with Storage Bucket + * + * This script ensures all GeoJSON files in the storage bucket are registered + * in the service_area_geometries table with proper metadata. + * + * Usage: + * STAGING=true node sync-geometries-table.js (syncs staging) + * node sync-geometries-table.js (syncs production) + */ + +import { createClient } from '@supabase/supabase-js' +import { config } from 'dotenv' + +// Load .env file +if (!process.env.GITHUB_ACTIONS) { + config() +} + +const supabaseUrl = process.env.SUPABASE_URL +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY || process.env.SUPABASE_ANON_KEY + +if (!supabaseUrl || !supabaseServiceKey) { + console.error('❌ Missing required environment variables!') + console.error('Please set SUPABASE_URL and SUPABASE_SERVICE_KEY in .env') + process.exit(1) +} + +const supabase = createClient(supabaseUrl, supabaseServiceKey) + +// Determine environment +const isStaging = process.env.STAGING === 'true' +const bucket = isStaging ? 'staging-service-area-boundaries' : 'service-area-boundaries' +const table = isStaging ? 'service_area_geometries_staging' : 'service_area_geometries' +const env = isStaging ? 'STAGING' : 'PRODUCTION' + +console.log(`🌍 Environment: ${env}`) +console.log(`📦 Bucket: ${bucket}`) +console.log(`📋 Table: ${table}\n`) + +async function syncGeometriesTable() { + // Step 1: List all files in storage bucket + console.log('📡 Fetching files from storage bucket...') + const { data: files, error: listError } = await supabase.storage + .from(bucket) + .list('', { limit: 1000 }) + + if (listError) { + console.error('❌ Error listing files:', listError) + process.exit(1) + } + + const geojsonFiles = files.filter(f => f.name.endsWith('.geojson')) + console.log(` Found ${geojsonFiles.length} geometry files in bucket\n`) + + // Step 2: Get existing entries in database table + console.log('📊 Fetching existing entries from database...') + const { data: existingEntries, error: dbError } = await supabase + .from(table) + .select('geometry_name') + + if (dbError) { + console.error('❌ Error fetching from database:', dbError) + process.exit(1) + } + + const existingNames = new Set(existingEntries?.map(e => e.geometry_name) || []) + console.log(` Found ${existingNames.size} existing entries in table\n`) + + // Step 3: Insert missing entries + console.log('📝 Syncing table with storage...') + + let inserted = 0 + let skipped = 0 + let failed = 0 + + for (const file of geojsonFiles) { + const geometryName = file.name.replace('.geojson', '') + + if (existingNames.has(geometryName)) { + console.log(` ⏭️ ${geometryName} (already exists)`) + skipped++ + continue + } + + // Create public URL + const { data: { publicUrl } } = supabase.storage + .from(bucket) + .getPublicUrl(file.name) + + // Insert into table + const { error: insertError } = await supabase + .from(table) + .insert({ + geometry_name: geometryName, + display_name: geometryName.replace(/-/g, ' '), + storage_url: publicUrl, + file_size: file.metadata?.size || 0, + created_at: file.created_at || new Date().toISOString() + }) + + if (insertError) { + console.error(` ❌ ${geometryName}: ${insertError.message}`) + failed++ + } else { + console.log(` ✅ ${geometryName} (inserted)`) + inserted++ + } + } + + console.log('\n📊 Sync Summary:') + console.log(` ✅ Inserted: ${inserted}`) + console.log(` ⏭️ Skipped (existing): ${skipped}`) + console.log(` ❌ Failed: ${failed}`) + console.log(` 📁 Total files: ${geojsonFiles.length}`) + + if (failed === 0) { + console.log('\n✅ Geometries table synced successfully!') + console.log('\n📝 Next steps:') + console.log(` Run: ${isStaging ? 'STAGING=true ' : ''}node rebuild-cache.js`) + } else { + console.log('\n⚠️ Some entries failed to insert. Please check errors above.') + process.exit(1) + } +} + +syncGeometriesTable().catch(error => { + console.error('❌ Fatal error:', error) + process.exit(1) +}) diff --git a/upload-geometries.js b/upload-geometries.js new file mode 100644 index 0000000..5a48148 --- /dev/null +++ b/upload-geometries.js @@ -0,0 +1,117 @@ +#!/usr/bin/env node + +/** + * Upload Geometry Files to Supabase Storage + * + * This script uploads all GeoJSON files from the local geometries/ folder to Supabase storage. + * It compares with existing files and only uploads new or changed files. + * + * Usage: + * STAGING=true node upload-geometries.js (uploads to staging) + * node upload-geometries.js (uploads to production) + */ + +import { createClient } from '@supabase/supabase-js' +import { config } from 'dotenv' +import { readFileSync, readdirSync } from 'fs' +import { join } from 'path' + +// Load .env file +if (!process.env.GITHUB_ACTIONS) { + config() +} + +const supabaseUrl = process.env.SUPABASE_URL +const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY || process.env.SUPABASE_ANON_KEY + +if (!supabaseUrl || !supabaseServiceKey) { + console.error('❌ Missing required environment variables!') + console.error('Please set SUPABASE_URL and SUPABASE_SERVICE_KEY in .env') + process.exit(1) +} + +const supabase = createClient(supabaseUrl, supabaseServiceKey) + +// Determine environment +const isStaging = process.env.STAGING === 'true' +const bucket = isStaging ? 'staging-service-area-boundaries' : 'service-area-boundaries' +const env = isStaging ? 'STAGING' : 'PRODUCTION' + +console.log(`🌍 Environment: ${env}`) +console.log(`📦 Bucket: ${bucket}\n`) + +async function uploadGeometries() { + console.log('📂 Reading local geometry files...') + + const geometriesPath = './geometries' + const localFiles = readdirSync(geometriesPath).filter(f => f.endsWith('.geojson')) + + console.log(` Found ${localFiles.length} local geometry files\n`) + + // Get list of existing files in bucket + console.log('📡 Fetching existing files from bucket...') + const { data: existingFiles, error: listError } = await supabase.storage + .from(bucket) + .list('', { limit: 1000 }) + + if (listError) { + console.error('❌ Error listing files:', listError) + process.exit(1) + } + + const existingFileNames = new Set(existingFiles?.map(f => f.name) || []) + console.log(` Found ${existingFileNames.size} existing files in bucket\n`) + + // Upload files + console.log('📤 Uploading geometry files...') + + let uploaded = 0 + let skipped = 0 + let failed = 0 + + for (const filename of localFiles) { + const filePath = join(geometriesPath, filename) + const fileContent = readFileSync(filePath) + + try { + // Upload or update file + const { error: uploadError } = await supabase.storage + .from(bucket) + .upload(filename, fileContent, { + contentType: 'application/json', + upsert: true // Overwrite if exists + }) + + if (uploadError) { + console.error(` ❌ ${filename}: ${uploadError.message}`) + failed++ + } else { + const action = existingFileNames.has(filename) ? 'Updated' : 'New' + console.log(` ✅ ${filename} (${action})`) + uploaded++ + } + } catch (error) { + console.error(` ❌ ${filename}: ${error.message}`) + failed++ + } + } + + console.log('\n📊 Upload Summary:') + console.log(` ✅ Uploaded/Updated: ${uploaded}`) + console.log(` ❌ Failed: ${failed}`) + console.log(` 📁 Total: ${localFiles.length}`) + + if (failed === 0) { + console.log('\n✅ All geometry files uploaded successfully!') + console.log('\n📝 Next steps:') + console.log(` Run: ${isStaging ? 'STAGING=true ' : ''}node rebuild-cache.js`) + } else { + console.log('\n⚠️ Some files failed to upload. Please check errors above.') + process.exit(1) + } +} + +uploadGeometries().catch(error => { + console.error('❌ Fatal error:', error) + process.exit(1) +}) From 9ba430ca662094cade296d47e15f8ca21397256e Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 20:46:09 -0700 Subject: [PATCH 21/24] Add GitHub Actions workflow for automatic cache updates Automatically runs when events.csv or geometry files are pushed to main or staging branches. Workflow: 1. Imports CSV to database 2. Uploads geometry files to storage 3. Syncs geometries table 4. Rebuilds cache Can also be manually triggered via workflow_dispatch. --- .github/workflows/update-cache.yml | 107 +++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 .github/workflows/update-cache.yml diff --git a/.github/workflows/update-cache.yml b/.github/workflows/update-cache.yml new file mode 100644 index 0000000..126443a --- /dev/null +++ b/.github/workflows/update-cache.yml @@ -0,0 +1,107 @@ +name: Update Data Cache + +on: + push: + branches: + - main + - staging + paths: + - 'events.csv' + - 'geometries/**' + + workflow_dispatch: + inputs: + environment: + description: 'Environment to update' + required: true + default: 'staging' + type: choice + options: + - staging + - production + +jobs: + update-cache: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Determine environment + id: env + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_OUTPUT + elif [ "${{ github.ref }}" = "refs/heads/main" ]; then + echo "environment=production" >> $GITHUB_OUTPUT + else + echo "environment=staging" >> $GITHUB_OUTPUT + fi + + - name: Import CSV to database + env: + SUPABASE_URL: ${{ secrets.SUPABASE_URL }} + SUPABASE_SERVICE_KEY: ${{ secrets.SUPABASE_SERVICE_KEY }} + STAGING: ${{ steps.env.outputs.environment == 'staging' }} + GITHUB_ACTIONS: true + run: | + if [ "${{ steps.env.outputs.environment }}" = "staging" ]; then + STAGING=true node import-csv.js + else + node import-csv.js + fi + + - name: Upload geometry files to storage + env: + SUPABASE_URL: ${{ secrets.SUPABASE_URL }} + SUPABASE_SERVICE_KEY: ${{ secrets.SUPABASE_SERVICE_KEY }} + STAGING: ${{ steps.env.outputs.environment == 'staging' }} + GITHUB_ACTIONS: true + run: | + if [ "${{ steps.env.outputs.environment }}" = "staging" ]; then + STAGING=true node upload-geometries.js + else + node upload-geometries.js + fi + + - name: Sync geometries table with storage + env: + SUPABASE_URL: ${{ secrets.SUPABASE_URL }} + SUPABASE_SERVICE_KEY: ${{ secrets.SUPABASE_SERVICE_KEY }} + STAGING: ${{ steps.env.outputs.environment == 'staging' }} + GITHUB_ACTIONS: true + run: | + if [ "${{ steps.env.outputs.environment }}" = "staging" ]; then + STAGING=true node sync-geometries-table.js + else + node sync-geometries-table.js + fi + + - name: Rebuild cache + env: + SUPABASE_URL: ${{ secrets.SUPABASE_URL }} + SUPABASE_SERVICE_KEY: ${{ secrets.SUPABASE_SERVICE_KEY }} + STAGING: ${{ steps.env.outputs.environment == 'staging' }} + GITHUB_ACTIONS: true + run: | + if [ "${{ steps.env.outputs.environment }}" = "staging" ]; then + STAGING=true node rebuild-cache.js + else + node rebuild-cache.js + fi + + - name: Summary + run: | + echo "✅ Cache updated successfully for ${{ steps.env.outputs.environment }}" + echo "Branch: ${{ github.ref_name }}" + echo "Commit: ${{ github.sha }}" From a8628aea10dc601b7dd61e9734338b9ff4261bf7 Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 21:06:06 -0700 Subject: [PATCH 22/24] Fix geometry field names to camelCase in cache Transform geometry fields from snake_case (geometry_name, geojson_data) to camelCase (geometryName, geojsonData) when building the cache. This fixes the issue where geometries weren't being found by the frontend because the field names didn't match. --- rebuild-cache.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/rebuild-cache.js b/rebuild-cache.js index b9b367a..0792f49 100644 --- a/rebuild-cache.js +++ b/rebuild-cache.js @@ -161,6 +161,17 @@ async function rebuildCache() { const serviceAreas = buildServiceAreasFromEvents(events, geometryMap) // STEP 4: Create final data structure + // Transform geometries to camelCase for frontend + const geometriesForFrontend = geometriesWithData.map(geo => ({ + geometryName: geo.geometry_name, + displayName: geo.display_name, + fileSize: geo.file_size, + createdAt: geo.created_at, + storageUrl: geo.storage_url, + geojsonData: geo.geojson_data, + error: geo.error + })); + const cacheData = { metadata: { generated_at: new Date().toISOString(), @@ -175,7 +186,7 @@ async function rebuildCache() { } }, events: events, - geometries: geometriesWithData, + geometries: geometriesForFrontend, service_areas: serviceAreas, date_range: { start: '2017-04-25T00:00:00+00:00', From ebbe1df6471963dfc438daf186390ea7cb89d7e6 Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 21:13:16 -0700 Subject: [PATCH 23/24] Add platform for Grand Rapids MI initial service Set platform to 'Grand Rapids' for the initial May Mobility Grand Rapids MI service to prevent it from showing as 'Unknown' and being filtered out by default. --- events.csv | 76 +++++++++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/events.csv b/events.csv index ad30944..2e8b27d 100644 --- a/events.csv +++ b/events.csv @@ -1,11 +1,11 @@ -date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_booking,service_model,supervision,access,fleet_partner,company_link,booking_platform_link,source_url,notes -2017-04-25,service_created,Waymo,Phoenix,waymo-phoenix-april-25-2017-boundary.geojson,Chrysler Pacifica Hybrid,Waymo,No,Yes,Flexible,Safety Driver,Waitlist,,https://waymo.com/rides/phoenix/,https://www.uber.com/newsroom/waymo-on-uber/,https://www.technologyreview.com/2017/04/25/152152/waymo-has-invited-the-public-to-hop-into-its-self-driving-cars/,Waymo Phoenix service -2017-11-07,supervision_updated,Waymo,Phoenix,,,,,,,Autonomous,,,,https://waymo.com/blog/2017/11/waymos-fully-self-driving-vehicles-are-here,Supervision level update -2019-07-25,service_created,May Mobility,Grand Rapids MI,may-mobility-grand-rapids-mi-25-july-2019-boundary.geojson,Polaris GEM,,No,Yes,Stop-to-Stop,Safety Driver,Public,,https://maymobility.com/locations/grand-rapids-michigan/,https://www.grandrapidsmi.gov/Government/Departments/Mobile-GR/Grand-Rapids-Autonomous-Vehicle-Initiative,https://www.michiganbusiness.org/press-releases/2019/07/public-private-partners-launch-grand-rapids-autonomous-vehicle-initiative-avgr/,Downtown Grand Rapids autonomous shuttle service -2020-10-08,access_policy_changed,Waymo,Phoenix,,,,,,,,Public,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Access policy update -2020-10-08,fares_policy_changed,Waymo,Phoenix,,,,Yes,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Fares policy update -2020-10-08,geometry_updated,Waymo,Phoenix,waymo-phoenix-october-8-2020-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Service area boundary update -2020-10-08,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace;Chrysler Pacifica Hybrid,,,,,,,,,https://techcrunch.com/2019/06/17/waymos-self-driving-jaguar-i-pace-vehicles-are-now-testing-on-public-roads/,Vehicle fleet expansion - adding Jaguar I-Pace +date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_booking,service_model,supervision,access,fleet_partner,company_link,booking_platform_link,source_url,notes +2017-04-25,service_created,Waymo,Phoenix,waymo-phoenix-april-25-2017-boundary.geojson,Chrysler Pacifica Hybrid,Waymo,No,Yes,Flexible,Safety Driver,Waitlist,,https://waymo.com/rides/phoenix/,https://www.uber.com/newsroom/waymo-on-uber/,https://www.technologyreview.com/2017/04/25/152152/waymo-has-invited-the-public-to-hop-into-its-self-driving-cars/,Waymo Phoenix service +2017-11-07,supervision_updated,Waymo,Phoenix,,,,,,,Autonomous,,,,https://waymo.com/blog/2017/11/waymos-fully-self-driving-vehicles-are-here,Supervision level update +2019-07-25,service_created,May Mobility,Grand Rapids MI,may-mobility-grand-rapids-mi-25-july-2019-boundary.geojson,Polaris GEM,Grand Rapids,No,Yes,Stop-to-Stop,Safety Driver,Public,,https://maymobility.com/locations/grand-rapids-michigan/,https://www.grandrapidsmi.gov/Government/Departments/Mobile-GR/Grand-Rapids-Autonomous-Vehicle-Initiative,https://www.michiganbusiness.org/press-releases/2019/07/public-private-partners-launch-grand-rapids-autonomous-vehicle-initiative-avgr/,Downtown Grand Rapids autonomous shuttle service +2020-10-08,access_policy_changed,Waymo,Phoenix,,,,,,,,Public,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Access policy update +2020-10-08,fares_policy_changed,Waymo,Phoenix,,,,Yes,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Fares policy update +2020-10-08,geometry_updated,Waymo,Phoenix,waymo-phoenix-october-8-2020-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Service area boundary update +2020-10-08,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace;Chrysler Pacifica Hybrid,,,,,,,,,https://techcrunch.com/2019/06/17/waymos-self-driving-jaguar-i-pace-vehicles-are-now-testing-on-public-roads/,Vehicle fleet expansion - adding Jaguar I-Pace 2021-07-26,geometry_updated,May Mobility,Grand Rapids MI,may-mobility-grand-rapids-mi-26-july-2021-boundary.geojson,,,,,,,,,,,https://www.prnewswire.com/news-releases/may-mobility-announces-on-demand-autonomous-service-in-grand-rapids-michigan-301351595.html, 2021-07-26,platform_updated,May Mobility,Grand Rapids MI,,,May Mobility,,,,,,,,,https://www.prnewswire.com/news-releases/may-mobility-announces-on-demand-autonomous-service-in-grand-rapids-michigan-301351595.html, 2021-07-26,vehicle_types_updated,May Mobility,Grand Rapids MI,,Polaris GEM;Lexus RX 450h,,,,,,,,,,https://www.prnewswire.com/news-releases/may-mobility-announces-on-demand-autonomous-service-in-grand-rapids-michigan-301351595.html, @@ -13,38 +13,38 @@ date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_bookin 2022-04-29,service_ended,May Mobility,Grand Rapids MI,,,,,,,,,,,,https://www.grandrapidsmi.gov/Government/Departments/Mobile-GR/Grand-Rapids-Autonomous-Vehicle-Initiative, 2022-09-28,service_created,May Mobility,Grand Rapids MN,may-mobility-grand-rapids-mn-september-28-2022-boundary.geojson,Toyota Sienna,May Mobility,No,Yes,Stop-to-Stop,Safety Driver,Public,,https://maymobility.com/locations/grand-rapids-minnesota/,https://gomarti.com/,https://maymobility.com/posts/may-mobility-and-via-launch-first-rural-transit-program-to-use-wheelchair-accessible-ada-compliant-autonomous-vehicless/, 2022-11-01,geometry_updated,Cruise,San Francisco,cruise-san-francisco-november-1-2022-boundary.geojson,,,,,,,,,,,https://sfstandard.com/2022/11/01/self-driving-cruise-cars-are-expanding-to-most-of-sf-says-ceo/,CPUC approved public expansion and 24/7 operations -2022-11-01,geometry_updated,Waymo,Phoenix,waymo-phoenix-november-1-2022-boundary.geojson,,,,,,,,,,https://techcrunch.com/2022/11/01/waymo-launches-autonomous-rides-to-phoenix-airport/,Service area boundary update -2022-12-16,service_created,Waymo,San Francisco,waymo-san-francisco-december-16-2022-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/rides/san-francisco/,,https://waymo.com/blog/2022/12/wheels-up-for-waymo-as-we-expand,Waymo San Francisco service -2023-03-30,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace,,,,,,,,,https://techcrunch.com/2023/03/30/waymo-retires-its-self-driving-chrysler-pacifica-minivan/,Vehicle fleet change - retiring Chrysler Pacifica Hybrid -2023-05-04,geometry_updated,Waymo,Phoenix,waymo-phoenix-may-4-2023-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2023/05/waymo-one-doubles-service-area-in,Service area boundary update -2023-08-21,fares_policy_changed,Waymo,San Francisco,,,,Yes,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Fares policy update -2023-08-21,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-21-2023-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Service area boundary update +2022-11-01,geometry_updated,Waymo,Phoenix,waymo-phoenix-november-1-2022-boundary.geojson,,,,,,,,,,https://techcrunch.com/2022/11/01/waymo-launches-autonomous-rides-to-phoenix-airport/,Service area boundary update +2022-12-16,service_created,Waymo,San Francisco,waymo-san-francisco-december-16-2022-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/rides/san-francisco/,,https://waymo.com/blog/2022/12/wheels-up-for-waymo-as-we-expand,Waymo San Francisco service +2023-03-30,vehicle_types_updated,Waymo,Phoenix,,Jaguar I-Pace,,,,,,,,,https://techcrunch.com/2023/03/30/waymo-retires-its-self-driving-chrysler-pacifica-minivan/,Vehicle fleet change - retiring Chrysler Pacifica Hybrid +2023-05-04,geometry_updated,Waymo,Phoenix,waymo-phoenix-may-4-2023-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2023/05/waymo-one-doubles-service-area-in,Service area boundary update +2023-08-21,fares_policy_changed,Waymo,San Francisco,,,,Yes,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Fares policy update +2023-08-21,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-21-2023-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2023/08/waymos-next-chapter-in-san-francisco,Service area boundary update 2023-10-24,service_ended,Cruise,San Francisco,,,,,,,,,,,,https://www.wired.com/story/cruise-robotaxi-self-driving-permit-revoked-california/,California DMV suspended operations due to pedestrian dragging incident -2023-10-26,platform_updated,Waymo,Phoenix,,,Waymo;Uber,,,,,,,,https://waymo.com/blog/2023/10/the-waymo-driver-now-available-on-uber-in-phoenix,Booking platform update -2024-03-13,service_created,Waymo,Los Angeles,waymo-los-angeles-march-13-2024-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/rides/los-angeles/,,https://waymo.com/blog/2024/03/scaling-waymo-one-safely-across-four-cities-this-year,Waymo Los Angeles service -2024-04-10,fares_policy_changed,Waymo,Los Angeles,,,,Yes,,,,,,,https://www.nbcnews.com/tech/innovation/waymo-will-launch-paid-robotaxi-service-los-angeles-wednesday-rcna147101,Fares policy update -2024-06-05,geometry_updated,Waymo,Phoenix,waymo-phoenix-june-5-2024-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2024/06/largest-autonomous-ride-hail-territory-in-us-now-even-larger,Service area boundary update -2024-06-25,access_policy_changed,Waymo,San Francisco,,,,,,,,Public,,,https://waymo.com/blog/2024/06/waymo-one-is-now-open-to-everyone-in-san-francisco,Access policy update -2024-08-06,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-august-6-2024-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update -2024-08-06,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-6-2024-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update +2023-10-26,platform_updated,Waymo,Phoenix,,,Waymo;Uber,,,,,,,,https://waymo.com/blog/2023/10/the-waymo-driver-now-available-on-uber-in-phoenix,Booking platform update +2024-03-13,service_created,Waymo,Los Angeles,waymo-los-angeles-march-13-2024-boundary.geojson,Jaguar I-Pace,Waymo,No,Yes,Flexible,Autonomous,Waitlist,,https://waymo.com/rides/los-angeles/,,https://waymo.com/blog/2024/03/scaling-waymo-one-safely-across-four-cities-this-year,Waymo Los Angeles service +2024-04-10,fares_policy_changed,Waymo,Los Angeles,,,,Yes,,,,,,,https://www.nbcnews.com/tech/innovation/waymo-will-launch-paid-robotaxi-service-los-angeles-wednesday-rcna147101,Fares policy update +2024-06-05,geometry_updated,Waymo,Phoenix,waymo-phoenix-june-5-2024-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2024/06/largest-autonomous-ride-hail-territory-in-us-now-even-larger,Service area boundary update +2024-06-25,access_policy_changed,Waymo,San Francisco,,,,,,,,Public,,,https://waymo.com/blog/2024/06/waymo-one-is-now-open-to-everyone-in-san-francisco,Access policy update +2024-08-06,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-august-6-2024-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update +2024-08-06,geometry_updated,Waymo,San Francisco,waymo-san-francisco-august-6-2024-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2024/08/expanding-destinations-for-san-francisco-and-los-angeles-riders,Service area boundary update 2024-09-12,service_created,May Mobility,Martinez CA,may-mobility-martinez-september-12-2024-boundary.geojson,Toyota Sienna,May Mobility,No,Yes,Stop-to-Stop,Safety Driver,Public,,https://maymobility.com/locations/martinez-california/,https://ridepresto.com/martinez/,https://ccta.net/news/contra-costa-transportation-authority-and-may-mobility-launch-autonomous-vehicle-service-in-martinez-california/, 2024-10-07,service_created,May Mobility,Peachtree Corners,may-mobility-peachtree-corners-october-7-2024-boundary.geojson,Toyota Sienna,May Mobility,No,Yes,Stop-to-Stop,Safety Driver,Public,,https://maymobility.com/locations/peachtree-corners-georgia/,,"https://maymobility.com/posts/peachtree-corners-launch-autonomous-vehicle-may-mobility-t-mobile/#:~:text=Peachtree%20Corners%2C%20Ga.,Corners%20City%20Manager%20Brian%20Johnson.",Peachtree Corners autonomous shuttle service -2024-11-12,access_policy_changed,Waymo,Los Angeles,,,,,,,,Public,,,https://waymo.com/blog/2024/11/waymo-one-open-to-all-in-los-angeles,Access policy update -2024-12-05,fleet_partner_changed,Waymo,Phoenix,,,,,,,,,Moove,,https://www.prnewswire.com/news-releases/moove-partners-with-waymo-to-redefine-the-future-of-urban-mobility-302324144.html,Fleet partnership with Moove established +2024-11-12,access_policy_changed,Waymo,Los Angeles,,,,,,,,Public,,,https://waymo.com/blog/2024/11/waymo-one-open-to-all-in-los-angeles,Access policy update +2024-12-05,fleet_partner_changed,Waymo,Phoenix,,,,,,,,,Moove,,https://www.prnewswire.com/news-releases/moove-partners-with-waymo-to-redefine-the-future-of-urban-mobility-302324144.html,Fleet partnership with Moove established 2025-02-16,supervision_updated,May Mobility,Peachtree Corners,,,,,,,Autonomous,,,,,https://www.iotworldtoday.com/transportation-logistics/may-mobility-launches-first-commercial-driverless-car-service, -2025-03-04,service_created,Waymo,Austin,waymo-austin-march-4-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://waymo.com/waymo-on-uber/,https://www.uber.com/us/en/u/waymo-on-uber/,https://www.cnbc.com/2025/03/04/waymo-uber-begin-offering-robotaxi-rides-in-austin-ahead-of-sxsw.html,Waymo Austin service -2025-03-11,service_created,Waymo,Silicon Valley,waymo-silicon-valley-march-11-2025-boundary.geojson,Jaguar I-Pace,Waymo,Yes,Yes,Flexible,Autonomous,Public,,https://support.google.com/waymo/answer/15976820?hl=en,,https://www.mercurynews.com/2025/03/11/alphabets-waymo-to-offer-self-driving-rides-in-silicon-valley/,Waymo Silicon Valley service -2025-06-17,geometry_updated,Waymo,San Francisco,waymo-san-francisco-june-17-2025-boundary.geojson,,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update -2025-06-17,geometry_updated,Waymo,Silicon Valley,waymo-silicon-valley-june-17-2025-boundary.geojson,,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update -2025-06-18,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-june-18-2025-boundary.geojson,,,,,,,,,,https://techcrunch.com/2025/06/17/waymo-robotaxis-are-pushing-into-even-more-california-cities/,Service area boundary update -2025-06-22,service_created,Tesla,Austin,tesla-austin-june-22-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Flexible,Safety Attendant,Waitlist,,https://www.tesla.com/support/robotaxi/,,https://www.cnbc.com/2025/06/20/tesla-robotaxi-launch-austin.html,Tesla Austin service -2025-06-24,service_created,Waymo,Atlanta,waymo-atlanta-june-24-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://waymo.com/waymo-on-uber/,https://www.uber.com/us/en/u/waymo-on-uber/,https://www.uber.com/newsroom/waymo-on-uber-atl/,Waymo Atlanta service -2025-07-14,geometry_updated,Tesla,Austin,tesla-austin-july-14-2025-boundary.geojson,,,,,,,,,,https://www.businessinsider.com/tesla-new-robotaxi-geofence-austin-shape-elon-musk-bigger-waymo-2025-7,Service area boundary update -2025-07-17,geometry_updated,Waymo,Austin,waymo-austin-july-17-2025-boundary.geojson,,,,,,,,,,https://www.axios.com/local/austin/2025/07/17/waymo-expands-austin-service-area,Service area boundary update -2025-07-31,service_created,Tesla,Bay Area,tesla-bay-area-july-31-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Flexible,Safety Driver,Waitlist,,https://www.tesla.com/support/robotaxi/,,https://www.businessinsider.com/teslas-ride-hailing-service-live-in-san-francisco-musk-says-2025-7,Tesla Bay Area service -2025-08-03,geometry_updated,Tesla,Austin,tesla-austin-august-3-2025-boundary.geojson,,,,,,,,,,https://www.pcmag.com/news/teslas-robotaxi-coverage-expands-four-times-the-size-of-initial-austin,Service area boundary update -2025-08-26,geometry_updated,Tesla,Austin,tesla-austin-august-26-2025-boundary.geojson,,,,,,,,,,https://electrek.co/2025/08/27/tesla-announces-50-increase-in-austin-robotaxi-but-50-from-what/,Service area boundary update -2025-09-01,supervision_updated,Tesla,Austin,,,,,,,Safety Driver,,,,https://mashable.com/article/tesla-robotaxi-human-safety-monitor-drivers-seat#:~:text=Tesla%20now%20puts%20their%20robotaxi%20safety%20monitors%20in%20the%20driver%27s&text=Texas%20SB%202807%2C%20which%20went%20into%20effect%20on%20Sept.,Supervision level update +2025-03-04,service_created,Waymo,Austin,waymo-austin-march-4-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://waymo.com/waymo-on-uber/,https://www.uber.com/us/en/u/waymo-on-uber/,https://www.cnbc.com/2025/03/04/waymo-uber-begin-offering-robotaxi-rides-in-austin-ahead-of-sxsw.html,Waymo Austin service +2025-03-11,service_created,Waymo,Silicon Valley,waymo-silicon-valley-march-11-2025-boundary.geojson,Jaguar I-Pace,Waymo,Yes,Yes,Flexible,Autonomous,Public,,https://support.google.com/waymo/answer/15976820?hl=en,,https://www.mercurynews.com/2025/03/11/alphabets-waymo-to-offer-self-driving-rides-in-silicon-valley/,Waymo Silicon Valley service +2025-06-17,geometry_updated,Waymo,San Francisco,waymo-san-francisco-june-17-2025-boundary.geojson,,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update +2025-06-17,geometry_updated,Waymo,Silicon Valley,waymo-silicon-valley-june-17-2025-boundary.geojson,,,,,,,,,,https://www.theverge.com/news/688202/waymo-sf-la-service-area-expand-robotaxi,Service area boundary update +2025-06-18,geometry_updated,Waymo,Los Angeles,waymo-los-angeles-june-18-2025-boundary.geojson,,,,,,,,,,https://techcrunch.com/2025/06/17/waymo-robotaxis-are-pushing-into-even-more-california-cities/,Service area boundary update +2025-06-22,service_created,Tesla,Austin,tesla-austin-june-22-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Flexible,Safety Attendant,Waitlist,,https://www.tesla.com/support/robotaxi/,,https://www.cnbc.com/2025/06/20/tesla-robotaxi-launch-austin.html,Tesla Austin service +2025-06-24,service_created,Waymo,Atlanta,waymo-atlanta-june-24-2025-boundary.geojson,Jaguar I-Pace,Uber,Yes,No,Flexible,Autonomous,Public,,https://waymo.com/waymo-on-uber/,https://www.uber.com/us/en/u/waymo-on-uber/,https://www.uber.com/newsroom/waymo-on-uber-atl/,Waymo Atlanta service +2025-07-14,geometry_updated,Tesla,Austin,tesla-austin-july-14-2025-boundary.geojson,,,,,,,,,,https://www.businessinsider.com/tesla-new-robotaxi-geofence-austin-shape-elon-musk-bigger-waymo-2025-7,Service area boundary update +2025-07-17,geometry_updated,Waymo,Austin,waymo-austin-july-17-2025-boundary.geojson,,,,,,,,,,https://www.axios.com/local/austin/2025/07/17/waymo-expands-austin-service-area,Service area boundary update +2025-07-31,service_created,Tesla,Bay Area,tesla-bay-area-july-31-2025-boundary.geojson,Tesla Model Y,Robotaxi,Yes,Yes,Flexible,Safety Driver,Waitlist,,https://www.tesla.com/support/robotaxi/,,https://www.businessinsider.com/teslas-ride-hailing-service-live-in-san-francisco-musk-says-2025-7,Tesla Bay Area service +2025-08-03,geometry_updated,Tesla,Austin,tesla-austin-august-3-2025-boundary.geojson,,,,,,,,,,https://www.pcmag.com/news/teslas-robotaxi-coverage-expands-four-times-the-size-of-initial-austin,Service area boundary update +2025-08-26,geometry_updated,Tesla,Austin,tesla-austin-august-26-2025-boundary.geojson,,,,,,,,,,https://electrek.co/2025/08/27/tesla-announces-50-increase-in-austin-robotaxi-but-50-from-what/,Service area boundary update +2025-09-01,supervision_updated,Tesla,Austin,,,,,,,Safety Driver,,,,https://mashable.com/article/tesla-robotaxi-human-safety-monitor-drivers-seat#:~:text=Tesla%20now%20puts%20their%20robotaxi%20safety%20monitors%20in%20the%20driver%27s&text=Texas%20SB%202807%2C%20which%20went%20into%20effect%20on%20Sept.,Supervision level update 2025-09-02,geometry_updated,May Mobility,Grand Rapids MN,may-mobility-grand-rapids-mn-september-2-2025-boundary.geojson,,,,,,,,,,,https://www.kaxe.org/local-news/2025-08-11/grand-rapids-autonomous-transit-expanding-to-nearby-cities-tribal-stops, -2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Flexible,Safety Driver,Public,,https://maymobility.com/locations/atlanta-georgia/,https://www.lyft.com/autonomous/maymobility,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service -2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Stop-to-Stop,Autonomous,Public,,https://zoox.com/las-vegas/,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service +2025-09-10,service_created,May Mobility,Atlanta,may-mobility-atlanta-september-10-2025-boundary.geojson,Toyota Sienna,Lyft,Yes,No,Flexible,Safety Driver,Public,,https://maymobility.com/locations/atlanta-georgia/,https://www.lyft.com/autonomous/maymobility,https://maymobility.com/posts/lyft-and-may-mobility-deploy-their-first-autonomous-vehicle-fleet-in-atlanta/,May Mobility Atlanta service +2025-09-10,service_created,Zoox,Las Vegas,zoox-las-vegas-september-10-2025-boundary.geojson,Zoox Robotaxi,Zoox,No,Yes,Stop-to-Stop,Autonomous,Public,,https://zoox.com/las-vegas/,,https://techcrunch.com/2025/09/10/zoox-opens-its-las-vegas-robotaxi-service-to-the-public/,Zoox Las Vegas service From a76ff1db9d21eb53873d60c3d6ff7bef11f42f19 Mon Sep 17 00:00:00 2001 From: jackson Date: Wed, 15 Oct 2025 22:40:00 -0700 Subject: [PATCH 24/24] adding new geometries to the map! --- events.csv | 2 +- ...nd-rapids-mi-25-july-2019-boundary.geojson | 8 +++++++ ...nd-rapids-mi-26-july-2021-boundary.geojson | 8 +++++++ ...apids-mn-september-2-2025-boundary.geojson | 8 +++++++ ...pids-mn-september-28-2022-boundary.geojson | 8 +++++++ ...ee-corners-october-7-2024-boundary.geojson | 8 +++++++ verify-links.js | 22 +++++++++++++++++++ 7 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 geometries/may-mobility-grand-rapids-mi-25-july-2019-boundary.geojson create mode 100644 geometries/may-mobility-grand-rapids-mi-26-july-2021-boundary.geojson create mode 100644 geometries/may-mobility-grand-rapids-mn-september-2-2025-boundary.geojson create mode 100644 geometries/may-mobility-grand-rapids-mn-september-28-2022-boundary.geojson create mode 100644 geometries/may-mobility-peachtree-corners-october-7-2024-boundary.geojson create mode 100644 verify-links.js diff --git a/events.csv b/events.csv index 2e8b27d..1ab02e1 100644 --- a/events.csv +++ b/events.csv @@ -1,7 +1,7 @@ date,event_type,company,city,geometry_file,vehicles,platform,fares,direct_booking,service_model,supervision,access,fleet_partner,company_link,booking_platform_link,source_url,notes 2017-04-25,service_created,Waymo,Phoenix,waymo-phoenix-april-25-2017-boundary.geojson,Chrysler Pacifica Hybrid,Waymo,No,Yes,Flexible,Safety Driver,Waitlist,,https://waymo.com/rides/phoenix/,https://www.uber.com/newsroom/waymo-on-uber/,https://www.technologyreview.com/2017/04/25/152152/waymo-has-invited-the-public-to-hop-into-its-self-driving-cars/,Waymo Phoenix service 2017-11-07,supervision_updated,Waymo,Phoenix,,,,,,,Autonomous,,,,https://waymo.com/blog/2017/11/waymos-fully-self-driving-vehicles-are-here,Supervision level update -2019-07-25,service_created,May Mobility,Grand Rapids MI,may-mobility-grand-rapids-mi-25-july-2019-boundary.geojson,Polaris GEM,Grand Rapids,No,Yes,Stop-to-Stop,Safety Driver,Public,,https://maymobility.com/locations/grand-rapids-michigan/,https://www.grandrapidsmi.gov/Government/Departments/Mobile-GR/Grand-Rapids-Autonomous-Vehicle-Initiative,https://www.michiganbusiness.org/press-releases/2019/07/public-private-partners-launch-grand-rapids-autonomous-vehicle-initiative-avgr/,Downtown Grand Rapids autonomous shuttle service +2019-07-25,service_created,May Mobility,Grand Rapids MI,may-mobility-grand-rapids-mi-25-july-2019-boundary.geojson,Polaris GEM,,No,Yes,Stop-to-Stop,Safety Driver,Public,,https://maymobility.com/locations/grand-rapids-michigan/,https://www.grandrapidsmi.gov/Government/Departments/Mobile-GR/Grand-Rapids-Autonomous-Vehicle-Initiative,https://www.michiganbusiness.org/press-releases/2019/07/public-private-partners-launch-grand-rapids-autonomous-vehicle-initiative-avgr/,Downtown Grand Rapids autonomous shuttle service 2020-10-08,access_policy_changed,Waymo,Phoenix,,,,,,,,Public,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Access policy update 2020-10-08,fares_policy_changed,Waymo,Phoenix,,,,Yes,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Fares policy update 2020-10-08,geometry_updated,Waymo,Phoenix,waymo-phoenix-october-8-2020-boundary.geojson,,,,,,,,,,https://waymo.com/blog/2020/10/waymo-is-opening-its-fully-driverless-service-in-phoenix,Service area boundary update diff --git a/geometries/may-mobility-grand-rapids-mi-25-july-2019-boundary.geojson b/geometries/may-mobility-grand-rapids-mi-25-july-2019-boundary.geojson new file mode 100644 index 0000000..ac608ef --- /dev/null +++ b/geometries/may-mobility-grand-rapids-mi-25-july-2019-boundary.geojson @@ -0,0 +1,8 @@ +{ +"type": "FeatureCollection", +"name": "may-mobility-grand-rapids-mi-25-july-2019-boundary", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, +"features": [ +{ "type": "Feature", "properties": { "fid": 1, "DN": 198 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -85.666332393295974, 42.967897703874492 ], [ -85.666289796507158, 42.964887638390699 ], [ -85.670367526938222, 42.961808888658076 ], [ -85.674770517473391, 42.963758562902811 ], [ -85.676200788284163, 42.96382013055679 ], [ -85.676752804573781, 42.963546282926998 ], [ -85.67658990808637, 42.963872075901804 ], [ -85.677377241108829, 42.96381777707267 ], [ -85.677703034083635, 42.963329087610461 ], [ -85.679793539005331, 42.963220489952185 ], [ -85.683920250019582, 42.963410535854159 ], [ -85.684761881871168, 42.963763478243536 ], [ -85.688589949325177, 42.967075706820765 ], [ -85.700019852858063, 42.967075706820765 ], [ -85.704662402749094, 42.971501061395251 ], [ -85.702816242558512, 42.973673014560646 ], [ -85.703440679093561, 42.976849496065036 ], [ -85.702544748412834, 42.977202438454412 ], [ -85.701784564804953, 42.977745426745763 ], [ -85.701811714219517, 42.978777104499322 ], [ -85.701458771830133, 42.981383448297798 ], [ -85.699531163395847, 42.982306528393089 ], [ -85.695730245356415, 42.982306528393089 ], [ -85.69564879711271, 42.9804603682025 ], [ -85.695132958235931, 42.979673035180049 ], [ -85.695078659406789, 42.978179817378837 ], [ -85.694752866431983, 42.977935472647737 ], [ -85.693232499216208, 42.97758253025836 ], [ -85.693232499216208, 42.975654921824066 ], [ -85.693096752143376, 42.975383427678395 ], [ -85.680255079052984, 42.974976186459884 ], [ -85.680255079052984, 42.974704692314212 ], [ -85.679304849543115, 42.973808761633485 ], [ -85.679033355397451, 42.973238623927571 ], [ -85.678408398422889, 42.971115222474388 ], [ -85.673949947635478, 42.971266634130593 ], [ -85.673440575996551, 42.973320072171269 ], [ -85.673141932436309, 42.973455819244109 ], [ -85.671458668733138, 42.97334722158584 ], [ -85.670508439223269, 42.97334722158584 ], [ -85.670426990979564, 42.972967129781892 ], [ -85.669748255615389, 42.972532739148818 ], [ -85.669150968494904, 42.971582509638957 ], [ -85.667685542098752, 42.970537101812937 ], [ -85.667620423423557, 42.970004427209851 ], [ -85.667563598564996, 42.968770894012572 ], [ -85.666332393295974, 42.967897703874492 ] ] ] ] } } +] +} diff --git a/geometries/may-mobility-grand-rapids-mi-26-july-2021-boundary.geojson b/geometries/may-mobility-grand-rapids-mi-26-july-2021-boundary.geojson new file mode 100644 index 0000000..aa1679e --- /dev/null +++ b/geometries/may-mobility-grand-rapids-mi-26-july-2021-boundary.geojson @@ -0,0 +1,8 @@ +{ +"type": "FeatureCollection", +"name": "may-mobility-grand-rapids-mi-26-july-2021-boundary", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, +"features": [ +{ "type": "Feature", "properties": { "fid": 1, "DN": 198 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -85.669341014396878, 42.956894676357976 ], [ -85.670291243906732, 42.957057572845386 ], [ -85.671214324002023, 42.957736308209569 ], [ -85.67371207014223, 42.957682009380434 ], [ -85.673793518385935, 42.957872055282408 ], [ -85.674825196139494, 42.958523641232027 ], [ -85.675992620965886, 42.959012330694236 ], [ -85.675911172722195, 42.960586996739146 ], [ -85.675721126820221, 42.961021387372227 ], [ -85.676182666867859, 42.961401479176175 ], [ -85.67726864345056, 42.962894696977379 ], [ -85.677132896377728, 42.963356237025025 ], [ -85.676752804573781, 42.963546282926998 ], [ -85.67658990808637, 42.963872075901804 ], [ -85.677377241108829, 42.96381777707267 ], [ -85.677703034083635, 42.963329087610461 ], [ -85.679793539005331, 42.963220489952185 ], [ -85.680933814417159, 42.962894696977379 ], [ -85.683051468753419, 42.962677501660842 ], [ -85.683920250019582, 42.963410535854159 ], [ -85.684761881871168, 42.963763478243536 ], [ -85.688589949325177, 42.967075706820765 ], [ -85.700019852858063, 42.967075706820765 ], [ -85.704662402749094, 42.971501061395251 ], [ -85.702816242558512, 42.973673014560646 ], [ -85.703440679093561, 42.976849496065036 ], [ -85.702544748412834, 42.977202438454412 ], [ -85.701784564804953, 42.977745426745763 ], [ -85.701811714219517, 42.978777104499322 ], [ -85.701458771830133, 42.981383448297798 ], [ -85.699531163395847, 42.982306528393089 ], [ -85.695730245356415, 42.982306528393089 ], [ -85.69564879711271, 42.9804603682025 ], [ -85.695132958235931, 42.979673035180049 ], [ -85.695078659406789, 42.978179817378837 ], [ -85.694752866431983, 42.977935472647737 ], [ -85.693232499216208, 42.97758253025836 ], [ -85.693232499216208, 42.975654921824066 ], [ -85.693096752143376, 42.975383427678395 ], [ -85.680255079052984, 42.974976186459884 ], [ -85.680255079052984, 42.974704692314212 ], [ -85.679304849543115, 42.973808761633485 ], [ -85.679033355397451, 42.973238623927571 ], [ -85.677621585839944, 42.972396992075979 ], [ -85.676535609257243, 42.971392463736983 ], [ -85.676399862184397, 42.971093820176741 ], [ -85.675341035016274, 42.971473911980688 ], [ -85.673522024240256, 42.972939980367329 ], [ -85.673440575996551, 42.973320072171269 ], [ -85.673141932436309, 42.973455819244109 ], [ -85.672218852341018, 42.973618715731511 ], [ -85.671458668733138, 42.97334722158584 ], [ -85.670508439223269, 42.97334722158584 ], [ -85.670426990979564, 42.972967129781892 ], [ -85.669748255615389, 42.972532739148818 ], [ -85.669150968494904, 42.971582509638957 ], [ -85.667684900108256, 42.970577981299961 ], [ -85.667576302449987, 42.969519154131831 ], [ -85.667331957718886, 42.969003315255051 ], [ -85.665485797528305, 42.967320051551873 ], [ -85.663992579727093, 42.966288373798307 ], [ -85.663422442021172, 42.965528190190419 ], [ -85.663015200802661, 42.965256696044747 ], [ -85.663042350217225, 42.964740857167968 ], [ -85.663911131483388, 42.964170719462047 ], [ -85.66380253382512, 42.963763478243536 ], [ -85.663368143192045, 42.963356237025025 ], [ -85.66328669494834, 42.962948995806514 ], [ -85.664101177385362, 42.961537226249007 ], [ -85.664644165676705, 42.9601254566915 ], [ -85.66592018816138, 42.959012330694236 ], [ -85.666381728209018, 42.958822284792262 ], [ -85.66700616474408, 42.958116400013516 ], [ -85.668146440155908, 42.957220469332789 ], [ -85.668607980203547, 42.956921825772547 ], [ -85.669341014396878, 42.956894676357976 ] ] ] ] } } +] +} diff --git a/geometries/may-mobility-grand-rapids-mn-september-2-2025-boundary.geojson b/geometries/may-mobility-grand-rapids-mn-september-2-2025-boundary.geojson new file mode 100644 index 0000000..56b10d6 --- /dev/null +++ b/geometries/may-mobility-grand-rapids-mn-september-2-2025-boundary.geojson @@ -0,0 +1,8 @@ +{ +"type": "FeatureCollection", +"name": "may-mobility-grand-rapids-mn-september-2-2025-boundary", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, +"features": [ +{ "type": "Feature", "properties": { "fid": 1, "DN": 162 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -93.518444910733024, 47.202243986765993 ], [ -93.518684083603276, 47.202243986765993 ], [ -93.519760361519374, 47.200211017368915 ], [ -93.52023870725985, 47.200211017368915 ], [ -93.520597466565221, 47.199732671628432 ], [ -93.52107581230571, 47.199732671628432 ], [ -93.524304646054006, 47.197938875101599 ], [ -93.532197350772051, 47.198417220842089 ], [ -93.536382876001312, 47.201885227460622 ], [ -93.538296258963271, 47.205592406949407 ], [ -93.538535431833509, 47.205592406949407 ], [ -93.539013777573999, 47.209180000003059 ], [ -93.538535431833509, 47.218148982637203 ], [ -93.539013777573999, 47.218866501247938 ], [ -93.540807574100825, 47.219464433423546 ], [ -93.542960129933022, 47.219584019858665 ], [ -93.547384828032534, 47.217431464026475 ], [ -93.549298210994479, 47.216953118285986 ], [ -93.553722909093992, 47.216953118285986 ], [ -93.557071329277406, 47.217790223331839 ], [ -93.558745539369113, 47.218986087683056 ], [ -93.559463057979841, 47.219105674118182 ], [ -93.56651865765204, 47.218148982637203 ], [ -93.570106250705692, 47.219344846988427 ], [ -93.573335084453987, 47.222334507866471 ], [ -93.573095911583749, 47.226520033095738 ], [ -93.569388732094964, 47.228194243187446 ], [ -93.566757830522278, 47.228313829622572 ], [ -93.561735200247156, 47.228313829622572 ], [ -93.559104298674484, 47.226878792401102 ], [ -93.552766217613012, 47.226998378836228 ], [ -93.552048699002285, 47.227835483882082 ], [ -93.55013531604034, 47.228194243187446 ], [ -93.549298210994479, 47.228672588927935 ], [ -93.54917862455936, 47.229748866844034 ], [ -93.548939451689122, 47.229748866844034 ], [ -93.548461105948633, 47.23106431763037 ], [ -93.547743587337891, 47.23154266337086 ], [ -93.545830204375946, 47.232021009111349 ], [ -93.542242611322294, 47.232021009111349 ], [ -93.539492123314488, 47.231183904065496 ], [ -93.53710039461204, 47.229509693973789 ], [ -93.535306598085214, 47.229031348233299 ], [ -93.533991147298877, 47.229150934668425 ], [ -93.533991147298877, 47.230705558325006 ], [ -93.534230320169115, 47.230705558325006 ], [ -93.534469493039367, 47.23154266337086 ], [ -93.536024116695955, 47.232618941286958 ], [ -93.538176672528138, 47.232858114157203 ], [ -93.540090055490097, 47.233934392073301 ], [ -93.553962081964244, 47.233934392073301 ], [ -93.555157946315461, 47.234891083554274 ], [ -93.555397119185699, 47.235847775035246 ], [ -93.555636292055951, 47.235847775035246 ], [ -93.555636292055951, 47.237043639386471 ], [ -93.554918773445209, 47.237402398691835 ], [ -93.545112685765218, 47.237402398691835 ], [ -93.5449930993301, 47.241109578180613 ], [ -93.544753926459848, 47.241109578180613 ], [ -93.54451475358961, 47.242903374707446 ], [ -93.536502462436431, 47.243142547577683 ], [ -93.536382876001312, 47.245175516974761 ], [ -93.541883852016923, 47.245055930539635 ], [ -93.544395167154477, 47.246251794890853 ], [ -93.544753926459848, 47.246849727066468 ], [ -93.545591031505708, 47.247328072806951 ], [ -93.545591031505708, 47.249241455768903 ], [ -93.544275580719358, 47.250796079425491 ], [ -93.541525092711552, 47.251513598036219 ], [ -93.536143703131074, 47.251513598036219 ], [ -93.535187011650095, 47.25091566586061 ], [ -93.531719005031562, 47.25091566586061 ], [ -93.531001486420834, 47.251752770906464 ], [ -93.528729344153518, 47.252948635257681 ], [ -93.528370584848147, 47.25354656743329 ], [ -93.530403554245225, 47.255101191089878 ], [ -93.530881899985701, 47.255101191089878 ], [ -93.532914869382779, 47.256416641876221 ], [ -93.533154042253017, 47.257373333357194 ], [ -93.53231693720717, 47.257971265532802 ], [ -93.529566449199365, 47.258808370578656 ], [ -93.526457201886203, 47.258808370578656 ], [ -93.524663405359362, 47.258330024838166 ], [ -93.522271676656928, 47.256655814746466 ], [ -93.521434571611081, 47.254503258914269 ], [ -93.52251084952718, 47.252589875952317 ], [ -93.524543818924244, 47.251513598036219 ], [ -93.524543818924244, 47.251274425165974 ], [ -93.521673744481319, 47.251154838730855 ], [ -93.520836639435473, 47.250198147249883 ], [ -93.518684083603276, 47.249839387944512 ], [ -93.514857317679372, 47.250078560814757 ], [ -93.509595514534013, 47.24840435072305 ], [ -93.50899758235839, 47.24792600498256 ], [ -93.508877995923271, 47.247088899936706 ], [ -93.508160477312543, 47.246251794890853 ], [ -93.506127507915465, 47.245055930539635 ], [ -93.506127507915465, 47.242903374707446 ], [ -93.505529575739857, 47.242544615402075 ], [ -93.504812057129129, 47.24230544253183 ], [ -93.502779087732051, 47.242544615402075 ], [ -93.498832735373028, 47.244577584799146 ], [ -93.497038938846202, 47.245055930539635 ], [ -93.496680179540846, 47.245414689844999 ], [ -93.495962660930104, 47.245414689844999 ], [ -93.487591610471569, 47.242903374707446 ], [ -93.484362776723287, 47.240631232440123 ], [ -93.484004017417917, 47.240272473134759 ], [ -93.484123603853035, 47.225682928049885 ], [ -93.484362776723287, 47.224008717958178 ], [ -93.484601949593525, 47.224008717958178 ], [ -93.484960708898896, 47.22281285360696 ], [ -93.487113264731079, 47.221497402820617 ], [ -93.489026647693038, 47.220899470645008 ], [ -93.490222512044255, 47.221138643515253 ], [ -93.495962660930104, 47.223171612912324 ], [ -93.499909013289127, 47.225324168744521 ], [ -93.505409989304738, 47.227357138141592 ], [ -93.506007921480347, 47.227835483882082 ], [ -93.506605853655955, 47.227835483882082 ], [ -93.50899758235839, 47.229031348233299 ], [ -93.510432619579859, 47.229509693973789 ], [ -93.513781039763273, 47.229390107538663 ], [ -93.513781039763273, 47.22843341605769 ], [ -93.507682131572054, 47.228313829622572 ], [ -93.507323372266683, 47.226041687355249 ], [ -93.503137847037422, 47.224487063698668 ], [ -93.502659501296932, 47.224128304393304 ], [ -93.502659501296932, 47.223649958652814 ], [ -93.50337701990766, 47.22281285360696 ], [ -93.504572884258891, 47.222454094301597 ], [ -93.504453297823758, 47.220062365599155 ], [ -93.504931643564248, 47.219584019858665 ], [ -93.507682131572054, 47.219464433423546 ], [ -93.513900626198392, 47.2203015384694 ], [ -93.514020212633511, 47.210375864354283 ], [ -93.514378971938882, 47.210256277919157 ], [ -93.517009873511569, 47.205114061208917 ], [ -93.517249046381806, 47.205114061208917 ], [ -93.518444910733024, 47.202243986765993 ] ] ] ] } } +] +} diff --git a/geometries/may-mobility-grand-rapids-mn-september-28-2022-boundary.geojson b/geometries/may-mobility-grand-rapids-mn-september-28-2022-boundary.geojson new file mode 100644 index 0000000..280a4b4 --- /dev/null +++ b/geometries/may-mobility-grand-rapids-mn-september-28-2022-boundary.geojson @@ -0,0 +1,8 @@ +{ +"type": "FeatureCollection", +"name": "may-mobility-grand-rapids-mn-september-28-2022-boundary", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, +"features": [ +{ "type": "Feature", "properties": { "fid": 1, "DN": 57961 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -93.529499239075861, 47.208682691673985 ], [ -93.530473554932271, 47.209061592284812 ], [ -93.531339613471303, 47.209927650823836 ], [ -93.531339613471303, 47.219454294753156 ], [ -93.567364309134248, 47.219513873226866 ], [ -93.567335171499678, 47.219508423411845 ], [ -93.568471873332157, 47.219724938046596 ], [ -93.569121417236431, 47.220590996585628 ], [ -93.569121417236431, 47.2237845874483 ], [ -93.568417744673468, 47.224650645987325 ], [ -93.567768200769194, 47.224758903304703 ], [ -93.531339613471303, 47.224758903304703 ], [ -93.531339613471303, 47.234989219796979 ], [ -93.535561648849068, 47.234989219796979 ], [ -93.5364277073881, 47.235584635042564 ], [ -93.536535964705479, 47.235801149677322 ], [ -93.536590093364168, 47.245436050924013 ], [ -93.541840573257033, 47.245490179582703 ], [ -93.543302047041635, 47.245706694217461 ], [ -93.544059848263288, 47.246031466169597 ], [ -93.544980035461009, 47.246951653367319 ], [ -93.545142421437077, 47.247384682636827 ], [ -93.545142421437077, 47.248521384469306 ], [ -93.544980035461009, 47.249116799714891 ], [ -93.543951590945909, 47.250199372888673 ], [ -93.541894701915723, 47.250903045451636 ], [ -93.533125859208056, 47.251444332038524 ], [ -93.529499239075861, 47.254096636314301 ], [ -93.529499239075861, 47.255503981440228 ], [ -93.52895795248898, 47.256099396685805 ], [ -93.52798363663257, 47.25658655461401 ], [ -93.526684548824022, 47.25658655461401 ], [ -93.526035004919748, 47.256315911320563 ], [ -93.525060689063338, 47.255395724122849 ], [ -93.525439589674164, 47.253771864362164 ], [ -93.525764361626301, 47.253392963751345 ], [ -93.528037765291259, 47.25182323264935 ], [ -93.528579051878154, 47.251606718014592 ], [ -93.530798326884408, 47.250091115571294 ], [ -93.530960712860477, 47.249712214960468 ], [ -93.52322031466791, 47.249658086301778 ], [ -93.522787285398394, 47.249658086301778 ], [ -93.522354256128878, 47.24949570032571 ], [ -93.521975355518052, 47.249008542397512 ], [ -93.521758840883294, 47.247980097882412 ], [ -93.51206981097792, 47.247980097882412 ], [ -93.510445951217235, 47.247601197271585 ], [ -93.509579892678204, 47.24684339604994 ], [ -93.509525764019514, 47.236504822240285 ], [ -93.509904664630341, 47.235638763701253 ], [ -93.510933109145441, 47.235043348455669 ], [ -93.512935869516937, 47.234826833820911 ], [ -93.513098255493006, 47.234826833820911 ], [ -93.521055168320331, 47.234772705162221 ], [ -93.521055168320331, 47.233690131988439 ], [ -93.520297367098692, 47.233040588084165 ], [ -93.519810209170487, 47.232932330766786 ], [ -93.518673507338008, 47.23222865820383 ], [ -93.518511121361939, 47.232336915521209 ], [ -93.51840286404456, 47.232012143569072 ], [ -93.518132220751113, 47.232174529545141 ], [ -93.518186349409802, 47.231958014910383 ], [ -93.516887261601255, 47.230929570395283 ], [ -93.516400103673064, 47.230117640514948 ], [ -93.516291846355685, 47.223946973424361 ], [ -93.507901904258844, 47.223946973424361 ], [ -93.507523003648018, 47.223730458789611 ], [ -93.506981717061123, 47.223026786226647 ], [ -93.506981717061123, 47.222214856346305 ], [ -93.50725236035457, 47.221619441100728 ], [ -93.507901904258844, 47.221186411831212 ], [ -93.516345975014374, 47.221186411831212 ], [ -93.516345975014374, 47.209927650823836 ], [ -93.516887261601255, 47.209278106919562 ], [ -93.518132220751113, 47.208845077650054 ], [ -93.518186349409802, 47.208682691673985 ], [ -93.529499239075861, 47.208682691673985 ] ] ] ] } } +] +} diff --git a/geometries/may-mobility-peachtree-corners-october-7-2024-boundary.geojson b/geometries/may-mobility-peachtree-corners-october-7-2024-boundary.geojson new file mode 100644 index 0000000..7f3a479 --- /dev/null +++ b/geometries/may-mobility-peachtree-corners-october-7-2024-boundary.geojson @@ -0,0 +1,8 @@ +{ +"type": "FeatureCollection", +"name": "may-mobility-peachtree-corners-october-7-2024-boundary", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, +"features": [ +{ "type": "Feature", "properties": { "fid": 1, "DN": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -84.231719471144785, 33.953602611711553 ], [ -84.234632677117332, 33.954237541218383 ], [ -84.234352561158431, 33.956086306547114 ], [ -84.234352561158431, 33.956515817684092 ], [ -84.233680282857065, 33.95690798002655 ], [ -84.233082702144756, 33.957505560738866 ], [ -84.232354400651616, 33.958065792656662 ], [ -84.230748402487265, 33.958159164642957 ], [ -84.230169496172209, 33.958271211026521 ], [ -84.227984591692802, 33.959783837204569 ], [ -84.226061128775044, 33.961856695300419 ], [ -84.223166597199764, 33.963649437437368 ], [ -84.220776274350499, 33.964620506094882 ], [ -84.21963713611764, 33.965572900355134 ], [ -84.219599787323119, 33.96566627234143 ], [ -84.221000367117611, 33.968037920793435 ], [ -84.219674484912161, 33.970260174067363 ], [ -84.218666067460134, 33.970334871656405 ], [ -84.216331767802643, 33.970334871656405 ], [ -84.214053491336941, 33.969102361437251 ], [ -84.213493259419138, 33.966506620218126 ], [ -84.213474585021885, 33.964956645245557 ], [ -84.214539025665701, 33.96432171573872 ], [ -84.216014303049221, 33.96432171573872 ], [ -84.216555860569756, 33.96407894857434 ], [ -84.2171907900766, 33.963313298286685 ], [ -84.217489580432755, 33.961931392889454 ], [ -84.218292579514937, 33.961016347423723 ], [ -84.219767856898457, 33.960381417916885 ], [ -84.221896738186089, 33.960512138697702 ], [ -84.222867806843595, 33.958644698971717 ], [ -84.223353341172356, 33.957337491163528 ], [ -84.223876224295637, 33.956964003218324 ], [ -84.224772595364115, 33.95644112009505 ], [ -84.227872545309253, 33.954947168314263 ], [ -84.230225519363998, 33.954032122848524 ], [ -84.231514052774926, 33.953583937314292 ], [ -84.231719471144785, 33.953602611711553 ] ] ] ] } } +] +} diff --git a/verify-links.js b/verify-links.js new file mode 100644 index 0000000..936ecc3 --- /dev/null +++ b/verify-links.js @@ -0,0 +1,22 @@ +const response = await fetch('https://vbqijqcveavjycsfoszy.supabase.co/storage/v1/object/public/staging-data-cache/all-data.json'); +const data = await response.json(); + +console.log('Checking service links in cache...\n'); + +// Check Waymo Phoenix +const waymoPhoenix = data.service_areas.find(s => s.company === 'Waymo' && s.name === 'Phoenix' && !s.endDate); +console.log('Waymo Phoenix:'); +console.log(' companyLink:', waymoPhoenix?.companyLink); +console.log(' bookingPlatformLink:', waymoPhoenix?.bookingPlatformLink); + +// Check May Mobility Atlanta +const mayMobility = data.service_areas.find(s => s.company === 'May Mobility' && !s.endDate); +console.log('\nMay Mobility Atlanta:'); +console.log(' companyLink:', mayMobility?.companyLink); +console.log(' bookingPlatformLink:', mayMobility?.bookingPlatformLink); + +// Check Zoox Las Vegas +const zoox = data.service_areas.find(s => s.company === 'Zoox' && !s.endDate); +console.log('\nZoox Las Vegas:'); +console.log(' companyLink:', zoox?.companyLink); +console.log(' bookingPlatformLink:', zoox?.bookingPlatformLink || '(none)');