iOS 谷歌地图,集群和单个标记的不同自定义图像

标签 ios objective-c google-maps

我在我的 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/

相关文章:

ios - iOS通知可以推送文件吗

android - 谷歌地图自定义标记内存不足错误(API V2)

java - map View : Could not find class A referenced from method B

ios - 再次按下时禁用所选选项卡的重新初始化

ios - 快速查找 iPod 库中歌曲的位置?

ios - 文字超出 iPhone 上的 View

ios - 如何在 Objective-C 中访问 protected 变量

ios - 在循环中重复分配 NSString 同时避免内存泄漏

ios - 从 iOS 图像中提取的 GPS 值未显示正确的正值或负值

ios - 计算类中的行数并选择给定数字的行