1

I have a network layer of roads and a point layer containing points (towns) on that network. I need to create layers containing each pair of towns and its true shape route line. So for example from A-B, A-C, A-D, ... etc. So that every pair has its own shapefile with the line.

I tried the OD Matrix solution in Network Analyst in ArcMap 10.3 which created what I wanted as far as attributes go, but it draws only straight lines between each pair, it doesn't draw the line along the network. I need that. Closest Facility solution provides true shapes along the network but it doesn't create what OD matrix does. I need one shapefile for every pair.

Any advice or direction?

I tried to implement what Paul in Answer 1 suggested but I couldn't complete the script. I still need a tool to address correct points in pairs so they could be solved. It could be done sql query maybe? Any further advice?

from collections import defaultdict
import itertools
import pprint

import arcpy
from arcpy import env
import os

# generate pairs
ddict = defaultdict(list)
    for start,end in itertools.combinations(range(10), 2):
    ddict[start].append(end)

# viz example 3
try:
#Check out the Network Analyst extension license
arcpy.CheckOutExtension("Network")

#Set environment settings
env.workspace = r"E:/Dokumenty/GISdata/PID"
env.overwriteOutput = True

#Set local variables
inNetworkDataset = r"E:/Dokumenty/GISdata/PID/silnice_krnap_ND.nd"
impedanceAttribute = "Length"
accumulateAttributeName = ["Length"]

for key,value in ddict.items():
    for v in value:
        inFacilities = r"PID/Obce_body_luzka" # melo by byt key
        inIncidents = r"PID/Obce_body_luzka" # melo by byt v
        outNALayerName = "Dvojice_bodu_{}_{}".format(key, v)
        outLayerFile = os.path.join(r"E:/dokumenty/gisdata/output2", outNALayerName + ".lyr")
        NAResultObject = arcpy.na.MakeClosestFacilityLayer(inNetworkDataset,outNALayerName,impedanceAttribute,"TRAVEL_TO","",1, accumulateAttributeName,"NO_UTURNS")

        #Get the layer object from the result object. The closest facility layer can
        #now be referenced using the layer object.
        outNALayer = NAResultObject.getOutput(0)

        #Get the names of all the sublayers within the closest facility layer.
        subLayerNames = arcpy.na.GetNAClassNames(outNALayer)
        #Stores the layer names that we will use later
        facilitiesLayerName = subLayerNames["Facilities"]
        incidentsLayerName = subLayerNames["Incidents"]

        # Import system modules
        import arcpy

        # Set data path
        intable = "E:\Dokumenty\GISdata\PID\Obce_body_luzka.dbf"

        # Get the fields from the input
        fields= arcpy.ListFields(intable)

        # Create a fieldinfo object
        fieldinfo = arcpy.FieldInfo()

        # Iterate through the fields and set them to fieldinfo
        for field in fields:
            fieldinfo.addField(field.name, field.name, "VISIBLE", "")
            arcpy.MakeTableView_management(intable, "crime_view", "", "", fieldinfo)

        arcpy.na.AddLocations(outNALayer, facilitiesLayerName, "Obce_body_luzka", "", "")
        arcpy.na.AddLocations(outNALayer, incidentsLayerName, "Obce_body_luzka", "", "")

        #Solve the closest facility layer
        arcpy.na.Solve(outNALayer)

        #Save the solved closest facility layer as a layer file on disk with
        #relative paths
        arcpy.management.SaveToLayerFile(outNALayer,outLayerFile,"RELATIVE")

print "Script completed successfully"

except Exception as e:
# If an error occurred, print line number and error message
import traceback, sys
tb = sys.exc_info()[2]
print "An error occured on line %i" % tb.tb_lineno
print str(e)

I worked with the idea of using the closest facility method, while thinking that "the closest" route is also "the only route" from A-B, etc.

  • 1
    Not terribly familiar with this, but can you choose the option that creates a single shapefile, then separate each line into individual shapefiles? Just adding one step. You can do this with model builder or python very easily. – Stella Nov 30 '16 at 20:32
  • Do you want to assume the route from A to B is same as from B to A? – Kirk Kuykendall Nov 30 '16 at 20:56
  • Stella: I'm not familiar with what you mean. Adding one step to where? Thank you. – M. Tomas Nov 30 '16 at 21:03
  • Kirk Kuykendall: Yes, AB = BA. – M. Tomas Nov 30 '16 at 21:04
  • 1
    @Stella means, if you're happy with the result of Closest Facility but would like 1 feature class for each output line, just export each line to a separate feature class, see answers to this question: Exporting feature class into multiple feature classes based on field values using ArcGIS for Desktop?. – GISGe Dec 1 '16 at 8:18
2

No need to use Closest Facility when you're only routing between two stops.

In pseudo code:

  1. Calculate Locations for your points feature class (will improve loading times)
  2. Make Feature Layer on points
  3. Create nested for loops to build def queries
  4. Add Locations to your NA layer
  5. Solve!
  6. Export the solve result to shapefile

3 is the trickiest, so this should help you get started. Since the route from A->B is the same as B->A, you'll need a way to ensure you're not routing the same points in reverse order.

Consider the following, which when used with your key field (OID), should work quite well.

from collections import defaultdict
import itertools
import pprint

ddict = defaultdict(list)

for start,end in itertools.combinations(range(10), 2):
    ddict[start].append(end)

pprint.pprint(dict(ddict))

{0: [1, 2, 3, 4, 5, 6, 7, 8, 9],
 1: [2, 3, 4, 5, 6, 7, 8, 9],
 2: [3, 4, 5, 6, 7, 8, 9],
 3: [4, 5, 6, 7, 8, 9],
 4: [5, 6, 7, 8, 9],
 5: [6, 7, 8, 9],
 6: [7, 8, 9],
 7: [8, 9],
 8: [9]}

Applying the above to our def query example:

for key,value in ddict.items():
    for v in value:
        query = "OBJECTID IN ({}, {})".format(key, v)
        # apply query to point layer
        # Add Locations
        # Solve
        # Export

You could do this in model builder, but it's probably non-trivial.

  • Thank you for your answer. I edited my original post with the code I came up with. I don't know if it's any good, but I could be on right way. – M. Tomas Dec 14 '16 at 19:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.