Разбор геометрии до широты, долгота не работает - PullRequest
0 голосов
/ 08 мая 2018

У меня есть таблица местоположений со значениями широты и долготы.

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. Я использую запрос с использованием приведенного ниже фрагмента.

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 голосов
/ 08 мая 2018

У вас есть значение g.geocode_latitude или g.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
...