2013-01-18 50 views
7

द्वारा सबसे छोटी दूरी मेरे पास डेटाबेस है और इसमें मेरे पास जीपीएस निर्देशांक के साथ कक्षा होटल है। मैं जो निर्देश चुनता हूं उसके समन्वय के लिए निकटतम स्थान प्राप्त करना चाहता हूं।सी # - LINQ - जीपीएस अक्षांश और देशांतर

मुझे लगता है कि यह इस तरह दिखना चाहिए (मैं कई उदाहरण कोड यहां पाया और इस तरह):

var coord = new GeoCoordinate(latitude, longitude); 
var nearest = (from h in db.hotels 
       let geo = new GeoCoordinate(h.gps.lat, h.gps.lng) 
       orderby geo.GetDistanceTo(coord) 
       select h).Take(10); 
समस्या

मैं यह त्रुटि है वह यह है कि जब मैं किसी चीज़ की खोज करने की कोशिश की:

केवल parameterless निर्माणकर्ता और initializers संस्थाओं को LINQ में समर्थित हैं

मैं इसे एक गूगल करने की कोशिश की डी मैंने पाया कि उस लिनक को दो में विभाजित करने से मेरी मदद मिल सकती है लेकिन मुझे यकीन नहीं है कि कैसे। मदद के लिए धन्यवाद।

+0

कि वर्तमान में गणित करने के लिए कोशिश कर रहा है * के इस कार्यान्वयन का उपयोग * सफलता के बारे में एक उचित पड़ा है। मुझे संदेह है कि बहुत सारे काम किए बिना काम नहीं करेगा। आप शायद एक संग्रहित proc या एक यूडीएफ चाहते हैं। –

उत्तर

6

आप पैरामिट्रीकृत निर्माता के बजाय ऑब्जेक्ट प्रारंभकर्ता उपयोग कर सकते हैं:

var nearest = (from h in db.hotels 
      let geo = new GeoCoordinate{ Latitude = h.gps.lat, Longitude = h.gps.lng} 
      orderby geo.GetDistanceTo(coord) 
      select h).Take(10); 

लेकिन आप की संभावना GetDistanceTo विधि की वजह से समस्याओं होगा, आपको लगता है कि विधि के क्रियान्वयन प्रदान कर सकता है?

+0

हाँ, आप सही हैं। आपने पैरामीटर रहित कन्स्ट्रक्टर के साथ अपनी समस्या हल की लेकिन मुझे उस विधि में समस्या है। मैं इसे लागू नहीं कर रहा हूं। यह GeoCoordinate कक्षा द्वारा प्रदान की गई विधि है। जैसा कि मैंने पाया कि मेरे पास लिंकक में केवल कुछ अंकगणितीय परिचालन हैं, इसलिए मुझे उनका उपयोग करना होगा और इसके लिए कुछ एल्गोरिदम मिलेगा, क्या मैं सही हूँ? –

+0

@ बिबो ओह, पता नहीं था कि जियोकोर्डिनेट एक ढांचा वर्ग था। लिंक से इकाइयों को एक एसक्यूएल स्क्रिप्ट का आंतरिक रूप से निर्माण किया जाता है जिसे बाद में डेटाबेस के खिलाफ निष्पादित किया जाएगा, उदाहरण के लिए एक IQueryable पर एक ToList() को कॉल करें, इसलिए आप सही हैं कि SQL डेटा मैनिपुलेशन भाषा की अनुमति देने वाले कुछ संचालन तक सीमित हैं। – TKharaishvili

+0

@Bibo आपको निम्न दो कक्षाएं उपयोगी मिल सकती हैं: http://msdn.microsoft.com/en-us/library/system.data.objects.entityfunctions.aspx http://msdn.microsoft.com/ en-us/library/system.data.objects.sqlclient.sqlfunctions.aspx – TKharaishvili

4

मैं यहां अपना समाधान पोस्ट करता हूं जिसका मैं अभी उपयोग कर रहा हूं। लेकिन मैं GwynnBliedd उत्तर चुनता हूं क्योंकि वह प्रश्न में मेरी समस्या हल करता है।

मैंने अपनी कक्षा में डीबीजीओोग्राफी प्रकार जोड़ा और मैं डेटाबेस में अक्षांश और देशांतर को बचाने के बजाय इसका उपयोग कर रहा हूं।

locationField = DbGeography.FromText(String.Format("POINT({0} {1})", orig.gps.lat.ToString().Replace(",", "."), orig.gps.lng.ToString().Replace(",", "."))); 

तो यह LINQ उपयोग करने के लिए बहुत आसान है:

var coord = DbGeography.FromText(String.Format("POINT({0} {1})", latitude.ToString().Replace(",", "."), longitude.ToString().Replace(",", "."))); 
      var nearest = (from h in db.hotels 
          where h.location != null 
          orderby h.location.Distance(coord) 
          select h).Take(limit); 
      return nearest; 

अब यह काम कर रहा है समाधान के लिए और यह अच्छी बात है। कुछ समय के लिए मैं इसका उपयोग कर रहा हूं लेकिन कुछ उपयोगकर्ताओं ने यहां कहा है कि मैं शायद हाउवरिन फॉर्मूला को लागू करने के साथ यूडीएफ का प्रयास करूंगा (जैसे this answer में)।

+0

+1 - डीबीजीओग्राफी कक्षा के सूचक के लिए धन्यवाद! हालांकि: मुझे लगता है कि आपके पास FromText विधि में रेखांश और अक्षांश तर्कों का क्रम उलट है; देखें: http://stackoverflow.com/questions/16546598/dbgeography-pointfromtext-throws-latitude-values-must-be-between-90-and-90-d –

3

मैं डेटाबेस में Haversine Distance सूत्र

var startPoint = new { Latitude = 1.123, Longitude = 12.3 }; 

var closest = entities.Something.OrderBy(x => 12742 * SqlFunctions.Asin(SqlFunctions.SquareRoot(SqlFunctions.Sin(((SqlFunctions.Pi()/180) * (x.Latitude - startPoint.Latitude))/2) * SqlFunctions.Sin(((SqlFunctions.Pi()/180) * (x.Latitude - startPoint.Latitude))/2) + 
            SqlFunctions.Cos((SqlFunctions.Pi()/180) * startPoint.Latitude) * SqlFunctions.Cos((SqlFunctions.Pi()/180) * (x.Latitude)) * 
            SqlFunctions.Sin(((SqlFunctions.Pi()/180) * (x.Longitude - startPoint.Longitude))/2) * SqlFunctions.Sin(((SqlFunctions.Pi()/180) * (x.Longitude - startPoint.Longitude))/2)))).Take(5);