我在我的 iOS 应用中使用 Google Maps SDK。我正在使用聚类方法填充 map 。
我已经为不同的聚类桶设置了自定义图像。 10,20...
然而,各个标记具有默认值(谷歌地图红色标记图标)。
我想要一个用于聚类的自定义图标和一个用于单个标记的不同图标。
但是在呈现添加标记的集群的方法中,如果您设置标记图标,它会更改所有图像,而不仅仅是单张图像。
单体和集群如何设置不同的图标?
这会将项目添加到 clusterManager
id<GMUClusterItem> item =
[[POIItem alloc] initWithPosition:CLLocationCoordinate2DMake([bay.latitude doubleValue], [bay.longitude doubleValue]) name:bay.name status:bay.marker_status];
[clusterManager addItem:item];
这里我添加了集群桶的图标
- (id<GMUClusterIconGenerator>)iconGeneratorWithImages {
return [[GMUDefaultClusterIconGenerator alloc] initWithBuckets:@[ @10, @50, @100, @200, @1000 ]
backgroundImages:@[
[UIImage imageNamed:@"big_parking_pin_img"],
[UIImage imageNamed:@"big_parking_pin_img"],
[UIImage imageNamed:@"big_parking_pin_img"],
[UIImage imageNamed:@"big_parking_pin_img"],
[UIImage imageNamed:@"big_parking_pin_img"]
]];
}
这是google集群类添加标记的地方
- (void)renderCluster:(id<GMUCluster>)cluster animated:(BOOL)animated {
float zoom = _mapView.camera.zoom;
if ([self shouldRenderAsCluster:cluster atZoom:zoom]) {
CLLocationCoordinate2D fromPosition;
if (animated) {
id<GMUCluster> fromCluster =
[self overlappingClusterForCluster:cluster itemMap:_itemToOldClusterMap];
animated = fromCluster != nil;
fromPosition = fromCluster.position;
}
UIImage *icon = [_clusterIconGenerator iconForSize:cluster.count];
GMSMarker *marker = [self markerWithPosition:cluster.position
from:fromPosition
userData:cluster
clusterIcon:icon
animated:animated];
[_markers addObject:marker];
} else {
for (id<GMUClusterItem> item in cluster.items) {
CLLocationCoordinate2D fromPosition;
BOOL shouldAnimate = animated;
if (shouldAnimate) {
GMUWrappingDictionaryKey *key = [[GMUWrappingDictionaryKey alloc] initWithObject:item];
id<GMUCluster> fromCluster = [_itemToOldClusterMap objectForKey:key];
shouldAnimate = fromCluster != nil;
fromPosition = fromCluster.position;
}
GMSMarker *marker = [self markerWithPosition:item.position
from:fromPosition
userData:item
clusterIcon:nil
animated:shouldAnimate];
[_markers addObject:marker];
[_renderedClusterItems addObject:item];
}
}
[_renderedClusters addObject:cluster];
}
// Returns a marker at final position of |position| with attached |userData|.
// If animated is YES, animates from the closest point from |points|.
- (GMSMarker *)markerWithPosition:(CLLocationCoordinate2D)position
from:(CLLocationCoordinate2D)from
userData:(id)userData
clusterIcon:(UIImage *)clusterIcon
animated:(BOOL)animated {
CLLocationCoordinate2D initialPosition = animated ? from : position;
GMSMarker *marker = [GMSMarker markerWithPosition:initialPosition];
marker.userData = userData;
if (clusterIcon != nil) {
marker.icon = clusterIcon;
marker.groundAnchor = CGPointMake(0.5, 0.5);
}
marker.map = _mapView;
if (animated) {
[CATransaction begin];
[CATransaction setAnimationDuration:kGMUAnimationDuration];
marker.layer.latitude = position.latitude;
marker.layer.longitude = position.longitude;
[CATransaction commit];
}
return marker;
}
最佳答案
我 2 天前遇到了类似的问题,我刚刚找到了解决方案。希望它对你有用。 例如,您有一个 mapView 并在正确的位置为它设置了一个委托(delegate):
[self.mapView setDelegate:self];
然后您需要实现 GMSMapViewDelegate 协议(protocol)中的可选方法:
- (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position {
[self performSelector:@selector(updateMarkers) withObject:nil afterDelay:0.2];
}
我使用延迟 0.2 秒,因为如果您使用更小的值,标记将不会更新它们的图标。 下一步是更新图标的实现方法:
-(void) updateMarkers {
// "mapView" property in your self.mapView has type GMSVectorMapView,
//and it is hidden, so you can't get like self.mapView.mapView
id vectorMap = [self.mapView valueForKey:@"mapView"];
// "accessibilityItems" - property that have all items in visible part of map.
NSMutableArray* GMSMarkersArray = [vectorMap mutableArrayValueForKey:@"accessibilityItems"];
// Very often you'll get object of GMSPointOfInteretUIItem class, and you don't need it =)
NSMutableArray *discardedItems = [NSMutableArray array];
for (id item in GMSMarkersArray) {
if (![item isKindOfClass:[GMSMarker class]])
[discardedItems addObject:item];
}
[GMSMarkersArray removeObjectsInArray:discardedItems];
// If marker don't have icon image, he use default red pin, but property is still have nil-value ...
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"icon = nil"];
NSArray* singleMarkers = [GMSMarkersArray filteredArrayUsingPredicate:predicate];
// ... and here you can setup any icon you want, for all singles markers in visible part of map.
for(GMSMarker* marker in singleMarkers) {
marker.icon = [UIImage imageNamed:@"yourIcon.png"];
}
}
此外,如果您创建自己的标记并将其添加到集群中,您可以在最后一个循环中从 GMSMarker 对象的 userData 属性中获取它。例如,你有你想要的带有图标的自定义标记,只需将最后一个循环更改为:
for(GMSMarker* marker in singleMarkers) {
YourMarkerClass* yourMaker = marker.userData;
marker.icon = yourMaker.icon;
}
对于可能出现的错误,我们深表歉意,如果您不明白,请提出问题 =)
关于iOS 谷歌地图,集群和单个标记的不同自定义图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39369945/