lrs(1grass)

✨ LRS β€” Toolset for LRS (Linear Referencing System) ✨

okay so this is the lrs(1grass) page from the GRASS User's Manual, and bestie, it's a whole vibe πŸ’… it's a toolset, not a single command, so buckle up πŸŽ€


🌸 DESCRIPTION 🌸

okay so real talk: a Linear Referencing System (LRS) is a system where features (points or segments) get localized by a measure along a linear element. That's it, that's the whole girlboss concept πŸ’–

The LRS can be used to reference events for any network of linear features β€” like roads, railways, rivers, pipelines, electric and telephone lines, water and sewer networks. An event is defined in LRS by a route ID and a measure. A route is a path on the network, usually composed from more features in the input map. And events can be either points or lines (segments). no cap 🫢

LRS is created from input lines and points in vector map. The points β€” MP (mileposts) β€” must have attached attributes specifying line and distance. The distances from the beginning of the linear feature in real world are specified by MP+offset. Typically, MP is in kilometers and offset in meters. iconic fr πŸ“

The implementation of LRS in GRASS has some particularities. buckle up πŸ¦‹

πŸ’« Double referenced system πŸ’«

This feature gives a possibility to continue to use most of old mileposts if only a small part of a linear object in real world has changed. Example time:

--- road (linear feature)
 +   MP (milepost, point, distance from the beginning in km)
Old situation:
+----+----+----+----+----+
0    2    3    4    5    6
New situation (for example a new bypass around the village)
          ?    ?
          +----+
          |    |
          |    |
+----+----+    +----+----+
0    2    3    4    5    6

so the segment between km 3 and 4 is now longer β€” it's now 3 km, not 1 km like in the old version. It would be expensive to change also all MP >= 4, but bestie, we cannot use km 4 twice 😭 It IS possible to use another notation for the new segment: we reference the segment from the kilometer 3, using only offset. like:

      3+1000  3+2000
          +----+
          |    |
          |    |
+----+----+    +----+----+
0    2    3  3+3000 5    6
               4

This way, there is no ambiguity and minimal changes are needed. But the MP 4 is no more the end of segment 3 - 4, it's now the end of segment 3+2000 - 3+3000. This information must be entered to the system, and it is done by optional MP attributes:

  • end_mp β€” end MP
  • end_off β€” end offset

In this case original MP on km 4 will have these attributes:

start_mp:  4
start_off: 0
end_mp:    3
end_off:   3000

Because each MP can keep 2 values (start, end) it is called a 'double' referenced LRS. two moods, one milepost πŸ’…

To avoid potential confusion, MP values are limited to integers only. It would be ambiguous to have for example segments 3.500 - 3.500+200 and 3.600 - 3.600+200. The position 3+650 would fall into 2 segments, correct would be 3.600+50. That means MP must be the beginning of an autonomous segment, and all parts which become longer than before must be referenced from the last not-changed MP. lowkey strict but it's for your own good πŸ™ˆ

The MP start_mp and end_mp columns must be decimal, but v.lrs.create takes only the decimal part, and adds its value to offset and prints a warning. ⚠️

It is highly recommended to work with polylines instead of segmented vector lines. The command v.build.polylines creates this map structure. do it bestie, don't be messy 🌸

πŸ“‹ LRS table structure πŸ“‹

okay here's the whole table layout, one bullet per column because we're keeping every single detail πŸ‘‘

  • rsid β€” integer β€” reference segment ID, unique in the table
  • lcat β€” integer β€” category of the line in the LRS map
  • lid β€” integer β€” route ID (LID)
  • start_map β€” double precision β€” distance measured along the line in LRS map from the beginning of the line to the beginning of the segment (absolute milepost distance)
  • end_map β€” double precision β€” distance measured along the line in LRS map from the beginning of the line to the end of the segment (absolute distance of subsequent milepost)
  • start_mp β€” double precision β€” milepost number assigned to the start of the segment
  • start_off β€” double precision β€” distance from start_mp to the start of the segment measured along the physical object
  • end_mp β€” double precision β€” milepost number assigned to the end of the segment
  • end_off β€” double precision β€” distance from end_mp to end of the segment measured along the physical object
  • end_type β€” integer β€” 1: the same as specified for from_ ; 2: calculated from map along the line from previous MP; 3: defined by user

πŸŽ€ Available commands πŸŽ€

  • v.lrs.create β€” to create a linear referencing system,
  • v.lrs.label β€” to create stationing on the LRS,
  • v.lrs.segment β€” to create points/segments on LRS, and
  • v.lrs.where β€” to find line id and real km+offset for given points in vector map using linear referencing system.

the whole squad honestly 🫢

🧚 Input lines for v.lrs.segment and v.lrs.label 🧚

v.lrs.create joins all connected lines of the same line ID into one line β€” the LRS library and other modules using LRS expect this! (like, they expect it, do not test them 😭)

LR_get_nearest_offset in the LRS library checks duplicate segments only by line_cat and map_offset, not by coordinates in map. noted. periodt. πŸ’…

πŸ’€ Duplicate positions πŸ’€

It can happen that one offset appears on 2 different lines:

------1-------     --------2------
+0.0            +1.0              +2.0

In this case, the module gives error because the position results in 2 points. πŸ’€

It can be also intended, for example a part of the road is shared with another one, but MP are used only for one:

 + road1/km15         + road1/km22
  \                  /
   \ road1/km17     / road1/km20
    +--------------+
   / road2/km52     \ road2/km52
  /                  \
 + road2/km50         + road2/km54

sharing is caring, but the MP are monogamous for this one πŸ₯°


✨ NOTES ✨

Explanations of selected options, coming right up:

  • llayer β€” vector layer in line map (usually 1; see vectorintro for "layer" concept)
  • player β€” vector layer in point map (usually 1; see vectorintro for "layer" concept)
  • rsdriver β€” Driver name for LRS table - DBMI SQL driver (dbf, pg, mysql, sqlite, etc)
  • rsdatabase β€” Database name for LRS table - DBMI SQL database name (e.g., "lrsdb")
  • rstable β€” Name of the LRS table - DBMI SQL table name (e.g., "streamslrs")

πŸ“š SEE ALSO πŸ“š

go read the lore bestie, it's giving academic:

  • R. Blazek, 2004, Introducing the Linear Reference System in GRASS, Bangkok, GRASS User Conf. Proc.
  • R. Blazek, 2005, Introducing the Linear Reference System in GRASS, International Journal of Geoinformatics, Vol. 1(3), pp. 95-100

and the modules you'll actually be typing:

  • v.build.polylines
  • v.lrs.create
  • v.lrs.segment
  • v.lrs.where
  • v.lrs.label

πŸ’– AUTHORS πŸ’–

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

πŸ”₯ SOURCE CODE πŸ”₯

Available at: LRS source code (history)

Accessed: Friday May 08 10:38:24 2026

Main index | Topics index | Keywords index | Graphical index | Full index


and that's the tea β˜• this whole thing is lrs(1grass) from GRASS 8.5.0, the GRASS 8.5.0 Reference Manual, Β© 2003-2026 GRASS Development Team, and we were last touched by the fine folks on Friday May 08 10:38:24 2026. slay, go build yourself a linear referencing system bestie πŸ’…βœ¨πŸŒˆ

πŸ“¦ where this page comes from