4

我正在使用適用於iOS的Google Maps API,並且想要使用標記羣集實用程序。我想出瞭如何顯示羣集標記,但我想定製標記。有人可以解釋如何設置/更改每個標記或羣集標記的圖標和標題嗎?示例代碼將非常有用。如何在Swift中實現GMUClusterRenderer

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和更新函數。

+0

你需要展示你試過的東西。 – Feldur

回答

1

如果您將Google-Maps-iOS-Utils源文件包含到項目中,則有一種「髒」的方式可以更改標記圖標。

不幸的是,沒有公共方法來設置自定義圖標,但您可以在源文件中更改它。

在谷歌地圖的Utils /羣集/查看/ GMUDefaultClusterRenderer.m

- (void)renderCluster:(id<GMUCluster>)cluster animated:(BOOL)animated { 
... 

     GMSMarker *marker = [self markerWithPosition:item.position 
               from:fromPosition 
              userData:item 
             clusterIcon:[UIImage imageNamed:@"YOUR_CUSTOM_ICON"] 
              animated:shouldAnimate]; 
... 

} 

比你能設置你的集羣管理器(SWIFT)

private func setupClusterManager() { 
     let iconGenerator = GMUDefaultClusterIconGenerator() 
     let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm() 
     let renderer = GMUDefaultClusterRenderer(mapView: mapView, 
               clusterIconGenerator: iconGenerator) 


     clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, 
              renderer: renderer) 

} 
+0

謝謝。這是我正在尋找的答案。 –

2

我設法找到 「乾淨」 的解決方案,甚至儘管它仍然令人困惑。但它的作品!

1)創建.h文件中 「MarkerManager」

#import <Foundation/Foundation.h> 
@import CoreLocation; 
#import "GMUClusterItem.h" 
#import <GoogleMaps/GoogleMaps.h> 


@interface MarkerManager: NSObject 

@property (nonatomic) CLLocationCoordinate2D location; 
@property (nonatomic, strong) GMSMarker *marker; 

@end 

2)轉到谷歌,地圖-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)創建新雨燕類,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 CLA ss和覆蓋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)的MapViewController初始化POIItem在generateClusterItems方法:

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") 

現在你可以設置邏輯擁有更多的自定義標記。

+0

我喜歡你的解決方案,它適用於Swift 3,但現在在Swift 4中,你會得到一個「隱式的Objective-C入口點,在聲明中添加顯式的'@objc'來發出Swift 4中的Objective-C入口點。你有沒有找到另一種解決方法? –

+0

在POIItem類中,只需在「var marker」前添加@objc,我編輯瞭解決方案。 對不起,延遲迴復。 – nja

+0

謝謝你的迴應。 –

2

我發現了一個乾淨的解決方案爲集羣的標記,在斯威夫特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

相關問題