Problem with Locate Features Along Route (Linear Referencing)

8249
16
Jump to solution
09-20-2013 07:12 AM
toddsams
New Contributor III
Hi,

I am attempting to measure the distance between sites (points; n=50) that were sampled along a trail using the Linear Referencing tools. I created a "route" from my trail feature class (line; dissolved into one single feature) and was able to run the Locate Features Along Route tool without any errors. I then ran Make Route Event Layer so that I could view my points after they had been "snapped" to the trail, which all looked great.

The problem I am having is with the values in the Measure Field, which is supposed to list the distance at which each point exists along the trail. I sorted the Measure Field in descending order and expected that my sites would then be listed in the order in which they appear along the trail, and this is the case for the first 12 sites. However, the 13th site listed is the one at the opposite end of the trail and then the remaining sites are listed in sequential order and meet back up with the 12th site. I checked to see if this could be explained due to the values being measured from the other end of the trail, but this didn't add up.

So basically, it seems that the Measure Field was not calculated properly. I would greatly appreciated any insight into this. Many thanks in advance!
1 Solution

Accepted Solutions
RichardFairhurst
MVP Honored Contributor
I got the code to work just fine. It calculated 15 in the MMONOTONIC field. Seems like I do not have monotonicity. How can I correct this? Simplify the line?

I switched RID to 1 and re-generated the Event Table (attached).

I zoomed into points 13 and 14 and there doesn't appear to be any complex curving here.


A rating of 15 is the most messed up it can get and there is no way you can expect the measures to behave as though you had a simple monotonic route as the input.  Some measures are increasing, others are decreasing, others are identical next to each other and others are unassigned.  The measure order is true to the measure distribution on the route and your events give some clue how the route is actually pieced together in the underlying geometry, so that if you sorted the points in order by number that will show how the measures are assigned actually along the route.  Such errors are almost always due to bad topology at very small detail levels.

In an edit session I would inspect the sketch properties to see if the Route is singlepart or multipart.  It is almost certainly multipart and joined together in a random segment order.  So lines are skipped and then reverse direction and double back.  To find out how many parts your line is made up of add a long field called Parts and calculate it with a simple Python calculation of:

!Shape.PartCount!

Assuming you have multiple parts I would probably use the explode tool in the Advanced Editing toolbar or the MultiPart to SinglePart tool to break the Route back up to its original component lines.

The original lines are probably both overlapping each other and not touching exactly end to end to begin with.  Bad topology like that will definitely mess up the measures and the way the Route is pieced together by the Create Route tool.  No lines can overlap each other or cross over each other and all nearly coincident ends must actually touch end to end to avoid errors.  To fix that I would convert it all to a file geodatabase feature class within a dataset and build a topology with rules for single part, no dangles, no crossings, and no overlaps and use the topology tools to fix the lines.

If you don't want to go with the topology option, use either the Integrate tool or the Snap tool on the singlepart lines to make sure they join end to end without overlaps.  Running the Intersect tool with the lines option would show you where line segments overlap.  Running the Intersect tool again and with the points option where they cross or connect end to end.

Once that is fixed I would build the Route using the Create Route tool with the Upper Right or Lower Left orientation Option (assuming the line does not curve around to another direction trend at the actual ends of the overall line).

View solution in original post

0 Kudos
16 Replies
RichardFairhurst
MVP Honored Contributor
Hi,

I am attempting to measure the distance between sites (points; n=50) that were sampled along a trail using the Linear Referencing tools. I created a "route" from my trail feature class (line; dissolved into one single feature) and was able to run the Locate Features Along Route tool without any errors. I then ran Make Route Event Layer so that I could view my points after they had been "snapped" to the trail, which all looked great.

The problem I am having is with the values in the Measure Field, which is supposed to list the distance at which each point exists along the trail. I sorted the Measure Field in descending order and expected that my sites would then be listed in the order in which they appear along the trail, and this is the case for the first 12 sites. However, the 13th site listed is the one at the opposite end of the trail and then the remaining sites are listed in sequential order and meet back up with the 12th site. I checked to see if this could be explained due to the values being measured from the other end of the trail, but this didn't add up.

So basically, it seems that the Measure Field was not calculated properly. I would greatly appreciated any insight into this. Many thanks in advance!


Are multiple trails in your route feature class?  Did you use the get nearest route or keep all locations option with the Get Rotue Locations tool?  Are you sure the 13th event was linked to the same route as the others?  Sort by RID and then by measure and be sure all of the events have the same RID values.

Are you sure you have a simple monotonic route (all measures increase on each successive vertex)?  Is the Route a singlepart feature or multipart feature?  Does the trail loop back on itself or have branches?  Any complexity to the route will cause odd results, so that is the first thing to eliminate.  Just because everything is merged together does not mean that the route measures are properly formed.  Did you manually calculate the measures or use the Create Route tool to assign measures?

Here is code that will fill in a field to rate the MMonotonicity of your routes.  Add a long field called MMONOTONIC to your routes and calculate it with this formula (any result other than 1 is potentially bad):

Parser: Python

Show Codeblock: Checked

Pre-Logic Script Code:
def MMonotonicity(feat):
 partnum = 0

 # Count the number of points in the current multipart feature
 partcount = feat.partCount
 pntcount = 0
 mmonotonicity = 0
 lastM = -100000000

 # Enter while loop for each part in the feature (if a singlepart feature
 # this will occur only once)
 #
 while partnum < partcount:
  part = feat.getPart(partnum)
  pnt = part.next()

  # Enter while loop for each vertex
  #
  while pnt:
   pntcount += 1
   if lastM < pnt.M and lastM != -100000000:
    mmonotonicity = mmonotonicity | 1
   if lastM == pnt.M and lastM != -100000000:
    mmonotonicity = mmonotonicity | 2
   if lastM > pnt.M and lastM != -100000000:
    mmonotonicity = mmonotonicity | 4
   if not pnt.M:
    mmonotonicity = mmonotonicity | 8
   lastM = pnt.M
   pnt = part.next()
   
   # If pnt is null, either the part is finished or there is an 
   # interior ring
   #
   if not pnt: 
    pnt = part.next()
  partnum += 1
 return mmonotonicity


Expression: MMonotonicity( !Shape!)

The MMonotonicy values of the calculation and their domain translations are:

1 = Strictly Increasing
2 = All Measures are Level
3 = Increasing with Levels
4 = Strictly Decreasing
5 = Increasing and Decreasing
6 = Decreasing with Levels
7 = Increasing and Decreasing with Levels
8 = All Measures are NaN
9 = Increasing with NaN
10 = Measures with Levels and NaN only
11 = Increasing with Levels and Nan
12 = Decreasing with NaN
13 = Increasing and Decreasing with NaN
14 = Decreasing with Levels and NaN
15 = Increasing and Decreasing with Levels and NaN
toddsams
New Contributor III
Thank you for the detailed reply. Responses to your questions are in red below:

Are multiple trails in your route feature class? No.

Did you use the get nearest route or keep all locations option with the Get Rotue Locations tool? The Locate Features Along Routes tool (in V10.1) has the option to "Keep only the closest route location", which I have checked.

Are you sure the 13th event was linked to the same route as the others? Yes.

Sort by RID and then by measure and be sure all of the events have the same RID values. The RID field includes zeros for each record. Maybe this is a clue to the problem?

Are you sure you have a simple monotonic route (all measures increase on each successive vertex)? Is the Route a singlepart feature or multipart feature? Does the trail loop back on itself or have branches? It seems that the route is a simple monotonic route. It is a singlepart feature (dissolved into a single line represented by one record). The trail has some meandering, but is generally linear with no major switchbacking etc. and no branching.

Did you manually calculate the measures or use the Create Route tool to assign measures? I used the Create Route tool to convert my standard polyline (representing the trail) into a "route" (polyline M). Then I used the Locate Features Along Route tool to populate the measures field.

Thank you for the code. I do have some Python experience. However, I am not sure how I would implement/modify this code for my situation. Can this be used in the Python window in ArcMap or would it require IDLE (or other)? Would I reference my data by defining a variable named "feat" which points to my point feature class?
0 Kudos
RichardFairhurst
MVP Honored Contributor
Sort by RID and then by measure and be sure all of the events have the same RID values.   The RID field includes zeros for each record. Maybe this is a clue to the problem?


Is your actual Route ID for your trail 0? If not, these records are not located events and probably have a 0 measure, which would fall at the beginning of the route. However, I would have thought the events that did not locate properly would have been dropped by the tool, so I am not sure why you have these records at all if they are not actual events.

Thank you for the code. I do have some Python experience. However, I am not sure how I would implement/modify this code for my situation. Can this be used in the Python window in ArcMap or would it require IDLE (or other)? Would I reference my data by defining a variable named "feat" which points to my point feature class?


This is a Field Calculation not a Python script and it is for the Routes not the points. It is just to make sure the Route measures are well formed. Right click the MMONOTONIC field I told you to add to the Routes and choose the Calculate Field. Then input the calculation. Each step is listed from top to bottom of the field calculator tool and there are 4 things you need to set. No modification of the code is needed. It just ensures that there are no hdden problems in your routes and become more important when you start dealing with large datasets, such as the 30,000+ routes I deal with.
0 Kudos
toddsams
New Contributor III
Is your actual Route ID for your trail 0?


Yes, the Route ID of the trail is zero. So it seems that the RID field of the Events is populated appropriately.

Right click the MMONOTONIC field I told you to add to the Routes and choose the Calculate Field.  Then input the calculation. Each step is listed from top to bottom of the field calculator tool and there are 4 things you need to set.  No modification of the code is needed.  It just ensures that there are no hdden problems in your routes and become more important when you start dealing with large datasets, such as the 30,000+ routes I deal with.


I ran the code you provided using field calculator in a new "MMONOTONIC" field (long integer) and recieved error 999999 (attached). Maybe because I only have one route represented by one record?

The attached image also shows the section of the trail where the calculation jumps and the attribute table of the route layer. For reference, this distance between the 13th and 14th point is about 500 meters.
0 Kudos
RichardFairhurst
MVP Honored Contributor
Yes, the Route ID of the trail is zero. So it seems that the RID field of the Events is populated appropriately.

I ran the code you provided using field calculator in a new "MMONOTONIC" field (long integer) and recieved error 999999 (attached). Maybe because I only have one route represented by one record?

The attached image also shows the section of the trail where the calculation jumps and the attribute table of the route layer. For reference, this distance between the 13th and 14th point is about 500 meters.


Here is a screen shot of how the calculation should look for the MMONOTONIC field.  The codeblock only shows the beginning of the code, but the full code in my post code block is in that area.  I ran this calculation on my 30K+ routes and it worked fine.  I have not tested the code on actual NaN values in the route measures, so if the code fails NaN measures would be my suspected cause.  You can see the route MMonotonic value using the Get Route Locations tool in the Customize Linear Referencing commands area.

Go ahead and screen shot the sorted event table so I can see what the actual events and values are.  Expand the tableview to full screen so I can see all of it.

I personally would not use an ID of 0, since that can confuse blank values in a shapefile with real values, since both will defualt to 0.  Also zoom into the 13 and 14 points.  Complex curving routes can cause 2 locations to be chosen by the tool within the search radius and then randomly pick which it wants to keep.
0 Kudos
toddsams
New Contributor III
I got the code to work just fine. It calculated 15 in the MMONOTONIC field. Seems like I do not have monotonicity. How can I correct this? Simplify the line?

I switched RID to 1 and re-generated the Event Table (attached).

I zoomed into points 13 and 14 and there doesn't appear to be any complex curving here.
0 Kudos
RichardFairhurst
MVP Honored Contributor
I got the code to work just fine. It calculated 15 in the MMONOTONIC field. Seems like I do not have monotonicity. How can I correct this? Simplify the line?

I switched RID to 1 and re-generated the Event Table (attached).

I zoomed into points 13 and 14 and there doesn't appear to be any complex curving here.


A rating of 15 is the most messed up it can get and there is no way you can expect the measures to behave as though you had a simple monotonic route as the input.  Some measures are increasing, others are decreasing, others are identical next to each other and others are unassigned.  The measure order is true to the measure distribution on the route and your events give some clue how the route is actually pieced together in the underlying geometry, so that if you sorted the points in order by number that will show how the measures are assigned actually along the route.  Such errors are almost always due to bad topology at very small detail levels.

In an edit session I would inspect the sketch properties to see if the Route is singlepart or multipart.  It is almost certainly multipart and joined together in a random segment order.  So lines are skipped and then reverse direction and double back.  To find out how many parts your line is made up of add a long field called Parts and calculate it with a simple Python calculation of:

!Shape.PartCount!

Assuming you have multiple parts I would probably use the explode tool in the Advanced Editing toolbar or the MultiPart to SinglePart tool to break the Route back up to its original component lines.

The original lines are probably both overlapping each other and not touching exactly end to end to begin with.  Bad topology like that will definitely mess up the measures and the way the Route is pieced together by the Create Route tool.  No lines can overlap each other or cross over each other and all nearly coincident ends must actually touch end to end to avoid errors.  To fix that I would convert it all to a file geodatabase feature class within a dataset and build a topology with rules for single part, no dangles, no crossings, and no overlaps and use the topology tools to fix the lines.

If you don't want to go with the topology option, use either the Integrate tool or the Snap tool on the singlepart lines to make sure they join end to end without overlaps.  Running the Intersect tool with the lines option would show you where line segments overlap.  Running the Intersect tool again and with the points option where they cross or connect end to end.

Once that is fixed I would build the Route using the Create Route tool with the Upper Right or Lower Left orientation Option (assuming the line does not curve around to another direction trend at the actual ends of the overall line).
0 Kudos
toddsams
New Contributor III
I exploded the multipart feature into single parts (n = ~700). Then I ran the integrate tool with a 2 meter tolerance, which reduced the number of single parts by about one-half. Using the Intersect functions you suggested, I identified two locations of overlapping line segments and fixed these errors.

I tried re-building the route with the cleaned up trail lines and "upper right" option. The measures are now more random than before.

Re-calculating MMONOTONIC gave me a value of 10 for each of the records.

Is there something else I should do to ensure monotonicity in the dataset?
0 Kudos
toddsams
New Contributor III
I built topology and rules for the trail then checked for errors and found many! I may try to generalize the line using Smooth Line since my measures do not need to be very precise.
0 Kudos