# cost matrix

2339
12
09-12-2010 06:12 PM
New Contributor
Hi there,

I have a network dataset which represents roads and a shapefile with cities ....what I wanna do is to generate a cost matrix that contains the distance between two connected cities in the network. For this case the OD_matrix_solver is not desired because it calculates shortest distances between cities.... all I want is the "link_length" between cities..... I've been looking some scripts but most of them just compute euclidean distances between connected points..the question is how I can do the same but using the real shape.

I imagine that analogously to OD_matrix_solver...first I'd have to snap locations to my road network and next to generate the matrix.

Can anyone give me a little help here???...thanks
Tags (2)
12 Replies
Esri Regular Contributor
You start of by saying that you want the distance between two cities and then it is not clear from your post what you need to generate. Can you elaborate on what is "link length" as opposed to "shortest distance" that the OD Cost Matrix generates? OD Cost matrix generates the shortest path distance (route over the network) between the sets of origins and destinations. Not sure what other distance you need. Please elaborate.
Jay Sandhu
New Contributor
To make it clearer, you have your network with edges and vertices(cities)... each edge (or link connecting two vertices) has a weight associated (in this case distance "d")....I wanna extract the weight of each link from my map and put them in a matrix like (instead of "ones" I need distances):

Esri Regular Contributor
Ok. What you want is the connectivity matrix of the network graph and the edge costs. You can generate that by using some VBA that I list below. To use this, add the network dataset to ArcMap. Make sure to change the name of the attribute name (in this case I have it as meters) to the one that is in your data. The run it in the VBA. The immedate window will show the results. You can re-format the debug.print lines (change them to write to a file) as needed. The output will currently look like this:

Junction: 1 is adjacent to: 1 junctions.
Junction: 2 is adjacent to: 3 junctions.

Regards,
Jay Sandhu

On Error GoTo eh

Dim pMxDoc As IMxDocument
Set pMxDoc = ThisDocument

Dim pNLayer As INetworkLayer
Set pNLayer = pMxDoc.FocusMap.Layer(0)

Dim pND As INetworkDataset
Set pND = pNLayer.NetworkDataset

Dim pNQ As INetworkQuery
Set pNQ = pND

Dim pEnumNE As IEnumNetworkElement
Set pEnumNE = pNQ.Elements(esriNETJunction)

Dim pNEdge As INetworkEdge
Set pNEdge = pNQ.CreateNetworkElement(esriNETEdge)
Dim pNEFromJunc As INetworkJunction
Set pNEFromJunc = pNQ.CreateNetworkElement(esriNETJunction)
Dim pNEToJunc As INetworkJunction
Set pNEToJunc = pNQ.CreateNetworkElement(esriNETJunction)

Dim pNE As INetworkElement
Set pNE = pEnumNE.Next

Dim pNEJunc As INetworkJunction
Set pNEJunc = pNE

Dim i As Integer
Do Until pNE Is Nothing
Debug.Print "Junction: " & pNEJunc.EID & " is adjacent to: " & pNEJunc.EdgeCount & " junctions."
For i = 0 To pNEJunc.EdgeCount - 1  'For each connected edge...
pNEJunc.QueryEdge i, True, pNEdge   'Get that connected edge
pNEdge.QueryJunctions pNEFromJunc, pNEToJunc  'Get To junction of current edge
Debug.Print " Adjacent Junction: " & pNEToJunc.EID & " Length " & pNEdge.AttributeValueByName("Meters") 'List the adjacency
Next
Set pNE = pEnumNE.Next
Loop
Exit Sub
eh:
MsgBox "Error: " & Err.Description
End Sub
New Contributor
Thanks very much Jay for you valuable help.

Regards

Philip
New Contributor
Hi JAy ,

I've been trying to run the code, but my ArcGIS report an "Automation error"...but there is not specification what error is...no error number, nothing....any idea what  problem might be??

THanks

Philip

Ok. What you want is the connectivity matrix of the network graph and the edge costs. You can generate that by using some VBA that I list below. To use this, add the network dataset to ArcMap. Make sure to change the name of the attribute name (in this case I have it as meters) to the one that is in your data. The run it in the VBA. The immedate window will show the results. You can re-format the debug.print lines (change them to write to a file) as needed. The output will currently look like this:

Junction: 1 is adjacent to: 1 junctions.
Junction: 2 is adjacent to: 3 junctions.

Regards,
Jay Sandhu

On Error GoTo eh

Dim pMxDoc As IMxDocument
Set pMxDoc = ThisDocument

Dim pNLayer As INetworkLayer
Set pNLayer = pMxDoc.FocusMap.Layer(0)

Dim pND As INetworkDataset
Set pND = pNLayer.NetworkDataset

Dim pNQ As INetworkQuery
Set pNQ = pND

Dim pEnumNE As IEnumNetworkElement
Set pEnumNE = pNQ.Elements(esriNETJunction)

Dim pNEdge As INetworkEdge
Set pNEdge = pNQ.CreateNetworkElement(esriNETEdge)
Dim pNEFromJunc As INetworkJunction
Set pNEFromJunc = pNQ.CreateNetworkElement(esriNETJunction)
Dim pNEToJunc As INetworkJunction
Set pNEToJunc = pNQ.CreateNetworkElement(esriNETJunction)

Dim pNE As INetworkElement
Set pNE = pEnumNE.Next

Dim pNEJunc As INetworkJunction
Set pNEJunc = pNE

Dim i As Integer
Do Until pNE Is Nothing
Debug.Print "Junction: " & pNEJunc.EID & " is adjacent to: " & pNEJunc.EdgeCount & " junctions."
For i = 0 To pNEJunc.EdgeCount - 1  'For each connected edge...
pNEJunc.QueryEdge i, True, pNEdge   'Get that connected edge
pNEdge.QueryJunctions pNEFromJunc, pNEToJunc  'Get To junction of current edge
Debug.Print " Adjacent Junction: " & pNEToJunc.EID & " Length " & pNEdge.AttributeValueByName("Meters") 'List the adjacency
Next
Set pNE = pEnumNE.Next
Loop
Exit Sub
eh:
MsgBox "Error: " & Err.Description
End Sub
New Contributor
a short update...I was able to fix the "Automation error"...but now I'm gettin a "type mismatch error"...

Cheers

Philip
New Contributor
Thanks very much Jay.... I was able to run the code.....However, I notice you are using the Network_Junctions as vertices... my network consists of a road layer and cities_layer (points) ..the latter supposedly is my "vertex" layer. Is there a way to use my cities_ layer as vertices rather than the Network_Junctions so that the distance between cities populates the  matrix??. (usually cities_layer does not match with your Junction_layer)
Regards

Philip
Esri Regular Contributor
You can make another point source be part of your network dataset. So you could include the cities to be part of th network. Then change the code to only look at junctions of type cities.
However, I am not sure how you will get length to the next city with the code I sent as the cities may not be linked to other cities with one to one edges. In fact, your post has again made it un-clear what you are trying to achieve. It looks like all you need is shortest distance between SOME set of cities. How do you determine what cities are connected to a given city?

Jay Sandhu
New Contributor
We wanna test a new shortest path algorithm so no optimization is desired at this stage. I'm just using ArcGIS to extract the adjencecy matrix from a real network.... I have a shapeline which represents a road system ...this is built with small polylines ...I additionally have another shapefile (over 2000 points) with represents cities .

Cities are not connected by just one polyline..... many small pieces make the connection among cities. So to get the edge_length between two cities (if they are connected) we have to sum all the small pieces (unless we have a way to merge them into one long polyline)... You are right....the real question is how to find out what cities are connected to a given city.

My idea is to extend your code to firstly identify cities (intead of junctions) and next try to compute adjancency and distance....somehow I'll have to figure out how to keep tracking of the shape_lengh in the road_system.

Any help will be very appreciated.

Philip