【问题标题】:Custom Marker using GMUClusterManager使用 GMUClusterManager 的自定义标记
【发布时间】:2016-11-28 05:31:36
【问题描述】:

我想使用GMUClusterManager 显示自定义标记。我遵循了标记聚类here的所有步骤。

但是有像这样的蓝色和红色图标。

但是当我放大该地图时,它只显示红色标记,但我不希望这样。

我已经实现了我的逻辑但没有用的实例方法。

    - (instancetype)initWithMapView:(GMSMapView *)mapView clusterIconGenerator:(id<GMUClusterIconGenerator>)iconGenerator
{
    if ((self = [super init])) {

        GMSMarker *marker= [GMSMarker markerWithPosition:CLLocationCoordinate2DMake(24.0, 75.30)];

        UIView *customMarker =[[UIView alloc] initWithFrame:CGRectMake(0, 0, 63, 40)];
        customMarker.backgroundColor = [UIColor blueColor];

        marker.iconView = [self EmployeeMarker:0] ;
        marker.appearAnimation = kGMSMarkerAnimationPop;
        marker.map = mapView;
    }
    return self;
}

-(UIView *)EmployeeMarker:(int)labelTextInt{
    UIView *customMarker =[[UIView alloc] initWithFrame:CGRectMake(0, 0, 63, 40)];
    UIImageView *imgViewCustomMarker = [[UIImageView alloc]initWithFrame:CGRectMake(0, 15, 24, 25)];
    imgViewCustomMarker.image = [UIImage imageNamed:@"iconMapUser.png"];
    [customMarker addSubview:imgViewCustomMarker];
    UIView *viewRatingCustom = [[UIView alloc] initWithFrame:CGRectMake(15, 0, 40, 15)];
    viewRatingCustom.backgroundColor = [UIColor colorWithRed:192.0/255.0 green:192.0/255.0 blue:192.0/255.0 alpha:1.0];
    UILabel *lblRatingEmployees = [[UILabel alloc] initWithFrame:CGRectMake(8, 1, 17,8)];
    lblRatingEmployees.textColor = [UIColor colorWithRed:0.00/255.0 green:100.0/255.0 blue:150.0/255.0 alpha:1.0];
    lblRatingEmployees.text = @"1";
    lblRatingEmployees.font = [UIFont fontWithName:@"Helvetica-Bold" size:10];
    [lblRatingEmployees sizeToFit];
    [viewRatingCustom addSubview:lblRatingEmployees];
    UIImageView *imageViewStar = [[UIImageView alloc] initWithFrame:CGRectMake(25, 3, 10, 8)];
    imageViewStar.image = [UIImage imageNamed:@"iconBlueStar.png"];
    [viewRatingCustom addSubview:imageViewStar];
    [customMarker addSubview:viewRatingCustom];
    return customMarker;
}

我已使用此方法显示默认为红色的标记的可能数量。

id<GMUClusterAlgorithm> algorithm = [[GMUNonHierarchicalDistanceBasedAlgorithm alloc] init];

id<GMUClusterIconGenerator> iconGenerator = [[GMUDefaultClusterIconGenerator alloc] init];


id<GMUClusterRenderer> renderer =
  [[GMUDefaultClusterRenderer alloc] initWithMapView:_mapView
                                clusterIconGenerator:iconGenerator];

_clusterManager =
  [[GMUClusterManager alloc] initWithMap:_mapView algorithm:algorithm renderer:renderer];

 // Generate and add random items to the cluster manager.

// [self generateClusterItems];


for (int i = 0; i<latitudeArray.count; i++) {

    id<GMUClusterItem> item =

    [[POIItem alloc]initWithPosition:CLLocationCoordinate2DMake([[latitudeArray objectAtIndex:i]doubleValue], [[longitudeArray objectAtIndex:i]doubleValue]) name:@"Name"];

    [_clusterManager addItem:item];
}

添加委托和集群方法。

 [_clusterManager cluster];
 [_clusterManager setDelegate:self mapDelegate:self];

所以请帮我添加自定义标记来代替默认的红色。

【问题讨论】:

标签: ios objective-c google-maps markerclusterer


【解决方案1】:

您需要创建符合GMUClusterIconGenerator协议的自定义类:

CustomClusterIconGenerator.h 文件

@interface CustomClusterIconGenerator : NSObject
<GMUClusterIconGenerator>

@end

CustomClusterIconGenerator.m 文件

@implementation CustomClusterIconGenerator

- (UIImage *)iconForSize:(NSUInteger)size {
    // Return custom icon for cluster
    return [UIImage imageNamed:@"Your Custom Cluster Image"];
}

- (UIImage *)iconForMarker {
    // Return custom icon for pin
    return [UIImage imageNamed:@"Your Custom Marker Image"];
}

- (CGPoint)markerIconGroundAnchor {
    // If your marker icon center shifted, return custom value for anchor
    return CGPointMake(0, 0);
}

- (CGPoint)clusterIconGroundAnchor {
    // If your cluster icon center shifted, return custom value for anchor
    return CGPointMake(0, 0);
}

@end

然后,而不是

id<GMUClusterIconGenerator> iconGenerator = [[GMUDefaultClusterIconGenerator alloc] init];

使用

CustomClusterIconGenerator *iconGenerator = [[GMUDefaultClusterIconGenerator alloc] init];

这是我项目中的示例:

【讨论】:

  • CustomClusterIconGenerator iconGenerator = [[GMUDefaultClusterIconGenerator alloc] init];在这个地方有错误。
  • iconForMarker 不工作.. 使用此代码作为集群标记工作 - (UIImage *)iconForSize:(NSUInteger)size
  • @MadBurea 抱歉,有错字。应该是CustomClusterIconGenerator *iconGenerator。我更新了答案。
  • @MadBurea 关于iconForSize - 也许库自我上次使用以来已更新。这可以。随意使用iconForSize。你可以随时查看GMUClusterIconGenerator 协议声明:-)
  • @MadBurea iconForMarker 用于 MARKER,iconForSize 用于 CLUSTER
【解决方案2】:

Swift 4.2 中:

将此扩展添加到您的控制器并确保您的控制器是GMUClusterRendererDelegate 的代表:

willRenderMarker 将在每次渲染标记时调用(集群标记和 clusterItemMarker,因此您可以通过简单的 if 进行检查)。因此您可以在将其显示给用户之前修改它的图标等

extension YourController: GMUClusterRendererDelegate {
    func renderer(_ renderer: GMUClusterRenderer, willRenderMarker marker: GMSMarker) {
        // if your marker is pointy you can change groundAnchor
        marker.groundAnchor = CGPoint(x: 0.5, y: 1)
        if  let markerData = (marker.userData as? PersonMarker) {
           let icon = markerData.imageURL
           marker.iconView = CustomMarkerView(forUrl: url)
        }
    }
}

而 PersonMarker 是您的标记类,它是 NSObjectGMUClusterItem 的子类:(您可以使用 GMUClusterItem 的默认类,但如果您需要其他一些属性,您可以将其子类化) p>

class PersonMarker: NSObject, GMUClusterItem {

  var position: CLLocationCoordinate2D
  var imageURL : String?
  var name: String?
  var userdId: String?
  var lastSeen: String?

  init(position: CLLocationCoordinate2D, url: String?, name: String?, userId: String?, lastSeen: String?) {
      self.position = position
      self.imageURL = url
      self.name = name
      self.userdId = userId
      self.lastSeen = lastSeen
  }

}

您可以像这样将PersonMarker 添加到您的GMUClusterManager

let position = CLLocationCoordinate2D(latitude: item.latitude!, longitude: item.longitute!)
let person = PersonMarker(position: position, url: item.user?.avaterUrl, name: item.user?.name, userId: item.user?.userId, lastSeen: item.lastUpdate)
clusterManager.add(person)

【讨论】:

  • 让 renderer = CustomRendererMarkers(mapView: mapView, clusterIconGenerator: iconGenerator) renderer.delegate = self
【解决方案3】:

从 1.1.0 版开始,添加了新功能,以便轻松自定义标记 (read more)。

您可以添加GMUClusterRendererDelegateGMUDefaultClusterRenderer.h并添加方法- (void)renderer:(id&lt;GMUClusterRenderer&gt;)renderer willRenderMarker:(GMSMarker *)marker;

在那里,您可以自定义标记和集群。例如:

- (void)renderer:(id<GMUClusterRenderer>)renderer willRenderMarker:(GMSMarker *)marker{
    if ([marker.userData conformsToProtocol:@protocol(GMUCluster)]) {
        marker.icon=[UIImage imageNamed:@"custom_cluster_image.png"];
    }else if ([marker.userData conformsToProtocol:@protocol(GMUClusterItem)]) {
        marker.icon=[UIImage imageNamed:@"custom_marker_image.png"];
    }
}

记得正确设置委托:

id<GMUClusterRenderer> renderer = [[GMUDefaultClusterRenderer alloc] initWithMapView:_mapView clusterIconGenerator:iconGenerator];
((GMUDefaultClusterRenderer *)renderer).delegate=self;

【讨论】:

    【解决方案4】:

    您需要实现 GMUClusterIconGenerator 的自定义类,并使用设计的 func icon(forSize size: UInt) -&gt; UIImage! 方法为您的集群返回 UIImage

    我建议创建视图和功能以添加带有集群标题的设计标签,然后从您的UIView 创建UIImage

    然后您就可以像这样创建您的自定义集群生成器:

    let iconGenerator = ClusterIconGenerator()
    

    示例结果:


    工作生成器:

    class ClusterIconGenerator: NSObject, GMUClusterIconGenerator {
    
        private struct IconSize {
    
            private let initialFontSize: CGFloat = 12
            private let fontMultiplier: CGFloat = 0.1
    
            private let initialSize: CGFloat = 25
            private let sizeMultiplier: CGFloat = 0.18
    
            /**
             Rounded cluster sizes  (like 10+, 20+, etc.)
             */
            private let sizes = [10,20,50,100,200,500,1000]
    
            let size: UInt
    
            /**
             Returns scale level based on size index in `sizes`. Returns `1` if size doesn't have rounded representation
             */
            private var scaleLevel: UInt {
                if let index = sizes.lastIndex(where: { $0 <= size }) {
                    return UInt(index) + 2
                } else {
                    return 1
                }
            }
    
            /**
             Returns designed title from cluster's size
             */
            var designedTitle: String {
                if let size = sizes.last(where: { $0 <= size }) {
                    return "\(size)+"
                } else {
                    return "\(size)"
                }
            }
    
            /**
             Returns initial font size multiplied by recursively created multiplier
             */
            var designedFontSize: CGFloat {
                let multiplier: CGFloat = (1...scaleLevel).reduce(1) { n,_ in n + n * fontMultiplier }
                return initialFontSize * multiplier
            }
    
            /**
             Returns initial `CGSize` multiplied by recursively created multiplier
             */
            var designedSize: CGSize {
                let multiplier: CGFloat = (1...scaleLevel).reduce(1) { n,_ in n + n * sizeMultiplier }
                return CGSize(width: initialSize * multiplier, height: initialSize * multiplier)
            }
    
        }
    
        /**
         Returns image based on current cluster's size
         */
        func icon(forSize size: UInt) -> UIImage! {
    
            let iconSize = IconSize(size: size)
    
            let frame = CGRect(origin: .zero, size: iconSize.designedSize)
    
            let view = UIView(frame: frame)
            view.layer.cornerRadius = iconSize.designedSize.height / 2
            view.backgroundColor = .green
    
            let label = UILabel(frame: frame)
            label.textAlignment = .center
            label.textColor = .white
            label.text = iconSize.designedTitle
            view.addSubview(label)
    
            return view.asImage
        }
    
    }
    
    extension UIView {
    
        var asImage: UIImage {
            let renderer = UIGraphicsImageRenderer(bounds: bounds)
            return renderer.image { rendererContext in
                layer.render(in: rendererContext.cgContext)
            }
        }
    
    }
    

    【讨论】:

      【解决方案5】:

      您可能想查看教程 - Marker Clustering with Google's Utility library for Maps SDK (Google-Maps-iOS-Utils),它提供了一个完美的示例,说明您希望在您的应用中实现的东西。还有来自blog 的Google sample codes,您可能想尝试一下。最后在 github 上报告了一个关于 Way to customize individual markers added to cluster manager? 的问题,它可能会帮助您了解如何在 GMUClusterManager 中自定义标记。希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-27
        • 1970-01-01
        • 2011-08-20
        • 1970-01-01
        • 2015-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多