I'm getting some strange results from a closest facility problem (~40 facilities, ~1100 incidents) in Network analyst. In addition to a Total_Length, which is my impedance measure, I am calculating lengths for each route within several mutually exclusive and exhaustive categories. In other words, when summed for any edge in my network dataset, they add to Total_Length for that edge. Let's call them LengthA, LengthB, LengthC etc. I do this by setting them as Accumulation Attributes.
The resulting Routes look fine, except that the Total_Length of each is not the same as the sum of the lengths by category. The difference is sometimes too large to be because e.g. I am assigning locations to the nearest network location within 5000 meters.
Here's the part that makes me think someone out there will know the answer: All datasets I am using are in the same feature dataset in a sinusoidal projection. The percent difference between Total_Length and Sum(LengthA, LengthB, LengthC...) is highly correlated (0.85) with the percent difference between the analogous straight line distances calculated using latitude/longitude in the Haversine formula and using projected (sinusoidal) coordinates.
I can't think of any reason why the Plate Carree ("Geographic") or any projection other than the original sinusoidal would be used for one set of calculations but not the other.
Adam, First are you solving on Length? OR are you solving on say, travel time and accumulating Length to get the Total_Length field? Second, how was the Length attribute added/defined in the network dataset? Third, how are the length by category attributes set up? Are they based on the same "Length" attribute of that edge? Or were they set up by some other formula? Network Analyst itself is not doing any projections to figure out the lengths of the edges. And it will accumulate what ever fields you ask. There is no error in simply summing up attributes to report out the accumulation of the various attributes. Any differences have to exist in the input data. If you use the network identify tool (second icon from right on the NA toolbar), it will list out all the attribute values for that edge. Use that to see if the length and the length by category are the same. Most likely they are not same and that is source of the differences. Regards, Jay Sandhu
Jay, Thank you for your response, and sorry for the lack of details. I am solving on Length. The length by category fields were calculated on the the only feature class in the network, prior to building the network, just working with the table in a python script, assigning the [Shape_Length] field to the length-by-category field for each feature in the corresponding category. Below is a summary of inputs for the network build. I've removed all but two of the length-by-category fields - they are all analogous.
As you suggest, the discrepancy already appears when using the Network identify tool, so whatever is going wrong is at the network build stage and not the solver. But when using the (simple, non-network) identify tool on the feature dataset used to build the network, on the analogous fields for a network element that is identical to a line in the feature class, there is no discrepancy. In fact, of the four lengths identified in this way (network total length, network length-by-category, underlying feature class total length, and underlying feature class length-by-category), only network total length is different. It can be shorter or longer, depending on the segment (in a way that suggests some sort of implicit reprojection as I mentioned before).
Adam, The [Shape_Length] field is the computed length based on the projection of the data. The [Shape] field used in the evaluator will compute/return the true geodesic length of the feature in the units specified (meters in this case).
So these two will most likely not be the same.
So one way to fix is to continue using the [Shape_Legnth] in all places by changing your settings as: AfrRoads (From-To): Field - [Shape_Length] AfrRoads (To-From): Field - [Shape_Length]
Add a field to your street data and calculate it to the true geodesic distance by using the Haversine formula. And then update your Len22, Len23, etc, fields based on this new field. But this will be more work.
Jay, Thanks for this. If the geodesic distances are being calculated for every edge in the network build anyway, is there any way to access them, to put them into a tabular field that can then be passed into the various categories, either directly or through a spaital join with the original feature dataset from which the network was built? This seems like it would be much better than adding projection error to the (total) Length field just to make it match the others. Unless there's a better trick for using the Haversine on complex lines, I suspect that splitting into COGO, with well over a million segments, will crash my machine.
Adam, Probably the quickest way would be dump out the network dataset edge attribute information to a table and then add it to ArcMap and do a join.
As long as you have one line source in your network dataset and simple end point connectivity, i.e. the input line features were not split into multiple edges in the network, then you can use the following VBA to write out a file with the ID and Length. Modify as needed. Regards, Jay Sandhu
Public Sub List_ND_Topology()
Dim pMxDoc As IMxDocument Set pMxDoc = ThisDocument Dim pNLayer As INetworkLayer Set pNLayer = pMxDoc.SelectedLayer Dim pND As INetworkDataset Set pND = pNLayer.NetworkDataset Dim pNQ As INetworkQuery Set pNQ = pND Dim pEnumNE As IEnumNetworkElement Set pEnumNE = pNQ.Elements(esriNETEdge) Dim pNE As INetworkElement Set pNE = pEnumNE.Next Dim pNEdge As INetworkEdge Set pNEdge = pNE Dim i As Integer
Open "c:\ND_Length.csv" For Output As #1 'set path as needed Print #1, """EdgeOID"", ""Length_Attribute""" Do Until pNE Is Nothing Print #1, pNE.OID; ","; pNE.AttributeValueByName("Length") Set pNE = pEnumNE.Next Loop Close #1 End Sub
In this context, the shape_length is the length of each edge in the network and the total_length is he length of the path that the route solver finds. (it may be the sum of the shape_lengths of each edge if that is what the route was solved on).