География SQL Server и DbGeography

у меня есть две координаты GPS, которые я хотел рассчитать расстояние между ними, но результат на SQL server полностью отличается от результата в C# я погуглил и обнаружил, что оба подхода возвращают расстояние в метрах, но эта разница сводит меня с ума.

SQL SERVER Query

select geography::Point(25.3132666, 55.2994054 ,4326)
                         .STDistance(geography::Point(25.25434, 55.32820,4326)) as Distance;

Result of above sql query

Web В API

String format = "POINT(25.25434 55.32820)";
                DbGeography myLocation = DbGeography.PointFromText(format, 4326);
                var users = context.Users.Select(u => new
                {
                    fullName = u.name,
                    lat = u.location.Latitude,
                    lng = u.location.Longitude,
                    distance = myLocation.Distance(u.location)
                }).ToList();

ответ

,{"fullName":"jons smith","lat":25.3132666,"lng":55.2994054,"distance":4133581.8647264037}

спасибо заранее.

3 ответов


Проверьте широту и долготу порядок в представлении WKT точки в SQL при определении точки, они следующие GEOGRAPHY::POINT(Latitude, Longitude, srid):

SELECT GEOGRAPHY::Point(25.3132666,55.2994054 ,4326)
                    .STDistance(GEOGRAPHY::Point(25.25434, 55.32820,4326)) as distance;
//distance: 7142.94965953253

но при определении DBGeography в коде C# порядок отличается:"POINT(Longitude Latitude)"

String format = "POINT(55.32820 25.25434)";
DbGeography myLocation = DbGeography.PointFromText(format, 4326);
var users = context.Users.Select(u => new
{
    fullName = u.name,
    lat = u.location.Latitude,
    lng = u.location.Longitude,
    distance = myLocation.Distance(u.location)
}).ToList();

//distance: 7142.949659532529

также вы должны проверить те места, вставленные в Users таблица. Убедитесь, что при вставке они были правильно вставлены. В противном случае они будут где-то еще не расположение Users

больше:

SELECT GEOGRAPHY::Point(25, 55 ,4326).Lat                       //25

DbGeography.PointFromText("POINT(25  55)", 4326).Latitude.Value //55

Microsoft.SqlServer.Types.SqlGeography.STPointFromText(
            new System.Data.SqlTypes.SqlChars("POINT(25 55)"), 4326).Lat.Value;
                                                                //55

что такое WKT и откуда он берется? Это Well -Known Text представление различных типов геометрии, которое вводится OGC в Простой Доступ К Функциям спецификация и все поставщики программного обеспечения советуют следовать ей ради совместимости. Эта спецификация показывает нам, как определить точка, линия (линия), полигон и некоторые другие типы геометрии, как текст (WKT) и двоичный (WKB).

SQL Server не полностью следуют этой спецификации, и мы видим результат несоблюдения стандартов, вызывает такие проблемы в разных компонентах даже одной и той же компании.


переключите Lat / Lng в версии API. В API он должен идти Lng Lat

select geography::Point(25.3132666, 55.2994054 ,4326).STDistance(geography::Point(25.25434, 55.32820,4326))  as Distance

возвращает

7142.94965953253

вот где я перевернул один лат / СПГ usinq мой UDF

Select [dbo].[udf-Geo-Meters](55.2994054,25.3132666  ,25.25434,55.32820)

возвращает

4135883.9028193

проблема очень незначительная, но сложная

SQL SERVER Query

geography::Point(25.3132666, 55.2994054 ,4326)

SQL Server определяет точку таким образом, что первое значение-широта, а второе-долгота.

Web API

String format = "POINT(25.25434 55.32820)";
DbGeography myLocation = DbGeography.FromText(format);

C# определяет точку из формата выше таким образом, что первое значение-долгота, а второе-широта