25. 线性参照

线性参照(有时称为“动态分段”)是一种表示特征的方法,这些特征可以通过参照一组基础线性特征来描述。使用线性参照建模的常见特征示例包括

  • 公路资产,以沿公路网络的英里数为参照

  • 道路维护作业,以沿道路网络的一对英里测量值之间发生的作业为参照。

  • 水生资源清单,其中鱼类存在记录为在一段上游里程测量值之间存在。

  • 河流的水文特征(“河段”),以起始里程和终止里程记录。

线性参照模型的优点是,依赖的空间观测不需要与基础观测分开记录,并且可以对基础观测层进行更新,知道依赖观测将自动跟踪新的几何形状。

注意

Esri 的线性参照术语约定是,有一个线性空间特征的基础表,以及一个非空间的“事件”表,其中包含对空间特征的外键引用以及沿所引用特征的测量值。我们将使用术语“事件表”来指代我们构建的非空间表。

25.1. 创建线性参照

如果您有一个现有的点表,您想将其参照到线性网络,请使用 ST_LineLocatePoint 函数,该函数接受一条线和一个点,并返回该点可以在该线上找到的比例。

-- 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

我们可以使用 ST_LineLocatePointnyc_subway_stations 转换为相对于街道的“事件表”。

-- 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);

一旦我们有了事件表,将其转换回空间视图就很有趣,这样我们就可以可视化事件相对于它们派生自的原始点的相对位置。

要从测量值转换为点,我们使用 ST_LineInterpolatePoint 函数。以下是我们之前简单示例的反向

-- 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)

我们可以将 nyc_subway_station_events 表与 nyc_streets 表连接起来,并使用 measure 属性生成空间事件点,而无需引用原始的 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);

查看原始点(红星)和事件点(蓝圈)以及街道,您可以看到事件是如何直接捕捉到最近的街道线的。

_images/lrs1.jpg

注意

线性参考函数的一个令人惊讶的用途与线性参考模型无关。如上所示,可以使用这些函数将点捕捉到线性要素。对于像 GPS 轨迹或其他预期参考线性网络的输入,捕捉是一个方便的功能。

25.2. 函数列表