This repository contains the main script used to generate an interactive HTML map of Chicago parking permit zones from the CSV in the project's data folder.
The current entry point is:
src/create_parking_permit_map.py
The script geocodes the address ranges in the source CSV, draws each permit segment on a Folium map, and adds browser-side filtering and address search controls.
- Reads parking permit zone rows from
../data/Parking_Permit_Zones_20260313.csv - Geocodes the low and high address for each row
- Draws each row as a colored line segment on a map of Chicago
- Adds UI controls for:
- status filtering
- buffer filtering
- ward filtering
- address search
- Reuses a JSON geocode cache so repeat runs are faster
When checking to see whether an address is part of a residential permit parking zone, the City of Chicago provides the following resource: https://ezbuy.chicityclerk.com/zone-lookup
This site allows you to enter an address and it will tell you the zone if it is in one. You must have an address in mind and cannot easily discern the boundaries of the zones.
There did not exist (to my knowledge) a visual resource showing all zones on a map -- there are some wards which provide maps of the zones but they can be in my experience pretty tricky to find.
So I made one!
The parking permit zone data used is from: https://data.cityofchicago.org/Transportation/Parking-Permit-Zones/u9xt-hiju/about_data
The output is not perfect -- different geocoders will give varying accuracy. I have only used nominatim and arcgis -- these geocoders sometimes don't give accurate coordinates for the high or low addresses (especially when the address doesn't physically exist) which results in lines that are far too long on the map. If anyone has access to another geocoder and wants to try, feel free to share the cached output!
Only nominatim and arcgis have been verified to work -- while there is implementation for others, it is not guaranteed to work
ArcGIS provides cleaner output than Nominatim.
GitHub Copilot was used to develop this program.
- Python 3.10 or newer is recommended
- Internet access for geocoding
- A Python virtual environment is recommended
From the repository root:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r .\src\requirements.txtFrom the repository root:
python .\src\create_parking_permit_map.pyBy default, the script uses:
- Input CSV:
data/Parking_Permit_Zones_20260313.csv - Output HTML:
output/parking_permit_zones_map.html - Cache file:
data/geocode_cache_chicago.json - Geocoder:
nominatim
When the run finishes, open the generated HTML file in a browser.
Process only a few rows for a quick test:
python .\src\create_parking_permit_map.py --max-rows 10Write to a custom output file:
python .\src\create_parking_permit_map.py --output .\output\parking_permit_zones_map_test.htmlUse ArcGIS instead of Nominatim:
python .\src\create_parking_permit_map.py --geocoder arcgisTune geocoding rate limiting:
python .\src\create_parking_permit_map.py \
--geocoder nominatim \
--geocode-min-delay-seconds 1.5 \
--geocode-timeout 15 \
--geocode-max-retries 3The script supports these --geocoder values:
Only nominatim and arcgis have been verified to work -- while there is implementation for others, it is not guaranteed to work
nominatim(verified)arcgis(verified)photongoogleheremapbox
Some providers require environment variables.
Google:
$env:GEOCODER_GOOGLE_API_KEY = "your-google-key"
python .\src\create_parking_permit_map.py --geocoder googleHere:
$env:GEOCODER_HERE_API_KEY = "your-here-key"
python .\src\create_parking_permit_map.py --geocoder hereMapbox:
$env:GEOCODER_MAPBOX_API_KEY = "your-mapbox-key"
python .\src\create_parking_permit_map.py --geocoder mapboxThe most useful options are:
--csv: path to the source CSV file--output: path for the generated HTML map--cache: path to the geocode cache JSON--max-rows: limit processing to the firstNrows for testing--geocoder: choose the geocoding provider--geocode-timeout: timeout per request in seconds--geocode-min-delay-seconds: minimum delay between requests--geocode-max-retries: retry count for failed requests--geocode-error-wait-seconds: delay before retrying after an error
Show the built-in help:
python .\src\create_parking_permit_map.py --helpPrimary outputs:
- HTML map file in
output/ - Geocode cache file in
data/
The zone data is embedded within the HTML map so it is completely portable. No need for internet access.
The cache is reused across runs and is namespaced by geocoder provider, which helps avoid mixing results from different providers.
- The first full run can take a while because every uncached address must be geocoded.
- Subsequent runs are much faster if the cache file is preserved.
- If many rows are skipped, try a different geocoder provider.
--max-rowsis mainly useful for quick testing before running the full dataset.
requirements.txt: Python dependencies for this scriptrun_command.txt: example PowerShell command