Google Maps iOS Utils에서 마커를 함께 표시

14288 단어 iOSSwiftGoogleMapsAPI
Google Maps SDK를 사용하고 있으며지도에 마커를 설정하는 경우가 많습니다.
다만, 맵상에 마커를 너무 세게 하면, 광역 표시로 했을 때에 마커가 밀집해 버려 보기 흉해져 버리는 일도 자주 있다고 생각합니다

그런 때 마커를 하나로 정리하고 싶다고 생각했으므로, 그 실장 방법을 남겨두고 싶다고 쫓습니다



개발 환경



Xcode:11.1(11A1027)
Swift 5
iOS: 13.1
CocoaPods: 1.8.0

구현



라이브러리 설치



Google Maps iOS Utils를 설치하려면 CocoaPods를 사용하십시오.
다음과 같이 Podfile을 편집하고 pod install를 실행하십시오.
target 'YOUR_APPLICATION_TARGET_NAME_HERE' do
  use_frameworks!

  pod 'GoogleMaps'
  pod 'Google-Maps-iOS-Utils'
end

여기 설정 가이드 에도 기재되어 있습니다만,
CocoaPods 버전이 1.8.1 이상은 지원되지 않는 것 같습니다.

1.6.1이 권장되는 것으로 보이지만 Xcode11에서는 1.6.1을 사용할 때 빌드가 통과되지 않았기 때문에 이번에는 1.8.0을 사용하고 있습니다.

CocoaPods 버전을 낮추려면 여기을 참조하십시오.

마커를 함께 표시하는 클래스를 만듭니다.



평소에는 GMSMarker class 를 사용해 마커를 표시하고 있습니다만,
마커를 한꺼번에 표시하려면 GMUClusterItem protocol 에 준거한 class 를 작성해, 그 class 를 사용해 마커를 표시할 필요가 있습니다
import GoogleMapsUtils

class POIItem: NSObject, GMUClusterItem {

    var position: CLLocationCoordinate2D

    init(position: CLLocationCoordinate2D) {
        self.position = position
    }
}

지도에 마커 배치



방금 만든 class POIItem를 사용하여 마커를 Google Map에 표시합니다.
import UIKit
import GoogleMaps
import GoogleMapsUtils

class ViewController: UIViewController {

  // デフォルトの位置情報(仮で東京駅付近にしています)
    let defaultPositionLat = 35.681223
    let defaultPositionLng = 139.767059
    private var mapView: GMSMapView!
    /// Map 上に表示するマーカーを管理するためのプロパティ
    private var clusterManager: GMUClusterManager!

    override func viewDidLoad() {
        super.viewDidLoad()

        // GoogleMapの初期位置
        let camera = GMSCameraPosition.camera(withLatitude: defaultPositionLat, longitude: defaultPositionLng, zoom: 17.0)
        mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
        view = mapView

        let iconGenerator = GMUDefaultClusterIconGenerator()
        let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
        let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
        clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)

        // マーカーをランダムに生成して Map 上に表示
        generateClusterItems()
    }

    private func generateClusterItems() {
        let extent = 0.01
        for _ in 1...100 {
            let lat = defaultPositionLat + extent * randomScale()
            let lng = defaultPositionLng + extent * randomScale()
            let item = POIItem(position: CLLocationCoordinate2DMake(lat, lng))
            clusterManager.add(item)
        }
        // Map にマーカーを描画
        clusterManager.cluster()
    }

    /// ランダムな位置にマーカーを表示するための乱数を生成
    private func randomScale() -> Double {
        return Double(arc4random()) / Double(UINT32_MAX) * 2.0 - 1.0
    }
}

위의 코드를 실행하면 처음에 올린 gif와 같은 거동이 될 것이라고 생각합니다.

Delegate 라든지



마커를 탭했을 때의 액션을 설정하고 싶은 경우, 아래와 같이 GMUClusterManagerDelegateGMSMapViewDelegate
class ViewController: UIViewController, GMUClusterManagerDelegate, GMSMapViewDelegate {

    private var mapView: GMSMapView!
    private var clusterManager: GMUClusterManager!

    override func viewDidLoad() {
        super.viewDidLoad()

        // ... Rest of code omitted for easy reading.

        // Register self to listen to both GMUClusterManagerDelegate and
        // GMSMapViewDelegate events.
        clusterManager.setDelegate(self, mapDelegate: self)
    }

    // MARK: - GMUClusterManagerDelegate
    func clusterManager(clusterManager: GMUClusterManager, didTapCluster cluster: GMUCluster) {
        let newCamera = GMSCameraPosition.cameraWithTarget(cluster.position,
      zoom: mapView.camera.zoom + 1)
        let update = GMSCameraUpdate.setCamera(newCamera)
        mapView.moveCamera(update)
    }

    // MARK: - GMUMapViewDelegate
    func mapView(mapView: GMSMapView, didTapMarker marker: GMSMarker) -> Bool {
        if let poiItem = marker.userData as? POIItem {
            NSLog("Did tap marker for cluster item \(poiItem.name)")
        } else {
            NSLog("Did tap a normal marker")
        }
        return false
    }
}


끝에



Google Maps iOS Utils라는 라이브러리는 마커를 결합 할뿐만 아니라,
마커의 이미지를 커스터마이징하거나 KML이나 GeoJSON을 렌더링 할 수 있으며 다른 많은 기능을 사용할 수 있기 때문에 기회가 있으면 만져볼까 생각합니다.

참고


  • Marker Clustering
  • Marker Clustering Setup and Demo
  • github:google-maps-ios-utils
  • 좋은 웹페이지 즐겨찾기