2012-10-02 7 views
5

मुझे उपयोगकर्ता द्वारा चुने गए किसी विशेष स्थान से n शहरों/कस्बों तक दूरी प्रदर्शित करने में सक्षम होना चाहिए। यह मानचित्र पर क्लिक करने और 100 मील के भीतर सभी गंतव्यों को प्राप्त करने की तरह है, केवल यह कि यह एक नक्शा नहीं बल्कि वेबपृष्ठ पर एक लिंक होगा।डीबी में शहरों और कस्बों के बीच दूरी को कैसे व्यवस्थित करें

मुझे ऐसे समाधान का चयन करने की आवश्यकता है जो एक राज्य के भीतर से दुनिया भर में वैश्विक रूप से संभावित रूप से हो - जिसका मतलब हज़ार से सौ हजार स्थानों से है।

मैं एक रिलेशनल डीबी तालिका में CITY1_ID, CITY2_ID & DISTANCE को संग्रहीत करने के बावजूद, लेकिन मुझे संदेह है कि यह वेब अनुप्रयोग (पंक्तियों के लाखों) के लिए अच्छा होगा।

क्या यह नोएसक्यूएल डेटाबेस या ग्राफ डीबी का उपयोग करके अधिक कुशलता से किया जा सकता है? या आरडीबीएमएस उचित डिजाइन के साथ इस समस्या के लिए पर्याप्त है?

जोड़ा गया: अगर मैं डीबी में स्टोर नहीं करता हूं तो मुझे कुछ कैसे मिलेगा: सैन जोस के 100 मील के भीतर मुझे सभी शहरों में प्राप्त करें?

उत्तर

4

आपको प्रत्येक शहर के लिए city_id, latitude, longitude स्टोर करना चाहिए - फिर रनटाइम इनपुट के आधार पर दूरी की गणना करना चाहिए।

+0

हाँ यह है ...। यद्यपि वह दूसरा "फिर गणना करें" चरण थोड़ा मुश्किल है: डी शहर-शहर की दूरी को स्टोर करना निश्चित रूप से एक बुरा विचार है (हर बार जब आप एक को जोड़ते हैं तो आपको 'एन' गणना /' सम्मिलित करना 'होता है)। डेटाबेस प्रकार (आरडीबीएमएस या नोएसक्यूएल) कोई फर्क नहीं पड़ता। – Rudu

+0

यदि मैं डीबी में स्टोर नहीं करता हूं तो मुझे कुछ कैसे मिलेगा: मुझे सैन जोस के 100 मील के भीतर सभी शहरों में लाएं? –

+0

ग्रेट सर्कल डिस्टेंस फॉर्मूला, या हैवरिन डिस्टेंस के लिए जाँच करें। – Randy

0

इसे स्टोर न करें, इसे रेखांश और अक्षांश के साथ रनटाइम की गणना करें। शहरों के बीच सभी दूरी बचाने के विपरीत, काफी स्केलेबल।

आपके पास अपने सभी शहर के रिकॉर्ड के माध्यम से एक संदर्भ बिंदु (सैन जोस) और लूप है और इसे रनटाइम की गणना करना (कई अभिलेखों के मामले में, क्लाइंट द्वारा यह गणना की गई है, शायद जावास्क्रिप्ट या कुछ के साथ, क्योंकि यदि आपके पास है सर्वर यह करता है, यह जल्द ही अपने टोल खर्च करेगा)।

var R = 6371; // Radius of the earth in km 
var dLat = (lat2-lat1).toRad(); // Javascript functions in radians 
var dLon = (lon2-lon1).toRad(); 
var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
     Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * 
     Math.sin(dLon/2) * Math.sin(dLon/2); 
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
var d = R * c; // Distance in km 

कोड ऊपर से here

नोट आता है:: जावास्क्रिप्ट कुछ इस तरह लग सकता है यह किलोमीटर में है के रूप में मैं डच हूँ और इस प्रकार मीट्रिक प्रणाली

+0

उपर्युक्त प्रश्न जैसा कि मैं अपने स्रोत LongLat की कुछ दूरी के भीतर सभी शहरों को कैसे प्राप्त करूंगा। और इन स्थानों के आधार पर मुझे डीबी से इन शहरों के बारे में कुछ और जानकारी खींचनी होगी। –

+0

@ एजे। ऊपर दिए गए – stealthjong

+0

देखें यदि मेरे पास लाखों रिकॉर्ड हैं तो इसका अर्थ है कि इसे दस लाख बार सर्वर या क्लाइंट के लिए करना है? –

0

मैं कुछ के लिए Neo4J उपयोग कर रहा हूँ का उपयोग कर इसी तरह, यह किसी भी प्रकार के डेटा के लिए वास्तव में अच्छी तरह से स्केल करता है जिसे ग्राफ के रूप में प्रदर्शित किया जा सकता है।

0

आप के रूप में दूसरों का उल्लेख किया है, प्रत्येक प्रविष्टि के लिए अक्षांश/देशांतर coords की दुकान और दूरी की गणना करने के कुछ इसी तरह कार्यावधि में निम्नलिखित है, जो किमी/मील दूरी आउटपुट प्रदान करता है का उपयोग कर सकता है:

function distance($lat1, $lng1, $lat2, $lng2, $miles = true) 
{ 
     $pi80 = M_PI/180; 
     $lat1 *= $pi80; 
     $lng1 *= $pi80; 
     $lat2 *= $pi80; 
     $lng2 *= $pi80; 

     $r = 6372.797; // mean radius of Earth in km 
     $dlat = $lat2 - $lat1; 
     $dlng = $lng2 - $lng1; 
     $a = sin($dlat/2) * sin($dlat/2) + cos($lat1) * cos($lat2) * sin($dlng/2) * sin($dlng/2); 
     $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); 
     $km = $r * $c; 

     return ($miles ? ($km * 0.621371192) : $km); 
} 

संपादित करें : यह त्रिज्या खोज के भीतर n मैचों के लिए उपयुक्त नहीं है। दिए गए त्रिज्या के भीतर कस्बों/शहरों की घनत्व को देखते हुए, एसक्यूएल में दूरी की गणना को तेज़ी से आगे बढ़ाना बेहतर है और आप x किमी/मील के भीतर उन लोगों के साथ मिल सकते हैं।

+0

इसका मतलब एनएक्सएन संयोजनों के लिए रनटाइम पर गणना करें और फिर 100 मील के साथ सभी स्थान चुनें। व्यवहार्य नहीं लगता @ निकर –

+0

बस अपना अपडेट देखा - मैंने पिछले वर्ष में यह सटीक कार्य किया है, लेकिन याद नहीं कर सकता कि हमने इसे अंत में कैसे हासिल किया। जांच करूंगा। – nickhar

+0

हमने वास्तव में एसक्यूएल में कैल्क्स किया क्योंकि यह PHP का उपयोग करने से कहीं अधिक तेज था और त्रिज्या के बजाए एक वर्ग के भीतर (त्रिज्या के भीतर अधिक जटिल है)। यहां एक छद्म समाधान है [लिंक] (http://board.phpbuilder.com/showthread.php?10384415-RESOLVED- ज़िप- कोड- त्रिज्या-etc।) लेकिन हमारे पास एक बेहतर संस्करण था जिसे मैं अभी भी खोज रहा हूं के लिये। – nickhar

0

एक सरल समाधान मैं कई बार इस्तेमाल किया गया है (लेकिन mysql के साथ नहीं) चार मापदंडों latitude1, longitude1, latitude2, longitude2 जो दूरी रिटर्न और फिर बस उस दूरी के खिलाफ सब कुछ परीक्षण के साथ एक उपयोगकर्ता समारोह some_distance_function परिभाषित बनाने है कार्य करें और प्रत्येक आइटम के लिए देखें, चाहे दूरी किसी दिए गए मान से कम या बराबर हो। यदि आपके पास केवल कुछ हज़ार स्थान हैं, तो यह काफी बढ़िया और कुशल है।

यदि आपको लाखों अभिलेखों के विरुद्ध यह क्वेरी चलाने की आवश्यकता है, तो आप देखना चाहते हैं कि जीआईएस (भूगोल सूचना प्रणाली) एक्सटेंशन आपके पसंद के डेटाबेस के लिए उपलब्ध हैं, क्योंकि बेहतर हैं (कम से कम खोज-योग्यता के मामले में) खोज के लिए लगातार डेटा संरचनाओं हालांकि बड़ी संख्या में स्थानों।

संपादित करें: कि Microsoft यह करता है का एक उदाहरण देने के लिए, को देखने के http://technet.microsoft.com/en-us/library/bb964712(v=sql.105).aspx

यह MySQL की तरह दिखता है सामान्य रूप में स्थानिक एक्सटेंशन का समर्थन:

http://dev.mysql.com/doc/refman/5.0/en/gis-introduction.html
http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html

द्वितीय संपादित करें:

ऐसा लगता है कि यह प्रश्न भी सहायक हो सकता है।

Find the distance between two points in MYSQL. (using the Point Datatype)

0

यहाँ एक समाधान RDBMS का उपयोग कर रहा है। दो तालिकाओं

  • CityByLat रखें {अक्षांश, city_id} अक्षांश पर संकुल अनुक्रमणिका और साथ
  • CityByLng {logitude, city_id} देशांतर

जब आप एक निश्चित भीतर शहरों को खोजने की जरूरत पर संकुल अनुक्रमणिका के साथ किसी दिए गए अक्षांश और देशांतर से त्रिज्या आप अक्षांश और देशांतर की एक निश्चित सीमा के भीतर शहरों को प्राप्त करने के लिए दो तालिकाओं पर एक कुशल श्रेणी क्वेरी कर सकते हैं। इसके बाद आप केवल शहरों से वास्तविक दूरी की गणना कर सकते हैं।

2

2 शहरों के बीच की दूरी की गणना करने के बजाय 100 मील के बाध्यकारी बॉक्स की गणना करने के बजाय आपके डेटाबेस में प्लग करने के लिए आपके पास 4 फ्लोट चर हैं - फ्लोट तुलना डेटाबेस में दूरी की गणना से बहुत तेज है। नीचे की ओर आपको कोनों में थोड़ा और दूरी मिलती है।

पीएचपी समारोह फिर बॉक्स

 
function getBoundingBox($lat_degrees,$lon_degrees,$distance_in_miles) 
{ 
     $radius = 3963.1; // of earth in miles 

     // bearings 
     $due_north = 0; 
     $due_south = 180; 
     $due_east = 90; 
     $due_west = 270; 

     // convert latitude and longitude into radians 
     $lat_r = deg2rad($lat_degrees); 
     $lon_r = deg2rad($lon_degrees); 

     // find the northmost, southmost, eastmost and westmost corners $distance_in_miles away 
     // original formula from 
     // http://www.movable-type.co.uk/scripts/latlong.html 

     $northmost = asin(sin($lat_r) * cos($distance_in_miles/$radius) + cos($lat_r) * sin ($distance_in_miles/$radius) * cos($due_north)); 
     $southmost = asin(sin($lat_r) * cos($distance_in_miles/$radius) + cos($lat_r) * sin ($distance_in_miles/$radius) * cos($due_south)); 

     $eastmost = $lon_r + atan2(sin($due_east)*sin($distance_in_miles/$radius)*cos($lat_r),cos($distance_in_miles/$radius)-sin($lat_r)*sin($lat_r)); 
     $westmost = $lon_r + atan2(sin($due_west)*sin($distance_in_miles/$radius)*cos($lat_r),cos($distance_in_miles/$radius)-sin($lat_r)*sin($lat_r)); 

     $northmost = rad2deg($northmost); 
     $southmost = rad2deg($southmost); 
     $eastmost = rad2deg($eastmost); 
     $westmost = rad2deg($westmost); 

     //return 2 points NW corner and SE corner 
     return array($northmost,$westmost,$southmost,$eastmost); 
} 

बाउंडिंग अपने एसक्यूएल गणना करने के लिए

SELECT * FROM table WHERE latitude <= $northmost AND longitude >= $westmost AND latitude >= $southmost AND longitude <= $eastmost

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