arcpy – How to Resolve Duplicate Route IDs with Overlapping Time in LRS Network from Polyline Feature Class

arcgis-proarcgis-roads-highwaysarcpylinear-referencing

I am using ArcGIS Pro 2.9.3 with the Location Referencing extension.

I am trying to create an LRS dataset with and LRS Network, and then to Append Routes into that LRS Network from a test polyline feature class.

The test polyline feature class looks like this – it has two polylines making up Route1 and one polyine making up Route2.

enter image description here

The empty LRS dataset, empty LRS Network and the test polyline feature class are created using the code below. The last step of the code is to use the Append Routes tool to try and append routes from the test polyline feature class into the LRS Network and create centerlines in the Centerline feature class. It is at the last step that I get an error.

# This script is intended to create an empty LRS dataset and load
# the geometries of a test polyline feature class with route IDs (TEXT),
# Route Names (TEXT) and from/to measures (DOUBLE) into it so that an
# LRS Line Network with those routes can be created
import arcpy

arcpy.env.overwriteOutput = True

srWGS84 = arcpy.SpatialReference("GCS_WGS_1984")
arcpy.management.CreateFileGDB(r"C:\temp","test")
gdb = r"C:\temp\test.gdb"

# Create empty TestLRS dataset with default names for three feature classes
# (Calibration_Point,Centerline,Redline) and an LRS Hierarchy (TestLRS)
# within it, and three tables (Centerline_Sequence, Lrs_Edit_Log,Lrs_Locks)        
print("Creating LRS dataset named {0} in {1}".format("TestLRS",gdb))
arcpy.locref.CreateLRS(gdb,"TestLRS","Centerline","Calibration_Point",
                       "Redline","Centerline_Sequence",srWGS84)
lrsFD = r"{0}\{1}".format(gdb,"TestLRS")

# Create empty feature class and its schema
testFC = r"{0}\testFC".format(lrsFD)
print('Creating "route-ready" polyline feature class ({0}) in LRS dataset ({1})'.format(testFC,lrsFD))
arcpy.management.CreateFeatureclass(lrsFD,"testFC","POLYLINE")
arcpy.management.AddField(testFC,"TestFCRouteID","TEXT", None, None, 10)
arcpy.management.AddField(testFC,"TestFCRouteName","TEXT", None, None, 10)
arcpy.management.AddField(testFC,"TestFCFromMeasure","DOUBLE")
arcpy.management.AddField(testFC,"TestFCToMeasure","DOUBLE")
arcpy.management.AddField(testFC,"FromDate","DATE")
arcpy.management.AddField(testFC,"ToDate","DATE")

# Write two lines and their attributes to the feature class
cursor = arcpy.da.InsertCursor(testFC,["SHAPE@","TestFCRouteID","TestFCRouteName","TestFCFromMeasure","TestFCToMeasure"])
array = arcpy.Array([arcpy.Point(0.0,0.0),
                     arcpy.Point(0.0,1.0)])
polyline = arcpy.Polyline(array,srWGS84)
cursor.insertRow([polyline,"Route1","Route1",0.0,1000.0])
array = arcpy.Array([arcpy.Point(0.0,1.0),
                     arcpy.Point(1.0,1.0)])
polyline = arcpy.Polyline(array,srWGS84)
cursor.insertRow([polyline,"Route1","Route1",1000.0,2000.0])
array = arcpy.Array([arcpy.Point(1.0,1.0),
                     arcpy.Point(1.0,0.0)])
polyline = arcpy.Polyline(array,srWGS84)
cursor.insertRow([polyline,"Route2","Route2",0.0,999.0])
del cursor
arcpy.management.CalculateField(testFC, "FromDate", "datetime.datetime.now()", "PYTHON3", '', "TEXT", "NO_ENFORCE_DOMAINS")

# Create empty TestLRSNetwork in TestLRS dataset 
print("Creating LRS Network ({0}) in LRS dataset ({1})".format("TestLRSNetwork","TestLRS"))
arcpy.locref.CreateLRSNetwork(gdb, "TestLRS", "TestLRSNetwork",
                              "TestFCRouteID", "TestFCRouteName", "FromDate", "ToDate", "DO_NOT_DERIVE", '',
                              "DO_NOT_INCLUDE", "LineId", "LineName", "LineOrder", "METERS")
lrsNetworkFC = r"{0}\{1}".format(lrsFD,"TestLRSNetwork")

# Append routes from testFC into TestLRSNetwork which should append them into Centerline feature class at the same time
print("Appending Routes from {1} into LRS Network ({1}) in LRS dataset ({2})".format(testFC,"TestLRSNetwork","TestLRS"))
arcpy.locref.AppendRoutes(testFC,lrsNetworkFC, "TestFCRouteID", "TestFCRouteName", "FromDate", "ToDate", None, None, None, None, "ADD")

Start Time: Saturday, 25 June 2022 6:22:00 PM
Creating LRS dataset named TestLRS in C:\temp\test.gdb
Creating "route-ready" polyline feature class (C:\temp\test.gdb\TestLRS\testFC) in LRS dataset (C:\temp\test.gdb\TestLRS)
Creating LRS Network (TestLRSNetwork) in LRS dataset (TestLRS)
Appending Routes from TestLRSNetwork into LRS Network (TestLRSNetwork) in LRS dataset (TestLRS)
Traceback (most recent call last):
  File "\\...\test.py", line 66, in <module>
    arcpy.locref.AppendRoutes(testFC,lrsNetworkFC, "TestFCRouteID", "TestFCRouteName", "FromDate", "ToDate", None, None, None, None, "ADD")
  File "C:\Program Files\ArcGIS\Pro\Resources\ArcPy\arcpy\locref.py", line 193, in AppendRoutes
    raise e
  File "C:\Program Files\ArcGIS\Pro\Resources\ArcPy\arcpy\locref.py", line 190, in AppendRoutes
    retval = convertArcObjectToPythonObject(gp.AppendRoutes_locref(*gp_fixargs((source_routes, in_lrs_network, route_id_field, route_name_field, from_date_field, to_date_field, line_id_field, line_name_field, line_order_field, field_map, load_type), True)))
  File "C:\Program Files\ArcGIS\Pro\Resources\ArcPy\arcpy\geoprocessing\_base.py", line 512, in <lambda>
    return lambda *args: val(*gp_fixargs(args, True))
arcgisscripting.ExecuteError: Validation of route attributes failed.  See log for details.


More details can be found at '\\...\GP_7CB24.txt'.
Failed to execute (AppendRoutes).
Failed script test...
Failed to execute (test).
Failed at Saturday, 25 June 2022 6:22:56 PM (Elapsed Time: 56.43 seconds)

When I examine \…\GP_7CB24.txt it has this content:

The following duplicate route IDs with an overlapping time representation were found in the source data. A route ID must only have one representation at a given point in time.

Object ID   Route ID    From Date   To Date
1   Route1  25/06/2022 6:22:38 PM   NULL
2   Route1  25/06/2022 6:22:38 PM   NULL

Why is it that the first route in my polyline feature class (which is made up of two features with the same route ID and name) cannot be appended into my LRS Network?

Best Answer

After completing the "non-Events" (I don't need them until later) parts of ArcGIS Roads and Highways: Introduction to Modeling and Data Management in a Desktop Environment (an online course from Esri) I think I now know what I need to do in order to get past where I was stuck.

My mistake was to ask Append Routes to read two lines for Route1. I had two lines because they have different from/to measure field values that are important for calibration. However, my new understanding is that I need to leave the calibration until after Append Routes, and to append routes from a non-measured, dissolved (on RouteID) polyline feature class instead.

I have not done the calibration of my network yet but the code below now allows me to Append Routes into it.

# This script is intended to create an empty LRS dataset and load
# the geometries of a test polyline feature class with route IDs (TEXT),
# Route Names (TEXT) and from/to measures (DOUBLE) into it so that an
# LRS Line Network with those routes can be created
import arcpy

arcpy.env.overwriteOutput = True

srWGS84 = arcpy.SpatialReference("GCS_WGS_1984")
arcpy.management.CreateFileGDB(r"C:\temp","test")
gdb = r"C:\temp\test.gdb"

# Create empty TestLRS dataset with default names for three feature classes
# (Calibration_Point,Centerline,Redline) and an LRS Hierarchy (TestLRS)
# within it, and three tables (Centerline_Sequence, Lrs_Edit_Log,Lrs_Locks)        
print("Creating LRS dataset named {0} in {1}".format("TestLRS",gdb))
arcpy.locref.CreateLRS(gdb,"TestLRS","Centerline","Calibration_Point",
                       "Redline","Centerline_Sequence",srWGS84)
lrsFD = r"{0}\{1}".format(gdb,"TestLRS")

# Create empty feature class and its schema
testFC = r"{0}\testFC".format(lrsFD)
print('Creating "route-ready" polyline feature class ({0}) in LRS dataset ({1})'.format(testFC,lrsFD))
arcpy.management.CreateFeatureclass(lrsFD,"testFC","POLYLINE")
arcpy.management.AddField(testFC,"RouteID","TEXT", None, None, 10)
arcpy.management.AddField(testFC,"RouteName","TEXT", None, None, 10)
arcpy.management.AddField(testFC,"FromMeasure","DOUBLE")
arcpy.management.AddField(testFC,"ToMeasure","DOUBLE")
arcpy.management.AddField(testFC,"FromDate","DATE")
arcpy.management.AddField(testFC,"ToDate","DATE")

# Write two polylines and their attributes to the feature class
cursor = arcpy.da.InsertCursor(testFC,["SHAPE@","RouteID","RouteName","FromMeasure","ToMeasure"])
array = arcpy.Array([arcpy.Point(0.0,0.0),
                     arcpy.Point(0.0,1.0)])
polyline = arcpy.Polyline(array,srWGS84)
cursor.insertRow([polyline,"Route1","",0.0,1000.0])
array = arcpy.Array([arcpy.Point(0.0,1.0),
                     arcpy.Point(1.0,1.0)])
polyline = arcpy.Polyline(array,srWGS84)
cursor.insertRow([polyline,"Route1","",1000.0,2000.0])
array = arcpy.Array([arcpy.Point(1.0,1.0),
                     arcpy.Point(1.0,0.0)])
polyline = arcpy.Polyline(array,srWGS84)
cursor.insertRow([polyline,"Route2","",0.0,999.0])
del cursor
arcpy.management.CalculateField(testFC, "FromDate", "datetime.datetime.now()", "PYTHON3", '', "TEXT", "NO_ENFORCE_DOMAINS")

# Dissolve testFC so that there's only one polyline per route
testDissolvedFC = r"{0}{1}".format(testFC,"_Dissolve")
print("Dissolving {0} primarily on RouteID to create {1}".format(testFC,testDissolvedFC))
arcpy.management.Dissolve(testFC,testDissolvedFC,
                          "RouteID;RouteName;FromDate;ToDate",
                          None, "SINGLE_PART", "UNSPLIT_LINES")

# Create empty TestLRSNetwork in TestLRS dataset 
print("Creating LRS Network ({0}) in LRS dataset ({1})".format("TestLRSNetwork","TestLRS"))
arcpy.locref.CreateLRSNetwork(gdb, "TestLRS", "TestLRSNetwork",
                              "RouteID", "RouteName", "FromDate", "ToDate", "DO_NOT_DERIVE", '',
                              "DO_NOT_INCLUDE", "LineId", "LineName", "LineOrder", "METERS")
lrsNetworkFC = r"{0}\{1}".format(lrsFD,"TestLRSNetwork")

# Append routes from testFC into TestLRSNetwork which should append them into Centerline feature class at the same time
print("Appending Routes from {1} into LRS Network ({1}) in LRS dataset ({2})".format(testFC,"TestLRSNetwork","TestLRS"))
arcpy.locref.AppendRoutes(testDissolvedFC,lrsNetworkFC, "RouteID", "RouteName", "FromDate", "ToDate", None, None, None, None, "ADD")

The resultant feature classes are:

enter image description here

enter image description here

Something that surprised me was that the Centerline_Sequence table had no rows but for now I will treat that as an observation that I can come back to after completing the calibration.

enter image description here