Формула Хаверсина с использованием SQL-сервера для поиска ближайшего места - vb.net

Я хватаю почтовый индекс из формы. Затем я могу преобразовать этот почтовый индекс в lng, lat координаты, поскольку они хранятся в таблице.

SELECT lng, lat from postcodeLngLat WHERE postcode = 'CV1'

У меня есть еще одна таблица, в которой хранятся lng, lat выбора мест.

SELECT v.lat, v.lng, v.name, p.lat, p.lng, p.postcode, 'HAVERSINE' AS distance FROM ************** v, postcodeLngLat p WHERE p.outcode = 'CB6' ORDER BY distance

То, что я пытаюсь сделать, - создать datagrid, который показывает расстояние каждого места от почтового индекса (CV1 в этом случае). Я знаю, что формула Хаверсина должна делать то, что я пытаюсь достичь, но я теряюсь относительно того, где я должен начать включать ее в свой запрос. Я думаю, что формула должна идти туда, куда я положил 'HAVERSINE' в запрос выше.

Любые идеи?

ИЗМЕНИТЬ

SELECT o.outcode AS lead_postcode, v.venue_name, 6371.0E * ( 2.0E *asin(case when 1.0E < (sqrt(square(sin(((RADIANS(CAST(o.lat AS FLOAT)))-(RADIANS(CAST(v.lat AS FLOAT))))/2.0E)) + (cos(RADIANS(CAST(v.lat AS FLOAT))) * cos(RADIANS(CAST(o.lat AS FLOAT))) * square(sin(((RADIANS(CAST(o.lng AS FLOAT)))-(RADIANS(CAST(v.lng AS FLOAT))))/2.0E))))) then 1.0E else (sqrt(square(sin(((RADIANS(CAST(o.lat AS FLOAT)))-(RADIANS(CAST(v.lat AS FLOAT))))/2.0E)) + (cos(RADIANS(CAST(v.lat AS FLOAT))) * cos(RADIANS(CAST(o.lat AS FLOAT))) * square(sin(((RADIANS(CAST(o.lng AS FLOAT)))-(RADIANS(CAST(v.lng AS FLOAT))))/2.0E))))) end )) AS distance FROM ************** v, outcodepostcodes o WHERE o.outcode='CB6' ORDER BY distance

2 ответа

Я думаю, вы бы лучше положили его в UDF и использовали это в своем запросе:

SELECT v.lat, v.lng, v.name, p.lat, p.lng, p.postcode, udf_Haversine(v.lat, v.lng, p.lat, p.lng) AS distance FROM ************** v, postcodeLngLat p WHERE p.outcode = 'CB6' ORDER BY distance
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


В качестве альтернативы вы также можете использовать типы данных географии SQL Server 2008. Если вы в настоящее время храните longitude/latitide как varchar() в БД, вам придется хранить их как тип данных географа, а затем использовать функцию типа STIntersects() для получения расстояния.

licensed under cc by-sa 3.0 with attribution.