Select to view content in your preferred language

Route (Analysis Network) in Python generates the same route 3 times for each OD pair

984
2
10-20-2022 12:53 PM
ConnieSu
Emerging Contributor

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!

0 Kudos
2 Replies
DanPatterson
MVP Esteemed Contributor

formatted code, with line numbers would be helpful

Code formatting ... the Community Version - Esri Community


... sort of retired...
0 Kudos
ConnieSu
Emerging Contributor

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)
0 Kudos