【问题标题】:iOS Google Maps, different custom images for Clusters and individual markersiOS 谷歌地图,集群和单个标记的不同自定义图像
【发布时间】:2017-01-15 03:32:07
【问题描述】:

我在我的 iOS 应用中使用 Google Maps SDK。我正在使用聚类方法填充地图。

我已经为不同的聚类桶设置了自定义图像。 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"]
                                                                     ]];
}

这是谷歌集群类添加标记的地方

        - (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;
}

【问题讨论】:

    标签: ios objective-c google-maps


    【解决方案1】:

    两天前我遇到了类似的问题,我刚刚找到了解决方案。希望它对你有用。 例如,您有一个 mapView,并在正确的位置为它设置了一个委托:

    [self.mapView setDelegate:self];
    

    那么你需要实现 GMSMapViewDelegate 协议中的可选方法:

    - (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;
    }
    

    对可能的错误表示歉意,如果您有不明白的地方,请提出问题 =)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-24
      • 1970-01-01
      • 2018-03-08
      • 1970-01-01
      • 2012-05-27
      相关资源
      最近更新 更多