Stationing and offset is a simple and precise method of locating and capturing information, typically during a construction project, along linear assets like roads, railways, or pipelines.
Stationing is the measurement of distance along a designated centerline or alignment. In ArcGIS, stationing is a measurement value (m-value) that is dynamically associated with a linear feature or route in an Linear Referencing System (LRS). Offset is the perpendicular distance from the centerline to a specific point – like where the mobile worker is capturing information.
Within a civil construction project, stationing and offset information is captured as part of specific inspection tasks to ensure roads or pipelines are built according to design specifications. Stationing provides reference and when combined with offset, provide accuracy of measurements.
Now, with ArcGIS Field Maps, you can automatically capture stationing and offset values along with other route characteristics while filling out inspection form details. Paired with an external GNSS receiver, referenced locations can be accurate to the cm. If a design surface is provided, Field Maps can also validate that current construction is “at grade” with design. Please read our earthworks blog article for how to configure Field Maps to capture cut and fill measurements.
In this article, we’ll show you how to configure your map to capture these important attributes. Not included below is the expectation that you already have a horizontal alignment published as a linear feature layer that includes m-values. This may be a route stored and managed using ArcGIS Roads and Highways or ArcGIS Pipeline Referencing, or an alignment that has been imported from a CAD drawing using ArcGIS Pro.
For step-by-step instructions on how to add expressions to the form in Field Maps Designer, see Add calculated expressions. These expressions utilize the PointToCoordinate function available in the latest release of ArcGIS Field Maps.
Add Alignment Form Elements
Using Field Maps Designer, start by adding these attributes and form elements to your form:
- Station – Field type: String, Field name: Station, Input type: Text – single line
- Offset (ft) – Field type: String, Field name: RelOffset, Input type: Text – single line
- RouteID – Field type: String, Field name: RouteID, Input type: Text – single line
- Measure (mile) – Field type double, Field name: Measure, Input type: number – double
Calculated expressions
With the above form elements added, follow the directions below to include calculated expressions that will reference values from your horizontal alignment feature layer.
Station field: get road alignment station
//The measure value is in miles, and it is converted to feet
var station = $feature.Measure*5280;
var IsNegative = 0 //tracks +/- values
var Type = ‘Feet’ //”Meters” Switch type as needed
if (station < 0) {
//convert all negative stations to positive and append back the – at the end
station = station * –1
IsNegative = 1
}
//##00+00.0 or ##0+000.0 – These functions will provide this format regardless the length of the field
//formatting with decimals after the + sign – if there is not
if (Type == ‘Feet‘) var StationlbR = Text(station, ‘00.0‘)
if (Type == ‘Meters’) var StationlbR = Text(station, ‘000.0‘)
//Getting rid of the two initial character dividing by 100 or 1000. formatting result with 2 zeros and room for more characters
//using the Split function to extract from the second character from the left of the decimal point
if (Type == ‘Feet‘)
var StationlbL = Text(First(Split(station / 100, ‘.’, 1)), ‘###00‘)
if (Type == ‘Meters‘)
var StationlbL = Text(First(Split(station / 1000, ‘.’, 1)), ‘###000‘)
var Stationlb = Concatenate([StationlbL, StationlbR], ‘+‘)
if (IsNegative == 1) Stationlb = ‘-‘ + Stationlb
return Stationlb
Offset (ft) field: get road alignment offset distance (geodetic)
var roads = FeatureSetByName($map, “AllRoutes“)
var nearestFeature = First(Intersects(roads, BufferGeodetic($feature, 10, “meter“)));
//Get the nearest point coordinate in the road alignment
var m_point = PointToCoordinate(nearestFeature, $feature).coordinate
//Get the geodetic distance between point feature and the nearest point coordinate
var offsetGeodeticDis_ft = Round(distanceGeodetic($feature, m_point, ‘feet‘),2) //Return geodetic distance
return offsetGeodeticDis_ft
RouteID field: get the route identifier field value of linear referenced feature
//Get the routes layer
var roads = FeatureSetByName($map, “AllRoutes“)
//Find the nearest route feature
var nearestFeature = First(Intersects(roads, BufferGeodetic($feature, 10, “meter“)));
//Return Route ID
return nearestFeature.RouteID
Measure (miles): Get measure m-value in miles
//Get the routes layer
var roads = FeatureSetByName($map, “AllRoutes“)
//Find the nearest route feature
var nearestFeature = First(Intersects(roads, BufferGeodetic($feature, 10, “meter“)));
// Find the nearest coordinate’s M value of the search point feature to the route
var closestM= Round(PointToCoordinate(nearestFeature, $feature).coordinate.m,4)
// Return measure M-value. It uses miles
return closestM
After constructing the form and including the horizontal alignment in your map, all that’s left is to test and deploy your new stationing and offset solution!
In a related article, learn how you can capture elevation values in Field Maps and compare the elevation from your GNSS receiver to a surface model. Combining stationing and offset with earthwork capture can streamline construction inspection workflows.
Article Discussion: