【问题标题】:Find the furthest distance of points找到点的最远距离
【发布时间】:2021-08-20 10:39:30
【问题描述】:

在这种情况下,我有一组 ID 1 和 2 的四个点。我需要找到并选择距离我的设置点最远且 ID 相同的两个点。

该表在此处编写脚本:

ID  name    point                                           id_point
====================================================================
1   DN700   POINT (-550493.96 -1218974.69)                  1
1   DN700   POINT (-550513.92733318976 -1218929.5493905835) 2
1   DN700   POINT (-550490.62291509821 -1218980.7209425652) 3
1   DN700   POINT (-550512.43436134933 -1218933.2777663434) 4
2   DN700   POINT (-550235.5039543492 -1219120.0737476321)  5
2   DN700   POINT (-550278.61165674869 -1219099.6880138929) 6
2   DN700   POINT (-550301.89265282557 -1219088.8117909778) 7
2   DN700   POINT (-550330.76399739366 -1219075.4882849427) 8

对于ID 1,最远的点是id_point 2和3。我将在另一个过程中使用它,我必须定义起点和终点,这在这种情况下,正是第 2 点和第 3 点。

我知道解决方案是使用 STDistance() 函数比较具有相同 ID 的点,然后从结果中选择一个 MAX 值,但我卡在这里。

感谢任何帮助,非常感谢!

这是我在 cmets 中描述的查询示例。 #points_on_lin 是我之前编写的有问题的表格。唯一的区别是点存储为几何:

DECLARE @max_id int, @current_id int = 1;
SET @max_id = (SELECT MAX(ID_point) FROM #points_on_lin)
    WHILE @current_id <= @max_id
        BEGIN
            DECLARE @point1 geometry, @point2 geometry, @ID int, @IDP int;
            SET @point1 = (SELECT points FROM #points_on_lin WHERE ID_point = @current_id)
            SET @point2 = (SELECT points FROM #points_on_lin WHERE ID_point = @current_id + 1)
            SET @ID = (SELECT ID FROM #points_on_linia WHERE ID_point = @current_id)
            SET @name = (SELECT name FROM #points_on_lin WHERE ID_point = @current_id)
            SET @IDP = (SELECT ID_point FROM #points_on_lin WHERE ID_point = @current_id)
                INSERT INTO #points_dist
                    SELECT @ID, @name, @point1.STDistance(@point2), @IDP
            SET @current_ID = @current_ID +1
        END

#points_dist 表的结果在这里:

ID  name    distance            IDP
1   DN700   49.3595888677907    1
1   DN700   56.228317019116     2
1   DN700   52.216799572342     3
1   DN700   334.040699536517    4
2   DN700   47.6849257758674    5
2   DN700   25.696244924673     6
2   DN700   31.7973324390265    7
2   DN700   544.411492523736    8

【问题讨论】:

  • 那么当您尝试实现STDistanceMAX 时,您的尝试是什么?为什么它不起作用?
  • @Larnu 使用这些点,我创建了一个 ID 为 1 的迭代,但仅从一个 id_point 到下一个点。所以我只能回到从一个到另一个的距离。但是,我必须选择最远的点,在这种情况下是 id_point 2 和 3,但是我的距离计算中的最大值是在点 4,这意味着最远的距离是从 3 到 4。当然这是错误的.现在我不知道下一步该做什么。创建从一个点到具有相同 ID 的其他点的迭代,然后为 ID 1 选择最大值?嗯,也许这是正确的方法:/
  • 把你的尝试放在这个问题上。使用edit 功能。
  • @Roman 你能添加你的数据和表格脚本吗?
  • 好的,我已经编辑了我的问题,你可以看看。谢谢。

标签: sql-server tsql spatial


【解决方案1】:

试试这个:

;WITH CTE AS
(
    SELECT ID FROM #points_on_lin GROUP BY ID
)
SELECT CTE.ID, Point1, Point2, Distance FROM CTE
CROSS APPLY
(
    SELECT TOP 1 
        T1.id_point AS Point1, T2.id_point AS Point2, T1.Point.STDistance(T2.Point) AS Distance 
    FROM 
        #points_on_lin T1 join #points_on_lin T2 on T1.ID = T2.ID AND T1.id_point < T2.id_point
    WHERE 
        T1.ID = CTE.ID
    ORDER BY
        Distance DESC   
) A

输出:

ID  Point1  Point2  Distance
1   2       3       56.228317019116
2   5       8       105.177655821281

【讨论】:

  • 这正是我想要的!非常感谢@hsn !!
【解决方案2】:

我这样做了:

create table #MainTable
(
    id int,
    name nvarchar(10),
    point nvarchar(max),    
    id_point int
)

insert into #MainTable
values
        (1 ,'DN700','POINT (-550493.96 -1218974.69)' ,1),
        (1 ,'DN700','POINT (-550513.92733318976 -1218929.5493905835)' ,2),
        (1 ,'DN700','POINT (-550490.62291509821 -1218980.7209425652)' ,3),
        (1 ,'DN700','POINT (-550512.43436134933 -1218933.2777663434)' ,4),
        (2 ,'DN700','POINT (-550235.5039543492 -1219120.0737476321)' ,5),
        (2 ,'DN700','POINT (-550278.61165674869 -1219099.6880138929)' ,6),
        (2 ,'DN700','POINT (-550301.89265282557 -1219088.8117909778)' ,7),
        (2 ,'DN700','POINT (-550330.76399739366 -1219075.4882849427)' ,8)

create table #Result
(
    id int,
    name nvarchar(10),
    distance float,
    id_point int 
)

declare @minId as int=(select min(id) from #MainTable)
declare @maxId as int=(select max(id) from #MainTable)
declare @p1 as int=0
declare @p2 as int=0
DECLARE @point1 geometry, @point2 geometry
declare @Distance as float=0

while @minId<=@maxId
    begin
        set @p1=(select min(id_point) from #MainTable where id=@minId)
        set @p2=(select max(id_point) from #MainTable where id=@minId)
        while @p1<@p2
            begin
                set @point1=(select geometry::STGeomFromText(point,0) from #MainTable where id_point=@p1)
                set @point2=(select geometry::STGeomFromText(point,0) from #MainTable where id_point=@p1+1)
                set @Distance=@point1.STDistance(@point2)
                insert into #Result (id,name,distance,id_point)
                select id,name,@Distance,@p1 from #MainTable where id_point=@p1

                insert into #Result (id,name,distance,id_point)
                select id,name,@Distance,@p1+1 from #MainTable where id_point=@p1+1
                set @p1=@p1+1
            end     
        set @minId=@minId+1
    end

select r1.* 
from #Result r1 
inner join (select id,max(distance)maxDistance
            from #Result
            group by id)r2 on r1.id=r2.id
                                and r1.distance=r2.maxDistance
order by id

drop table #MainTable,#Result

结果如下: Result of code

希望对你有帮助。

【讨论】:

  • 感谢您的回复。第一个 ID 的值是正确的,但第二个是不正确的。正确的 ID_point 是 5 和 8。感谢您的解决方案,但我将在此回答 @hsn!
猜你喜欢
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-16
  • 1970-01-01
相关资源
最近更新 更多