Skip to content

Commit 76ca785

Browse files
Add GTFS-to-TDEI Converter Utility
1 parent 5017704 commit 76ca785

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Utilities related to the TDEI.
3232

3333
- **[GoInfoGame Images Exif Data Update Script](utilities/update-exif.ps1)**
3434
- **[GoInfoGame Images Exif Data Update Script (Recursive)](utilities/update-exif-recursive.ps1)**
35+
- **[GTFS-to-TDEI Converter Script](utilities/gtfs-to-tdei-converter.ps1)**
3536
- **[Quest ID Update Script](utilities/update-quest-ids.ps1)**
3637
- **[Workspaces Export Script](utilities/workspace-export.ps1)**
3738
- **[Workspaces JOSM Settings Script](utilities/workspace-josm.ps1)**
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Name: GTFS-to-TDEI Converter Script
2+
# Version: 1.1
3+
# Description: This script takes a GTFS archive, processes it to convert stops.txt to stops.geojson, and zips the result into an archive ready for upload to TDEI.
4+
# Author: Amy Bordenave, Taskar Center for Accessible Technology, University of Washington
5+
# Date: 2025-08-05
6+
# License: CC-BY-ND 4.0 International
7+
8+
# This script is designed to be run in a PowerShell environment.
9+
10+
# Ask for and validate inputs
11+
Write-Host "GTFS-to-TDEI Converter Script v1.0" -ForegroundColor DarkBlue
12+
Write-Host ""
13+
Write-Host "Enter the path to the GTFS zip archive:" -ForegroundColor Green
14+
$InputZip = Read-Host
15+
16+
# Check if input ZIP exists
17+
if (-not (Test-Path $InputZip)) {
18+
Write-Error "Input ZIP file not found: $InputZip"
19+
exit 1
20+
}
21+
22+
# Create temp directory
23+
$tempDir = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
24+
New-Item -ItemType Directory -Path $tempDir | Out-Null
25+
26+
# Extract stops.txt from ZIP
27+
$stopsPath = Join-Path $tempDir "stops.txt"
28+
Add-Type -AssemblyName System.IO.Compression.FileSystem
29+
$zip = [System.IO.Compression.ZipFile]::OpenRead($InputZip)
30+
$stopsEntry = $zip.Entries | Where-Object { $_.Name -eq "stops.txt" }
31+
32+
if (-not $stopsEntry) {
33+
Write-Error "stops.txt not found in ZIP archive"
34+
$zip.Dispose()
35+
Remove-Item -Path $tempDir -Recurse -Force
36+
exit 1
37+
}
38+
39+
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($stopsEntry, $stopsPath, $true)
40+
$zip.Dispose()
41+
42+
# Read the CSV file
43+
$stops = Import-Csv $stopsPath
44+
45+
# Create GeoJSON structure
46+
$geojson = @{
47+
'$schema' = 'https://sidewalks.washington.edu/opensidewalks/0.2/schema.json'
48+
'type' = 'FeatureCollection'
49+
'features' = @()
50+
'dataTimestamp' = (Get-Date).ToString('o') # ISO 8601 timestamp
51+
'dataSource' = @{
52+
'name' = 'GTFS stops.txt from ' + [System.IO.Path]::GetFileName($InputZip)
53+
'timestamp' = (Get-Item $InputZip).LastWriteTime.ToString('o')
54+
}
55+
}
56+
57+
# Initialize counter for generating numeric IDs
58+
$idCounter = 1
59+
60+
# Process each stop
61+
foreach ($stop in $stops) {
62+
# Get all properties and prefix them with 'ext:'
63+
$properties = @{}
64+
$stop.PSObject.Properties | ForEach-Object {
65+
$properties["ext:$($_.Name)"] = $_.Value
66+
}
67+
68+
# Create feature object following OpenSidewalks schema for CustomPoint
69+
$feature = @{
70+
type = 'Feature'
71+
geometry = @{
72+
type = 'Point'
73+
coordinates = @(
74+
[double]$stop.stop_lon,
75+
[double]$stop.stop_lat
76+
)
77+
}
78+
properties = @{
79+
# Add required _id field using sequential counter
80+
'_id' = $idCounter++
81+
# Store original stop_id as ext:stop_id
82+
'ext:stop_id' = $stop.stop_id
83+
# Add all GTFS properties with ext: prefix
84+
}
85+
}
86+
87+
# Add the ext: prefixed properties
88+
$stop.PSObject.Properties | ForEach-Object {
89+
$feature.properties["ext:$($_.Name)"] = $_.Value
90+
}
91+
92+
# Add feature to collection
93+
$geojson.features += $feature
94+
}
95+
96+
# Convert to JSON and save
97+
$geojsonPath = "stops.geojson"
98+
$zipPath = "stops.zip"
99+
$geojson | ConvertTo-Json -Depth 10 | Set-Content $geojsonPath
100+
101+
# Create ZIP archive
102+
if (Test-Path $zipPath) {
103+
Remove-Item $zipPath
104+
}
105+
Compress-Archive -Path $geojsonPath -DestinationPath $zipPath
106+
Remove-Item $geojsonPath # Clean up the temporary GeoJSON file
107+
108+
# Clean up temp directory
109+
Remove-Item -Path $tempDir -Recurse -Force
110+
111+
Write-Host "Success! Created stops.zip - ready for upload to TDEI." -ForegroundColor Blue
112+
113+
# Prevent the PowerShell window from closing automatically
114+
Read-Host -Prompt "Press <Enter> to exit"

0 commit comments

Comments
 (0)