Sql server TSQL-获取线串上距离点最近的坐标
考虑一个过于简单的例子:点(0)和线串(1-10,110) 直线上距离该点最近的点为1,0 在TSQL中如何确定这一点?我简单但不完全准确的方法是制作一个线串(点-点),并延伸出一个坐标的X坐标,直到两个线串相交 因此:Sql server TSQL-获取线串上距离点最近的坐标,sql-server,tsql,gis,Sql Server,Tsql,Gis,考虑一个过于简单的例子:点(0)和线串(1-10,110) 直线上距离该点最近的点为1,0 在TSQL中如何确定这一点?我简单但不完全准确的方法是制作一个线串(点-点),并延伸出一个坐标的X坐标,直到两个线串相交 因此: 线串(0,0.25 0)(不相交) 线串(0,0.50)(不相交) 线串(0,0.75 0)(不相交) 线串(0,1 0)(交点-因此1 0是距离点最近的点 这种准方法奏效了,但似乎不是实现这一点的最佳/更有效的方法 例如,一个低效之处是我将其移动一个方向(正增量),如果没有匹
另一个可接受的假设是,线串将相当“垂直”于点。我认为您可以通过数学方法而不是使用蛮力迭代算法来实现这一点 有一篇文章描述了这种方法 我将此方法转换为SQL,它返回正确的值(1,0)。您的“平凡”示例实际上有点边缘情况(具有无限斜率的垂直线),因此它看起来很健壮 我还用这个例子测试了源代码:使用(-1,2)(3,0)行的输入和(2,2)处的一个点得到了正确的答案(1.4,0.8) SQL代码(也在SQL FIDLE at中)
谢谢-我想有更优雅的方式来做这件事。我把小提琴转换成了现实世界中的拉特/拉隆——我一定是在转换过程中弄错了什么(漫漫长夜,需要(很多)更多的咖啡:)。这些值似乎不在线段上。(SQLFiddle只输出1行,但在MgmtStudio中有7行)@meisen99I可能无法在接下来的几个小时内看到这一点;不确定为什么SQLFIDLE只输出一行,我注意到昨晚执行多个SELECT语句时也是如此。就点而言,该算法假设直线是无限的,并且提供的点只是该直线上的两个点。可能需要进行测试,以查看最近的点是否为直线的两个端点之一。你能检查返回的点是否在由你的坐标定义的(无限)线上吗?我用它来表示我的字符串
declare@LineString GEOMETRY=GEOMETRY::stgeomefromtext('LineString(-74.7 21.8,-75.7 22.1,-77.8 22.6,-79.4 23.3,-80.4 24.5,-81.5 28,-84 33,-87 36)”,4326)
my将线字符串分成两对(所以-74.7 21.8,-75.7 22.1;然后-75.7 22.1,-77.8 22.6;等等)在你的SQL Fiddler中修复了它。你的深夜和咖啡意味着你在计算“atp_dot_atb”的行中使用了两次“@lat”:set@atp_dot_atb=(@lat-@x1)*(@x2-@x1)+(@lat-@y1)*(@y2-@y1)更新,结果看起来更合理。。。
DECLARE @x int, @y int, @x1 int, @y1 int, @x2 int, @y2 int
DECLARE @atb2 float, @atp_dot_atb float
DECLARE @t float
--SELECT @x=0, @y=0
--SELECT @x1=1, @y1=10, @x2=1, @y2=-10
SELECT @x=2, @y=2
SELECT @x1=-1, @y1=2, @x2=3, @y2=0
SELECT @atb2 = SQUARE(@x2-@x1) + SQUARE(@y2-@y1) -- Basically finding the squared magnitude of a_to_b
SELECT @atp_dot_atb = (@x-@x1)*(@x2-@x1) + (@y-@y1)*(@y2-@y1) -- The dot product of a_to_p and a_to_b
SELECT @t = @atp_dot_atb / @atb2 -- The normalized "distance" from a to your closest point
SELECT @x1 + (@x2-@x1)*@t, @y1 + (@y2-@y1)*@t --Add the distance to A, moving towards B