---
name: v.lrs.create
description: Creates a linear reference system.
keywords: [ vector, linear reference system, network ]
---

# v.lrs.create

Creates a linear reference system.

=== "Command line"

    **v.lrs.create**
    **in_lines**=*name*
    **out_lines**=*name*
    [**err**=*name*]
    **points**=*name*
    [**llayer**=*string*]
    [**player**=*string*]
    **lidcol**=*string*
    **pidcol**=*string*
    [**start_mp**=*string*]
    [**start_off**=*string*]
    [**end_mp**=*string*]
    [**end_off**=*string*]
    [**rsdriver**=*string*]
    [**rsdatabase**=*string*]
    **rstable**=*string*
    [**threshold**=*float*]
    [**--overwrite**]
    [**--verbose**]
    [**--quiet**]
    [**--qq**]
    [**--ui**]

    Example:

    ```sh
    v.lrs.create in_lines=name out_lines=name points=name lidcol=string pidcol=string rstable=string
    ```

=== "Python (grass.tools)"

    *grass.tools.Tools.v_lrs_create*(**in_lines**,
        **out_lines**,
        **err**=*None*,
        **points**,
        **llayer**=*"1"*,
        **player**=*"1"*,
        **lidcol**,
        **pidcol**,
        **start_mp**=*"start_mp"*,
        **start_off**=*"start_off"*,
        **end_mp**=*"end_mp"*,
        **end_off**=*"end_off"*,
        **rsdriver**=*"sqlite"*,
        **rsdatabase**=*"$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite/sqlite.db"*,
        **rstable**,
        **threshold**=*1*,
        **overwrite**=*None*,
        **verbose**=*None*,
        **quiet**=*None*,
        **superquiet**=*None*)

    Example:

    ```python
    tools = Tools()
    tools.v_lrs_create(in_lines="name", out_lines="name", points="name", lidcol="string", pidcol="string", rstable="string")
    ```

    This grass.tools API is experimental in version 8.5 and expected to be stable in version 8.6.

=== "Python (grass.script)"

    *grass.script.run_command*("***v.lrs.create***",
        **in_lines**,
        **out_lines**,
        **err**=*None*,
        **points**,
        **llayer**=*"1"*,
        **player**=*"1"*,
        **lidcol**,
        **pidcol**,
        **start_mp**=*"start_mp"*,
        **start_off**=*"start_off"*,
        **end_mp**=*"end_mp"*,
        **end_off**=*"end_off"*,
        **rsdriver**=*"sqlite"*,
        **rsdatabase**=*"$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite/sqlite.db"*,
        **rstable**,
        **threshold**=*1*,
        **overwrite**=*None*,
        **verbose**=*None*,
        **quiet**=*None*,
        **superquiet**=*None*)

    Example:

    ```python
    gs.run_command("v.lrs.create", in_lines="name", out_lines="name", points="name", lidcol="string", pidcol="string", rstable="string")
    ```

## Parameters

=== "Command line"

    **in_lines**=*name* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Input vector map containing lines  
    **out_lines**=*name* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Output vector map where oriented lines are written  
    **err**=*name*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output vector map of errors  
    **points**=*name* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Input vector map containing reference points  
    **llayer**=*string*  
    &nbsp;&nbsp;&nbsp;&nbsp;Layer number or name  
    &nbsp;&nbsp;&nbsp;&nbsp;Line layer  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **player**=*string*  
    &nbsp;&nbsp;&nbsp;&nbsp;Layer number or name  
    &nbsp;&nbsp;&nbsp;&nbsp;Point layer  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **lidcol**=*string* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing line identifiers for lines  
    **pidcol**=*string* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing line identifiers for points  
    **start_mp**=*string*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing milepost position for the beginning of next segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *start_mp*  
    **start_off**=*string*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing offset from milepost for the beginning of next segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *start_off*  
    **end_mp**=*string*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing milepost position for the end of previous segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *end_mp*  
    **end_off**=*string*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing offset from milepost for the end of previous segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *end_off*  
    **rsdriver**=*string*  
    &nbsp;&nbsp;&nbsp;&nbsp;Driver name for reference system table  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *dbf, odbc, ogr, pg, sqlite*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *sqlite*  
    **rsdatabase**=*string*  
    &nbsp;&nbsp;&nbsp;&nbsp;Database name for reference system table  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite/sqlite.db*  
    **rstable**=*string* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of table where the reference system will be written  
    &nbsp;&nbsp;&nbsp;&nbsp;New table is created by this module  
    **threshold**=*float*  
    &nbsp;&nbsp;&nbsp;&nbsp;Maximum distance of point to line allowed  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **--overwrite**  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    **--help**  
    &nbsp;&nbsp;&nbsp;&nbsp;Print usage summary  
    **--verbose**  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    **--quiet**  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    **--qq**  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    **--ui**  
    &nbsp;&nbsp;&nbsp;&nbsp;Force launching GUI dialog

=== "Python (grass.tools)"

    **in_lines** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Input vector map containing lines  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, vector, *name*  
    **out_lines** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output vector map where oriented lines are written  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, vector, *name*  
    **err** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output vector map of errors  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, vector, *name*  
    **points** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Input vector map containing reference points  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, vector, *name*  
    **llayer** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Layer number or name  
    &nbsp;&nbsp;&nbsp;&nbsp;Line layer  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, layer  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **player** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Layer number or name  
    &nbsp;&nbsp;&nbsp;&nbsp;Point layer  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, layer  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **lidcol** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing line identifiers for lines  
    **pidcol** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing line identifiers for points  
    **start_mp** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing milepost position for the beginning of next segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *start_mp*  
    **start_off** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing offset from milepost for the beginning of next segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *start_off*  
    **end_mp** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing milepost position for the end of previous segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *end_mp*  
    **end_off** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing offset from milepost for the end of previous segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *end_off*  
    **rsdriver** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Driver name for reference system table  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *dbf, odbc, ogr, pg, sqlite*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *sqlite*  
    **rsdatabase** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Database name for reference system table  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite/sqlite.db*  
    **rstable** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of table where the reference system will be written  
    &nbsp;&nbsp;&nbsp;&nbsp;New table is created by this module  
    **threshold** : float, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Maximum distance of point to line allowed  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **overwrite** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **verbose** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **quiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **superquiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  

    Returns:

    **result** : grass.tools.support.ToolResult | None  
    If the tool produces text as standard output, a *ToolResult* object will be returned. Otherwise, `None` will be returned.

    Raises:

    *grass.tools.ToolError*: When the tool ended with an error.

=== "Python (grass.script)"

    **in_lines** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Input vector map containing lines  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, vector, *name*  
    **out_lines** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output vector map where oriented lines are written  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, vector, *name*  
    **err** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output vector map of errors  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, vector, *name*  
    **points** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Input vector map containing reference points  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, vector, *name*  
    **llayer** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Layer number or name  
    &nbsp;&nbsp;&nbsp;&nbsp;Line layer  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, layer  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **player** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Layer number or name  
    &nbsp;&nbsp;&nbsp;&nbsp;Point layer  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, layer  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **lidcol** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing line identifiers for lines  
    **pidcol** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing line identifiers for points  
    **start_mp** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing milepost position for the beginning of next segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *start_mp*  
    **start_off** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing offset from milepost for the beginning of next segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *start_off*  
    **end_mp** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing milepost position for the end of previous segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *end_mp*  
    **end_off** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Column containing offset from milepost for the end of previous segment  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *end_off*  
    **rsdriver** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Driver name for reference system table  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *dbf, odbc, ogr, pg, sqlite*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *sqlite*  
    **rsdatabase** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Database name for reference system table  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite/sqlite.db*  
    **rstable** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of table where the reference system will be written  
    &nbsp;&nbsp;&nbsp;&nbsp;New table is created by this module  
    **threshold** : float, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Maximum distance of point to line allowed  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **overwrite** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **verbose** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **quiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **superquiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*

## DESCRIPTION

*v.lrs.create* generates a LRS (Linear Reference System) from vector
line and point data.

It is highly recommended to work with polylines instead of segmented
vector lines. The command *v.build.polylines* creates this map
structure.

## NOTES

The mileposts (point) vector map columns *start_mp*, *start_off*,
*end_mp*, *end_off* must be of 'double precision' type. For milepost
ordering, it is sufficient to enter increasing numbers into the
*start_mp* column indicating the order along the vector line.

The *lidcol* and *pidcol* columns contain the line IDs which relate
mileposts and vector line(s) to each other.

When creating a LRS with this module, any existing *rstable* will be
replaced.

## EXAMPLE

This example is written for the Spearfish dataset.

As first step, bus route data are prepared.

```sh
# break into segments for correct route selection
v.clean roads_net out=busroute_tmp tool=break

# make polyline for easier line selection by coordinate pairs
v.build.polylines busroute_tmp out=busroute_tmp2

# reverse delete: reduce route map to bus route (enter in one line)
v.edit -r busroute_tmp2 tool=delete coords=590273,4927304,\
590346,4927246,590414,4927210,590438,4927096,590468,4926966,\
590491,4926848,590566,4926798,590637,4926753,590701,4926698,\
590830,4926726,590935,4926751,590993,4926830,590972,4926949,\
590948,4927066,590922,4927182,590957,4927251 threshold=5

# vector line needs to be polyline
v.build.polylines busroute_tmp2 out=busroute_tmp3
v.category busroute_tmp3 out=busroute op=add
g.remove -f type=vector name=busroute_tmp,busroute_tmp2,busroute_tmp3
```

The result can be visualized:

```sh
g.region vector=busroute n=n+100 s=s-100 w=w-100 e=e+100
d.mon x0
d.vect roads_net
d.vect busroute col=red width=2
```

The vector map 'busroute' needs have an attribute table which contain an
integer column *lidcol* with value be '22' for this example (bus route):

```sh
v.db.addtable busroute col="lid integer"
v.db.update busroute col=lid value=22
v.db.select busroute
cat|lid
1|22
```

A new point map 'busstops' shall contain mileposts (bus stops) along
this line (use *thresh* to define maximal accepted deviation from this
line):

```sh
# generate points map
echo "590263|4927361
590432|4927120
590505|4926776
590660|4926687
590905|4926742
590972|4926949
591019|4927263" | v.in.ascii out=busstops

d.vect busstops icon=basic/triangle col=blue
d.vect busstops disp=cat lcol=blue
```

The milepost attributes table needs to be created with specific columns:

```sh
v.db.addtable busstops col="lid integer, start_mp double precision, \
            start_off double precision, end_mp double precision, \
            end_off double precision"
v.db.update busstops col=lid value=22
```

Since the digitizing order of v.in.ascii above reflects the bus stop
order along the route, we can simply copy the category number as
milepost order number in column *start_mp*:

```sh
v.db.update busstops col=start_mp qcol=cat
# verify table
v.db.select busstops
cat|lid|start_mp|start_off|end_mp|end_off
1|22|1|||
2|22|2|||
3|22|3|||
4|22|4|||
5|22|5|||
6|22|6|||
7|22|7|||

# visualize with start_mp to check order
d.erase
d.vect roads_net
d.vect busroute col=red width=2
d.vect busstops icon=basic/triangle col=blue
d.vect busstops disp=attr attrcol=start_mp lcol=blue
```

Offsets (*start_off*, *end_off*) can be later used in case the route or
mileposts get modified.

As second step, the linear reference network is created:

```sh
v.lrs.create busroute points=busstops out=route_lrs err=lrs_error \
             lidcol=lid pidcol=lid rstable=route_lrs threshold=50
```

This creates the maps 'route_lrs' containing the LRS and 'lrs_error'
containing the errors if any. The resulting LRS table and map can be
shown:

```sh
# show LRS table
db.select table=route_lrs

d.vect route_lrs col=blue width=2
```

## SEE ALSO

*[v.build.polylines](v.build.polylines.md),
[v.lrs.segment](v.lrs.segment.md), [v.lrs.where](v.lrs.where.md),
[v.lrs.label](v.lrs.label.md)*

*[LRS tutorial](lrs.md),  
[Introducing the Linear Reference System in
GRASS](https://foss4g.asia/2004/Full-Paper_PDF/Introducing-the-Linear-Reference-System-in-GRASS.pdf)*

## AUTHORS

Radim Blazek, ITC-irst/MPA Solutions  
Documentation update (based on above journal article and available
fragments): Markus Neteler

## SOURCE CODE

Available at: [v.lrs.create source code](https://github.com/OSGeo/grass/tree/main/vector/v.lrs/v.lrs.create)
([history](https://github.com/OSGeo/grass/commits/main/vector/v.lrs/v.lrs.create))  
Latest change: Friday May 09 14:33:40 2025 in commit [b356c7e](https://github.com/OSGeo/grass/commit/b356c7e108fcbeca77474c8e83ebec8f1e7b3e4a)
