MMonotoniticy Calculation - How to Tell if Your Route is Simple or Complex

Blog Post created by rfairhur24 on Jun 7, 2015

I am gathering some of the posts and code I have written over the years that I regularly want to reference and reposting them under my Blog to hopefully make them easier for me to find.  I generally have difficulty finding these posts, because they were responses to questions by other users and the original post title they can be found under often is poorly related to the post I wrote.


Here is how to calculate the MMonotonicity of a feature.  MMonotonicity describes the trend of the M values as you traverse the polyline's vertices.  This is seen in the Identify Route Locations tool in the Measure Values section, but is more useful as a field value to allow you to select routes where measures do not continuously increase.  Anything other than a 1 (Strictly Increasing) indicates a complex route design that may cause problems.


The MMonotonicy values 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


Here is the calculation:


Parser:  Python

Show Codeblock:  Checked

Pre-Logic Script Code:

import numpy  
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 numpy.isnan(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!)