इसलिए, फिल के सुझाव का उपयोग करते हुए, मैंने इसे स्थानिक का उपयोग करके बहुत कुछ फिर से लिखा। यह बहुत अच्छा काम किया, आपको बस .NET4.5, EF5+ और sql सर्वर (2008 और ऊपर मुझे विश्वास है) की आवश्यकता है। मैं EF6 + Sql सर्वर 2012 का उपयोग कर रहा हूँ।
सेट-अप
पहला कदम एक Geography
जोड़ना था मेरे डेटाबेस में कॉलम EventListings
तालिका (उस पर राइट क्लिक करें -> डिज़ाइन)। मैंने अपने स्थान का नाम रखा:
इसके बाद, चूंकि मैं डेटाबेस-प्रथम के साथ ईडीएम का उपयोग कर रहा हूं, इसलिए मुझे अपने द्वारा बनाए गए नए क्षेत्र का उपयोग करने के लिए अपने मॉडल को अपडेट करना पड़ा। फिर मुझे भूगोल को डबल में बदलने में सक्षम नहीं होने के बारे में एक त्रुटि प्राप्त हुई, इसलिए मैंने इसे ठीक करने के लिए जो किया वह था इकाई में स्थान संपत्ति का चयन करें, इसके गुणों पर जाएं और इसके प्रकार को डबल से Geography
में बदलें। :
त्रिज्या के भीतर क्वेरी करना और स्थानों के साथ ईवेंट जोड़ना
फिर आपको बस इतना करना है कि अपने निकाय संग्रह को इस तरह से क्वेरी करें:
var events = EventRepository.EventListings
.Where(x => x.Location.Distance(originCoordinates) * 0.00062 <= radiusParam);
दूरी विस्तार विधि वर्तमान वस्तु से उस "अन्य" वस्तु तक की दूरी प्राप्त करती है जिसमें आप गुजरते हैं। यह अन्य वस्तु DbGeography
प्रकार की है . आप बस एक स्थिर विधि कहते हैं और यह इन पिल्लों में से एक बनाता है, फिर बस अपना देशांतर और अक्षांश एक बिंदु के रूप में इसमें फेंक दें:
DBGeography originCoordinates = DBGeography.fromText("Point(" + originLongitude + " " + originLatitude + ")");
ऐसा नहीं है कि मैंने अपना मूल निर्देशांक बनाया है। मैंने एक अलग डेटाबेस डाउनलोड किया जिसमें सभी ज़िप कोड और उनके अक्षांश और देशांतर की सूची थी। मैंने Geography
. प्रकार का एक कॉलम जोड़ा है उस को भी। मैं दिखाऊंगा कि इस उत्तर के अंत में कैसे। फिर मैंने ज़िपकोड तालिका में स्थान फ़ील्ड से DbGeography ऑब्जेक्ट प्राप्त करने के लिए ज़िपकोड संदर्भ की पूछताछ की।
यदि उपयोगकर्ता केवल एक ज़िप कोड की तुलना में अधिक विशिष्ट उत्पत्ति चाहता है, तो मैं Google मानचित्र API (जियोकोड अधिक विशिष्ट होने के लिए) को कॉल करता हूं और एक webservice के माध्यम से उपयोगकर्ताओं के विशिष्ट पते के लिए अक्षांश और देशांतर प्राप्त करता हूं, और एक DBGeography ऑब्जेक्ट बनाता हूं। प्रतिक्रिया में अक्षांश और देशांतर मान।
जब मैं कोई ईवेंट भी बनाता हूं तो मैं Google API का उपयोग करता हूं। मैंने अपनी इकाई को EF में जोड़ने से पहले इस तरह से स्थान चर सेट किया है:
someEventEntity.Location = DBGeography.fromText("Point(" + longitudeFromGoogle+ " " + latitudeFromGoogle + ")");
अन्य टिप्स और ट्रिक्स और समस्या निवारण
मुझे दूरी विस्तार विधि कैसे मिली?
विस्तार विधि प्राप्त करने के लिए Distance
आपको अपने प्रोजेक्ट में एक संदर्भ जोड़ना होगा:System.Data.Entity
ऐसा करने के बाद आपको निम्न का उपयोग करना होगा:using System.Data.Entity.Spatial;
अपनी कक्षा को।
Distance
एक्सटेंशन विधि मीटर के माप की इकाई . के साथ दूरी लौटाती है (मुझे लगता है कि आप इसे बदल सकते हैं, लेकिन यह डिफ़ॉल्ट है)। यहाँ, मेरा त्रिज्या पैरामीटर मीलों में था इसलिए मैंने कनवर्ट करने के लिए कुछ गणित किया।
नोट :एक DBGeography
है System.Data.Spatial
. में क्लास . यह गलत वाला है और यह मेरे लिए काम नहीं करेगा। इंटरनेट पर मुझे मिले बहुत सारे उदाहरणों ने इसका इस्तेमाल किया।
अक्षांश/लंबे समय को भूगोल कॉलम में कैसे बदलें
इसलिए, यदि आप मेरी तरह होते और सभी Latitude
. के साथ एक ज़िपकोड डेटाबेस डाउनलोड करते हैं &Longitude
कॉलम, और फिर महसूस किया कि इसमें भूगोल कॉलम नहीं है... इससे मदद मिल सकती है:
1) अपनी तालिका में स्थान कॉलम जोड़ें। प्रकार को भूगोल पर सेट करें।
2) निम्नलिखित sql निष्पादित करें
UPDATE [ZipCodes]
SET Location = geography::STPointFromText('POINT(' + CAST([Longitude] AS VARCHAR(20)) + ' ' + CAST([Latitude] AS VARCHAR(20)) + ')', 4326)
भूगोल की किसी वस्तु का विवरण कैसे देखें
इसलिए, जब आप कुछ DbGeography आइटम डालने के बाद Sql Server Management Studio में अपनी EventListings तालिका को क्वेरी करते हैं, तो आपको Location
दिखाई देगा कॉलम में हेक्स मान होता है जैसे:0x1234513462346। जब आप यह सुनिश्चित करना चाहते हैं कि सही मान डाले गए हैं तो यह बहुत उपयोगी नहीं है।
वास्तव में इस क्षेत्र के अक्षांश और देशांतर को देखने के लिए आपको इसे इस तरह से पूछना होगा:
SELECT Location.Lat Latitude, Location.Long Longitude
FROM [EventListings]