如何在Google地图上使用相同位置处理多个标记?

时间:2013-10-31 10:34:38

标签: android ios objective-c google-maps google-maps-markers

我在应用中使用Google地图,很可能会将多个标记附加到每个标记代表一个人的同一位置。在这种情况下,用户不会知道此特定标记后面还有其他标记/人员。

我环顾四周来处理这种情况,关于SO的一个问题表明我可以显示一个标记并将所有人与该单个标记相关联。当用户点击该标记时,我应该显示与该标记关联的所有用户的列表。这是一个很好的解决方法,但我希望避免显示主要隐藏谷歌地图的视图。

有没有人在类似的情况下使用过任何解决方法?

5 个答案:

答案 0 :(得分:15)

我使用的解决方法是在地图上显示相同位置的标记,以便用户轻松了解多个标记。

我跟踪地图上的标记及其在地图上的位置,每当我想在地图上添加标记时,我都要确保在同一位置上没有显示其他标记。如果是,那么我添加一个偏移量到我要添加的新标记的位置。

static final float COORDINATE_OFFSET = 0.00002f; // You can change this value according to your need

下面的方法返回必须用于新标记的位置。此方法将新标记的当前纬度和经度作为参数。

// Check if any marker is displayed on given coordinate. If yes then decide
// another appropriate coordinate to display this marker. It returns an
// array with latitude(at index 0) and longitude(at index 1).
private String[] coordinateForMarker(float latitude, float longitude) {

    String[] location = new String[2];

    for (int i = 0; i <= MAX_NUMBER_OF_MARKERS; i++) {

        if (mapAlreadyHasMarkerForLocation((latitude + i
                * COORDINATE_OFFSET)
                + "," + (longitude + i * COORDINATE_OFFSET))) {

            // If i = 0 then below if condition is same as upper one. Hence, no need to execute below if condition.
            if (i == 0)
                continue;

            if (mapAlreadyHasMarkerForLocation((latitude - i
                    * COORDINATE_OFFSET)
                    + "," + (longitude - i * COORDINATE_OFFSET))) {

                continue;

            } else {
                location[0] = latitude - (i * COORDINATE_OFFSET) + "";
                location[1] = longitude - (i * COORDINATE_OFFSET) + "";
                break;
            }

        } else {
            location[0] = latitude + (i * COORDINATE_OFFSET) + "";
            location[1] = longitude + (i * COORDINATE_OFFSET) + "";
            break;
        }
    }

    return location;
}

// Return whether marker with same location is already on map
private boolean mapAlreadyHasMarkerForLocation(String location) {
    return (markerLocation.containsValue(location));
}

在上面的代码中,markerLocation是一个HashMap。

HashMap<String, String> markerLocation;    // HashMap of marker identifier and its location as a string

这个答案包含Android的代码,但同样的逻辑适用于iOS。

答案 1 :(得分:1)

也许你应该看一下标记聚类。这是在同一个地方展示大量标记的常见解决方案。 关于它的Google文章:https://developers.google.com/maps/articles/toomanymarkers

还有现有的库可以做到这一点,例如:

答案 2 :(得分:0)

您可以处理(单个)标记的点击事件,并使用它来更新位于Google地图画布之外的元素,其中包含有关该标记的人员的详细信息。

答案 3 :(得分:0)

当用户放大到最大值时,给予偏移会使标记变得更远。所以我找到了实现这一目标的方法。这可能不是一个正确的方法,但它运作得很好。

for loop markers
{
 //create marker
 let mapMarker = GMSMarker()
 mapMarker.groundAnchor = CGPosition(0.5, 0.5)
 mapMarker.position = //set the CLLocation
 //instead of setting marker.icon set the iconView
 let image:UIIMage = UIIMage:init(named:"filename")
 let imageView:UIImageView = UIImageView.init(frame:rect(0,0, ((image.width/2 * markerIndex) + image.width), image.height))
 imageView.contentMode = .Right
 imageView.image = image
 mapMarker.iconView = imageView
 mapMarker.map = mapView
}

设置标记的zIndex,以便您可以看到要在顶部看到的标记图标,否则它将为自动交换等标记设置动画。 当用户点击标记处理时,zIndex使用zIndex Swap将标记置于顶部。

答案 4 :(得分:0)

受怪胎answer的启发,我创建了一个函数。此函数几乎以循环的方式返回原始值附近的新纬度经度对。可根据需要调整COORINDATE_OFFSET。

private static final float COORDINATE_OFFSET = 0.000085f;
private ArrayList<LatLng> markerCoordinates = new ArrayList<>();
private int offsetType = 0;

private LatLng getLatLng(LatLng latLng) {

    LatLng updatedLatLng;

    if (markerCoordinates.contains(latLng)) {
        double latitude = 0;
        double longitude = 0;
        if (offsetType == 0) {
            latitude = latLng.latitude + COORDINATE_OFFSET;
            longitude = latLng.longitude;
        } else if (offsetType == 1) {
            latitude = latLng.latitude - COORDINATE_OFFSET;
            longitude = latLng.longitude;
        } else if (offsetType == 2) {
            latitude = latLng.latitude;
            longitude = latLng.longitude + COORDINATE_OFFSET;
        } else if (offsetType == 3) {
            latitude = latLng.latitude;
            longitude = latLng.longitude - COORDINATE_OFFSET;
        } else if (offsetType == 4) {
            latitude = latLng.latitude + COORDINATE_OFFSET;
            longitude = latLng.longitude + COORDINATE_OFFSET;
        }
        offsetType++;
        if (offsetType == 5) {
            offsetType = 0;
        }


        updatedLatLng = getLatLng(new LatLng(latitude, longitude));

    } else {
        markerCoordinates.add(latLng);
        updatedLatLng = latLng;
    }
    return updatedLatLng;
}