# How can I create mileposts for roads and trails with ArcGIS 10.2?

10013
5
07-01-2015 04:30 PM
New Contributor II

We need to be able create milepost points from our shapefiles for road lines and trail lines . I have Advanced ArcGIS Desktop 10.2 and our transportation folks have Basic 10.2. Is there a python script or a geoprocessing tool available to do this?

5 Replies
MVP Emeritus

Some threads on the web cover several alternatives for your versions...check these options and depending upon your needs, one should suit

arcgis 10.1 - How to create a point file along a line (trail) at regular distances (0.20 miles)? - G...

PS searching for mileposts on the help (ie within linear referencing) basically assumes that they have already been created

New Contributor II

Thank you, Dan!  I will get this out and see if it works for us.

Esri Esteemed Contributor

You could create a script that creates a point for each milepost. A simple snippets is shown below:

```def main():
import arcpy
interval = 1000 # adjust

flds = ("SHAPE@")
lst = []
with arcpy.da.SearchCursor(fc, flds) as curs:
for row in curs:
line = row[0]
dist = 0
while dist <= line.length:
pnt = line.positionAlongLine(dist, use_percentage = False)
lst.append(pnt)
dist += interval
arcpy.CopyFeatures_management(lst, fc_out)

if __name__ == '__main__':
main()```

This however, only creates points and has no attributes, so you would not be able to label the mileposts. The alternative would be to create the empty output featureclass (with a field to store the mileage) and to use an arcpy.da.InsertCursor to fill it.

Be aware that this procedure only uses the length of the polyline and linear unit of the spatial reference into account. In case you have M-aware geometries you may have a line that starts at M=1.5 (miles) and end in M=10.27 (miles). This would require reading the M value to correctly place the mileposts.

As an alternative (if you are looking to locate and label mileposts) you could use Create Routes—Help | ArcGIS for Desktop if the lines aren't already routes, and use About hatching route feature classes—Help | ArcGIS for Desktop to do the job.

New Contributor II

Thank you, Xander. I will get this out and see if it works for us.

MVP

I do it like this because I use LRS.  With this script I can use my routes with measures to create points at different increments for different LRS Reference Methods:

``````'''
Created on Jul 14, 2015
This script will create route events as points along the route features at specific increments
the points can be symbolically displayed as route hatches for web mapping
@author: Kyle Gonterwitz with, as always the amazing help from Dirk Talley
@contact: Kyleg@Ksdot.org
'''

#import arcpy
from arcpy import (AddField_management, MakeFeatureLayer_management, CreateTable_management,da, Exists, AddXY_management,
TruncateTable_management, Append_management, MakeRouteEventLayer_lr, Delete_management, FeatureClassToFeatureClass_conversion, env)
#set the geodatabase parameters for the input route data
env.overwriteOutput = True
wsPath = r"Database Connections\shared@SQLGIS_cansys_gis_dev.sde" #enter the workspace path that has the data owner login
StatefcRoutes = r"\\gisdata\arcgis\GISdata\Connection_files\RO@sqlgisprod_GIS_cansys.sde\GIS_CANSYS.SHARED.SMLRS"  # State Route feature class with begin/end attribs
CountyfcRoutes = r"\\gisdata\arcgis\GISdata\Connection_files\RO@sqlgisprod_GIS_cansys.sde\GIS_CANSYS.SHARED.CMLRS"  #County Route Feature Class with begin/end attribs
#State and County are the Two main Linear Referecing Methods used by KDOT which will be hatched
StateOutTable = "SMHatch"
CountyOutTable=  "CMHatch"
StateFields = ["LRS_Route", "BEG_STATE_LOGMILE", "END_STATE_LOGMILE"]
CountyFields = ["LRS_KEY", "BEG_CNTY_LOGMILE", "END_CNTY_LOGMILE"]
#this field sets the hatch separation/spacing.  For a hatch point every 1/10 of a mile, enter 0.1.  For a hatch every 1/100th of a mile, choose 0.01.
#for mapping in KanPlan 1/10 mile seems plenty sufficient, and will create about 108,000 points for each LRM.
#1/100 would create 1,080,000 points which might suffer from use of in-memory processing, already this script takes a few minutes to run for each LRM
HatchSep = 0.1
countyLRM = [CountyfcRoutes, CountyOutTable, CountyFields]
stateLRM = [StatefcRoutes, StateOutTable, StateFields]
LRMethod = [countyLRM, stateLRM]

for method in LRMethod:
print "creating hatches for " + str(method[1])
#add route table as feature layer
if Exists("RouteLyr"):
Delete_management("RouteLyr")
else:
pass
MakeFeatureLayer_management(method[0], "RouteLyr", "DIRECTION in (  1 ,  2 )")
#create event table in memory
mem_table = "HatchEvents"
if Exists(r"in_memory\\"+mem_table):
print str(mem_table) +"already existed, deleting"
Delete_management(r"in_memory\\"+mem_table)
else:
print "Creating table for processing route increments of " + str(HatchSep)

CreateTable_management("in_memory", mem_table)
mem_table = r"in_memory\\"+mem_table

for row in sorted(da.SearchCursor("RouteLyr", (method[2]))): # @UndefinedVariable
LRSKEY = row[0]
if LRSKEY == (LRSKEY):
# use this loop to test the script against a single route
iter0 = row[1]
#print row[0]+ ' from '+str(row[1])+' to '+str(row[2])  #print the current LRS Key
#set the begin and end parameters from which to create incremental values
if HatchSep == 0.1:
round_dec = 1
elif HatchSep == 0.01:
round_dec = 2
else:
round_dec = 0
print "check hatch separation value"
minlog = round(row[1], round_dec)
if minlog > row[1]:
minlog = minlog - HatchSep
else:
pass
maxlog = round(row[2], round_dec)
if maxlog < row[2]:
maxlog = maxlog + HatchSep
else:
pass
#set the starting point for the route segment
itermile = minlog
#now loop between the start and end logmiles for each route segment, and insert the step increment into the event table in memory
while itermile <= maxlog and itermile >= minlog:
#print str(itermile)
with da.InsertCursor(mem_table, ("RouteID", "LogMile")) as insert:# @UndefinedVariable
insertfields = [LRSKEY, itermile]
insert.insertRow(insertfields)
itermile = itermile + HatchSep
del minlog
del maxlog

MakeRouteEventLayer_lr("RouteLyr", method[2][0], mem_table, "RouteID POINT LogMile", "HatchPoints_events", "", "ERROR_FIELD", "ANGLE_FIELD", "NORMAL", "COMPLEMENT", "LEFT", "POINT")
#add XY points, later on these coordinates can be used to hyperlink to google street view, bing maps, etc.  Make sure we are in NAD83 Lat/Long CRS here.