Другой результат для формул Haversine - PullRequest
1 голос
/ 25 февраля 2012

Я использую mysql для подсчета близости, и для этого я создал одну процедуру с именем distance, которая выглядит следующим образом, но эта процедура не работает должным образом, но оператор sql работает, так что в чем разница здесь, как я думаю, оба Haversine formulas но не дает мне должного результата. я действительно don't know wht i am missing in formula one.

Структура данных моей таблицы выглядит следующим образом

для формулы 1

id  varchar(100)    
userid  varchar(100)    
username varchar(100)
currLoc point           
radius  int(10)

для формулы два

id  varchar(30)
userid  varchar(30)
username varchar(40)
lat float(10,6)
lan float(10,6)
radius  varchar(100)

Формула 1: ссылка

sql statement to execute distance function

SELECT userid, username, distance(userstatus.currLoc, 
 GeomFromText('POINT(23.039574  72.56602)')) AS cdist 
    FROM userstatus HAVING cdist <= 0.6 ORDER BY cdist LIMIT 10


 RETURN 6371 * 2 *
    ASIN( SQRT(POWER(SIN(RADIANS(ABS(X(a)) - ABS(X(b)))), 2) + 
               COS(RADIANS(ABS(X(a)))) * COS(RADIANS(ABS(X(b)))) *
                    POWER(SIN(RADIANS(Y(a) - Y(b))), 2)));

Формула два: ссылка

SELECT *,(((acos(sin((23.039574*pi()/180)) * 

        sin((lat *pi()/180))+cos((23.039574*pi()/180)) * 

         cos((lat *pi()/180)) * cos(((72.56602- lon)*pi()/180))))*

     180/pi())*60*1.1515*1.609344) as distance

FROM status HAVING distance <= 0.6

здесь 0,6 - радиус в километрах

1 Ответ

3 голосов
/ 25 февраля 2012

Одна версия выражения использует ABS (X (a)) и т. Д., А другая - нет. Тот, кто использует ABS, является подозрительным. Вы не можете позволить себе игнорировать знак на углах. Вы получите разные результаты в некоторых регионах мира (например, вблизи экватора или главного меридиана или вблизи полюсов).

Ваши константы тоже разные.

60*1.1515*1.609344

против

6371 * 2

В одном выражении используется SQRT, в другом - нет.

В одном выражении используется ASIN, а в другом - ACOS.

По сути, между ними нет ничего общего ...

См. Обсуждение в Википедии «Формула Хаверсайна» , и, в частности, ссылки на числовую устойчивость при малом расстоянии между точками.

Вы также можете повысить вероятность того, что люди помогут вам, сделав формулы, которые вы используете, получитаемыми, разделив их на строки.

Например:

 RETURN 6371 * 2 *
        ASIN( SQRT(POWER(SIN(RADIANS(ABS(X(a)) - ABS(X(b)))), 2) + 
                   COS(RADIANS(ABS(X(a)))) * COS(RADIANS(ABS(X(b)))) *
                        POWER(SIN(RADIANS(Y(a) - Y(b))), 2)));

И

(((acos(sin((23.039574*pi()/180)) * sin((lat *pi()/180)) +
        cos((23.039574*pi()/180)) * cos((lat *pi()/180)) *
        cos(((72.56602-lan)*pi()/180))
       )
   ) * 180/pi()) * 60 * 1.1515 * 1.609344)

Последнее ссылается на 'lan'; это значит быть "одиноким"? Во втором примере вы, по-видимому, закодировали одну из двух позиций как 23.039574 ° с.ш. и 72.56602 ° з.д., а lat и lan взяты из таблицы в запросе SQL.

...