25. Referencia Lineal

La referenciación lineal (a veces llamada «segmentación dinámica») es un medio de representar entidades que pueden describirse haciendo referencia a un conjunto base de entidades lineales. Ejemplos comunes de entidades que se modelan usando referenciación lineal son:

  • Activos de carreteras, que se referencian usando millas a lo largo de una red de carreteras

  • Operaciones de mantenimiento de carreteras, que se referencian como ocurriendo a lo largo de una red vial entre un par de medidas de millas.

  • Inventarios acuáticos, donde la presencia de peces se registra como existente entre un par de medidas río arriba.

  • Caracterizaciones hidrológicas («reaches») de arroyos, registradas con una milla de inicio y de fin.

El beneficio de los modelos de referenciación lineal es que las observaciones espaciales dependientes no necesitan ser registradas por separado de las observaciones base, y las actualizaciones a la capa de observación base pueden llevarse a cabo sabiendo que las observaciones dependientes seguirán automáticamente la nueva geometría.

Nota

La convención terminológica de Esri para la referenciación lineal es tener una tabla base de entidades espaciales lineales y una tabla no espacial de «eventos» que incluye una clave foránea de referencia a la entidad espacial y una medida a lo largo de la entidad referenciada. Usaremos el término «tabla de eventos» para referirnos a las tablas no espaciales que construimos.

25.1. Creando referencias lineales

Si tienes una tabla de puntos existente que quieres referenciar a una red lineal, usa la función ST_LineLocatePoint, que toma una línea y un punto, y devuelve la proporción a lo largo de la línea donde se puede encontrar el punto.

-- Simple example of locating a point half-way along a line
SELECT ST_LineLocatePoint('LINESTRING(0 0, 2 2)', 'POINT(1 1)');
-- Answer 0.5

-- What if the point is not on the line? It projects to closest point
SELECT ST_LineLocatePoint('LINESTRING(0 0, 2 2)', 'POINT(0 2)');
-- Answer 0.5

Podemos convertir la tabla nyc_subway_stations en una «tabla de eventos» relativa a las calles usando ST_LineLocatePoint.

-- All the SQL below is in aid of creating the new event table
CREATE TABLE nyc_subway_station_events AS
-- We first need to get a candidate set of maybe-closest
-- streets, ordered by id and distance...
WITH ordered_nearest AS (
SELECT
  ST_GeometryN(streets.geom,1) AS streets_geom,
  streets.gid AS streets_gid,
  subways.geom AS subways_geom,
  subways.gid AS subways_gid,
  ST_Distance(streets.geom, subways.geom) AS distance
FROM nyc_streets streets
  JOIN nyc_subway_stations subways
  ON ST_DWithin(streets.geom, subways.geom, 200)
ORDER BY subways_gid, distance ASC
)
-- We use the 'distinct on' PostgreSQL feature to get the first
-- street (the nearest) for each unique street gid. We can then
-- pass that one street into ST_LineLocatePoint along with
-- its candidate subway station to calculate the measure.
SELECT
  DISTINCT ON (subways_gid)
  subways_gid,
  streets_gid,
  ST_LineLocatePoint(streets_geom, subways_geom) AS measure,
  distance
FROM ordered_nearest;

-- Primary keys are useful for visualization softwares
ALTER TABLE nyc_subway_station_events ADD PRIMARY KEY (subways_gid);

Una vez que tenemos una tabla de eventos, es divertido convertirla nuevamente en una vista espacial, para que podamos visualizar los eventos en relación con los puntos originales de los que se derivaron.

Para ir de una medida a un punto, usamos la función ST_LineInterpolatePoint. Aquí están nuestros ejemplos simples anteriores invertidos:

-- Simple example of locating a point half-way along a line
SELECT ST_AsText(ST_LineInterpolatePoint('LINESTRING(0 0, 2 2)', 0.5));

-- Answer POINT(1 1)

Y podemos unir las tablas nyc_subway_station_events de nuevo a la tabla nyc_streets y usar el atributo measure para generar los puntos de eventos espaciales, sin hacer referencia a la tabla original nyc_subway_stations.

-- New view that turns events back into spatial objects
CREATE OR REPLACE VIEW nyc_subway_stations_lrs AS
SELECT
  events.subways_gid,
  ST_LineInterpolatePoint(ST_GeometryN(streets.geom, 1), events.measure)AS geom,
  events.streets_gid
FROM nyc_subway_station_events events
JOIN nyc_streets streets
ON (streets.gid = events.streets_gid);

Viendo los puntos originales (estrella roja) y los puntos de eventos (círculo azul) con las calles, puedes ver cómo los eventos se ajustan directamente a las líneas de calle más cercanas.

_images/lrs1.jpg

Nota

Un uso sorprendente de las funciones de referenciación lineal no tiene nada que ver con modelos de referenciación lineal. Como se muestra arriba, es posible usar las funciones para ajustar puntos a entidades lineales. Para casos de uso como trayectorias GPS u otras entradas que se espera que hagan referencia a una red lineal, el ajuste es una característica útil a tener disponible.

25.2. Lista de funciones