2011-02-02 10 views
5

मैं गूगल मैप्स रिवर्स-जियोकोडिंग API से अक्षांश और देशांतर और फिर मैं कुछ इस तरह की जरूरत है:MySQL के साथ हावर्सिन फॉर्मूला का उपयोग करके दूरी को मापने के लिए कैसे?

mysql_query("SELECT users.*, ".mysql_distance_column($lat,$lng)." FROM users ORDER BY DISTANCE"; 

function mysql_distance_column($lat=40 , $lng=-73) { 

    $defaultLatitudeColumn = 'user_lat'; 
    $defaultLongitudeColumn='user_lng'; 
    $defaultColumnName='user_distance'; 
    return "(( 
(3956 * 2 * ASIN(SQRT(POWER(SIN(({$lat} - abs({$defaultLatitudeColumn})) 
* pi()/180/2), 2) + COS({$lat} * pi()/180) 
* COS(abs({$defaultLatitudeColumn}) * pi()/180) 
* POWER(SIN(({$lng} - {$defaultLongitudeColumn}) * pi()/180/2), 2))) 
))) as {$defaultColumnName} "; 

} 

अद्यतन मैं जीई नहीं कर सकते यह काम करने के लिए

delimiter // 
CREATE FUNCTION `GeoDistMiles`(lat1 FLOAT (10,6), lon1 FLOAT (10,6), lat2 FLOAT (10,6), lon2 FLOAT (10,6)) 
RETURNS FLOAT 
DETERMINISTIC 
NO SQL 
BEGIN 
    DECLARE pi, q1, q2, q3 FLOAT (10,6); 
    DECLARE rads FLOAT (10,6) DEFAULT 0; 
    SET pi = PI(); 
    SET lat1 = lat1 * pi/180; 
    SET lon1 = lon1 * pi/180; 
    SET lat2 = lat2 * pi/180; 
    SET lon2 = lon2 * pi/180; 
    SET q1 = COS(lon1-lon2); 
    SET q2 = COS(lat1-lat2); 
    SET q3 = COS(lat1+lat2); 
    SET rads = ACOS(0.5*((1.0+q1)*q2 - (1.0-q1)*q3)); 
    RETURN 3963.346 * rads; 
END 
+1

आपकी गणना कितनी दूर है? क्या वे बंद हैं या बस थोड़ा दूर हैं? – anon

उत्तर

2

यहाँ सूत्र है मैं उपयोग करता हूं। याद रखें कि पृथ्वी एक आदर्श क्षेत्र नहीं है, इसलिए परिणाम कभी भी सही नहीं होंगे।

 
CREATE DEFINER=`root`@`localhost` FUNCTION `GeoDistMiles`(lat1 FLOAT, lon1 FLOAT, lat2 FLOAT, lon2 FLOAT) RETURNS float 
BEGIN 
    DECLARE pi, q1, q2, q3 FLOAT; 
    DECLARE rads FLOAT DEFAULT 0; 
    SET pi = PI(); 
    SET lat1 = lat1 * pi/180; 
    SET lon1 = lon1 * pi/180; 
    SET lat2 = lat2 * pi/180; 
    SET lon2 = lon2 * pi/180; 
    SET q1 = COS(lon1-lon2); 
    SET q2 = COS(lat1-lat2); 
    SET q3 = COS(lat1+lat2); 
    SET rads = ACOS(0.5*((1.0+q1)*q2 - (1.0-q1)*q3)); 
    RETURN 3963.346 * rads; 
END 
+2

ध्यान दें कि एसीओएस उन बिंदुओं के लिए संख्यात्मक रूप से अस्थिर है जो एक साथ हैं। इस समस्या से बचने वाले सूत्र के लिए http://en.wikipedia.org/wiki/Haversine_formula देखें। – btilly

+0

जानना अच्छा है। धन्यवाद! – anon

+1

यह वास्तव में गलत परिणाम देता है! – Neo

1

मुझे लगता है कि आप http://en.wikipedia.org/wiki/Haversine_formula उपयोग करने के लिए कोशिश कर रहे हैं मान।

यह हल्के से परीक्षण किया जाता है, लेकिन मुझे लगता है कि अपने सूत्र होना चाहिए: (। मैं पेट कॉल हटाया)

(ROUND((3956 * 2 * ASIN(SQRT(POWER(SIN(({$lat} - {$defaultLatitudeColumn}) * pi()/180/2), 2) + COS({$lat} * pi()/180) * COS({$defaultLatitudeColumn} * pi()/180) *POWER(SIN(({$lng} - {$defaultLongitudeColumn}) * pi()/180/2), 2))))*{$magicNumber}))/{$magicNumber} 

+0

मैंने इसका इस्तेमाल किया और यह उसी उपयोगकर्ता को 4708.0 मील दूर themselve से दिखाता है। – Neo

+0

@Neo: मैंने इसका परीक्षण किया है, और महसूस किया है कि सूत्र में मेरे संपादन गलत थे। मेरा मानना ​​है कि आपके सूत्र में त्रुटि उस पेट के कारण है जो आप डिफ़ॉल्ट रूप से $ डिफ़ॉल्टता कर रहे थे। नतीजतन दक्षिणी गोलार्ध में स्थानों की तुलना उत्तरी गोलार्द्ध के समकक्ष स्थान से की जा रही थी, जो एक लंबा रास्ता है। मुझे पहली बार गलत होने के लिए खेद है। – btilly

0
SELECT ACOS(COS(RADIANS(lat)) * 
COS(RADIANS(lon)) * COS(RADIANS(34.7405350)) * COS(RADIANS(-92.3245120)) + 
COS(RADIANS(lat)) * SIN(RADIANS(lon)) * COS(RADIANS(34.7405350)) * 
SIN(RADIANS(-92.3245120)) + SIN(RADIANS(lat)) * SIN(RADIANS(34.7405350))) * 
3963.1 AS Distance 
FROM Stores 
WHERE 1 
HAVING Distance <= 50 

यहाँ कैसे मैं PHP में उपयोग है:

// Find rows in Stores within 50 miles of $lat,$lon 
$lat = '34.7405350'; 
$lon = '-92.3245120'; 

$sql = "SELECT Stores.*, ACOS(COS(RADIANS(lat)) * 
COS(RADIANS(lon)) * COS(RADIANS($lat)) * COS(RADIANS($lon)) + 
COS(RADIANS(lat)) * SIN(RADIANS(lon)) * COS(RADIANS($lat)) * 
SIN(RADIANS($lon)) + SIN(RADIANS(lat)) * SIN(RADIANS($lat))) * 
3963.1 AS Distance 
FROM Stores 
WHERE 1 
HAVING Distance <= 50"; 
1

हाय मेरे पास एक साधारण प्रक्रिया है जिसका उपयोग आप अपने काम के लिए कर सकते हैं।

प्रक्रिया बहुत सरल है और दो शहरों के बीच की दूरी की गणना करें। आप इसे अपने तरीके से संशोधित कर सकते हैं।

drop procedure if exists select_lattitude_longitude; 


delimiter // 

create procedure select_lattitude_longitude(In CityName1 varchar(20) , In CityName2 varchar(20)) 

begin 

declare origin_lat float(10,2); 

declare origin_long float(10,2); 

declare dest_lat float(10,2); 

declare dest_long float(10,2); 

if CityName1 Not In (select Name from City_lat_lon) OR CityName2 Not In (select Name from City_lat_lon) then 

select 'The Name Not Exist or Not Valid Please Check the Names given by you' as Message; 


else 

select lattitude into origin_lat from City_lat_lon where Name=CityName1; 

select longitude into origin_long from City_lat_lon where Name=CityName1; 

select lattitude into dest_lat from City_lat_lon where Name=CityName2; 

select longitude into dest_long from City_lat_lon where Name=CityName2; 


select origin_lat as CityName1_lattitude, 
origin_long as CityName1_longitude, 
dest_lat as CityName2_lattitude, 
dest_long as CityName2_longitude; 


SELECT 3956 * 2 * ASIN(SQRT(POWER(SIN((origin_lat - dest_lat) * pi()/180/2), 2) + COS(origin_lat * pi()/180) * COS(dest_lat * pi()/180) * POWER(SIN((origin_long-dest_long) * pi()/180/2), 2))) * 1.609344 as Distance_In_Kms ; 


end if; 

end ; 

// 

delimiter ; 
0
3956 * 2 * ASIN(SQRT(POWER(SIN(($latitude -(cp.latitude)) * pi()/180/2),2) + COS($latitude * pi()/180) * COS(abs(cp.latitude) * pi()/180) * POWER(SIN(($longitude - cp.longitude) * pi()/180/2), 2))) as distance 

रिटर्न मील या किलोमीटर?

संबंधित मुद्दे