5

मैं एंड्रॉइड पर मैपवॉइंट्स के विशाल (100k +) सेट से पथ खींचने में समस्या को हल करने का प्रयास कर रहा हूं। सबसे पहले मैं कहना चाहूंगा, मैंने स्टैक ओवरव्लो के माध्यम से बहुत कुछ खोजा है और मुझे कोई जवाब नहीं मिला है। मेरे कोड की बाधा वास्तव में कैनवास में नहीं आ रही है, लेकिन Projection.toPixels(GeoPoint, Point) या Rect.contains(point.x, point.y) विधि..मैं स्क्रीन पर दिखाई देने वाले बिंदुओं को छोड़ रहा हूं और वर्तमान ज़ूम-स्तर के अनुसार केवल प्रत्येक एनएचटी बिंदु प्रदर्शित करना। जब नक्शा ज़ूम किया जाता है-में मैं यथासंभव सटीक पथ के रूप में प्रदर्शित करना चाहता हूं, इसलिए मैं शून्य (या लगभग शून्य) अंक छोड़ना चाहता हूं, ताकि दृश्य बिंदुओं को ढूंढने पर मुझे संग्रह में प्रत्येक बिंदु के लिए प्रक्षेपण विधि को कॉल करने की आवश्यकता हो। और यही वास्तव में बहुत समय लगता है (सेकंड नहीं, लेकिन मानचित्र पैनिंग तरल पदार्थ नहीं है और मैं इसे एचटीसी वाइल्डफायर पर परीक्षण नहीं कर रहा हूं :))। मैंने गणना किए गए बिंदुओं को कैशिंग करने की कोशिश की, लेकिन चूंकि प्रत्येक मानचित्र पैन/ज़ूम के बाद अंक पुन: गणना किए जाने के बाद से में मदद नहीं मिली है।एंड्रॉइड में मानचित्र दृश्य में 100k + अंक ड्राइंग (फ़िल्टरिंग) ड्राइंग (फ़िल्टरिंग)

मैंने सरणी को फिर से चलाने के बजाय किसी प्रकार के प्रुन और खोज एल्गोरिदम के उपयोग के बारे में सोचा, लेकिन मुझे लगा कि इनपुट डेटा सॉर्ट नहीं किया गया है (मैं दो अदृश्य बिंदुओं के बीच किसी भी शाखा को फेंक नहीं सकता)। मैं शुरुआत में सरल प्रकार के साथ हल कर सकता हूं, लेकिन मुझे अभी भी यकीन नहीं है कि रैखिक के बजाय getProjection() और Rect.contains(point.x, point.y) कॉल की लॉगरिदमिक गिनती भी प्रदर्शन समस्या को हल करेगी।

बोलो मेरा वर्तमान कोड है। अगर आप जानते हैं कि इसे बेहतर कैसे बनाया जाए तो कृपया मेरी मदद करें। आपका बहुत बहुत धन्यवाद!

public void drawPath(MapView mv, Canvas canvas) { 
    displayed = false; 

    tmpPath.reset(); 

    int zoomLevel = mapView.getZoomLevel(); 
    int skippedPoints = (int) Math.pow(2, (Math.max((19 - zoomLevel), 0))); 
    int mPointsSize = mPoints.size(); 
    int mPointsLastIndex = mPointsSize - 1; 
    int stop = mPointsLastIndex - skippedPoints; 

    mapView.getDrawingRect(currentMapBoundsRect); 
    Projection projection = mv.getProjection(); 

    for (int i = 0; i < mPointsSize; i += skippedPoints) { 

     if (i > stop) { 
      break; 
     } 
//HERE IS THE PROBLEM I THINK - THIS METHOD AND THE IF CONDITION BELOW 
     projection.toPixels(mPoints.get(i), point); 

     if (currentMapBoundsRect.contains(point.x, point.y)) { 
      if (!displayed) { 
       Point tmpPoint = new Point(); 
       projection.toPixels(mPoints.get(Math.max(i - 1, 0)), 
         tmpPoint); 
       tmpPath.moveTo(tmpPoint.x, tmpPoint.y); 
       tmpPath.lineTo(point.x, point.y); 
       displayed = true; 
      } else { 

       tmpPath.lineTo(point.x, point.y); 

      } 

     } else if (displayed) { 
      tmpPath.lineTo(point.x, point.y); 
      displayed = false; 

     } 

    } 

    canvas.drawPath(tmpPath, this.pathPaint); 

} 
+0

तो मैंने कुछ ट्रेसिंग किया है और लगभग 85% लोड 'प्रक्षेपण .toPixels()' विधि लेता है .. वहाँ एक तरीका होना चाहिए कि इसे कैसे अनुकूलित किया जाए:/ – simekadam

+0

एक और तरीका किसी प्रकार का मैपिंग का उपयोग कर सकता है .. जैसा हैश मैप कुंजी के रूप में समन्वय के साथ .. दुनिया को आयताकार सेगमेंट में विभाजित करें और फिर उन मौजूदा फ़िल्टर के अनुसार फ़िल्टर करें देखें राज्य देखें। फिर इसे हैश मैप से लें और प्रदर्शित करें। लेकिन यह काफी जटिल दिखता है :) क्या आपको लगता है कि यह संभव है? बस यह समझ में आता है या नहीं .. – simekadam

उत्तर

3

तो मुझे पता चला कि इसे कितना तेज़ बनाना है! मैं इसे यहां पोस्ट करूंगा, किसी को भविष्य में इसे संभवतः उपयोगी पाया जा सकता है। यह उभरा है कि projection.toPixels() का उपयोग वास्तव में एप्लिकेशन प्रदर्शन को नुकसान पहुंचा सकता है। तो मुझे लगता है कि जिस तरह से से हर एक GeoPoint ले, यह Point में बदलने और उसके बाद जाँच लें कि यह नक्शा व्यूपोर्ट में निहित है बेहतर पता लगा है, जब मैं निम्नलिखित के रूप में नक्शे के actuall व्यूपोर्ट त्रिज्या गिनती:

mapView.getGlobalVisibleRect(currentMapBoundsRect); 
    GeoPoint point1 = projection.fromPixels(currentMapBoundsRect.centerX(), currentMapBoundsRect.centerY()); 
    GeoPoint point2 = projection.fromPixels(currentMapBoundsRect.left, currentMapBoundsRect.top); 
    float[] results2 = new float[3]; 
    Location.distanceBetween(point1.getLatitudeE6()/1E6, point1.getLongitudeE6()/1E6, point2.getLatitudeE6()/1E6, point2.getLongitudeE6()/1E6, results2); 

त्रिज्या परिणाम 2 में है [0] ..

तो मैं हर एक GeoPoint ले सकता हूं और नक्शे के केंद्र और mapView.getMapCenter() के बीच की दूरी को गिन सकता हूं। फिर मैं त्रिज्या की तुलना गणना की दूरी से कर सकता हूं और यह तय कर सकता हूं कि क्या बिंदु बिताया नहीं गया है।

तो यह है, उम्मीद है कि यह सहायक होगा।