180 से अधिक होने पर सही देशांतर की गणना करना |


11

मैं एक "सूत्र" विकसित करने की कोशिश कर रहा हूं ताकि लैंग-लैंग मानों को सही किया जा सके।

मैं वाउ-लीफलेट का उपयोग कर रहा हूं लेकिन जब आप "पहली" दुनिया के बाहर पैन करते हैं तो आपको बड़ी संख्या मिलती है। +180 से कम या -180 से कम।

उदाहरण के लिए: जब मैं दाईं ओर (पूर्व दिशा) में अमेरिका जाता हूं, तो मुझे 215 मिल जाती हैं। मेरे दिमाग में, मैं इसे ठीक नहीं करूंगा 215-360=-145

वही तब होता है जब मैं पूर्व रसिया से बाईं ओर (पश्चिम दिशा) में जाता हूं और मुझे उदाहरण -222 मिलता है। अब मुझे गणना करने की आवश्यकता है-222+360=138

हालांकि, चूंकि दुनिया अनिश्चितकालीन है इसलिए उपयोगकर्ता 8 वीं दुनिया में पैन कर सकता है और मुझे मूल्यों को समायोजित करना होगा।

क्या सही देशांतर की गणना करना संभव है? (और एक अन्य आवश्यकता यह है कि जब उपयोगकर्ता पहली दुनिया में है, तब भी 24 lng 24 lng होना चाहिए।

जवाबों:


16

आपको अपने मूल्य में 360 को बार-बार जोड़ने (या घटाने) की आवश्यकता है जब तक कि यह -180 - 180 की सीमा में न हो।

lon = -187;
while(lon < -180){
  lon +=360;
}
while (lon > 180){
  lon -= 360;
}

गलत तरीके से संकेत? पहले मामले में लोन + = 360 होना चाहिए।
9

4
आप इसे केवल एक लूप के साथ कर सकते हैं while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 }मैं इसे एक उत्तर के रूप में प्रदान नहीं कर रहा हूं, क्योंकि आपका संस्करण वास्तव में स्पष्टीकरण से मेल खाता है, जबकि मेरा संस्करण सिर्फ एक अनुकूलन है जो कि संभवत: कोई अंतर नहीं करता है। मैं इसे एक टिप्पणी के रूप में केवल एक अनुस्मारक के रूप में रखता हूं कि चीजों को कई तरीकों से किया जा सकता है, कुछ दूसरों की तुलना में अधिक अनुकूलित।
आंद्रेई

2
मुझे नहीं लगता कि मैं कभी भी इसका उपयोग करूंगा क्योंकि यह प्रति लूप में 2 फ़ंक्शन कॉल का उपयोग करता है और केवल मेरा एक लूप कभी भी निष्पादित करेगा। शायद इस उदाहरण में कोई फर्क नहीं पड़ता, लेकिन है कि मेरी पूर्वाग्रह है
इयान Turton

जब वे कार्यों की तरह दिखते हैं, तो जावास्क्रिप्ट में गणित कार्यों को क्रियात्मक प्रतीकों वाले ऑपरेटरों की तरह अधिक देखा जाना चाहिए। इस अर्थ में हम + - और यहां तक ​​कि <कार्यों को भी देख सकते हैं। संपादित करें: मेरा यहां समाधान था कि यह वास्तव में काम नहीं करता था
आंद्रेई

2
आप नहीं कर सकते lon %= 180?
निधि मोनिका मुकदमा

15

एक जवाब जो सशर्त और फ़ंक्शन कॉल से बचता है:

longitude = (longitude % 360 + 540) % 360 - 180

मैंने https://jsperf.com/longitude-normalisation पर एक त्वरित माइक्रोबेनमार्क लिखा और इनपुट मानों की 'उचित' श्रेणियों के लिए सशर्त कोड तेज़ (मेरी मशीन पर क्रोम में) प्रतीत होता है। सामान्य तौर पर आपको संभवतः इस तरह की छोटी गणनाओं में प्रदर्शन के बारे में पहले से चिंता नहीं करनी चाहिए, अपने बाकी के कोडबेस के साथ पठनीयता और स्थिरता के लिए अधिक वजन देना।

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


1
दिलचस्प। आइए एफपी डिवाइड के खिलाफ सशर्त जेएमपी दौड़ें। हम्मम मुझे आश्चर्य है।
जोशुआ

1
@ जोशुआ आप सशर्त कूद का उपयोग नहीं कर सकते। आपको कई सशर्त कूद , उर्फ ​​लूप का उपयोग करना होगा । (प्लस लूप में फ़्लोटिंग पॉइंट अतिरिक्त होता है, जो मुफ़्त नहीं है।) लूप की कितनी पुनरावृत्तियों की आवश्यकता इनपुट पर निर्भर करती है। इसलिए आपको प्रदर्शन को देखने के लिए डेटा के बारे में कुछ जानना होगा। यदि विशाल बहुमत वांछित सीमा के पास है और कुछ पुनरावृत्तियों की आवश्यकता है, तो निश्चित रूप से, अतिरिक्त लूप तेज हो सकता है, लेकिन यह उतना स्पष्ट नहीं है जितना कि आपके व्यंग्य से पता चलता है।
jpmc26

1
@ jpmc26: इस मामले में, एक से अधिक बार पाश के आसपास जाने की उम्मीद करना मूर्खतापूर्ण है।
जोशुआ

1
कोई व्यंग्य नहीं था। मैं वास्तव में नहीं जानता कि यह किस रास्ते पर पड़ेगा।
जोशुआ

1
@ जोशुआ हां, मुझे यकीन नहीं था :)। मैंने प्रदर्शन पर जवाब देने के लिए और (लूप कोड की एक संभावित विफलता के मामले में) जोड़ा
जो ली-मोयेट

5

एक लाइन:

normalized = remainder(longitude, 360);

स्पष्टीकरण: आप जानना चाहते हैं कि पूर्ण घुमाव (360 °) की अवहेलना करने के बाद क्या रहता है।

इस प्रक्रिया को सामान्यीकरण कहा जाता है।

उदाहरण (cpp.sh)


1
क्या यह परिणाम [0, 360) मान में नहीं, [-180, 180] जैसा कि Shadrix ने अनुरोध किया है?
गाय द हैट

@ THEGuywithTheHat इस उदाहरण को देखें: cpp.sh/7uy2v
आधारित

आह, यह सी + + पता नहीं था। जावास्क्रिप्ट का Shadrix के संदर्भ में, मैं व्याख्या remainderके रूप में modulus। जेएस में मापांक का परिणाम [0, 360) होगा।
द हेट

1
मुझे नहीं लगता कि यह काम करेगा। आपको 360 iff परिणाम> 180 को घटाना होगा। मुझे सिर्फ जावास्क्रिप्ट के साथ एक और समस्या यह है कि modulo 0 भर में सममित है, जैसे -1 % 3-1 है, 2 नहीं जैसा कि यहां काम करने के लिए आवश्यक होगा। remainderएक महान सी ++ समाधान है, लेकिन दुर्भाग्य से जेएस में सिर्फ कोई फ़ंक्शन / ऑपरेटर नहीं है जो उपयोगी होने के लिए समान है।
द हेट के साथ गाय

0

एक अन्य विकल्प: देशांतर = एटैन 2 (कॉस (लंबा), पाप (लंबा))


1
यह एक अच्छा विचार नहीं लगता है। यह समझना बहुत कठिन है, कम्प्यूटेशनल रूप से महंगा और संभावित रूप से गोलाई त्रुटियों के अधीन है।
डेविड रिचेर्बी

0

यदि आप जिस प्रोग्रामिंग भाषा का उपयोग कर रहे हैं, वह फ़्लोटिंग पॉइंट नंबरों (जैसे पायथन और रूबी) पर% (mod) ऑपरेटर का समर्थन करती है, तो मैं उसका उपयोग करने की सलाह दूंगा। अन्यथा, कुछ अन्य भाषाएँ (जैसे C और C ++) आपको fmod () का उपयोग करने की अनुमति देती हैं।

(जो भी मॉड ऑपरेटर आप उपयोग करते हैं, समय से पहले सुनिश्चित करें कि यह फ़्लोटिंग-पॉइंट नंबरों पर मॉड संचालन करेगा, और यह कि यह आपको हमेशा गैर-नकारात्मक उत्तर देगा। अन्यथा आप बाद में बहुत आश्चर्यचकित होंगे। lat / lon पॉइंट सही नहीं हैं।)

इसे इस तरह उपयोग करें:

# Put the longitude in the range of [0,360):
longitude %= 360

# Put the longitude in the range of [-180,180):
if longitude >= 180:
    longitude -= 360

यदि आप इसे एक पंक्ति में करना पसंद करते हैं:

# Put the longitude in the range of [-180,180):
longitude = (longitude + 180) % 360 - 180

इन तरीकों में कोई छोर नहीं है, इसलिए वे बार-बार जोड़ने या घटाने की आवश्यकता के बिना देशांतर मूल्यों को सामान्य करेंगे, चाहे कितनी बार आपका अवलोकन पृथ्वी के चारों ओर घूम गया हो।

संपादित करें:

हम्मम ... मैंने अभी देखा कि जावास्क्रिप्ट %नकारात्मक मूल्यों के साथ नहीं लगता है जैसे मैंने सोचा था कि यह होगा।

उस मामले में, यह एक-लाइनर आज़माएँ:

longitude = (longitude + 36180) % 360 - 180

36180हम जोड़ रहे हैं 36,000 + 180. 36,000 सकारात्मक डोमेन में एक नकारात्मक मूल्य स्थानांतरित करने के लिए है, और 180 से अधिक इतना है कि जब यह द्वारा modded है यह शिफ्ट करने के लिए है 360की सीमा में है, यह हो जाएगा [0360) । - 180भाग बदलाव यह [-180,180) की श्रृंखला के लिए वापस।

यहाँ एक और लाइनर है, एक जो 36,000 पर निर्भर नहीं करता है वह काफी बड़ा है:

longitude = (longitude % 360 + 360 + 180) % 360 - 180

longitude % 360 + 360भाग सकारात्मक डोमेन मूल्य रहता है यह सुनिश्चित करेंगे जब यह बाद में द्वारा modded है 360+ 180भाग बदलाव इस पर इतना है कि जब यह बाद में हो जाता है 180 यह (के साथ से घटाया - 180), यह [-180,180) के वांछित रेंज में हो जाएगा।


1
नोट: C, C ++ fmod(longitude, 360)-> (-360.0 ... +360.0) और ilongitude % 360-> [-359 ... +359]।
chux -

@chux - मुझे इसके बारे में पता नहीं था, इसलिए मैंने अभी इसका परीक्षण किया, और ऐसा प्रतीत होता है कि आप सही हैं। उसे इंगित करने के लिए धन्यवाद।
JL
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.