Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq to sql Haversine formula

I have an implementation of the Harversine formula in both c# and an example in TSQL. I'm unsure how is best to implement the formula on the server side so I'm able to use it within a Linq query.

Ideally, I'd just have my local formula linked to the function on the server. Thus avoiding the "no translation to sql" error and having everything nice and seamless.

Obviously any view on the problem is helpful.

I'm aware of the Geography types in SQL2008. However the code base i'm working against already has such a reliance on Linq to SQL I'd expect It's more effort than it's worth!

Thanks

like image 712
Ben Ford Avatar asked Dec 07 '25 13:12

Ben Ford


1 Answers

why not going 100% SQL as it's the best way to make the calculations, and simply get a table already filled up with the distances?

from an existing answer

CREATE FUNCTION dbo.udf_Haversine(@lat1 float, @long1 float, @lat2 float, @long2 float) RETURNS float 
  BEGIN
    DECLARE @dlon float, @dlat float, @rlat1 float, @rlat2 float, @rlong1 float, @rlong2 float, @a float, @c float, @R float, @d float, @DtoR float

    SELECT @DtoR = 0.017453293
    SELECT @R = 3937 --3976

    SELECT 
        @rlat1 = @lat1 * @DtoR,
        @rlong1 = @long1 * @DtoR,
        @rlat2 = @lat2 * @DtoR,
        @rlong2 = @long2 * @DtoR

    SELECT 
        @dlon = @rlong1 - @rlong2,
        @dlat = @rlat1 - @rlat2

    SELECT @a = power(sin(@dlat/2), 2) + cos(@rlat1) * cos(@rlat2) * power(sin(@dlon/2), 2)
    SELECT @c = 2 * atn2(sqrt(@a), sqrt(1-@a))
    SELECT @d = @R * @c

    RETURN @d 
  END

and used like:

var table = from r in db.VenuePostCodes 
            select new {
                lat = r.Latitude,
                lng = r.Longitude,
                name = r.Name,
                distance = db.udf_Haversine(
                                  r.Latitude,r.Longitude,
                                  r.Latitude,r.Longitude2)
            };

but the best is always to have everything on SQL so your hosting server has less to do, simply ad a VIEW to your SQL and call that view, let's imagine:

SELECT 
   latitude, longitude, name, latitude1, longitude2, postcode, 
   udf_Haversine(latitude, longitude, latitude2, longitude2) AS distance 
FROM 
   venuepostcodes
ORDER BY 
   distance

and use LINQ to call that view directly.

like image 141
balexandre Avatar answered Dec 10 '25 01:12

balexandre



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!