{ "cells": [ { "cell_type": "markdown", "id": "7faf195c", "metadata": {}, "source": [ "# LRS Creation and Compatibility\n", "\n", "This notebook covers creating a new Linear Referencing System from geometries, working with M-enabled geometry formats, and processing various data sources." ] }, { "cell_type": "code", "execution_count": 1, "id": "b9ed9b9d", "metadata": { "execution": { "iopub.execute_input": "2026-05-29T16:43:24.699498Z", "iopub.status.busy": "2026-05-29T16:43:24.699095Z", "iopub.status.idle": "2026-05-29T16:43:25.257796Z", "shell.execute_reply": "2026-05-29T16:43:25.257245Z" } }, "outputs": [], "source": [ "import linref as lr\n", "\n", "# Load roadways dataset with LRS pre-configured\n", "roadways = lr.datasets.load('roadways', set_lrs=True)" ] }, { "cell_type": "markdown", "id": "3f6590be", "metadata": {}, "source": [ "## Saving and Loading M-Enabled Geometry with WKT\n", "\n", "Due to limited support of M-enabled geometries in shapely and geopandas, saving and loading data containing linref's LineStringM geometries is best done using WKT.\n", "\n", "- **Loading Data.** When loading data, you can parse WKT with an M dimension using `df.lr.parse_geom_m_wkt(inplace=True)`. Be sure that the M-enabled geometry column is included in the LRS being used.\n", "\n", "- **Saving Data** When saving data to a text-based format, LineStringM objects will automatically be converted to WKT. When saving data to a database format, you must indicate the type of the M-enabled geometry column using `dtype={'geometry_m': str}`, such as when using pandas' `to_sql` or geopandas' `to_postgis`." ] }, { "cell_type": "markdown", "id": "ba1860b1", "metadata": {}, "source": [ "## Processing Various Data Formats\n", "\n", "Depending on the source, your data may be in a variety of states. Here is some general guidance on how to prepare data given a few case examples:\n", "\n", "### 1. Spatialized linear layer with no existing LRS\n", "\n", "Load the data using geopandas and generate a new LRS on the data using the `df.lr.generate_linear_events` method described below.\n", "\n", "### 2. Spatialized linear or point layer with event begin and end or location measures\n", "\n", "Load the data using geopandas and validate the existing LRS. First, check that all records have valid event information using `df.lr.invalid_events.sum() > 0` or by dropping invalid events with `df.lr.drop_invalid_events()`. Then, for linear events only, confirm that the data is properly chained with no disjoints within any unique route (i.e., dissolving the linear data produces single-part LineStrings) using `df.lr.is_chained`.\n", "\n", "### 3. Spatialized linear layer with M-enabled geometries\n", "\n", "As of version 2.1, shapely provides some basic support of loading M-enabled geometries. Geopandas may require the `use_arrow=True` parameter when loading the data to be able to process these geometries without losing the M dimension. Load the data using geopandas and convert the shapely LineString objects containing M values which have minimal support to the linref LineStringM class using `df['geometry_m'] = lr.ext.parse_geoms_m_shapely(df.geometry)` or similar. Because the M dimension in the loaded geometry column may cause issues with some functionality, you can then remove the M dimension using `df['geometry'] = df.lr.geoms_m_reduced`. Finally, extract the begin and end measures from the processed M-enabled geometries for each event using `df.lr.extract_m_values(inplace=True)`." ] }, { "cell_type": "markdown", "id": "244fb3d5", "metadata": {}, "source": [ "## Generating a Linear Referencing System on Linear Data\n", "\n", "If you have a dataset that contains linear geometries but is not linearly referenced, you can generate a new linear referencing system on that data using the `generate_linear_events` method. This will analyze your dataset, finding chains of contiguous geometries that share the same key column values. It then computes event begin and end measures according to the lengths of the chained geometries, defining each geometry's event boundaries.\n", "\n", "This can be helpful when working with data that doesn't already include a linear referencing system (e.g., OpenStreetMaps roadway network data), enabling LRS-driven data engineering, analysis, and more using linref or another program like QGIS. Other associated data can then be projected to this new LRS, such as point or linear assets like street signs or project boundaries, creating a unified data system.\n", "\n", "The `generate_linear_events` method will typically add a chain column to identify contiguous groups of geometries within each route. This is controlled by the `chain_col` parameter on the LRS, which defines the column name used for chain indices. When a route like `'Main St'` appears in multiple disconnected locations, each contiguous group of geometries gets a unique chain index, ensuring the LRS is not disjointed. If you are certain that this feature is not needed, you can avoid adding the chaining column with the parameter `add_chain=False`." ] }, { "cell_type": "code", "execution_count": 2, "id": "81122fe4", "metadata": { "execution": { "iopub.execute_input": "2026-05-29T16:43:25.259878Z", "iopub.status.busy": "2026-05-29T16:43:25.259462Z", "iopub.status.idle": "2026-05-29T16:43:25.270411Z", "shell.execute_reply": "2026-05-29T16:43:25.269833Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " route beg end\n", "7 I-5 0.0 22283.0\n", "8 I-5 22283.0 45831.0\n", "9 I-5 45831.0 67330.0\n" ] } ], "source": [ "# Generate a linear referencing system based on existing geometries\n", "generated = roadways.lr.generate_linear_events(\n", " scale=5280, # Scales the distances calculated based on the coordinate reference system (e.g., unit conversion)\n", " decimals=0, # Round the computed event measures after scaling is applied\n", " add_chain=False, # Don't add chaining because we already know routes are not disjointed\n", " replace=True # Replaces existing LRS information for the sake of this example\n", ")\n", "print(generated.lr.get_group('I-5')[['route', 'beg', 'end']])" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }