Adding slope directions to an ITN network dataset.

2260
14
05-08-2013 05:09 AM
Liam_
by
New Contributor II
Hi,

I am currently attempting to test the feasibility of a navigation solution that can calculate the best route to a destination based on fuel economy variables. It is my intention to calculate an impedance value based on said variables. One of the variables I have selected is slope as a vehicle travelling uphill will use more fuel then one travelling downhill.

I have downloaded and imported into ArcMap 10.1 the Ordnance Survey ITN. However, I cannot seem to work out a way of getting slope direction from a raster underneath the roads and storing it in such a way that can be used for an impedance calculation.

I have a moderate amount of experience with ArcMap and some programming experience but I could really use the help of an expert!

Thank you,

Liam.
Tags (2)
0 Kudos
14 Replies
MelindaMorang
Esri Regular Contributor
Okay, I think I've got it figured out.

You want to create your own global turn script evaluator that will add a certain number of liters of fuel needed for each type of transition between road types (turn).  So, the fuel usage on the edges will stay the same as you have them now, but each transition between edges can add some value, based on the way you want to calculate it.

First, when you create your network dataset, make sure you click the button that tells it you want to model global turns.

Next, set up the global turn evaluator, as follows:
- In the network dataset properties window, go to the Attributes tab.
- For your fuel usage attribute, click Evaluators.
- After the evaluators window pops up, go to the Default Values tab.
- In the Type column next to Turn, click to get a drop-down menu where you can select "Script".
- Click the Evaluator Properties button on the right (looks like a finger pointing at a piece of paper).  A dialog will appear where you can write a simple Python or VBScript that says how the solvers should calculate the fuel usage for turns in your network.  You should be able to use some if statements to give it a different value based on the road types of the fromEdge and toEdge.
0 Kudos
Liam_
by
New Contributor II
Hi,

Thank you again for all your help, here is the code I have used in the script evaluator: -

* SpeedCostTotalRoad is the total cost to transverse the road in litres and is calculated from literature values for average vehicles
* Economy is the name of my route network's cost evaluator.

dim result

If fromEdge.OID.Roadlinks.RoadDesc = "Minor Road" and toEdge.OID.Roadlinks.Nature = "Roundabout" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.20 )

ElseIf fromEdge.OID.Roadlinks.RoadDesc = "Local Street" and toEdge.OID.Roadlinks.Nature = "Roundabout" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.20 )


ElseIf fromEdge.OID.Roadlinks.RoadDesc = "B Road" and toEdge.OID.Roadlinks.Nature = "Roundabout" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.20 )


ElseIf fromEdge.OID.Roadlinks.RoadDesc = "A Road" and toEdge.OID.Roadlinks.Nature = "Roundabout" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.20 )


ElseIf fromEdge.OID.Roadlinks.RoadDesc = "Motorway" and toEdge.OID.Roadlinks.Nature = "Roundabout" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.20 )


ElseIf fromEdge.OID.Roadlinks.RoadDesc = "A Road" and toEdge.OID.Roadlinks.RoadDesc = "Minor Road" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.50 )


ElseIf fromEdge.OID.Roadlinks.RoadDesc = "A Road" and toEdge.OID.Roadlinks.RoadDesc = "Local Street" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.50 )


ElseIf fromEdge.OID.Roadlinks.RoadDesc = "A Road" and toEdge.OID.Roadlinks.RoadDesc = "B Road" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.50 )


ElseIf fromEdge.OID.Roadlinks.RoadDesc = "Motorway" and toEdge.OID.Roadlinks.RoadDesc = "Minor Road" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.50 )


ElseIf fromEdge.OID.Roadlinks.RoadDesc = "Motorway" and toEdge.OID.Roadlinks.RoadDesc = "Local Street" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.50 )


ElseIf fromEdge.OID.Roadlinks.RoadDesc = "Motorway" and toEdge.OID.Roadlinks.RoadDesc = "B Road" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.50 )


ElseIf fromEdge.OID.Roadlinks.RoadDesc = "Motorway" and toEdge.OID.Roadlinks.RoadDesc = "A Road" then
result = "Economy" + ( fromEdge.OID.Roadlinks.SpeedCostTotalRoad * 0.50 )
END IF


I have rebuilt the network, but it's not quite working as it should

I get the errors:

Error: The evaluator failed to return a value. [Attribute: Economy, Default Turns, OID = -1, EID = -1]
Error: Network element evaluator error. [Script Control Error -2147352319]

I have looked online, but I cannot find any guides on the use of the fromEdge.OID. variable. Have I missed something out?

Thanks again,

Liam.
0 Kudos
MelindaMorang
Esri Regular Contributor
Hi Liam.  I'm afraid I was incorrect in my earlier post.  You can't actually use the default turn script evaluator effectively unless you have actual turn features drawn into your network.  If you are going to use this method, you will have to manually create all the turn features.  As you mentioned before, this would undoubtedly be quite laborious.

As for why your code isn't working, it's a syntax problem.  In your if statements, you would need to use something like this:
fromEdge.AttributeValueByName( "RoadClass" )
Also, you won't be able to just call "Economy" by itself.  That value is meaningless unless associated with a particular edge element.  As I mentioned before, you can't update the cost of the edge element itself based on the next edge in the route because the route doesn't know what the next edge is going to be.  The reason I suggested the turns is that turns are the only cost-associated element that has information about the edge elements it's connected to.

So, unfortunately, this doesn't leave you with a lot of good options.  If you know ArcObjects, you could build your own custom evaluator, but this is not an easy process.  And, again, you can't use a custom evaluator to determine the cost of an edge based on the next edge in the route because the solver itself does not know what the next edge is going to be.

I'm really sorry I don't have a better answer for you.
0 Kudos
MelindaMorang
Esri Regular Contributor
Ack, sorry, I did some more experiments, and I now see that, in fact, you CAN do what I was suggesting.  You don't have to have a turn feature class with every turn digitized in to use a custom script evaluator for global turns.  It WILL work the way I originally suggested.  I think if you just fix your syntax, you should be good to go.

In the mean time, I'll see what I can do about us getting some better documentation for this subject.  If I work here and can't figure it out, we clearly didn't do a very good job.
0 Kudos
Liam_
by
New Contributor II
Hi,

Thank you again for your reply. As my project deadline is approaching fast, I have had to abandon my junction cost matrix and instead I have just added a +20% cost to routes that transverse a roundabout. At this stage, the project outcome is just a measure of the feasibility of using economy routing in vehicle satellite navigation systems (although I could list many other applications!).

This would not have been an issue if there was freely available point data for the locations of traffic controlled signals for the United Kingdom. Having said that, should I have some time at the end of my project, I shall return to the problem and attempt to refine the analysis following your latest advice.

Thank you again for all your help, I will post my solution here should I get it working for the benefits of others attempting similar tasks.

Thanks again,

Liam.
0 Kudos