State Planner

Ohio · October 30, 2026

County Mileposts on Ohio State Routes

This is a real answer State Planner produced from Ohio’s public data.

Ask this question, or one like it, in State Planner now. Sign up to try every feature free for 7 days, no card needed, and the question will be waiting in your new chat to change or send.

Ask this in State Planner →
  1. Ohio Mile Marker Map: Where Are the County Mileposts on Each State Route?


    County mileposts on Ohio's state routes

    County Mileposts on Ohio State RoutesCounty Mileposts on Ohio State Routes⬇ Image

    The map shows the 18,826 county milepost markers on Ohio's Interstate, US and State Routes, from ODOT's oh_county_milepost layer in TIMS. A county milepost marks a location's mileage on a route within one county. The count starts again at each county line, so it is not the statewide route mileage. Click any marker to see its route, county, milepost number, ODOT district and NLF ID, which identifies the route segment.

    Legend

    • 🟢 Green: State Route (SR) mileposts, 13,453 markers on 509 route numbers in all 88 counties
    • 🔵 Blue: US Route mileposts, 3,826 markers on 21 routes in 82 counties
    • 🔴 Red: Interstate mileposts, 1,547 markers on 20 routes in 48 counties
    • Grey outlines: county boundaries

    What the map shows

    • The markers are about one mile apart and line every state-system route, so together they trace Ohio's state highway network.
    • The highest county mileposts are on routes that run a long way inside one county:

    Highest county mileposts on the state system

    RouteCountyHighest county milepost
    SR 124Meigs66
    SR 7Washington54
    I-270Franklin54
    US 68Brown45
    I-275Hamilton41
    SR 163Ottawa41
    • Cuyahoga has the most state-system mileposts (471, on 32 routes). Next come Ashtabula (356), Franklin (346), Trumbull (346), Wayne (316) and Stark (313).

    Notes

    • The table also holds about 53,000 mileposts on County Roads (CR) and Township Roads (TR). I left them off because you asked about state routes. I can add them, or filter the map to one route (for example US 52 across the southern counties) or one county or ODOT district.
    • The table holds one perpetuation year, so this is a single snapshot. ODOT updates the layer once a year. For the statewide reference system, which doesn't reset at county lines, see oh_state_milepost.

Layers

  • …
  • …
    • …
    • …
    • …

Click anything on the map for its details.

The transcript below the answer shows every query it ran. Shapefiles of every layer, at full detail, can be downloaded in State Planner: sign up to ask your own question and export any map.

Data sets used

Ask your own question about Ohio

Send takes you to sign up (every feature free for 7 days, no card needed), or to sign in if you have an account. Your question will be waiting in your new chat.

Transcript

What follows is the transcript of this chat as State Planner generated it. It is here to show how the answer above was arrived at: every query State Planner ran, what each one returned, and where the data came from.

transcript.md

↑ Contents

State Planner chat · https://stateplanner.com

  • State: Ohio (OH)
  • Started: October 30, 2026, 2:01 PM UTC
  • Runtime: 33 sec
  • Status: completed
Prompt

Ohio Mile Marker Map: Where Are the County Mileposts on Each State Route?

Model: Anthropic: Claude Opus 5.5 (anthropic/claude-opus-5.5, via openrouter)

Response

County mileposts on Ohio's state routes

County Mileposts on Ohio State Routes

The map shows the 18,826 county milepost markers on Ohio's Interstate, US and State Routes, from ODOT's oh_county_milepost layer in TIMS. A county milepost marks a location's mileage on a route within one county. The count starts again at each county line, so it is not the statewide route mileage. Click any marker to see its route, county, milepost number, ODOT district and NLF ID, which identifies the route segment.

Legend

  • 🟢 Green: State Route (SR) mileposts, 13,453 markers on 509 route numbers in all 88 counties
  • 🔵 Blue: US Route mileposts, 3,826 markers on 21 routes in 82 counties
  • 🔴 Red: Interstate mileposts, 1,547 markers on 20 routes in 48 counties
  • Grey outlines: county boundaries

What the map shows

  • The markers are about one mile apart and line every state-system route, so together they trace Ohio's state highway network.
  • The highest county mileposts are on routes that run a long way inside one county:

Highest county mileposts on the state system

RouteCountyHighest county milepost
SR 124Meigs66
SR 7Washington54
I-270Franklin54
US 68Brown45
I-275Hamilton41
SR 163Ottawa41
  • Cuyahoga has the most state-system mileposts (471, on 32 routes). Next come Ashtabula (356), Franklin (346), Trumbull (346), Wayne (316) and Stark (313).

Notes

  • The table also holds about 53,000 mileposts on County Roads (CR) and Township Roads (TR). I left them off because you asked about state routes. I can add them, or filter the map to one route (for example US 52 across the southern counties) or one county or ODOT district.
  • The table holds one perpetuation year, so this is a single snapshot. ODOT updates the layer once a year. For the statewide reference system, which doesn't reset at county lines, see oh_state_milepost.
Exploratory Queries
Query 1 — Profile route codes, counties and milepost range.
   SELECT route_code,
          count(*) n,
          count(DISTINCT rte_number) routes,
          count(DISTINCT county) counties,
          min(milepost),
          max(milepost),
          count(DISTINCT perp_year) yrs
     FROM oh_county_milepost
 GROUP BY 1
 ORDER BY 2 DESC
route_codenroutescountiesminmaxyrs
CR28028691881351
TR251241576881261
SR13453509881661
US382621821451
IR154720481541

data/turn-1-query-1.csv

Query 2 — Check route number format and longest state-route milepost runs per county.
   SELECT route_code,
          rte_number,
          county,
          count(*) n,
          min(milepost) mn,
          max(milepost) mx,
          max(ST_NumGeometries(geom)) maxpts
     FROM oh_county_milepost
    WHERE route_code IN ('SR', 'US', 'IR')
 GROUP BY 1,
          2,
          3
 ORDER BY mx DESC
    LIMIT 12
route_coderte_numbercountynmnmxmaxpts
SR124MEG631661
SR7WAS505541
IR270FRA541541
US68BRO3412451
IR275HAM381411
SR163OTT401411
US52HAM1520401
US52SCI421391
US50ATH371391
SR13PER391391
US62STA331391
SR147BEL361371

data/turn-1-query-2.csv

Query 3 — Count state-system mileposts per county for the summary.
   SELECT county,
          count(*) n,
          count(DISTINCT route_code || rte_number) routes
     FROM oh_county_milepost
    WHERE route_code IN ('SR', 'US', 'IR')
 GROUP BY 1
 ORDER BY 2 DESC
    LIMIT 8
countynroutes
CUY47132
ATB35617
FRA34621
TRU34620
WOO31621
STA31321
COL29621
LOR29420

data/turn-1-query-3.csv

Map Layer Queries
Counties
   SELECT geom,
          county AS "County"
     FROM oh_county

Picture: maps/turn-1-county-mileposts-state-routes.png

County mileposts (state system) — colored by "System": State Route (SR) mileposts (#31a354), US Route mileposts (#3182bd), Interstate mileposts (#de2d26)
   SELECT geom,
          CASE route_code
                    WHEN 'IR' THEN 'Interstate'
                    WHEN 'US' THEN 'US Route'
                    ELSE 'State Route'
          END AS "System",
          route_code || ' ' || rte_number AS "Route",
          county AS "County",
          milepost AS "County milepost",
          district AS "ODOT District",
          nlf_id AS "NLF ID"
     FROM oh_county_milepost
    WHERE route_code IN ('SR', 'US', 'IR')
 ORDER BY CASE route_code
                    WHEN 'SR' THEN 1
                    WHEN 'US' THEN 2
                    ELSE 3
          END

Picture: maps/turn-1-county-mileposts-state-routes.png

Used Data Sets

data/turn-1-query-1.csv

↑ Contents
route_codenroutescountiesminmaxyrs
CR28028691881351
TR251241576881261
SR13453509881661
US382621821451
IR154720481541

5 rows.

data/turn-1-query-2.csv

↑ Contents
route_coderte_numbercountynmnmxmaxpts
SR124MEG631661
SR7WAS505541
IR270FRA541541
US68BRO3412451
IR275HAM381411
SR163OTT401411
US52HAM1520401
US52SCI421391
US50ATH371391
SR13PER391391
US62STA331391
SR147BEL361371

12 rows.

data/turn-1-query-3.csv

↑ Contents
countynroutes
CUY47132
ATB35617
FRA34621
TRU34620
WOO31621
STA31321
COL29621
LOR29420

8 rows.

provenance/oh_county.md

↑ Contents

Provenance: oh_county

This file describes how the rows in PostgreSQL table oh_county were obtained from an external source: where they were fetched and how fields were renamed and typed. Field meanings are in the mapping table below.

Identity
Pipeline (TIMS family)

Ohio DOT TIMS publishes this layer on the TIMS data page. The catalog behind that page is GET https://tims.dot.state.oh.us/tims/api/glossary. Each entry names a MapServer layer URL.

Data is fetched as GeoJSON from that layer's REST query endpoint (where=1=1, outFields=*, outSR=4326, f=geojson), paginated with resultOffset / resultRecordCount. GeoJSON was chosen over the portal's CSV/SHP/GDB/KMZ exports because it keeps full attribute names, keeps geometry, and loads into PostGIS via ST_GeomFromGeoJSON.

Esri field names become lowercase snake_case PostgreSQL columns (non [a-z0-9_] → _). Dates stored as Esri epoch-milliseconds become timestamptz. Geometry is ST_SetSRID(ST_GeomFromGeoJSON(…), 4326), wrapped in ST_Multi when the table's stored type is Multi*. Esri shape-area / shape-length system fields are dropped.

The same MapServer query is used whenever the table is refreshed.

Field → column mapping
Source fieldColumnEsri typeDescription
OBJECTIDobjectidesriFieldTypeOID
COUNTY_CDcounty_cdesriFieldTypeStringThe 3-letter code of the county within Ohio (88 counties total) [ODOT]
COUNTYcountyesriFieldTypeStringCounty name [ODOT]
COUNTY_SEATcounty_seatesriFieldTypeStringCity that serves as the County seat [ODOT]
ODOT_DISTRICTodot_districtesriFieldTypeSmallIntegerFrom 1-12 plus Central Office – the counties are grouped into districts in Ohio for ease of maintenance and funding [ODOT]
FIPS_COUNTY_CDfips_county_cdesriFieldTypeStringFIPS County Code (Federal Information Processing Standard) [ODOT]
POP_2020pop_2020esriFieldTypeInteger
POP_2010pop_2010esriFieldTypeIntegerCounty population in 2010
POP_2000pop_2000esriFieldTypeIntegerCounty population in 2000
POP_1990pop_1990esriFieldTypeIntegerCounty population in 1990
STATE_PLANE_ZONEstate_plane_zoneesriFieldTypeStringState plane zone in which the county falls, N - North or S - South
ELEVATION_MAXIMUMelevation_maximumesriFieldTypeSmallIntegerMaximum elevation within the County boundaries
ELEVATION_MINIMUMelevation_minimumesriFieldTypeSmallIntegerMinimum elevation within the County boundaries
LAT_NORTH_DDlat_north_ddesriFieldTypeDouble
LAT_SOUTH_DDlat_south_ddesriFieldTypeDouble
LONG_EAST_DDlong_east_ddesriFieldTypeDouble
LONG_WEST_DDlong_west_ddesriFieldTypeDouble
AREA_SQMIarea_sqmiesriFieldTypeDouble
AREA_IDarea_idesriFieldTypeInteger
(feature geometry)geomST_Multi(ST_SetSRID(ST_GeomFromGeoJSON(…), 4326))Feature geometry, WGS84
Geometry
  • SRID 4326 (WGS84). GIST index on geom.
  • Empty / null geometries stored as SQL NULL.

provenance/oh_county_milepost.md

↑ Contents

Provenance: oh_county_milepost

This file describes how the rows in PostgreSQL table oh_county_milepost were obtained from an external source: where they were fetched and how fields were renamed and typed. Field meanings are in the mapping table below.

Identity
Pipeline (TIMS family)

Ohio DOT TIMS publishes this layer on the TIMS data page. The catalog behind that page is GET https://tims.dot.state.oh.us/tims/api/glossary. Each entry names a MapServer layer URL.

Data is fetched as GeoJSON from that layer's REST query endpoint (where=1=1, outFields=*, outSR=4326, f=geojson), paginated with resultOffset / resultRecordCount. GeoJSON was chosen over the portal's CSV/SHP/GDB/KMZ exports because it keeps full attribute names, keeps geometry, and loads into PostGIS via ST_GeomFromGeoJSON.

Esri field names become lowercase snake_case PostgreSQL columns (non [a-z0-9_] → _). Dates stored as Esri epoch-milliseconds become timestamptz. Geometry is ST_SetSRID(ST_GeomFromGeoJSON(…), 4326), wrapped in ST_Multi when the table's stored type is Multi*. Esri shape-area / shape-length system fields are dropped.

The same MapServer query is used whenever the table is refreshed.

Field → column mapping
Source fieldColumnEsri typeDescription
OBJECTIDobjectidesriFieldTypeOID
MILEPOSTmilepostesriFieldTypeDoubleCounty milepost number along the route
NLF_IDnlf_idesriFieldTypeStringPrimary key field that is the basis for identifying unique roadway segments in ODOT's graphic roadway network. The attribute is made up of seven components that describe administrative and other characteristics related to a route segment; Positions (1)
DISTRICTdistrictesriFieldTypeDoubleFrom 1-12 plus Central Office – the counties are grouped into districts in Ohio for ease of maintenance and funding
ROUTE_CODEroute_codeesriFieldTypeStringIndicates the jurisdiction of the route in full text
COUNTYcountyesriFieldTypeStringThe 3-letter code of the county within Ohio (88 counties total)
PERP_YEARperp_yearesriFieldTypeStringRoadway perpetuation year
RTE_NUMBERrte_numberesriFieldTypeStringThe route number for the milepost selected
GMROTATIONgmrotationesriFieldTypeDoubleLegacy field used in Geomedia application
(feature geometry)geomST_Multi(ST_SetSRID(ST_GeomFromGeoJSON(…), 4326))Feature geometry, WGS84
Geometry
  • SRID 4326 (WGS84). GIST index on geom.
  • Empty / null geometries stored as SQL NULL.

© 2026 State Planner