ny_state.py builds New York from its own sources (no published layer). Port Authority crossings (GWB, Lincoln, Holland, Goethals, Bayonne, Outerbridge) are on the NJ page; the Canada bridges are recorded as not routable (the router is United States only).
thruway_2024_ny_ezpass_cpm, thruway_2024_non_ny_tbm_cpm) are in force through 2026; watch the Thruway's toll page (thruway_schedules_page) for the next schedule. Fixed-toll gantries: thruway_gantry_rate_charts; Cuomo Bridge: thruway_gmmcb_toll_charts; truck time bands: thruway_2026_incentive_charts. Gantry positions: the Thruway's own gantry API (thruway_gantry_api).mta_crossing_charges (TBTA, effective 2026-01-04). Re-fetch when MTA announces new crossing charges.mta_cbd_charges. The schedule prints three columns (2025-2027, 2028-2030, 2031 on); the builder reads the first column. In January 2028 the builder must read the second (first_amt in ny_state.py).nysba_toll_rates (eastbound only; amounts on the page are HTML entities, unescaped by the builder).ncba_toll_schedule_2024, the authority's own PDF; the file name carries the year: a new schedule means a new URL in urls.txt. No Tolls by Mail.python3 /home/geo1/system/handbuilt/fetch_list.py NY [names] (Bridge Authority, Niagara/Peace bridges, Port Authority guide, Atlantic Beach Bridge).thruway_* and mta_* source on b100: node ~/apitest/fetch_b100.mjs ~/nyfetch thruway_gantry_api=<url> ... (URLs are in /home/geo1/maps/toll/NY/urls.txt), then rsync -a ~/nyfetch/ geo1@192.168.50.220:/home/geo1/maps/toll/NY/sources/.python3 cbd_classify.py writes osm/ny_cbd_gantries.json (every MTA detection gantry in Manhattan, the way it stands on, which side of the zone line each end is).NY; OSM box -79.8,40.45,-71.8,45.05, then python3 tollnode_ways.py NY.nj_state.py, pa_state.py): NY writes osm/ny_not_toll_nodes.json (zone exits, excluded roads, interior gantries) and their untied lists must leave them out.cbd_role() decides for every zone gantry: entry (charged), exit, excluded (FDR Drive, West Side Highway/West Street), interior (two northbound 10th Avenue gantries), or unclear. Hard-coded nodes: Carey exit ramp to Trinity Place 2012177083 = entry; Holland ramp 14184450532 = exit; 10th Avenue 14173684889, 14184334270 = interior.osm/ny_lane_ways.json. The tunnel credit applies entering or exiting; an exit-only pass is $0.00.BOUND by milepost.ezpass_ny) vs "Non-NY E-ZPass / Tolls by Mail" on the Thruway; NYCSC tiers a/b/c at MTA crossings.Hosts: geo1 (192.168.50.220) holds the sources, builders, drafts, map and API; b100 (192.168.50.14) is the test client. All times are Eastern.
| what | where (geo1 unless said) |
|---|---|
| sources list | /home/geo1/maps/toll/NY/urls.txt (name <tab> URL) |
| archived sources | /home/geo1/maps/toll/NY/sources/<name>/<YYYY-MM-DD>/ (file + meta.json: url, fetched, sha256) |
| builder | /home/geo1/system/handbuilt/ny_state.py; shared code toll_common.py |
| OpenStreetMap inputs | /home/geo1/system/handbuilt/osm/ny_* (cut from /home/geo1/maps/osm/us-latest.osm.pbf) |
| output | draft /srv/toll/draft/NY/ (the builders write here); published /srv/toll/NY/ (copied from the draft by promote.py publish). The map and the API read the published page, or the draft while it is listed for review |
| toll engine | source /home/geo1/maps/web/tolls.js, served copy /srv/maps/tolls.js (the API runs the served copy) |
| API | /home/geo1/maps/api/server.mjs on 127.0.0.1:8090 behind nginx /api/; pid in logs/test.pid |
| regression trips | b100: ~/apitest/site/cases.json, runner ~/apitest/run.py, browser check ~/apitest/browser.mjs |
python3 /home/geo1/system/handbuilt/fetch_list.py NY [name ...] (no names = every line of urls.txt). A new source: add a line to urls.txt first, then fetch it by name.node ~/apitest/fetch_b100.mjs <out> <name>=<url> ..., then rsync -a <out>/ geo1@192.168.50.220:/home/geo1/maps/toll/NY/sources/. Its meta.json records that it came from b100.diff, pdftotext -layout for PDFs). Same content: nothing to do. Changed amounts or a new effective date: rebuild (step 2) and update the expected amounts of the affected regression trips from the operator's own figures.python3 /home/geo1/maps/toll/bin/tollup.py NY update fetches the adapter's sources (bin/adapters/ny.py), stores a document only when its content changes, writes one rate file per version under /home/geo1/maps/toll/NY/rates/ and appends every price change to history.csv (every run to runs.log). TOLL_WEB=/home/geo1/maps/toll/corpus python3 /home/geo1/maps/toll/bin/publish.py NY writes the corpus /home/geo1/maps/toll/corpus/NY from it (DE: plain publish.py DE writes /srv/toll/DE). Never hand-edit either. Then rebuild the draft (step 2) so it picks up the new rates.
cd /home/geo1/system/handbuilt && python3 ny_state.pybash /home/geo1/system/handbuilt/chain.sh NY (logs in /tmp/ny1.log ... ny6.log; it prints the points, any point on no road and the untied count). The builders written since October 2026 share state_kit.py (sources, booths, terms, rows, write) and own_state.py (keeps a state's untied list to toll nodes inside the state, by the local geocoder; cache osm/node_state.json).cd /home/geo1/system/handbuilt; H=$(ls osm/ny_highways_*.geojsonseq); J=$(ls osm/ny_junctions_*.geojsonseq)
python3 ny_state.py && python3 osm_streets.py NY $H $J && python3 ny_state.py && python3 osm_snap.py NY && python3 toll_ways.py NY && python3 ny_state.pytoll_ways.py's output: nodes claimed by two points: {} and points on no road: [] must both be empty.OSM way <id>) needs that way in osm/ny_lane_ways.json (the builder writes it). A point on a road priced entry to exit needs gantry in its location name, or toll_ways.py treats it as a position-only exit marker.osm/ny_not_toll_nodes.json (congestion-zone gantries that are not tolls); every state's untied list leaves those out, so rebuild NJ and PA after NY.tolls.js when it starts. Restart it: cd /home/geo1/maps/api && kill $(cat logs/test.pid); (nohup /home/geo1/maps/node/bin/node server.mjs > logs/server.log 2>&1 & echo $! > logs/test.pid) (it is started by hand, not a service).python3 ~/apitest/run.py ~/apitest/site/cases.json. Every trip must be OK. Add a trip for every rate or rule you change, with the amount taken from the operator's own source.tolls.js): edit /home/geo1/maps/web/tolls.js, check with /home/geo1/maps/node/bin/node --check, copy to /srv/maps/tolls.js with sudo install -o www-data -g www-data -m 644, restart the API, run the trips.The builders match toll points to the OSM way ids the router drives, so the extracts here must come from the same us-latest.osm.pbf the router (Valhalla, /home/geo1/maps/valhalla_data) was built from (now 2026-09-27). New OSM data means: rebuild the router tiles, then for each state cut the box, rebuild its OSM inputs and run the full chain, then compare untied_toll_nodes.csv and the estimated positions below. The box for NY and the cutting commands are in the state's procedure above; the toll-node and way index comes from python3 tollnode_ways.py NY.
A rebuild writes the draft (/srv/toll/draft/NY); the published page (/srv/toll/NY) does not change. python3 /home/geo1/maps/toll/bin/promote.py review NY lists the draft for review: the map and the API then read it instead of the published page. Run the regression trips from b100. After approval, python3 /home/geo1/maps/toll/bin/promote.py publish NY copies the draft to /srv/toll/NY (the previous page is kept under /home/geo1/maps/toll/NY/published/<time>/) and takes it off the review list. After a change, update the coverage line for NY in the API page (/api.html, generator /home/geo1/maps/api/doc/api_page.py) and rebuild this page: python3 /home/geo1/system/handbuilt/maintain_pages.py NY.
Each fetch is kept in its own dated folder under /home/geo1/maps/toll/NY/sources/<name>/; the builder always reads the newest one, so a new fetch takes effect at the next rebuild and the old one stays for comparison.
| source | fetched (newest) | fetches kept | how | listed in urls.txt | rows using it |
|---|---|---|---|---|---|
mta_cbd_abouthttps://www.mta.info/fares-tolls/tolls/congestion-relief-zone/about | 2026-10-08 | 1 | b100 (192.168.50.14), headless Chrome: the site refuses geo1 / scripts (HTTP 403) | yes | |
mta_cbd_chargeshttps://www.mta.info/document/138931 | 2026-10-08 | 1 | b100 (192.168.50.14), headless Chrome: the site refuses geo1 / scripts (HTTP 403) | yes | 521 |
mta_crossing_chargeshttps://www.mta.info/document/180046 | 2026-10-08 | 1 | b100 (192.168.50.14), headless Chrome: the site refuses geo1 / scripts (HTTP 403) | yes | 210 |
mta_vehicle_typeshttps://www.mta.info/fares-tolls/tolls/vehicle-types | 2026-10-08 | 1 | b100 (192.168.50.14), headless Chrome: the site refuses geo1 / scripts (HTTP 403) | yes | |
ncba_ezpasshttps://www.ncbaabb.com/ezpass/ | 2026-10-09 | 1 | fetch_list.py | yes | |
ncba_homehttps://www.ncbaabb.com/ | 2026-10-09 | 1 | fetch_list.py | yes | |
ncba_toll_schedule_2024https://www.ncbaabb.com/wp-content/uploads/2024-Toll-Rate-Schedule.pdf | 2026-10-09 | 1 | fetch_list.py | yes | 12 |
nfbc_tollshttps://www.niagarafallsbridges.com/crossing-info/toll-cost-vehicle-definitions | 2026-10-09 | 1 | fetch_list.py | yes | |
nysba_toll_historyhttps://www.nysba.ny.gov/toll-history | 2026-10-09 | 1 | fetch_list.py | yes | |
nysba_toll_rateshttps://www.nysba.ny.gov/toll-rates | 2026-10-09 | 1 | fetch_list.py | yes | 85 |
panynj_truckers_guide_2026https://www.panynj.gov/content/dam/bridges-tunnels/truckers-guides/Truckers%20Guide_Eng_Ap | 2026-10-09 | 1 | fetch_list.py | yes | |
peacebridge_tollshttps://www.peacebridge.com/?p=708 | 2026-10-09 | 1 | fetch_list.py | yes | |
thruway_2024_non_ny_tbm_cpmhttps://www.thruway.ny.gov/sites/default/files/2025-07/2024-non-ny-tbm-cpm.pdf | 2026-10-08 | 1 | b100 (192.168.50.14), headless Chrome: the site refuses geo1 / scripts (HTTP 403) | yes | 3708 |
thruway_2024_ny_ezpass_cpmhttps://www.thruway.ny.gov/sites/default/files/2025-07/2024-ny-e-zpass-cpm.pdf | 2026-10-08 | 1 | b100 (192.168.50.14), headless Chrome: the site refuses geo1 / scripts (HTTP 403) | yes | 3714 |
thruway_2026_incentive_chartshttps://www.thruway.ny.gov/sites/default/files/2025-12/2026-incentive-tolls-charts.pdf | 2026-10-08 | 1 | b100 (192.168.50.14), headless Chrome: the site refuses geo1 / scripts (HTTP 403) | yes | 218 |
thruway_classeshttps://www.thruway.ny.gov/travelers/classes | 2026-10-08 | 1 | b100 (192.168.50.14), headless Chrome: the site refuses geo1 / scripts (HTTP 403) | yes | |
thruway_gantry_apihttps://webdataapi.thruway.ny.gov/api/data/gantrylocations/xml | 2026-10-09 | 1 | fetch_list.py | yes | |
thruway_gantry_rate_chartshttps://www.thruway.ny.gov/sites/default/files/2025-07/gantry-rate-toll-charts.pdf | 2026-10-08 | 1 | b100 (192.168.50.14), headless Chrome: the site refuses geo1 / scripts (HTTP 403) | yes | 135 |
thruway_gmmcb_toll_chartshttps://www.thruway.ny.gov/sites/default/files/2025-07/gmmcb-toll-charts.pdf | 2026-10-08 | 1 | b100 (192.168.50.14), headless Chrome: the site refuses geo1 / scripts (HTTP 403) | yes | 21 |
thruway_interchangeshttps://data.ny.gov/api/views/7jkf-259w/rows.csv?accessType=DOWNLOAD | 2026-10-09 | 1 | fetch_list.py | yes | |
thruway_schedules_pagehttps://www.thruway.ny.gov/travelers/tolls/schedules | 2026-10-08 | 1 | b100 (192.168.50.14), headless Chrome: the site refuses geo1 / scripts (HTTP 403) | yes |
| id | facility | operator | points | rate / trip rows | effective dates in the rows | source |
|---|---|---|---|---|---|---|
NY-NYSTA-S5 | New York State Thruway - Segment 5 | New York State Thruway Authority | 17 | 2772 | 2024-01-01 | thruway_2024_ny_ezpass_cpm |
NY-NYSTA-S4 | New York State Thruway - Segment 4 | New York State Thruway Authority | 12 | 2376 | 2024-01-01 | thruway_2024_ny_ezpass_cpm |
NY-NYSTA-S3 | New York State Thruway - Segment 3 | New York State Thruway Authority | 4 | 216 | 2024-01-01 | thruway_2024_ny_ezpass_cpm |
NY-NYSTA-S2 | New York State Thruway - Segment 2 | New York State Thruway Authority | 6 | 540 | 2024-01-01 | thruway_2024_ny_ezpass_cpm |
NY-NYSTA-S1 | New York State Thruway - Segment 1 | New York State Thruway Authority | 5 | 360 | 2024-01-01 | thruway_2024_ny_ezpass_cpm |
NY-NYSTA-S6 | New York State Thruway - Segment 6 | New York State Thruway Authority | 8 | 1008 | 2024-01-01 | thruway_2024_ny_ezpass_cpm |
NY-NYSTA-FX | New York State Thruway - fixed tolls | New York State Thruway Authority | 16 | 352 | 2024-01-01, 2026-01-01 | thruway_gantry_rate_charts |
NY-NYSTA-GMMCB | Governor Mario M. Cuomo Bridge | New York State Thruway Authority | 2 | 164 | 2026-01-01 | thruway_gmmcb_toll_charts |
NY-MTA-VNB | Verrazzano-Narrows Bridge | Metropolitan Transportation Authority Bridges and Tunnels (TBTA) | 1 | 24 | 2026-01-04 | mta_crossing_charges |
NY-MTA-RFK | Robert F. Kennedy Bridge | Metropolitan Transportation Authority Bridges and Tunnels (TBTA) | 1 | 24 | 2026-01-04 | mta_crossing_charges |
NY-MTA-BWB | Bronx-Whitestone Bridge | Metropolitan Transportation Authority Bridges and Tunnels (TBTA) | 1 | 24 | 2026-01-04 | mta_crossing_charges |
NY-MTA-TNB | Throgs Neck Bridge | Metropolitan Transportation Authority Bridges and Tunnels (TBTA) | 1 | 24 | 2026-01-04 | mta_crossing_charges |
NY-MTA-QMT | Queens Midtown Tunnel | Metropolitan Transportation Authority Bridges and Tunnels (TBTA) | 1 | 24 | 2026-01-04 | mta_crossing_charges |
NY-MTA-HLC | Hugh L. Carey Tunnel | Metropolitan Transportation Authority Bridges and Tunnels (TBTA) | 1 | 24 | 2026-01-04 | mta_crossing_charges |
NY-MTA-HHB | Henry Hudson Bridge | Metropolitan Transportation Authority Bridges and Tunnels (TBTA) | 1 | 9 | 2026-01-04 | mta_crossing_charges |
NY-MTA-MPB | Marine Parkway-Gil Hodges Memorial Bridge | Metropolitan Transportation Authority Bridges and Tunnels (TBTA) | 1 | 24 | 2026-01-04 | mta_crossing_charges |
NY-MTA-CBB | Cross Bay Veterans Memorial Bridge | Metropolitan Transportation Authority Bridges and Tunnels (TBTA) | 1 | 24 | 2026-01-04 | mta_crossing_charges |
NY-NYSBA-BM | Bear Mountain Bridge | New York State Bridge Authority | 1 | 16 | (none printed) | nysba_toll_rates |
NY-NYSBA-NB | Newburgh-Beacon Bridge | New York State Bridge Authority | 1 | 16 | (none printed) | nysba_toll_rates |
NY-NYSBA-MH | Mid-Hudson Bridge | New York State Bridge Authority | 1 | 16 | (none printed) | nysba_toll_rates |
NY-NYSBA-KR | Kingston-Rhinecliff Bridge | New York State Bridge Authority | 1 | 16 | (none printed) | nysba_toll_rates |
NY-NYSBA-RVW | Rip Van Winkle Bridge | New York State Bridge Authority | 1 | 16 | (none printed) | nysba_toll_rates |
NY-MTA-CBD | Congestion Relief Zone (CBD toll) | Metropolitan Transportation Authority Bridges and Tunnels (TBTA) | 41 | 520 | 2025-01-05 | mta_cbd_charges |
NY-NCBA | Atlantic Beach Bridge | Nassau County Bridge Authority | 1 | 11 | 2024 | ncba_toll_schedule_2024 |
| point | facility | location | placed on | why |
|---|---|---|---|---|
NY-MTA-CBD-39 | Congestion Relief Zone (CBD toll) | Queens Midtown Tunnel entry gantry (estimated): westbound I-495 at the Manhattan portal | the tunnel's westbound exit lanes | R3 estimate: no MTA detection gantry is mapped at the Queens Midtown Tunnel's Manhattan portal; the tunnel exits inside the zone (E 37th St), so every westbound pass is an entry: a booth on each westbound lane just past the tunnel's gantries |
NY-MTA-CBD-40 | Congestion Relief Zone (CBD toll) | Queens Midtown Tunnel exit gantry (estimated): eastbound I-495 approach lanes at the Manhattan portal | the tunnel's eastbound approach lanes (I-495 and the two ramps from the street grid; the reversible lane is left out: its direction changes) | R3 estimate: the Queens Midtown Tunnel credit applies 'If entering or exiting the CBD via' it; no zone gantry is mapped on its Manhattan approach, so a booth on each approach lane upstream of the tunnel's own gantries marks a pass leaving the zone through it |
NY-MTA-CBD-41 | Congestion Relief Zone (CBD toll) | Hugh L. Carey Tunnel exit gantry (estimated): southbound approach at the Manhattan portal | the tunnel's one southbound approach lane, after the West Street and Battery Place ramps join | R3 estimate: the Hugh L. Carey Tunnel credit applies 'If entering or exiting the CBD via' it; no zone gantry is mapped on its Manhattan approach, so a booth on each approach lane upstream of the tunnel's own gantries marks a pass leaving the zone through it |
R1: 70, R2b: 54, R3: 3, direction: 10, not: 56, on: 1, plan: 3 (all in decisions.csv).
None.
Toll booths / gantries mapped in OpenStreetMap on or near this state's roads that no toll point claims; a route through one lists it under unpriced. After an OSM refresh, look at new ones here (untied_toll_nodes.csv): a new gantry on a priced road means a point is missing.
Run from b100 (never on geo1): python3 ~/apitest/run.py ~/apitest/site/cases.json. Every trip must come back OK; a changed amount is either a rate change (update the expected amount from the operator's own source) or a fault.
| trip | expected |
|---|---|
| NY Thruway Stewart/I-84 -> Saugerties (17 -> 20), NJ E-ZPass = Non-NY table $3.38 | $3.38 |
| NY Thruway Harriman -> Albany (16 -> 23), NJ E-ZPass = Non-NY table $7.94 | $7.94 |
| NY Thruway Utica area 31 -> Schenectady 26, NJ E-ZPass ($5.80) | $5.80 |
| NY Cuomo Bridge southbound Nyack -> Tarrytown, NJ E-ZPass ($12.69) | $12.69 |
| NY Cuomo Bridge northbound Tarrytown -> Nyack (no toll) | $0.00 |
| NY Verrazzano Staten Island -> Brooklyn, NJ E-ZPass = non-NYCSC ($12.03) | $12.03 |
| NY Verrazzano Brooklyn -> Staten Island, Tolls by Mail ($12.03) | $12.03 |
| NY Bear Mountain Bridge eastbound, NJ E-ZPass ($1.65) | $1.65 |
| NY Bear Mountain Bridge westbound (no toll) | $0.00 |
| NY Mid-Hudson Bridge eastbound Highland -> Poughkeepsie, Tolls by Mail ($2.15) | $2.15 |
| NY Weehawken -> Midtown 08:30 Wed, NJ E-ZPass: Lincoln Tunnel peak $16.79 + zone $9.00 - $3.00 Lincoln credit | $22.79 |
| NY Weehawken -> Midtown 23:00 Wed, Tolls by Mail: Lincoln $23.30 + zone overnight $3.30 | $26.60 |
| NY Upper West Side -> Midtown 10:00 Wed via 60th St, NJ E-ZPass: zone peak $9.00 | $9.00 |
| NY Midtown -> Upper West Side 10:00 Wed (leaving the zone: no charge) | $0.00 |
| NY Thruway Stewart/I-84 -> Saugerties (17 -> 20), NY E-ZPass table $1.93 | $1.93 |
| NY Thruway Harriman -> Albany (16 -> 23), NY E-ZPass table $4.54 | $4.54 |
| NY Thruway Utica area 31 -> Schenectady 26, NY E-ZPass table $3.31 | $3.31 |
| NY Cuomo Bridge southbound Nyack -> Tarrytown, NY E-ZPass ($7.25) | $7.25 |
| NY Verrazzano Staten Island -> Brooklyn, NY E-ZPass NYCSC ($7.46) | $7.46 |
| NY Bear Mountain Bridge eastbound, NY E-ZPass ($1.65) | $1.65 |
| NY Upper West Side -> Midtown 10:00 Wed, NY E-ZPass: zone peak $9.00 | $9.00 |
| NY LIC -> Midtown via Queens-Midtown Tunnel, Wed 10:00, E-ZPass: tunnel $12.03 + zone $9.00 - $1.50 QMT credit | $19.53 |
| NY LIC -> Midtown via QMT, Wed 23:00, E-ZPass: tunnel $12.03 + zone overnight $2.25 | $14.28 |
| NY LIC -> Midtown via QMT, Wed 10:00, bill by mail: tunnel $12.03 + zone $13.50 (no credit for mail) | $25.53 |
| NY Midtown -> LIC via QMT (pass began inside the zone): tunnel $12.03 only | $12.03 |
| NY Upper West Side -> LIC: enters at 60th St, exits via QMT: zone $9.00 - $1.50 exit credit + tunnel $12.03 | $19.53 |
| NY Red Hook -> Tribeca via Hugh L. Carey Tunnel (Trinity Pl ramp), E-ZPass: tunnel $12.03 + zone $9.00 - $1.50 | $19.53 |
| NY Red Hook -> Battery Park City via Carey + West St (excluded roadway): tunnel $12.03 only | $12.03 |
| NY Tribeca -> Red Hook via Carey (pass began inside the zone): tunnel $12.03 only | $12.03 |
| NY RFK Bronx -> Queens, E-ZPass non-NY: $12.03 (Bronx-leg gantries) | $12.03 |
| NY RFK Manhattan -> Bronx over the Manhattan span: $12.03 once | $12.03 |
| NY RFK Bronx -> Manhattan over the Manhattan span: $12.03 once | $12.03 |
| NY Atlantic Beach Bridge Lawrence -> Atlantic Beach, car, E-ZPass ($3.00, NCBA 2024 Toll Rate Schedule) | $3.00 |
| NY Atlantic Beach Bridge Atlantic Beach -> Lawrence, car, NY E-ZPass ($3.00; collected each passage, direction not stated) | $3.00 |
| NY Atlantic Beach Bridge, car, cash ($4.00) | $4.00 |
| NY Atlantic Beach Bridge, car + trailer (3 axles), cash ($4.00) | $4.00 |
| NY Atlantic Beach Bridge, 2-axle truck, E-ZPass ($8.00) | $8.00 |
| NY Atlantic Beach Bridge, 3-axle truck, cash ($12.00) | $12.00 |
| NY Atlantic Beach Bridge, 5-axle truck, E-ZPass ($16.00, 4+ axles) | $16.00 |
| NY Atlantic Beach Bridge, 2-axle bus, cash ($4.00 'All Buses - (CASH)') | $4.00 |
| NY Thruway 16 -> 23, account_ny = NY E-ZPass table $4.54 | $4.54 |
| NY Thruway 16 -> 23, account_ca (not accepted) = Tolls by Mail $7.94 | $7.94 |