English 中文(简体)
确定在LINESTRING(SQL服务器2008年地理)上是否还有两个组织。
原标题:Determine if a POINT is between two other POINTs on a LINESTRING (SQL Server 2008 Geography)

我的数据库有2008年服务器<代码>GEOGRAPHY数据类型,其中载有<代码>LINESTR。 描述了一条可能治愈的公路。

我有另一个表格,其中载有起点和终点,包括<代码>。 GEOGRAPHYPOINT s, on the road. 我需要知道,公路上这两点之间是否有第三点()。

目前,I m测试:

  • the third point is on the line
  • the distance between the new point to the start point and the distance between the new point and the end point are both less than the distance between the start point and end point

而如果路况本身! 是否有办法发挥作用?

最佳回答

如你所指出的,如果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);
问题回答

你们应当能够检查新点和起点与终点之间的分界线之间的距离。 这一距离应评估为零。 如果我有机会进一步调查地理数据类型,我就试图把确切的问话合在一起,但希望这能让大家开始。





相关问题
SQL SubQuery getting particular column

I noticed that there were some threads with similar questions, and I did look through them but did not really get a convincing answer. Here s my question: The subquery below returns a Table with 3 ...

难以执行 REGEXP_SUBSTR

I m 查询Oracle 10g。 我有两张表格(样本数据见下文)。 i m 试图提取一些领域

SQL Query Shortcuts

What are some cool SQL shorthands that you know of? For example, something I learned today is you can specify to group by an index: SELECT col1, col2 FROM table GROUP BY 2 This will group by col2

PHP array callback functions for cleaning output

I have an array of output from a database. I am wondering what the cleanest way to filter the values is example array Array ( [0] => Array ( [title] => title 1 ...

OracleParameter and DBNull.Value

we have a table in an Oracle Database which contains a column with the type Char(3 Byte). Now we use a parameterized sql to select some rows with a DBNull.Value and it doesn t work: OracleCommand ...

Running numbers in SQL

I have a SQL-statement like this: SELECT name FROM users WHERE deleted = 0; How can i create a result set with a running number in the first row? So the result would look like this: 1 Name_1 2 ...

How to get SQL queries for each user where env is production

I’m developing an application dedicated to generate statistical reports, I would like that user after saving their stat report they save sql queries too. To do that I wrote the following module: ...

热门标签