我正在使用适用于iOS的Google Maps API,并希望使用标记群集实用程序.我想出了如何显示聚类标记,但我想自定义标记.有人可以解释如何设置/更改每个标记或聚类标记的图标和标题吗?示例代码非常有用.
class POIItem: NSObject, GMUClusterItem { var position: CLLocationCoordinate2D var name: String! init(position: CLLocationCoordinate2D, name: String) { self.position = position self.name = name } } class MyRenderer: NSObject, GMUClusterRenderer { var mapView: GMSMapView var clusterIconGenerator: GMUClusterIconGenerator var clusterManager: GMUClusterManager init(mapView: GMSMapView, clusterIconGenerator: GMUClusterIconGenerator, clusterManager: GMUClusterManager) { self.mapView = mapView self.clusterIconGenerator = clusterIconGenerator self.clusterManager = clusterManager } func renderClusters(clusters: [GMUCluster]) { } func update() { } }
这就是我到目前为止所拥有的.我不知道如何处理renderClusters和更新函数.
我在Swift 4上为集群标记找到了一个干净的解决方案,使用集群内部集群数量的自定义映像:
class MapClusterIconGenerator: GMUDefaultClusterIconGenerator { override func icon(forSize size: UInt) -> UIImage { let image = textToImage(drawText: String(size) as NSString, inImage: UIImage(named: "cluster")!, font: UIFont.systemFont(ofSize: 12)) return image } private func textToImage(drawText text: NSString, inImage image: UIImage, font: UIFont) -> UIImage { UIGraphicsBeginImageContext(image.size) image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)) let textStyle = NSMutableParagraphStyle() textStyle.alignment = NSTextAlignment.center let textColor = UIColor.black let attributes=[ NSAttributedStringKey.font: font, NSAttributedStringKey.paragraphStyle: textStyle, NSAttributedStringKey.foregroundColor: textColor] // vertically center (depending on font) let textH = font.lineHeight let textY = (image.size.height-textH)/2 let textRect = CGRect(x: 0, y: textY, width: image.size.width, height: textH) text.draw(in: textRect.integral, withAttributes: attributes) let result = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return result! } }
比集群管理器的设置:
private func setupClustering() { guard let mapView = self.mapView else { return } let iconGenerator = MapClusterIconGenerator() let renderer = MapClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator) let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm() clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer) }
我还使用了自定义群集渲染器MapClusterRenderer
.
我设法找到"干净"的解决方案,即使它仍然令人困惑.但它的确有效!
1)创建.h文件"MarkerManager"
#import@import CoreLocation; #import "GMUClusterItem.h" #import @interface MarkerManager: NSObject @property (nonatomic) CLLocationCoordinate2D location; @property (nonatomic, strong) GMSMarker *marker; @end
2)转到Google-Maps-iOS-Utils文件夹中的GMUDefaultClusterRenderer类,导入MarkerManager.h类查找并更改此方法:
// 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 { GMSMarker *marker = [self markerForObject:userData]; CLLocationCoordinate2D initialPosition = animated ? from : position; marker.position = initialPosition; marker.userData = userData; if (clusterIcon != nil) { marker.icon = clusterIcon; marker.groundAnchor = CGPointMake(0.5, 0.5); } //added else { MarkerManager *data = userData; if(data != nil) { marker.icon = data.marker.icon; } } //ends here marker.zIndex = _zIndex; if ([_delegate respondsToSelector:@selector(renderer:willRenderMarker:)]) { [_delegate renderer:self willRenderMarker:marker]; } marker.map = _mapView; if (animated) { [CATransaction begin]; [CATransaction setAnimationDuration:kGMUAnimationDuration]; marker.layer.latitude = position.latitude; marker.layer.longitude = position.longitude; [CATransaction commit]; } if ([_delegate respondsToSelector:@selector(renderer:didRenderMarker:)]) { [_delegate renderer:self didRenderMarker:marker]; } return marker; }
3)创建新的swift类,POIItem:
class POIItem: NSObject, GMUClusterItem { var position: CLLocationCoordinate2D @objc var marker: GMSMarker! init(position: CLLocationCoordinate2D, marker: GMSMarker) { self.position = position self.marker = marker } }
4)扩展GMUDefaultClusterRenderer类并覆盖markerWithPosition方法:
import Foundation import UIKit class CustomMarkers: GMUDefaultClusterRenderer { var mapView:GMSMapView? let kGMUAnimationDuration: Double = 0.5 override init(mapView: GMSMapView, clusterIconGenerator iconGenerator: GMUClusterIconGenerator) { super.init(mapView: mapView, clusterIconGenerator: iconGenerator) } func markerWithPosition(position: CLLocationCoordinate2D, from: CLLocationCoordinate2D, userData: AnyObject, clusterIcon: UIImage, animated: Bool) -> GMSMarker { let initialPosition = animated ? from : position let marker = GMSMarker(position: initialPosition) marker.userData! = userData if clusterIcon.cgImage != nil { marker.icon = clusterIcon } else { marker.icon = self.getCustomTitleItem(userData: userData) } marker.map = mapView if animated { CATransaction.begin() CAAnimation.init().duration = kGMUAnimationDuration marker.layer.latitude = position.latitude marker.layer.longitude = position.longitude CATransaction.commit() } return marker } func getCustomTitleItem(userData: AnyObject) -> UIImage { let item = userData as! POIItem return item.marker.icon! } }
5)在generateClusterItems方法中的MapViewController init POIItem中:
private func generateClusterItems() { for object in DataManager.sharedInstance.mapItemsArray { let doubleLat = Double(object.latitude) let doubleLong = Double(object.longitude) let latitude = CLLocationDegrees(doubleLat!) let longitude = CLLocationDegrees(doubleLong!) let position = CLLocationCoordinate2DMake(latitude, longitude) let marker = GMSMarker(position: position) let item = POIItem(position: position, marker: marker) self.clusterManager.add(item) item.mapItem = object } }
在for循环中你可以调用:
marker.icon = UIImage(named:"YOUR_IMAGE_NAME")
现在,您可以将逻辑设置为具有多个自定义标记.