4

我正在尝试开发一些用于在地图上聚类标记的算法。显示标记的数量应取决于当前的缩放级别。如果我从 10 个组中显示一个标记,我想将其标题设置为“10”。问题是现在有时可见的标记根本没有标题,我不知道这怎么可能。这是我的代码:

public class MainActivity extends FragmentActivity {
private ArrayList<Marker> markers = new ArrayList<Marker>();
private Bitmap markerImage;
private float oldZoom = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    markerImage = BitmapFactory.decodeResource(this.getResources(), R.drawable.ic_launcher);

    setContentView(R.layout.activity_main);

    final GoogleMap map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
    map.getUiSettings().setMyLocationButtonEnabled(true);
    map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
        @Override
        public void onCameraChange(CameraPosition cameraPosition) {
            if (cameraPosition.zoom != oldZoom) {
                checkMarkers(map);
            }
            oldZoom = cameraPosition.zoom;
        }
    });
    createMarkers(map);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

private void createMarkers(GoogleMap map) {
    double initLat = 48.462740;
    double initLng = 35.039572;
    for (float i = 0; i < 2; i += 0.2) {
        LatLng pos = new LatLng(initLat + i, initLng);
        Marker marker = map.addMarker(new MarkerOptions()
                .position(pos)
                .icon(BitmapDescriptorFactory.fromBitmap(markerImage)));
        markers.add(marker);
    }
    for (float i = 0; i < 2; i += 0.2) {
        LatLng pos = new LatLng(initLat, initLng + i);
        Marker marker = map.addMarker(new MarkerOptions()
                .position(pos)
                .icon(BitmapDescriptorFactory.fromBitmap(markerImage)));
        markers.add(marker);
    }

    initLat = 40.462740;
    initLng = 30.039572;
    for (float i = 0; i < 2; i += 0.2) {
        LatLng pos = new LatLng(initLat + i, initLng + i);
        Marker marker = map.addMarker(new MarkerOptions()
                .position(pos)
                .icon(BitmapDescriptorFactory.fromBitmap(markerImage)));
        markers.add(marker);
    }

}


private void checkMarkers(GoogleMap map) {
    Projection projection = map.getProjection();
    LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds;
    HashMap<Marker, Point> points = new HashMap<Marker, Point>();
    for (Marker marker : markers) {
        if (bounds.contains(marker.getPosition())) {
            points.put(marker, projection.toScreenLocation(marker.getPosition()));
            marker.setVisible(false);
        }
    }
    CheckMarkersTask checkMarkersTask = new CheckMarkersTask();
    checkMarkersTask.execute(points);
}

private class CheckMarkersTask extends AsyncTask<HashMap<Marker, Point>, Void, HashMap<Point, ArrayList<Marker>>> {


    private double findDistance(float x1, float y1, float x2, float y2) {
        return Math.sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
    }

    @Override
    protected HashMap<Point, ArrayList<Marker>> doInBackground(HashMap<Marker, Point>... params) {
        HashMap<Point, ArrayList<Marker>> clusters = new HashMap<Point, ArrayList<Marker>>();
        HashMap<Marker, Point> points = params[0];
        boolean wasClustered;
        for (Marker marker : points.keySet()) {
            Point point = points.get(marker);
            wasClustered = false;
            for (Point existingPoint : clusters.keySet()) {
                if (findDistance(point.x, point.y, existingPoint.x, existingPoint.y) < 25) {
                    wasClustered = true;
                    clusters.get(existingPoint).add(marker);
                    break;
                }
            }
            if (!wasClustered) {
                ArrayList<Marker> markersForPoint = new ArrayList<Marker>();
                markersForPoint.add(marker);
                clusters.put(point, markersForPoint);
            }
        }
        return clusters;
    }

    @Override
    protected void onPostExecute(HashMap<Point, ArrayList<Marker>> clusters) {
        for (Point point : clusters.keySet()) {
            ArrayList<Marker> markersForPoint = clusters.get(point);
            Marker mainMarker = markersForPoint.get(0);
            mainMarker.setTitle(Integer.toString(markersForPoint.size()));
            mainMarker.setVisible(true);
        }
    }

}
}

如您所见,所有可见标记都应该有标题,但实际上通常没有。有什么问题吗?

UPD:我刚刚发现,如果在每个 CameraChange 上调用 map.clear() 和 readd 标记(而不是替换标题和可见性),一切正常。对我来说看起来很奇怪

4

1 回答 1

2

我已经通过清除每个 CameraChange 事件上的地图然后添加所需的标记来解决这个问题。这对我来说可以。

于 2013-02-06T15:28:12.250 回答