如你所指出的,如果S是起点,E是终点,X是检测点,那么你的方法就会失败:
确定在LINESTRING http://img10.imageshack.us/imgg10/4937/gmap.png上的另外两个组织之间
使用这种方法,点 X在S点和E点之间将产生错误的结果,因为它通过测试1和测试你的算法2:e。 点 点 X处于界线,从X到S和从X到E的距离都小于从S到E的距离。
www.un.org/Depts/DGACM/index_spanish.htm 一项可能的解决方案
您可以“探索”您的直线路线,形成两点,即:
LINESTRING(-122.360 47.656, -122.343 47.656, -122.310 47.690, -122.310 47.670)
(a) 将下列内容细分为:
LINESTRING(-122.360 47.656, -122.343 47.656)
LINESTRING(-122.343 47.656, -122.310 47.690)
LINESTRING(-122.310 47.690, -122.310 47.670)
然后,如果使用<代码>ST-Intersections,你就可以通过上述各行各部分进行试验。 当某一点穿过这一试验时,你将能够确定这是否属于起点和终点。
如果可能的话,我建议把你的开端/端点作为指数,放在你直线的道路上,而不是一个原始地理点。 首先,这将更容易解决这一问题,但除此以外,你将消除数据重复,因为如果你不能有一个不是线性内容的开端/端点,数据也会得到保证。 其不利之处在于,你无法在一线部分的中间点开端/端点,但必须站在一条路上。 现在,你必须确定这一限制是否在你的申请中可以接受。
如果你选择上述代表,我们就可以通过下列休养职能解决这一问题:@path
是代表公路的线体,@start_point
和@end_
。 系以下两个点的指数:@path
(第一个指数为1),@test_point
是将测试的地理点。 试验点可以位于 lie的任何地方。
CREATE FUNCTION [dbo].[func_PointBetween](@path geography,
@start_point int,
@end_point int,
@test_point geography)
RETURNS tinyint
AS
BEGIN
DECLARE @result tinyint = 0;
DECLARE @num_points int = @path.STNumPoints();
DECLARE @line_segment geography;
IF (@start_point < @end_point) AND (@end_point < @num_points)
BEGIN
/* Generate the line segment from the current start point
to the following point (@start_point + 1). */
SET @line_segment = geography::STLineFromText( LINESTRING( +
CAST(@path.STPointN(@start_point).Long AS varchar(32))+ +
CAST(@path.STPointN(@start_point).Lat AS varchar(32)) + , +
CAST(@path.STPointN(@start_point + 1).Long AS varchar(32))+ +
CAST(@path.STPointN(@start_point + 1).Lat AS varchar(32)) + ) ,
4326);
/* Add a buffer of 25m to @test_point. This is optional, but
recommended, otherwise it will be very difficult to get a
point exactly on the line. The buffer value may be tweaked
as necessary for your application. */
IF @test_point.STBuffer(25).STIntersects(@line_segment) = 1
BEGIN
/* The test point is on one of the line segments between
@start_point and @end_point. Return 1 and stop the
recursion. */
SET @result = 1;
END
ELSE
BEGIN
/* The test point is not between the @start_point and
@start_point + 1. Increment @start_point by 1 and
continue recursively. */
SET @result = [dbo].[func_PointBetween](@path,
@start_point + 1,
@end_point,
@test_point);
END
END
ELSE
BEGIN
/* There are no further points. The test point is not between the
@start_point and @end_point. Return 0 and stop the recursion. */
SET @result = 0;
END
RETURN @result;
END
为了测试上述职能,我正在界定上述地图所示的六点线。 然后,我们界定了两个测试点:@test_point_a
,确切地说,位于第三点和第四点之间;@test_point_b
,后者偏离了这条道路。
DECLARE @road geography;
DECLARE @test_point_a geography;
DECLARE @test_point_b geography;
SET @road = geography::STGeomFromText( LINESTRING(-122.360 47.656,
-122.343 47.656,
-122.310 47.690,
-122.310 47.670,
-122.300 47.670,
-122.290 47.660) ,
4326);
/* This point lies between point 3 and point 4 */
SET @test_point_a = geography::STGeomFromText( POINT(-122.310 47.680) , 4326);
/* This point lies outside the path */
SET @test_point_b = geography::STGeomFromText( POINT(-122.310 47.700) , 4326);
/* This returns 1, because the test point is between start and end */
SELECT dbo.func_PointBetween(@road, 2, 5, @test_point_a);
/* This returns 0 because the test point is not between start and end */
SELECT dbo.func_PointBetween(@road, 4, 5, @test_point_a);
/* This returns 0 because the test point lies outside the path */
SELECT dbo.func_PointBetween(@road, 1, 6, @test_point_b);