2017-03-14 9 views
5

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

try { 
       Collection<MarkerItemData> mapMarkers = algorithm.getItems(); 
       JSONObject jsonObject = new JSONObject(strings[0]); 
       JSONArray respondArray = jsonObject.getJSONArray("respond"); 
       list = new ArrayList(); 
       for (int i = 0; i < respondArray.length(); i++) { 
        JSONObject station = respondArray.getJSONObject(i); 
        int id = station.getInt("_id"); 
        boolean skip = false; 
        for (final MarkerItemData m : mapMarkers) { 
         if (m.getId() == id) { 
          skip = true; 
          break; 
         } 
        } 
       } 
      } 

हालांकि मुझे नहीं लगता कि इस दृष्टिकोण सबसे अच्छा है। मैं भी अन्य विचारों कि काम करना चाहिए है (कम से कम मुझे लगता है कि)

  • सर्वर स्क्रीन सीमा को भेजने के लिए और भी सभी मार्कर आईडी के स्क्रीन पर दिख रहे हैं (मैं सभी मार्करों स्क्रीन रेंज और जो आईडी में है चुन सकते हैं स्क्रीन सीमा में नहीं हैं)
  • हर बार Android एप्लिकेशन से मार्कर हटा सकते हैं और मूल रूप से हर बार सर्वर से सभी मार्करों पुन: (निजी तौर पर मुझे लगता है कि यह एक बुरा हल है)

तो उन विचारों का जो सबसे अच्छा कर रहे हैं ? कोई अन्य विचार? (मेरे अंग्रेजी के लिए खेद है)

+0

नक्शा स्थानांतरित होने पर हर बार मार्करों का स्थान प्राप्त करना आवश्यक है? क्या आप बस सभी को और पहले डाउनलोड नहीं कर सकते हैं और मार्कर दिखा सकते हैं? –

+0

@WaqasAhmedAnsari सभी मार्करों को आगे बढ़ाना अक्षम है जब कुल मार्कर गिनती सर्वर पर बड़ी है – BhalchandraSW

उत्तर

2

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

स्थानिक इंडेक्सिंग के लिए बहुत सी विधियां हैं और एक उपयोग मामले के आधार पर दूसरे की तुलना में थोड़ा बेहतर हो सकता है। लंबी कहानी कम करने के लिए, क्योंकि आपको इस परिदृश्य में सीमा पूछने की आवश्यकता है, आपको एक क्वाड्री लागू करना चाहिए। क्वाड्री को पेड़ डेटा संरचना कहा जाता है जिसमें प्रत्येक आंतरिक नोड में चार बच्चे होते हैं (उत्तरपश्चिम, पूर्वोत्तर, दक्षिणपश्चिम, दक्षिणपूर्व)। अगर आपको इस ढांचे के बारे में कोई जानकारी नहीं है, तो मेरा मानना ​​है कि आप एक घंटे में अपनी मूल बातें समझ सकते हैं लेकिन इसे स्क्रैच से विस्तार से समझाते हुए मेरे लिए बहुत अधिक समय का नुकसान होगा। इसलिए, मैं quadtrees के बारे में कार्यान्वयन विवरण छोड़ रहा हूँ। ऐसे कई स्रोत हैं जो पहले से ही इस संरचना को बेहतर तरीके से समझाते हैं, और आप आसानी से ओपन सोर्स लाइब्रेरी पा सकते हैं।

ArrayList<LatLng> queryRange(QuadLevel level, float[] screenBounds, ArrayList<LatLng> prevPoints) { 

    // Initialize a list to hold the found points 
    ArrayList<LatLng> pointsInRange = new ArrayList<>(); 

    if (!quadtreeBounds.intersects(screenBounds)) 
     return pointsInRange; 

    // Find the points that are in the current quad level 
    for (LatLng point : level.getPoints()) { 
     // If the current point is in screen bounds and it is not contained by prevPoints 
     if (point.isInRange(screenBounds) 
      && !prevPoints.contains(point)) 
      pointsInRange.add(point); 
    } 

    // If there are no children, return 
    if (level.hasNoChildren()) 
     return pointsInRange; 

    // Else, continue to look up children 
    pointsInRange.addAll(queryRange(level.northwest, screenBounds, prevPoints)); 
    pointsInRange.addAll(queryRange(level.northeast, screenBounds, prevPoints)); 
    pointsInRange.addAll(queryRange(level.southwest, screenBounds, prevPoints)); 
    pointsInRange.addAll(queryRange(level.southeast, screenBounds, prevPoints)); 

    return pointsInRange; 
} 
1

स्टोर सब देखने योग्य:

मैं केवल सभी बिंदुओं कि लोगों को जो पिछली स्क्रीन में पहले से ही छोड़कर स्क्रीन सीमा की सीमा के भीतर दिखाई देते हैं खोजने के लिए अपने quadtree के लिए छद्म-ish जावा विधि दे देंगे सर्वर

1

HashSet<MarkerOptions> बढ़ाएं, ताकि जब MarkerOptions जोड़ा गया हो, तो आप इसे अपने मानचित्र में जोड़ते हैं, तो सूची में मौजूदा मार्करों पर सूची में स्थानीय मार्करों पर मार्कर या अन्य स्थान पर मार्कर।

class MarkerSet extends HashSet<MarkerOptions> { 
    @Override 
    public boolean add(MarkerOptions markerOptions) { 

     boolean didAdd = super.add(markerOptions); 

     if(didAdd) { 
      mMap.addMarker(markerOptions); 
     } 
     return didAdd; 
    } 
} 

अपने मानचित्र गतिविधि में LatLngBounds ऑब्जेक्ट बनाए रखें।यह LatLngBounds ऑब्जेक्ट उन सीमाओं को संग्रहीत करेगा जिनके लिए आपने पहले ही सर्वर से डेटा का अनुरोध किया है।

जब नक्शा का कैमरा चलता है तो क्या नई सीमाएं वर्तमान में संग्रहीत सीमाओं के भीतर हैं यदि सर्वर का अनुरोध नहीं करते हैं और सीमाएं बढ़ाते हैं तो सर्वर से अनुरोध नहीं करते हैं।

mMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() { 
    @Override 
    public void onCameraMove() { 

     LatLngBounds currentBounds = mMap.getProjection().getVisibleRegion().latLngBounds; 

     if (mBounds == null) { 
      mBounds = currentBounds; 
      // Perform server request and get markers passing in currentBounds 
      // Following to be performed in server request's callback 
      MarkerOptions markerOptions = new MarkerOptions(); 
      // set marker options here 
      mMarkerSet.add(markerOptions); 

     } else { 

      if (!(mBounds.contains(currentBounds.northeast) || mBounds.contains(currentBounds.southwest))) { 
       mBounds = mBounds.including(currentBounds.northeast); 
       mBounds = mBounds.including(currentBounds.southwest); 

       // Perform server request and get markers passing in currentBounds 
       // Following to be performed in server request's callback 
       MarkerOptions markerOptions = new MarkerOptions(); 
       // set marker options here 
       mMarkerSet.add(markerOptions); 
      } 

     } 
    } 
}); 

सुनिश्चित करें कि आप हमेशा currentBounds के लिए सर्वर अनुरोध लागू कर रहे हैं। currentBounds और mBounds ओवरलैपिंग होने पर currentBounds को छोटा करने का प्रबंधन करते समय यह एल्गोरिदम बेहतर किया जा सकता है।

धारणा

कृपया ध्यान दें कि इस धारणा है कि यहाँ जब कैमरा चलता है, currentBounds थोड़ा mBounds से बाहर गिर जाएगी। अन्यथा, नए मार्कर लोड नहीं होते हैं। छवि का जिक्र करते हुए, यदि उपयोगकर्ता दृश्यमान हरे क्षेत्र से नारंगी तक mBounds मूल्य नीले आयताकार होगा, और इसलिए सफेद क्षेत्र को कवर नहीं किया जाएगा। हालांकि, व्यावहारिक रूप से, कैमरे को पूरी तरह से क्षैतिज या लंबवत स्थानांतरित करना आसान नहीं है, इससे अनचाहे क्षेत्र को लोड करने के लिए सर्वर विधि और नए मार्करों का आविष्कार हो जाएगा।

How mBounds will be aggregated?

आशा इस मदद करता है। :)

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