मानचित्र पर दो या अधिक बिंदुओं को प्रदर्शित करने के लिए इष्टतम ज़ूम-स्तर की गणना कैसे करें


12

हम स्थैतिक मानचित्र पर कई मार्करों को प्रदर्शित करना चाहते हैं और Google ज़ूम जैसे इष्टतम ज़ूम-स्तर की गणना करना चाहते हैं। हमने पहले से ही बाउंडिंग आयत और नक्शे के केंद्र बिंदु की गणना की है, लेकिन अब हमारे पास पूरे बाउंडिंग आयत को प्रदर्शित करने के लिए सही ज़ूमवेल की गणना करने के लिए एक कठिन समय है। क्या कोई कृपया हमें सही दिशा में इंगित कर सकता है?


यह बहुत परिष्कृत नहीं है, लेकिन एमबीआर को केवल 120% से क्यों न गुणा करें और उस पर ज़ूम करें? कुछ और "इष्टतम" की आपकी परिभाषा पर निर्भर करता है, है ना?
ThomM

+1 से ThomM का विचार। यह वही है जो आर्कगिस करता है।
रागी यासर बुरहूम

1
क्षमा करें, लेकिन यह एमबीआर क्या है?
रॉड्रिगो

जवाबों:


5

ज़ूम स्तर प्राप्त करने के लिए, आपको अपने मानचित्र के पिक्सेल आयामों को जानना होगा। आपको अपने गणित को गोलाकार व्यापारी निर्देशांक में करने की आवश्यकता होगी।

  1. अक्षांश अक्षांश, गोलाकार मेधावी x, y में परिवर्तित करें।
  2. गोलाकार व्यापारी में अपने दो बिंदुओं के बीच दूरी प्राप्त करें।
  3. भूमध्य रेखा लगभग 40 मीटर लंबी अनुमानित है और टाइलें 256 पिक्सेल चौड़ी हैं, इसलिए दिए गए ज़ूम स्तर पर उस नक्शे की पिक्सेल लंबाई लगभग 256 * दूरी / 40000000 * 2 ^ ज़ूम है । जूम = 0, ज़ूम = 1, ज़ूम = 2 आज़माएं जब तक कि आपके मानचित्र के पिक्सेल आयामों के लिए दूरी बहुत लंबी न हो।

1
आशा है कि मैं दूर से समझ गया हूँ कि आप वास्तव में क्या पूछ रहे हैं। = \
मीकल Migurski

इस उत्तर की तलाश में यह प्रश्न मिला, धन्यवाद।
बेंजामिनगोल्डर

@MichalMigurski आप बता सकते हैं कि गोलाकार व्यापारी में 2 बिंदुओं के बीच की दूरी की गणना कैसे करें? विशेष रूप से x निर्देशांक ... मैं धन्यवाद अटक गया हूँ।
otmezger

5

यह C # कोड है जो मैं शंकुधारी में उपयोग करता हूं :

    public void ZoomToArea (Bounds2 mapArea, float paddingFactor)
    {
        double ry1 = Math.Log((Math.Sin(GeometryUtils.Deg2Rad(mapArea.MinY)) + 1) 
            / Math.Cos(GeometryUtils.Deg2Rad(mapArea.MinY)));
        double ry2 = Math.Log((Math.Sin(GeometryUtils.Deg2Rad(mapArea.MaxY)) + 1) 
            / Math.Cos(GeometryUtils.Deg2Rad(mapArea.MaxY)));
        double ryc = (ry1 + ry2) / 2;
        double centerY = GeometryUtils.Rad2Deg(Math.Atan(Math.Sinh(ryc)));

        double resolutionHorizontal = mapArea.DeltaX / Viewport.Width;

        double vy0 = Math.Log(Math.Tan(Math.PI*(0.25 + centerY/360)));
        double vy1 = Math.Log(Math.Tan(Math.PI*(0.25 + mapArea.MaxY/360)));
        double viewHeightHalf = Viewport.Height/2.0f;
        double zoomFactorPowered = viewHeightHalf
            / (40.7436654315252*(vy1 - vy0));
        double resolutionVertical = 360.0 / (zoomFactorPowered * 256);

        double resolution = Math.Max(resolutionHorizontal, resolutionVertical) 
            * paddingFactor;
        double zoom = Math.Log(360 / (resolution * 256), 2);
        double lon = mapArea.Center.X;
        double lat = centerY;

        CenterMapOnPoint(new PointD2(lon, lat), zoom);
    }
  • mapArea: बाउंडिंग बॉक्स लंबे / लम्बे कोर्ड्स में (x = लंबा, y = lat)
  • paddingFactor: इसका उपयोग "120%" प्रभाव प्राप्त करने के लिए किया जा सकता है, जिसका अर्थ है थॉम्स। 1.2 का मान आपको 120% मिलेगा।

ध्यान दें कि मेरे मामले में zoomएक वास्तविक संख्या हो सकती है। वेब मैप्स के मामले में, आपको एक पूर्णांक ज़ूम मान की आवश्यकता होती है, इसलिए आपको (int)Math.Floor(zoom)इसे प्राप्त करने के लिए कुछ का उपयोग करना चाहिए ।

बेशक, यह कोड केवल वेब मर्केटर प्रोजेक्शन पर लागू होता है।


1
इसके लिए धन्यवाद। क्या CenterMapOnPoint के लिए कोड उपलब्ध है?
mcintyre321

उत्तम! मैं OsmDroid एसडीके में बाउंडिंगबॉक्स के ज़ूम की गणना करने के लिए इसका इस्तेमाल किया है और यह काम करता है :)
बिल्ला

मुझे ये लाइब्रेरी कहां से मिलेंगी? मुझे जियोमेट्रीयूटील्स या बाउंड्स 2 अस्मिता नहीं मिल रही है। क्या मुझे maperitive से कुछ डाउनलोड करने की आवश्यकता है? मैं केवल वहां एक ऐप देखता हूं।
डॉवल्स

@ डॉवल्स GeometryUtilsका उपयोग सिर्फ यहाँ डिग्री को रेडियन और बैक में परिवर्तित करने के लिए किया जाता है, यह एक सरल गणित सूत्र है। Bounds2मूल रूप से सिर्फ एक आयत संरचना है। इस कोड को सीधे कॉपी-पेस्ट करने योग्य चीज़ की तुलना में छद्म कोड के रूप में अधिक प्रदान किया गया था।
इगोर ब्रेजक

1
यह भयानक है @ IgorBrejc- बहुत बहुत धन्यवाद! मैंने इसे यहां अजगर में बदल दिया, जब अन्य लोग अजगर कोड लिख रहे हैं: gist.github.com/mpingvermont/d534539fa3ebe4a1e242644e528bf7b9
चार्ली हॉफमैन

1

यदि आप OpenLayers का उपयोग कर रहे हैं तो Map.getZoomForExtentउच्चतम ज़ूम स्तर की गणना करेगा जो मानचित्र पर संपूर्ण सीमा को फिट कर सकता है। extentजरूरतों को नक्शे के प्रक्षेपण में किया जाना है। आप fill_factorमानचित्र के किनारे पर अंक प्रदर्शित करने से बचने के लिए, और max_zoomसंभावित ज़ूम को सीमित करने के लिए भी उपयोग कर सकते हैं :

extent = extent.scale(1/fill_ratio);
var zoom = Math.min(map.getZoomForExtent(map_extent), max_zoom);
map.setCenter(extent.getCenterLonLat(), zoom);

इसने मेरे मुद्दे को ठीक नहीं किया, लेकिन इसने मुझे USC के फिटबाउंड विधि को खोजने के लिए प्रेरित किया, जिससे मेरा दिन बच गया।
शमूएलदेव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.