Select to view content in your preferred language

arcpy.nax.CalculateLocations

679
3
Jump to solution
03-31-2023 05:53 AM
Labels (1)
SOTIRIOSTRIANTOS
New Contributor III

i am trying to solve a route using network analyst module nax,  i want to snap the orders on network dataset junctions but i must be missing something, because the result doesnt take into account my settings. 

 

Below is a code snippet can anyone suggest a solution?

 

 

 nd_layer_name='Greece_J18_ND'
        arcpy.nax.MakeNetworkDatasetLayer(inNetworkDataset, nd_layer_name)
        nd_travel_modes = arcpy.nax.GetTravelModes(nd_layer_name)
        travel_mode = nd_travel_modes["Car Oneways"]
        arcpy.nax.CalculateLocations(inOrders, inNetworkDataset, search_tolerance="3000 Meters", search_criteria = [["GreeceRoadNetwork", "NONE"], ["Greece_J18_ND_Junctions", "SHAPE"]], search_query=[["GreeceRoadNetwork", '"Access" <> -1'],["Greece_J18_ND_Junctions", ""]], travel_mode=travel_mode)
        
        # Instantiate a VehicleRoutingProblem solver object using schema version Two
        vrp = arcpy.nax.VehicleRoutingProblem(inNetworkDataset, arcpy.nax.VehicleRoutingProblemSchemaVersion.Two)
        # Set properties
        vrp.travelMode = travel_mode
        vrp.distanceUnits = arcpy.nax.DistanceUnits.Meters
        vrp.routeShapeType = arcpy.nax.RouteShapeType.TrueShape
        vrp.returnDirections = True
        vrp.returnStopShapes=True
        vrp.searchSources=searchQuery
        vrp.searchTolerance=3000
        vrp.spatiallyClusterRoutes=True
        vrp.timeWindowFactor=arcpy.nax.Importance.High
        # Load inputs
        arcpy.CalculateField_management(inOrders, "AssignmentRule",3, "PYTHON_9.3")
        vrp.load(arcpy.nax.VehicleRoutingProblemInputDataType2.Orders, inOrders)
        #vrp.load(arcpy.nax.VehicleRoutingProblemInputDataType2.Orders, inOrders)
        vrp.load(arcpy.nax.VehicleRoutingProblemInputDataType2.Depots, inDepots)
        vrp.load(arcpy.nax.VehicleRoutingProblemInputDataType2.Routes, inRoutes)
        
## Solve the analysis.
result = vrp.solve()

 

 

 

0 Kudos
1 Solution

Accepted Solutions
MelindaMorang
Esri Regular Contributor

I think the problem is that when you call load() for your orders, you need to configure field mapping to ensure that the locations you calculated with Calculate Locations are actually used.

Here is some documentation that might be useful, including code samples: https://pro.arcgis.com/en/pro-app/latest/arcpy/network-analyst/setting-analysis-inputs.htm#ESRI_SECT...

I noticed in the call to CalculateLocations, you've applied a search query to the "GreeceRoadNetwork" source, but that source is set to NONE in search_criteria, so the query will not be used.  This isn't really a problem.  Just wanted to call your attention to it in case this isn't what you intended.

vrp.searchSources=searchQuery  The problem could be in there, but I can't see in your script what the value of the searchQuery variable is.

View solution in original post

0 Kudos
3 Replies
MelindaMorang
Esri Regular Contributor

I think the problem is that when you call load() for your orders, you need to configure field mapping to ensure that the locations you calculated with Calculate Locations are actually used.

Here is some documentation that might be useful, including code samples: https://pro.arcgis.com/en/pro-app/latest/arcpy/network-analyst/setting-analysis-inputs.htm#ESRI_SECT...

I noticed in the call to CalculateLocations, you've applied a search query to the "GreeceRoadNetwork" source, but that source is set to NONE in search_criteria, so the query will not be used.  This isn't really a problem.  Just wanted to call your attention to it in case this isn't what you intended.

vrp.searchSources=searchQuery  The problem could be in there, but I can't see in your script what the value of the searchQuery variable is.

0 Kudos
SOTIRIOSTRIANTOS
New Contributor III

Thank you, I followed your instructions and our goal to load specific Orders on network elements and specific  orders on junctions worked.

below is the code snippet

		nd_layer_name='Greece_J18_ND'
        arcpy.nax.MakeNetworkDatasetLayer(inNetworkDataset, nd_layer_name)
        nd_travel_modes = arcpy.nax.GetTravelModes(nd_layer_name)
        travel_mode = nd_travel_modes["Car Oneways"]
        #arcpy.nax.CalculateLocations(inOrders, inNetworkDataset, search_tolerance="3000 Meters", search_criteria = [["GreeceRoadNetwork", "NONE"], ["Greece_J18_ND_Junctions", "SHAPE"]], search_query=[["GreeceRoadNetwork", '"Access" <> -1'],["Greece_J18_ND_Junctions", ""]], travel_mode=travel_mode)
        
        # Instantiate a VehicleRoutingProblem solver object using schema version Two
        vrp = arcpy.nax.VehicleRoutingProblem(inNetworkDataset, arcpy.nax.VehicleRoutingProblemSchemaVersion.Two)
        # Set properties
        vrp.travelMode = travel_mode
        vrp.distanceUnits = arcpy.nax.DistanceUnits.Meters
        vrp.routeShapeType = arcpy.nax.RouteShapeType.TrueShape
        vrp.returnDirections = True
        vrp.returnStopShapes=True
        vrp.searchSources=searchQuery
        vrp.searchTolerance=3000
        vrp.spatiallyClusterRoutes=True
        vrp.timeWindowFactor=arcpy.nax.Importance.High

        arcpy.MakeFeatureLayer_management(inOrders, "inOrders_lyr")
        fields =['OBJECTID','Description','AssignmentRule'] 
        inordersNJ=arcpy.SelectLayerByAttribute_management("inOrders_lyr", "NEW_SELECTION", "Description like '%_NJ' and AssignmentRule not in (4,5)")

        search_tolerance = "300 Meters"
        search_criteria = [["GreeceRoadNetwork", "SHAPE"], ["Greece_J18_ND_Junctions", "NONE"]]
        arcpy.nax.CalculateLocations(inordersNJ, inNetworkDataset, search_tolerance, search_criteria, travel_mode=travel_mode)
        VRP_ORDERS_NJ =os.path.join(workSpace, "VRP_ORDERS_NJ"+jobID)
        arcpy.management.CopyFeatures(inordersNJ, VRP_ORDERS_NJ)  
        fieldMappingsOrders_NJ = vrp.fieldMappings(arcpy.nax.VehicleRoutingProblemInputDataType2.Orders, use_location_fields=True)
        vrp.load(arcpy.nax.VehicleRoutingProblemInputDataType2.Orders, VRP_ORDERS_NJ, fieldMappingsOrders_NJ)

        search_tolerance = "300 Meters"
        inordersJ=arcpy.SelectLayerByAttribute_management("inOrders_lyr", "NEW_SELECTION", "Description not like '%_NJ' and AssignmentRule not in (4,5)")
		search_criteria = [["GreeceRoadNetwork", "NONE"], ["Greece_J18_ND_Junctions", "SHAPE"]]
        arcpy.nax.CalculateLocations(inordersJ, inNetworkDataset, search_tolerance, search_criteria,travel_mode=travel_mode)
        VRP_ORDERS_J =os.path.join(workSpace, "VRP_ORDERS_J"+jobID)
		arcpy.management.CopyFeatures(inordersJ, VRP_ORDERS_J)  
        fieldMappingsOrders_J = vrp.fieldMappings(arcpy.nax.VehicleRoutingProblemInputDataType2.Orders, use_location_fields=True)
        vrp.load(arcpy.nax.VehicleRoutingProblemInputDataType2.Orders, VRP_ORDERS_J, fieldMappingsOrders_J)

        vrp.load(arcpy.nax.VehicleRoutingProblemInputDataType2.Depots, inDepots)
        vrp.load(arcpy.nax.VehicleRoutingProblemInputDataType2.Routes, inRoutes)

        result = vrp.solve() #no parameters

 

When using the above approach, i noticed two things, firstly i had to create a feature class in order to load the orders (feature layers are not supported?).

Secondly in the output lpkx file, in the orders layer the SnapX, SnapY, DistanceToNetworkInMeters are empty. Am i missing something?

lpkx_output.PNG

0 Kudos
MelindaMorang
Esri Regular Contributor

Loading feature layers should work.  I think the problem is that the inordersNJ variable is not a feature layer.  It's a GP Result object.  Usually the output of a geoprocessing tool is a GP Result object, and if you want to retrieve the layer object, you have to do .getOutput(0) or something like that.  The index depends on the geoprocessing tool.  The documentation for each tool should tell you the derived outputs and their order.

SnapX, SnapY, and DistanceToNetworkInMeters are informational output fields that get created when you locate inputs on the network but are not required to actually define a point's network location.  They don't get automatically mapped during load() when you include location fields.  If you want these to be included, I think you have to manually add them to your field mappings.

0 Kudos