Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NetTopologySuite Distance is returning odd results in .net Core 3

In my .Net Core 3 API, I set a user location like this:

userDetails.Location = new Point(userDetails.latitude, userDetails.longitude)
{
   SRID = 4326
};

and when I try getting users in a given radius

double radiusMeters = userSettings.Radius;
var usersWithinRadius = Context.UserDetails.Where(ud => ud.Location.Distance(userDetails.Location) <= radiusMeters).ToList();

When I set the radius to 75000 meters, for example, with the user Location being (32.600248, 35.1225), it returns a point that's more than 90km distance (31.78562 , 35.115335)

What am I doing wrong?

like image 494
Zion Hai Avatar asked Oct 16 '22 10:10

Zion Hai


1 Answers

it returns a point that's more than 90km distance

Note the arguments you pass in are lat & lon whose units are degree. As a result, the value returned is not a length in Meters. As you might find, the distance between (35.1225, 32.600248) and (35.115335,31.78562) returned by Distance() method is 0.81465950900299355. Basically , it equals:

Math.sqrt((35.1225 -35.115335)*(35.1225 -35.115335) + (32.600248 - 31.78562)*(32.600248 - 31.78562))

If the two points are close enough, you can treat its unit as Arc Degree roughly:

enter image description here

Assuming the earth is a perfect sphere and the Earth Circumference is 40,075.017 km.

According to How Far Is One Degree:

arc length

we can roughly calculate the distance as below:

distance = Circumference * d /360 
    = 40,075.017 km * 0.81465950900299355 / 360 
    = 90.69km

Since the Where() condition 0.81465950900299355 < 75000 is true, you'll get a point that's more than 90km distance.

Note we're assuming the two points are close enough here. In order to calculate the accurate distance, we need transform the (lon,lat) Coordinate to a projection Coordinate Systems before we invoke the Distance() method.

Quoted from Spatial Data -EF Core

This means that if you specify coordinates in terms of longitude and latitude, some client-evaluated values like distance, length, and area will be in degrees, not meters. For more meaningful values, you first need to project the coordinates to another coordinate system using a library like ProjNet4GeoAPI before calculating these values.

like image 177
itminus Avatar answered Nov 15 '22 04:11

itminus