我想使用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];
}
Adde代表和群集方法。
[_clusterManager cluster];
[_clusterManager setDelegate:self mapDelegate:self];
所以请帮我添加自定义标记代替默认的红色。
答案 0 :(得分:6)
您需要创建符合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];
答案 1 :(得分:2)
自版本1.1.0起,添加了新功能以便轻松自定义标记(read more)。
您可以添加GMUClusterRendererDelegate
和GMUDefaultClusterRenderer.h
并添加方法- (void)renderer:(id<GMUClusterRenderer>)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;
答案 2 :(得分: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是您的标记类,它是NSObject
和GMUClusterItem
的子类:(您可以使用默认的类GMUClusterItem
,但如果需要其他属性,可以将其子类化)
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)
答案 3 :(得分:0)
您需要使用设计好的GMUClusterIconGenerator
方法来实现func icon(forSize size: UInt) -> UIImage!
的自定义类,该方法为您的集群返回UIImage
。
我建议创建视图和功能以向其添加带有群集标题的设计标签,然后从您的UIImage
创建UIView
。
然后,您将能够像这样创建自定义集群生成器:
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)
}
}
}