Ближайшая точка на линии в SQL Server Spatial 2008 R2

В идеальном мире я бы работал на SQL Server 2012 и мог бы использовать функцию .ShortestLineTo() для поиска ближайшей точки на линии к точке другой точки. В настоящее время я могу найти ближайшую линию к моей точке, но теперь мне нужно найти координаты точки, ближайшей к моей рассматриваемой точке.

К сожалению, я застрял на SQL Server 2008 R2, поэтому у меня нет возможности использовать .ShortestLineTo().

Как другие достигают этого в типах пространственной геометрии SQL Server?

Ваше здоровье,

Мэтт


person Matt    schedule 28.01.2014    source источник


Ответы (2)


Поздний ответ, но если он все еще помогает (или кому-то еще), вы сможете сделать следующее с SQL 2008.

DECLARE @point GEOMETRY = GEOMETRY::STPointFromText('POINT(0 0)', 0);
DECLARE @line GEOMETRY = GEOMETRY::STLineFromText('POINT(10 10, 20 20)', 0);

SELECT STIntersection(@point.STBuffer(@point.STDistance(@line)));

По сути, вы вычисляете расстояние между двумя геометриями, используете его в качестве буфера в точке, которая должна привести к соприкосновению геометрий, и берете пересечение (точку) этого.

person Jon Bellamy    schedule 09.03.2014
comment
Кажется, это не работает для меня... мои линии имеют несколько наборов точек. - person Ravendarksky; 03.09.2014

Примечание. @Road — это то же самое, что и geography MULTILINESTRING

<Сильный> SET ИСХОДНЫЙ ROAD СЕГМЕНТ
SET @Road = география :: STMLineFromText ( 'MultiLineString ((-79,907603999999992 +32,851905999999985, -79,907708999999983 32,851751, -79,907879999999992 +32,851555999999995, -79,907889999999981 +32,851542999999992 , -79.90799599999983 32.851461, -79908133999999999999999999999999999999999999999999999999999999999999999999999999999992, -79999999999999999929110999999982 32.85097499999982 32.850974)) ', 4269);

ПОЛУЧИТЬ НАЧАЛЬНУЮ/КОНЕЧНУЮ ТОЧКУ СЕГМЕНТА ДОРОЖКИ ДЛЯ НОВОГО РАСЧЕТА СРЕДНЕЙ ТОЧКИ
SET @x1 = CAST(@Road.STStartPoint().Lat AS decimal(11,6) ))
SET @y1 = CAST(@Road.STStartPoint().Long AS decimal(12,6))
SET @x2 = CAST(@Road.STEndPoint().Lat AS decimal(11,6))
SET @y2 = CAST(@Road.STEndPoint().Long AS decimal(12,6) )

НАЗНАЧИТЬ ШИРОТУ/ДОЛГО СЕРЕДИНУ СЕГМЕНТА ДОРОГИ
SET @MidPointLat = CAST( {(@x1 + @x2) / 2) AS nvarchar(11))
SET @MidPointLon = CAST( {(@y1 + @y2) / 2) AS nvarchar(12))

УСТАНОВИТЬ НАЧАЛЬНЫЙ ЦЕНТРАЛЬНЫЙ ВНЕДОРОЖНИК
УСТАНОВИТЬ @RoadMidPt = geography::STPointFromText('POINT(' + @MidPointLon + ' ' + @MidPointLat + ')', 4269)

РАССЧИТАТЬ БУФЕРНОЕ РАССТОЯНИЕ ОБРАТНО ДО ДОРОГИ ДЛЯ .STIntersection (добавить .02, чтобы обеспечить пересечение)
SET @RoadMidPtBuffer = @RoadMidPt.STBuffer(@RoadMidPt.STDistance(@) Дорога) + .02)

Может пересекаться в нескольких точках! Использовать 1-ю точку пересечения дороги как центр тяжести
SET @RoadCentroid = @RoadMidPtBuffer.STIntersection(@Road).STPointN(1);

ПОСЛЕДНИЕ НОВЫЕ ШИРОТА/ДОЛГОТА БЛИЖАЙШЕЙ ДОРОГИ/ЦЕНТРАЛЬНОЙ ЛИНИИ
ВЫБЕРИТЕ @RoadCentroid.Lat, @RoadCentroid.Long

person Bryon    schedule 10.09.2014