OpenStreetMap Android - 滚动时覆盖和缓慢重绘

OpenStreetMap Android - overlays and slow redrawing during scrolling

我的 osm 应用程序有问题。我从我的服务器端应用程序中得到一组点,然后我想将它可视化为某个区域。所以我从这些点创建了一个多边形并将其添加到我的 mapView 对象中。它可以工作,但是随着区域变大,滚动会出现问题,直到我到达没有叠加层的区域。

如何提高地图重绘性能?

我想过将我的区域多边形分成更小的多边形,但它们只是相互相交并且颜色不均匀。

View of my map

这是我的部分代码。通常我每次在 AsyncTask 中从服务器收到包含新数据的消息并在 postExecute 方法上使 mapView 无效时调用它,但这并不重要,因为问题不只是绘图而是滚动,是吗?

List<Overlay> mapOverlays = new ArrayList<>();

Drawable icon = getIcon();

Marker marker = new Marker(mapView);
marker.setPosition(new GeoPoint(newPosition));
marker.setTitle(title);
marker.setIcon(icon);

mapOverlays.add(marker);

List<GeoPoint> listWithAreaPoints = new ArrayList<>();
listWithAreaPoints.addAll(setWithAreaPoints);

Polygon searchedArea = new Polygon(activity.getApplicationContext());
searchedArea.setPoints(listWithAreaPoints);
searchedArea.setFillColor(0x12121212);
searchedArea.setStrokeColor(0x12121212);
searchedArea.setStrokeWidth(0);
mapOverlays.add(searchedArea);

mapView.getOverlays().clear();
mapView.getOverlays().addAll(mapOverlays);
mapView.invalidate();

感谢任何建议。

我发现问题所在了。

我从服务器接收到的数据包含很多点(成百上千),我以混乱的顺序将它们提供给多边形对象的方法 setPoints()。因此,多边形方法 draw() 绘制了连续的线条,没有任何顺序可以在我的打印屏幕上看到(空白区域)。随着点数的增加,多边形的数量 "sides" 也增加,重绘性能下降。

解决方案是按距离对点列表进行排序,这样它就可以表示多边形的连续角列表,并在将重复项作为参数提供给方法 Polygon.setPoints() 之前删除重复项。

也许它会对将来的人有所帮助,所以我会在这里使用我的方法将 GeoPoints 排序为连续的多边形点:

 private List<GeoPoint> sortGeoPointsListByDistance(List<GeoPoint> searchedArea){

    List<GeoPoint> orderedSearchedArea = new ArrayList<>();
    orderedSearchedArea.add(searchedArea.remove(0));

    while (searchedArea.size() > 0) {
        GeoPoint point = orderedSearchedArea.get(orderedSearchedArea.size() - 1);
        int nearestPointIndex = findNearestPointIndex(point, searchedArea);
        GeoPoint nearestPoint = searchedArea.get(nearestPointIndex);
        if(nearesPointIsTheSamePoint(point, nearestPoint)){
            searchedArea.remove(nearestPointIndex);
        } else {
            orderedSearchedArea.add(searchedArea.remove(nearestPointIndex));
        }
    }

    return orderedSearchedArea;
}

 private int findNearestPointIndex(GeoPoint point, List<GeoPoint> listToSearch) {
    int index =0;
    double dist = 0;
    for(int i=0;i<listToSearch.size();i++){
        GeoPoint currentPoint = listToSearch.get(i);
        double currentPointDist = distFrom( point.getLatitude(),  point.getLongitude(),  currentPoint.getLatitude(),  currentPoint.getLongitude());
        if(i==0){
            index = i;
            dist = currentPointDist;
        } else if(currentPointDist<dist){
            index = i;
            dist = currentPointDist;
        }
    }
    return index;
}

  private boolean nearesPointIsTheSamePoint(GeoPoint point, GeoPoint nearestPoint){
    if(point.getLatitude()==nearestPoint.getLatitude() && point.getLongitude()==nearestPoint.getLongitude()){
        return true;
    } else{
        return false;
    }
}

 private double distFrom(double lat1, double lng1, double lat2, double lng2) {
    double earthRadius = 6371000; //meters
    double dLat = Math.toRadians(lat2-lat1);
    double dLng = Math.toRadians(lng2-lng1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                    Math.sin(dLng/2) * Math.sin(dLng/2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double dist =  (earthRadius * c);

    return dist;
}