ProConcepts Linear Referencing - Esri/arcgis-pro-sdk GitHub Wiki

The Linear Referencing API concepts cover the capabilities of the Pro SDK for linear referencing and dynamic segmentation.

Language:      C#
Subject:       Geodatabase
Contributor:   ArcGIS Pro SDK Team <[email protected]>
Organization:  Esri, https://www.esri.com
Date:          04/20/2026
ArcGIS Pro:    3.7
Visual Studio: 2026

In this topic

Introduction

Many organizations gather data about linear features like highways, city streets, railroads, rivers, and water and sewer networks. This data is described using x and y coordinates in a two-dimensional coordinate system. This system is suitable for keeping track of features with fixed characteristics. However, a one-dimensional linear referencing system is used to dynamically represent these linear features' characteristics.

The linear referencing system stores data using a relative position along a measured linear feature, and the feature's location is determined using a linear system of measured values instead of x and y coordinates. For example, road construction starts at Mile 15 instead of 30o40'25'' N, 96o22'32'' W.

The ArcGIS.Core.Data.LinearReferencing namespace provides functionality for working with linear referencing datasets, such as accessing routes, measures, and events, building dynamic segmentation, and locating features along routes.

Routes

Routes are linear features in an M-enabled polyline feature class with a unique route identifier field and measure values. These measure values define discrete locations along the linear feature.

The RouteInfo class represents information about a route feature class, such as RouteIDFieldName (a unique route identifier) and the underlying route feature class, which can be accessed from RouteInfo.GetRouteFeatureClass(), as follows:

using (FeatureClass routesFeatureClass = geodatabase.OpenDataset<FeatureClass>("Roads"))
{
    RouteInfo routeInfo = new RouteInfo(routesFeatureClass, "RID");
}

A route feature class can be created using the DDL operation, as shown below.

public void CreateRouteFeatureClass(SchemaBuilder schemaBuilder)
{
    FieldDescription routeIdDescription = FieldDescription.CreateIntegerField("RouteID");
    FieldDescription routeNameDescription = FieldDescription.CreateStringField("RouteName", 100);
    ShapeDescription shapeDescription = new ShapeDescription(
                     GeometryType.Polyline, SpatialReferences.WGS84) { HasM = true, HasZ = false };

    FeatureClassDescription routeFeatureClassDescription = new FeatureClassDescription(
          "Routes", new List<FieldDescription>() { routeIdDescription, routeNameDescription }, shapeDescription);

    // Create an M-enabled polyline feature class.
    schemaBuilder.Create(routeFeatureClassDescription);
    schemaBuilder.Build();
}

Measures

Measures are values stored along a linear feature that represent a location relative to the beginning of the feature or some point along it. They can use any unit of measurement, such as miles, meters, feet, or time. Each route vertex stores a measure value (X, Y, and M value). The measure values (M-values) are independent of the coordinates of a route feature class and can arbitrarily increase, decrease, or remain constant along the linear feature.

Event features can be identified using measurements along the line (route), as shown in the following diagram:

  • A point event at measure 12 along the line
  • A point event 4 units east of measure marker 10 along the line
  • A line event that starts at measure 18 and ends at 26

The Geometry Engine interface provides various measure-related operations, such as check if M-values are numbers, get minimum and maximum M-values, set M-values at a distance, multiply M-values, etc.

Events

An event is a linear or point feature that occurs on or describes a route feature. Events are stored in a route event table, with each row representing an event and its location expressed as measurements along a route feature. For example, a highway event table might include speed limits, road quality/condition, construction zones, and accidents.

A point event represents a discrete location along a route, such as a highway mile marker or an accident location. Similarly, a line event describes a portion of a route, such as construction zones or reduced-speed areas.

The EventInfo class represents information about the event table. The PointEventInfo class describes a measure, offset, and unique route identifier fields. Similarly, the LineEventInfo class holds information about the beginning and end of events in addition to the offset and unique route identifier fields.

using (Table eventsTable = geodatabase.OpenDataset<Table>("Accidents"))
{
    EventInfo eventInfo = new LineEventInfo(eventsTable, "RID", "fromMeasure", "toMeasure");
}

Dynamic Segmentation

Dynamic segmentation is the process of computing the shape (map location) of events stored in an event table along linear features.

Linear features such as highways, railroads, rivers, and pipelines typically have only one set of attributes, but dynamic segmentation provides an intuitive way for multiple attributes to be independently associated with any portion of an existing linear feature. These attributes can be displayed, queried, edited, and analyzed without affecting the underlying linear feature's geometry.

For example, users often have to document various characteristics of roads. Without using linear referencing, this could result in roads being divided into multiple small segments at each point where attribute values like number of lanes, road material, speed, and condition change. Dynamic segmentation enables these scenarios to be handled as linear referencing events along the roads, as illustrated in the figure below:

The result of the dynamic segmentation process is a dynamic feature class between routes and route events, known as the route event source.

Route Event Source

A route event source is a dynamic feature class that stores and manages information about events occurring along routes. Events are typically stored in an event table, which can be treated as a dynamic feature class by computing each row as an individual feature.

The RouteEventSource constructor takes RouteInfo, EventInfo, and RouteEventSourceOptions as parameters to create a dynamic feature class, i.e., RouteEventSource.

RouteEventSourceOptions defines the configuration used to create a RouteEventSource. Advanced dynamic segmentation options such as event locating angles, point events as multipoint features, offset direction, and event locating errors are also available depending on whether you are visualizing point events or line events.

PointEventRouteSourceOptions defines the configuration used to create a RouteEventSource from point events. If an angle type is provided in the PointEventRouteSourceOptions constructor, the LOC_ANGLE column will be added to the RouteEventSource to display the angle of the route where the event is placed.

// The dynamic segmentation process calculates the normal (perpendicular) angle of the route where the event is placed.
RouteEventSourceOptions pointEventSourceOptions = new PointEventSourceOptions(AngleType.Normal) 
{ 
    // Calculates the complement of the normal angle.
    ComplementAngle = true,
    AddErrorField = true
};

If the AddErrorField property is true, the LOC_ERROR column will be added to the RouteEventSource to indicate locating errors encountered during RouteEventSource creation. These errors can also be accessed from RouteEventSource.GetErrors().

Similarly, LineEventRouteSourceOptions defines the configuration used to create a RouteEventSource from line events.

When IsPositiveOffsetOnRight is set to true, a positive offset will be displayed on the right side of the route. To use this property, you must specify the offset field name in the EventInfo object.

public void ViewRoadPavementConditions(Geodatabase geodatabase, string routeFeatureClassName = "Roads", 
               string eventTableName = "Pavements", string routeIdFieldName = "RID", 
               string fromMeasureFieldName = "fromMeasure", string toMeasureFieldName = "toMeasure")
{
    using (FeatureClass routesFeatureClass = geodatabase.OpenDataset<FeatureClass>(routeFeatureClassName))
    using (Table eventsTable = geodatabase.OpenDataset<Table>(eventTableName))
    {
        RouteInfo routeInfo = new RouteInfo(routesFeatureClass, routeIdFieldName);
        EventInfo eventInfo = new LineEventInfo(
                    eventsTable, routeIdFieldName, fromMeasureFieldName, toMeasureFieldName);
        RouteEventSourceOptions routeEventSourceOptions = 
                         new LineEventSourceOptions() { IsPositiveOffsetOnRight = true };

        using (RouteEventSource routeEventSource = 
                     new RouteEventSource(routeInfo, eventInfo, routeEventSourceOptions))
        using (RouteEventSourceDefinition routeEventSourceDefinition = routeEventSource.GetDefinition())
        {
            // Locating errors
            IReadOnlyList<RouteEventSourceError> errors = routeEventSource.GetErrors();

            // Route event source fields
            IReadOnlyList<Field> routeEventSourceFields = routeEventSourceDefinition.GetFields();
        }
    }
}

The RouteEventSourceDefinition represents the metadata for RouteEventSource and inherits from FeatureClassDefinition.

To visualize a route event source in ArcGIS Pro, create a route event source layer (a temporary feature layer using routes and route events) with FeatureLayerCreationParams and add it to the map, as illustrated below.

// Add a route event source layer to ArcGIS Pro.
FeatureLayerCreationParams layerParams = new FeatureLayerCreationParams(routeEventSource)
{
    Name = "PavementConditions"
};

LayerFactory.Instance.CreateLayer<FeatureLayer>(layerParams, MapView.Active.Map);

The shapes of a RouteEventSource cannot be edited because they are generated dynamically by the dynamic segmentation process. Editing event attributes in the RouteEventSource updates the underlying event table.

Route event sources can be created from two different data store types. For example, routes from a file geodatabase and events from an enterprise geodatabase can be used to create a route event source through a dynamic segmentation process.

Locate Features Along Routes

Locating features along routes allows you to determine the route and measure information at locations where input features (point, line, or polygon) intersect the routes. This functionality is useful for finding information such as passenger stops along bus routes, construction zones along highways, manholes along city streets, and so on.

The RouteInfo.LocateFeatures method computes the intersection of input features and routes and writes the route and measure information to a new event table defined by EventTableConfiguration. Feature selection can be used to reduce the number of input features.

The PointEventTableConfiguration describes the configuration for creating an event table to store point events, and the LineEventTableConfiguration defines the configuration for storing line events.

When locating point features along routes, each point feature's route and measure information is computed and written to a point event table.

Similarly, when locating line or polygon features along routes, the feature's start and end measure information is calculated at the intersections between the line or polygon features and the route data and written to a line event table.

public void FindSlowTrafficZonesAlongRoads(Geodatabase geodatabase, string routeFeatureClassName = "Roads", 
                              string eventTableName = "TrafficTime", string routeIdFieldName = "RID", 
                              string fromMeasureFieldName = "fromMeasure", string toMeasureFieldName = "toMeasure")
{
    // Configure an event table
    EventTableConfiguration lineEventTableConfiguration = new LineEventTableConfiguration(
        eventTableName, routeIdFieldName, fromMeasureFieldName, toMeasureFieldName) 
        { 
            KeepAllFields = true, 
            MDirectionOffset = true 
        };

    using (FeatureClass routeFeatureClass = geodatabase.OpenDataset<FeatureClass>(routeFeatureClassName))
    using (FeatureClass slowZonesFeatureClass = geodatabase.OpenDataset<FeatureClass>("SlowZones"))
    {
        RouteInfo routeInfo = new RouteInfo(routeFeatureClass, routeIdFieldName);

        // Create an event table with route and measure information in the geodatabase.
        routeInfo.LocateFeatures(slowZonesFeatureClass, 0.5, lineEventTableConfiguration);        
    }
}
>To successfully locate features, they must fall within a specified tolerance of the routes. For points, the search tolerance specifies a search radius;
>for lines, it specifies a cluster tolerance and does not apply to polygons.
⚠️ **GitHub.com Fallback** ⚠️