将几何解析为纬度,经度失败

时间:2018-05-08 13:07:03

标签: sql-server sql-server-2012

我有一张包含纬度和经度值的位置表。

Loc_Nm || geocode_latitude || geocode_longitude
   A   ||    43.43044      ||    -80.0910793
   W   ||    43.9114523    ||    -80.0911329
   X   ||    43.9209011    ||    -80.091323
   Y   ||    43.9083203    ||    -80.0913039
   Z   ||    43.914577     ||    -80.091198

我有一个带有区域名称的几何表(如下所示),它已经从Shapefile转换为ogr2ogr。

Table2 我需要按照表2将Table1位置分组到特定区域。我正在使用下面提到的代码段进行查询。

select * from MyDB.dbo.Spatial_Data s, MyDB.dbo.geocodes_raw g 
where ogr_geometry.STContains(geometry::Parse('POINT(' + CAST(g.geocode_longitude AS VARCHAR(20)) + ' ' + CAST(g.geocode_latitude AS VARCHAR(20)) + ')'))=1;

但是,它失败了以下给定的错误。

Msg 6522, Level 16, State 1, Line 62
A .NET Framework error occurred during execution of user-defined routine or aggregate "geometry": 
System.FormatException: 24141: A number is expected at position 7 of the input. The input has ).
System.FormatException: 
   at Microsoft.SqlServer.Types.WellKnownTextReader.RecognizeDouble()
   at Microsoft.SqlServer.Types.WellKnownTextReader.ParsePointText(Boolean parseParentheses)
   at Microsoft.SqlServer.Types.WellKnownTextReader.ParseTaggedText(OpenGisType type)
   at Microsoft.SqlServer.Types.WellKnownTextReader.Read(OpenGisType type, Int32 srid)
   at Microsoft.SqlServer.Types.SqlGeometry.GeometryFromText(OpenGisType type, SqlChars text, Int32 srid)
   at Microsoft.SqlServer.Types.SqlGeometry.Parse(SqlString s)
.

这里可能有什么问题?

1 个答案:

答案 0 :(得分:0)

您的g.geocode_latitudeg.geocode_longitude值为空或无效作为坐标。

尝试执行以下操作,您将看到它失败并显示相同的错误消息:

SELECT geometry::Parse('POINT(43 )') -- Missing coordinate

要解决,只需过滤实际通知和纠正两个坐标的位置(表达式取决于数据类型)。你可以使用TRY_PARSE来解决这个问题。

要检查错误行,您可以使用以下方法快速检查:

SELECT
    T.*
FROM
    MyDB.dbo.geocodes_raw AS T
WHERE
    TRY_PARSE(T.geocode_longitude AS FLOAT) IS NULL OR
    TRY_PARSE(T.geocode_latitude AS FLOAT) IS NULL

或者使用光标更彻底(但更慢):

IF OBJECT_ID('tempdb..#ErrorGeocodes') IS NOT NULL
    DROP TABLE #ErrorGeocodes

CREATE TABLE #ErrorGeocodes (
    geocode_longitude VARCHAR(200),
    geocode_latitude VARCHAR(200))

DECLARE @c_geocode_longitude VARCHAR(200)
DECLARE @c_geocode_latitude VARCHAR(200)

DECLARE GeocodeCursor CURSOR FOR
    SELECT DISTINCT
        T.geocode_longitude,
        T.geocode_latitude
    FROM
        MyDB.dbo.geocodes_raw AS T

OPEN GeocodeCursor
FETCH NEXT FROM GeocodeCursor INTO @c_geocode_longitude, @c_geocode_latitude

WHILE @@FETCH_STATUS = 0
BEGIN

    BEGIN TRY

        DECLARE @v_GeometryTest GEOMETRY = 
            GEOMETRY::Parse('POINT(' + @c_geocode_longitude + ' ' + @c_geocode_latitude + ')')

    END TRY
    BEGIN CATCH

        INSERT INTO #ErrorGeocodes (
            geocode_latitude,
            geocode_longitude)
        SELECT
            geocode_latitude = @c_geocode_latitude,
            geocode_longitude = @c_geocode_longitude

    END CATCH

    FETCH NEXT FROM GeocodeCursor INTO @c_geocode_longitude, @c_geocode_latitude

END

CLOSE GeocodeCursor
DEALLOCATE GeocodeCursor

SELECT * FROM #ErrorGeocodes