Hello! I´m building a Python code in IDLE to run with ArcGIS Pro 2.9.
I have a list of OD pairs and a multimodal (road and rail) network dataset and I need to calculate the shortest route for each OD pair.
Here is the code that I have so far:
import arcpy as ap
import sys
# set environment
ap.env.workspace = "C:/Users/conni/Documents/EsriTraining/Tese_v1"
ap.env.overwriteOutput = "TRUE"
ap.CheckOutExtension("Network")
# set names for files with points and arcs (flows)
flow_feature = "C:/Users/conni/Documents/EsriTraining/Tese_v1/Tese_v1.gdb/ODLines4l1krc"
origins = "C:/Users/conni/Documents/EsriTraining/Tese_v1/Tese_v1.gdb/BR_Municipios_2021_MeanCenter"
destinations = "C:/Users/conni/Documents/EsriTraining/Tese_v1/Tese_v1.gdb/BR_Municipios_2021_MeanCenter"
# set local variables, create geodatabases (?)
out_gdb_path = "C:/Users/conni/Documents/EsriTraining/Tese_v1"
out_gdb_name = "Port_Warehouse_shift_link"
ap.CreateFileGDB_management(out_gdb_path, out_gdb_name)
out_path = out_gdb_path + "/" + out_gdb_name + ".gdb"
out_name = "stops"
geometry_type = "POINT"
# execute CreateFeatureclass
ap.CreateFeatureclass_management(out_path, out_name, geometry_type, spatial_reference = flow_feature)
# create field for LP_ID
ap.AddField_management(out_path + "/" + out_name, "LP_ID", "TEXT")
# assign variable to stops feature
stops = out_path + "/" + out_name
# create feature dataset for routes and edges
ap.CreateFeatureDataset_management(out_path, "routes", origins)
routes_path = out_path + "/" + "routes"
ap.CreateFeatureDataset_management(out_path, "edges", origins)
edges_path = out_path + "/" + "edges"
# a cursor is used to query information from the origins feature and insert rows on stops feature. ID's are assigned.
# "SHAPE@XY" allows to set the coordinate of each point in the feature class
with ap.da.SearchCursor(origins, ["CD_MUN", "SHAPE@XY"]) as cur_a:
for i,row in enumerate(cur_a,1):
cur_b = ap.da.InsertCursor(stops, ["LP_ID", "SHAPE@XY"])
cur_b.insertRow([row[0],row[1]])
with ap.da.SearchCursor(destinations, ["CD_MUN", "SHAPE@XY"]) as cur_a:
for i,row in enumerate(cur_a,1):
cur_b = ap.da.InsertCursor(stops, ["LP_ID", "SHAPE@XY"])
cur_b.insertRow([row[0],row[1]])
inNetworkDataset = "C:/Users/conni/Documents/EsriTraining/Tese_v1/Tese_v1.gdb/SantaCatarina/SC_ND"
intermodal_data = {}
ap.AddField_management(flow_feature, "MODE", "TEXT")
ap.AddField_management(flow_feature, "ACCESS", "TEXT")
ap.AddField_management(flow_feature, "EXIT", "TEXT")
with ap.da.UpdateCursor(flow_feature,["cod_mun_origem", "cod_mun_destino", "volume_total", "MODE", "ACCESS", "EXIT"]) as cur:
for i,row in enumerate(cur,1):
try:
ap.MakeFeatureLayer_management(stops, "stops_lyr")
where_clause_1 = '"LP_ID"' + " = '" + str(row[0]) + "'"
temp_select = ap.SelectLayerByAttribute_management('stops_lyr', 'NEW_SELECTION', where_clause_1)
where_clause_2 = '"LP_ID"' + " = '" + str(row[1]) + "'"
ap.SelectLayerByAttribute_management('stops_lyr', 'ADD_TO_SELECTION', where_clause_2)
inStops = temp_select
route_name = str(row[0]) + "_" + str(row[1])
result_object = ap.na.MakeRouteAnalysisLayer(inNetworkDataset, route_name, "Multimodal")
layer_object = result_object.getOutput(0)
sublayer_names = ap.na.GetNAClassNames(layer_object)
stops_layer_name = sublayer_names["Stops"]
routes_layer_name = sublayer_names["Routes"]
ap.na.AddLocations(layer_object, stops_layer_name, inStops, search_criteria = [["Clip_OutFeatureClass_Ferrovias", "NONE"],
["Clip_OutFeatureClass_Rodovias", "SHAPE"],
["SC_TIN_TinEdge", "NONE"],
["Rodo_OD", "SHAPE"],
["Rodo_TermFerrExistente", "SHAPE"],
["Rodo_TermFerrNovo", "SHAPE"],
["BR_RG_Imediatas_2021_MeanCenter", "SHAPE"],
["Clip_OutFeatureClass_fc_ferro_terminal_de_carga", "SHAPE"],
["SC_ND_Junctions", "NONE"]])
ap.na.Solve(layer_object)
routes_sublayer = ap.na.GetNASublayer(layer_object, routes_layer_name)
ap.management.CopyFeatures(routes_sublayer, routes_path + route_name)
ap.na.CopyTraversedSourceFeatures(layer_object, edges_path, "TraversedEdges_" + route_name, "TraversedJunctions_" + route_name, "TraversedTurns_" + route_name)
temp_junction = edges_path + "/" + "TraversedEdges_" + route_name
intermodal_data[route_name] = []
except Exception:
e = sys.exc_info()[1]
print(e.args[0])
ap.AddError(e.args[0])
cur.updateRow(row)
The program calculates the shortest route for each OD pair, but it calculates 3 times (please refer to the attached pictures). Does anyone know why it calculates 3 times and what can I do so it calculates only 1 time?
Thank you and regards!
formatted code, with line numbers would be helpful
Code formatting ... the Community Version - Esri Community
Hello Dan,
thanks for the tip! Please refer to the formatted code below:
import arcpy as ap
import sys
# set environment
ap.env.workspace = "C:/Users/conni/Documents/EsriTraining/Tese_v1"
ap.env.overwriteOutput = "TRUE"
ap.CheckOutExtension("Network")
# set names for files with points and arcs (flows)
flow_feature = "C:/Users/conni/Documents/EsriTraining/Tese_v1/Tese_v1.gdb/ODLines4l1krc"
origins = "C:/Users/conni/Documents/EsriTraining/Tese_v1/Tese_v1.gdb/BR_Municipios_2021_MeanCenter"
destinations = "C:/Users/conni/Documents/EsriTraining/Tese_v1/Tese_v1.gdb/BR_Municipios_2021_MeanCenter"
# set local variables, create geodatabases (?)
out_gdb_path = "C:/Users/conni/Documents/EsriTraining/Tese_v1"
out_gdb_name = "Port_Warehouse_shift_link"
ap.CreateFileGDB_management(out_gdb_path, out_gdb_name)
out_path = out_gdb_path + "/" + out_gdb_name + ".gdb"
out_name = "stops"
geometry_type = "POINT"
# execute CreateFeatureclass
ap.CreateFeatureclass_management(out_path, out_name, geometry_type, spatial_reference = flow_feature)
# create field for LP_ID
ap.AddField_management(out_path + "/" + out_name, "LP_ID", "TEXT")
# assign variable to stops feature
stops = out_path + "/" + out_name
# create feature dataset for routes and edges
ap.CreateFeatureDataset_management(out_path, "routes", origins)
routes_path = out_path + "/" + "routes"
ap.CreateFeatureDataset_management(out_path, "edges", origins)
edges_path = out_path + "/" + "edges"
# a cursor is used to query information from the origins feature and insert rows on stops feature. ID's are assigned.
# "SHAPE@XY" allows to set the coordinate of each point in the feature class
with ap.da.SearchCursor(origins, ["CD_MUN", "SHAPE@XY"]) as cur_a:
for i,row in enumerate(cur_a,1):
cur_b = ap.da.InsertCursor(stops, ["LP_ID", "SHAPE@XY"])
cur_b.insertRow([row[0],row[1]])
with ap.da.SearchCursor(destinations, ["CD_MUN", "SHAPE@XY"]) as cur_a:
for i,row in enumerate(cur_a,1):
cur_b = ap.da.InsertCursor(stops, ["LP_ID", "SHAPE@XY"])
cur_b.insertRow([row[0],row[1]])
inNetworkDataset = "C:/Users/conni/Documents/EsriTraining/Tese_v1/Tese_v1.gdb/SantaCatarina/SC_ND"
intermodal_data = {}
ap.AddField_management(flow_feature, "MODE", "TEXT")
ap.AddField_management(flow_feature, "ACCESS", "TEXT")
ap.AddField_management(flow_feature, "EXIT", "TEXT")
with ap.da.UpdateCursor(flow_feature,["cod_mun_origem", "cod_mun_destino", "volume_total", "MODE", "ACCESS", "EXIT"]) as cur:
for i,row in enumerate(cur,1):
try:
ap.MakeFeatureLayer_management(stops, "stops_lyr")
where_clause_1 = '"LP_ID"' + " = '" + str(row[0]) + "'"
temp_select = ap.SelectLayerByAttribute_management('stops_lyr', 'NEW_SELECTION', where_clause_1)
where_clause_2 = '"LP_ID"' + " = '" + str(row[1]) + "'"
ap.SelectLayerByAttribute_management('stops_lyr', 'ADD_TO_SELECTION', where_clause_2)
inStops = temp_select
route_name = str(row[0]) + "_" + str(row[1])
result_object = ap.na.MakeRouteAnalysisLayer(inNetworkDataset, route_name, "Multimodal")
layer_object = result_object.getOutput(0)
sublayer_names = ap.na.GetNAClassNames(layer_object)
stops_layer_name = sublayer_names["Stops"]
routes_layer_name = sublayer_names["Routes"]
ap.na.AddLocations(layer_object, stops_layer_name, inStops, search_criteria = [["Clip_OutFeatureClass_Ferrovias", "NONE"],
["Clip_OutFeatureClass_Rodovias", "SHAPE"],
["SC_TIN_TinEdge", "NONE"],
["Rodo_OD", "SHAPE"],
["Rodo_TermFerrExistente", "SHAPE"],
["Rodo_TermFerrNovo", "SHAPE"],
["BR_RG_Imediatas_2021_MeanCenter", "SHAPE"],
["Clip_OutFeatureClass_fc_ferro_terminal_de_carga", "SHAPE"],
["SC_ND_Junctions", "NONE"]])
ap.na.Solve(layer_object)
routes_sublayer = ap.na.GetNASublayer(layer_object, routes_layer_name)
ap.management.CopyFeatures(routes_sublayer, routes_path + route_name)
ap.na.CopyTraversedSourceFeatures(layer_object, edges_path, "TraversedEdges_" + route_name, "TraversedJunctions_" + route_name, "TraversedTurns_" + route_name)
temp_junction = edges_path + "/" + "TraversedEdges_" + route_name
intermodal_data[route_name] = []
except Exception:
e = sys.exc_info()[1]
print(e.args[0])
ap.AddError(e.args[0])
cur.updateRow(row)