I have a set of line and polygon object (SqlGeometry type) and a point object (SqlGeometry type). How can we find the the nearest point on each line from the given point object? Are there any API for doing this operation?
views:
462answers:
3I'm not sure if this is possible directly in SQL Server 2008:
http://social.msdn.microsoft.com/Forums/en/sqlspatial/thread/cb094fb8-07ba-4219-8d3d-572874c271b5
The workaround suggested in that thread is:
declare @g geometry = 'LINESTRING(0 0, 10 10)'
declare @h geometry = 'POINT(0 10)'
select @h.STBuffer(@h.STDistance(@g)).STIntersection(@g).ToString()
Otherwise you would have to write a script to read the geometry from your database and use separate spatial libraries.
If you are interested in actually finding the nearest point on the line (otherwise called a node) you can turn each line into a set of points with the same lineid. Then query for the closest and calc the distance.
If instead you are trying to calc the distance from a point to the nearest line - stdistance http://msdn.microsoft.com/en-us/library/bb933808.aspx I guess the problem that the other answer addresses is what to put in your where clause though you could use stdistance to specify a distance above which you don't care such as
Where pointGeom.stdistance(lineGeom) < "distance you care about"
Here a sample presenting possible solution using SqlGeometry and C#, no SQL Server is required:
using System;
using Microsoft.SqlServer.Types;
namespace MySqlGeometryTest
{
class ReportNearestPointTest
{
static void ReportNearestPoint(string wktPoint, string wktGeom)
{
SqlGeometry point = SqlGeometry.Parse(wktPoint);
SqlGeometry geom = SqlGeometry.Parse(wktGeom);
double distance = point.STDistance(geom).Value;
SqlGeometry pointBuffer = point.STBuffer(distance);
SqlGeometry pointResult = pointBuffer.STIntersection(geom);
string wktResult = new string(pointResult.STAsText().Value);
Console.WriteLine(wktResult);
}
static void Main(string[] args)
{
ReportNearestPoint("POINT(10 10)", "MULTIPOINT (80 70, 20 20, 200 170, 140 120)");
ReportNearestPoint("POINT(110 200)", "LINESTRING (90 80, 160 150, 300 150, 340 150, 340 240)");
ReportNearestPoint("POINT(0 0)", "POLYGON((10 20, 10 10, 20 10, 20 20, 10 20))");
ReportNearestPoint("POINT(70 170)", "POLYGON ((110 230, 80 160, 20 160, 20 20, 200 20, 200 160, 140 160, 110 230))");
}
}
}
The program output:
POINT (20 20)
POINT (160 150)
POINT (10 10)
POINT (70 160)