Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Server Geography vs DbGeography

I have two GPS Coordinates i wanted to calculate distance between those but the result on SQL server is entirely different from result in c# I googled and found that the both approaches return distance in meters but this difference is driving me crazy.

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();

Response

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

Thanks in advance.

like image 868
Muzammal Hussain Avatar asked May 18 '17 12:05

Muzammal Hussain


People also ask

What is geography in SQL Server?

The geography spatial data type, geography, is implemented as a .NET common language runtime (CLR) data type in SQL Server. This type represents data in a round-earth coordinate system. The SQL Server geography data type stores ellipsoidal (round-earth) data, such as GPS latitude and longitude coordinates.

What is the geography spatial data type?

The geography spatial data type, geography, is implemented as a .NET common language runtime (CLR) data type in SQL Server. This type represents data in a round-earth coordinate system.

What is the difference between geography and geometry data type?

The geography type is a little bit more restrictive than geometry. It can't cross different hemispheres and the outer ring must be drawn counter-clockwise. The rest can be found in Geography data type vs. Geometry data type in SQL Server.

What is spatial types in SQL Server?

Spatial Types - geography. The geography spatial data type, geography, is implemented as a .NET common language runtime (CLR) data type in SQL Server. This type represents data in a round-earth coordinate system. The SQL Server geography data type stores ellipsoidal (round-earth) data, such as GPS latitude and longitude coordinates.


Video Answer


3 Answers

Check latitude and longitude order in the WKT representation of the point in SQL when defining the point, they are as follow 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

But when defining DBGeography in C# code, the order is different:"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

Also you should check those locations inserted in the Users table. Make sure when inserting they have been correctly inserted. Otherwise they will be somewhere else not the location of your Users

More:

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

What is WKT and where does it come from? It's a Well-Known Text representation of different geometry types that is introduce by OGC in the Simple Feature Access specification and all software vendors are advised to follow it in the sake of the compatibility. This specification shows us how to define point, line (linestring), polygon and some other geometry types as text (WKT) and binary (WKB).

SQL Server do not completely follow this specification and we see the result of not following standards, causes such problems in different components of even the same company.

like image 95
Hossein Narimani Rad Avatar answered Oct 12 '22 22:10

Hossein Narimani Rad


Switch the Lat/Lng in in API Version. In the API, it should go Lng Lat

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

Returns

7142.94965953253

This is where I flipped one Lat/Lng usinq my UDF

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

Returns

4135883.9028193
like image 37
John Cappelletti Avatar answered Oct 12 '22 22:10

John Cappelletti


The issue is very minor but tricky

SQL SERVER Query

geography::Point(25.3132666, 55.2994054 ,4326)

SQL Server defines a point such that first value is latitude and second value is longitude.

Web API

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

C# defines a point from above format in such a way that first value is longitude and second value is latitude

like image 2
Muzammal Hussain Avatar answered Oct 12 '22 20:10

Muzammal Hussain