5

Tôi đang cố giải quyết sự cố khi vẽ đường dẫn từ bộ GeoPoints khổng lồ (100k +) đến MapView trên Android. Trước tiên tôi muốn nói, tôi đã tìm kiếm qua StackOverflow rất nhiều và không tìm thấy câu trả lời nào. Nút cổ chai của mã của tôi không thực sự vẽ thành canvas, nhưng phương pháp Projection.toPixels(GeoPoint, Point) hoặc Rect.contains(point.x, point.y)..Tôi bỏ qua các điểm không hiển thị trên màn hình và cũng chỉ hiển thị mọi điểm thứ n theo mức thu phóng hiện tại. Khi bản đồ được phóng to, tôi muốn hiển thị con đường chính xác nhất có thể để tôi bỏ qua số không (hoặc gần bằng 0), để khi tìm điểm hiển thị, tôi cần gọi phương thức chiếu cho mỗi điểm trong bộ sưu tập. Và đó là những gì thực sự mất rất nhiều thời gian (không phải giây, nhưng bản đồ panning không phải là chất lỏng và tôi không thử nghiệm nó trên HTC Wildfire :)). Tôi đã thử caching các điểm tính toán, nhưng kể từ khi các điểm được tính toán lại sau mỗi bản đồ pan/zoom nó đã không giúp ở tất cả.Vẽ (lọc) 100k + điểm vào MapView trong Android

Tôi nghĩ về cách sử dụng một số loại lược đồ và thuật toán tìm kiếm thay vì lặp lại mảng, nhưng tôi đã tìm ra dữ liệu đầu vào không được sắp xếp (tôi không thể vứt bỏ bất kỳ nhánh nào được xếp chồng lên nhau giữa hai điểm vô hình). Điều đó có thể tôi có thể giải quyết với loại đơn giản lúc đầu, nhưng tôi vẫn không chắc chắn ngay cả số logarit của getProjection()Rect.contains(point.x, point.y) cuộc gọi thay vì tuyến tính sẽ giải quyết vấn đề hiệu suất.

Dưới đây là mã hiện tại của tôi. Xin hãy giúp tôi nếu bạn biết cách làm tốt hơn. Cảm ơn rất nhiều!

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

Vì vậy, tôi đã thực hiện một số truy tìm và khoảng 85% tải có phương thức 'Projection.toPixels()' .. Có cách để tối ưu hóa điều đó:/ – simekadam

+0

Một cách khác có thể sử dụng một số loại ánh xạ..Giống như HashMap với sự phối hợp như khóa..Giống như chia thế giới thành các phân đoạn hình chữ nhật và sau đó lọc chúng theo trạng thái mapView hiện tại. Sau đó lấy nó từ HashMap và hiển thị. Nhưng điều này có vẻ khá phức tạp :) Bạn có nghĩ rằng nó có thể? Chỉ cần có hay không nó có ý nghĩa .. – simekadam

Trả lời

3

Vì vậy, tôi đã tìm ra cách làm cho nó nhanh hơn rất nhiều! Tôi sẽ đăng nó ở đây, ai đó có thể thấy nó hữu ích trong tương lai. Đã xuất hiện rằng việc sử dụng projection.toPixels() thực sự có thể gây hại cho hiệu suất ứng dụng. Vì vậy, tôi đã tìm ra cách tiếp thị tốt hơn tận dụng mọi đơn GeoPoint, chuyển nó sang Point và sau đó kiểm tra nếu nó được chứa trong đồ viewport là, khi tôi đếm actuall bán kính quan sát của bản đồ như sau:

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); 

Bán kính đang ở trong kết quả2 [0] ..

Sau đó, tôi có thể lấy từng số GeoPoint và đếm khoảng cách giữa nó và tâm của bản đồ mapView.getMapCenter(). Sau đó, tôi có thể so sánh bán kính với khoảng cách tính toán và quyết định liệu ot không ngoại giao điểm.

Vì vậy, đó là nó, hy vọng Nó sẽ hữu ích.

Các vấn đề liên quan