我从某个地方导入~1000个路径到我的postgis数据库到一个线串字段。
(编辑)我的表就像这样
+---------+---------------+------------------+
| id(int) | name(varchar) | path(LINESTRING) |
+---------+---------------+------------------+
| 123 | foo | 000002... |
| 124 | bar | 000002... |
我遇到的问题是每个路径都被分成了块,并且在某些情况下这些块被混淆了。
假设一个在第50和70号点分割的线串:
当我将其迁移到我的数据库中时,它们混合在一起,因此生成的线串可能会像这样结束:
因此产生从50到71的跳跃以及从100到51的另一个
(编辑)当我导入那些分成块的路径时,我认为它们是有序的,但事实是有些是混合的,这使我的一些线串与它们的点有序就像第二个例子一样。
我希望能够重新排序那些(点数)块,所以我想构建一个SQL查询来检测哪些路径有混合点,然后我可以手动(使用openlayers制作的工具)重新排列它们。
最好有一个SQL更新查询来解决这个问题,但我认为检测更容易(我认为有大约5%或更少的路径有错误)
EDIT3 :我认为检测脚本可以检查路径是否包含一对连续的点太远。也许从包含最长段的路径命令路径的SQL会很好。
如何创建一个函数来获取线串中最大段的长度?
这里我举一个例子: 这是它在数据库中的方式
这就是我想要它修复的方式
EDIT4 :就像我在EDIT3上计划的那样,可以编写一个函数来查找线串中两个连续点之间的最长距离,使用ST_NPoints()和{迭代线字符串的点{3}},然后可以进行查询以对具有最长距离的路径进行排序。具有该距离太长的线串极有可能出现所描述的问题。这样我就可以检测到它们并手动修复它们。
检测SQL的结果如下:
|ordered by this|
+---------+---------------+------------------+---------------+
| id(int) | name(varchar) | path(LINESTRING) | msbtcp(int) |
+---------+---------------+------------------+---------------+
| 123 | foo | 000002... | 1000 |
| 124 | bar | 000002... | 800 |
* msbtcp将是函数的结果:max_separation_between_two_consecutive_points(path)
答案 0 :(得分:3)
这听起来有点复杂,但是如果你只是在一个线串中两个连续点之间的最大距离之后:
CREATE OR REPLACE FUNCTION max_distance_in_linestring(line geometry) RETURNS float as $BODY$
DECLARE
i integer;
n integer;
d float;
m float;
BEGIN
d := 0;
n := ST_NPoints(line);
i := 2;
LOOP
EXIT WHEN i >= n;
m := ST_Distance(ST_PointN(line,i-1),ST_PointN(line,i));
-- use for lon,lats:
-- m := ST_Distance(ST_PointN(line,i-1)::geography,ST_PointN(line,i)::geography);
IF m > d THEN
d := m;
END IF;
i := i + 1;
END LOOP;
RETURN d;
END;
$BODY$
LANGUAGE plpgsql;
SELECT max_distance_in_linestring('LINESTRING(0 0, 1 1, 2 2)'::geometry);
SELECT max_distance_in_linestring('LINESTRING(0 0, 4 3, 2 2)'::geometry);
您可能希望将ST_PointN调用重新投射到:: geography以获得以米为单位的距离。
SQL就像这样:
SELECT
name, path
FROM
paths
ORDER BY
max_distance_in_linestring(path) DESC
答案 1 :(得分:0)
您想知道的是段如何链接,因此您需要将每个段的第一个和最后一个点与所有其他段进行比较:
SELECT foo.gid as segment_a, bar.gid as segment_b
FROM
segments AS foo,
(SELECT the_geom, gid FROM segments) AS bar
WHERE
bar.gid != foo.gid AND ( -- avoid same segments
ST_DWithin(
ST_GeometryN(foo.the_geom, ST_NumGeometries(foo.the_geom)) , -- last from foo
ST_GeometryN(bar.the_geom, ST_NumGeometries(bar.the_geom)) , -- last from bar
0.00005 ) OR -- precision, depends of your SRID
ST_DWithin(
ST_GeometryN(foo.the_geom, 1) , -- first from foo (start = 1 index)
ST_GeometryN(bar.the_geom, ST_NumGeometries(bar.the_geom)) , -- last from bar
0.00005 ) OR -- precision, depends of your SRID
ST_DWithin(
ST_GeometryN(foo.the_geom, ST_NumGeometries(foo.the_geom)) , -- last from foo
ST_GeometryN(bar.the_geom, 1) , -- first from bar
0.00005 ) OR -- precision, depends of your SRID
ST_DWithin(
ST_GeometryN(foo.the_geom, 1) , -- first from foo
ST_GeometryN(bar.the_geom, 1) , -- first from bar
0.00005 ) ) -- precision, depends of your SRID
瞧... ...!
您可以将此链接保存在新表中,并使用ST_Union将链接的段加入。