OpenStreetMap Android - 在滚动期间叠加并缓慢重绘

时间:2016-01-10 12:21:41

标签: android overlay polygon openstreetmap osmdroid

我的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();

感谢您的任何建议。

1 个答案:

答案 0 :(得分:0)

我发现了什么问题。

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

解决方案是按距离对点列表进行排序,以便它表示多边形的连续角的列表,并在将它们作为方法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;
}