เพิ่มแผนที่ลงในแอป iOS (Swift)

1. ก่อนที่คุณจะเริ่มต้น

โค้ดแล็บนี้จะสอนวิธีเริ่มต้นใช้งาน Google Maps Platform เพื่อสร้างแอป iOS ใน Swift คุณจะสร้างแอป iOS ที่ทำสิ่งต่อไปนี้

  • โหลด Maps SDK สำหรับ iOS และไลบรารียูทิลิตี Maps SDK สำหรับ iOS
  • แสดงแผนที่ที่อยู่ตรงกลางซิดนีย์ ประเทศออสเตรเลีย
  • แสดงเครื่องหมายที่กำหนดเองสำหรับจุด 100 จุดรอบซิดนีย์
  • ใช้การคลัสเตอร์เครื่องหมาย
  • เปิดใช้การโต้ตอบของผู้ใช้ที่จะจัดกึ่งกลางใหม่และวาดวงกลมบนแผนที่เมื่อแตะเครื่องหมาย

แผนที่ที่มีเครื่องหมายในแอป iOS

ข้อกำหนดเบื้องต้น

  • มีความรู้พื้นฐานเกี่ยวกับการพัฒนา Swift และ iOS

สิ่งที่คุณต้องดำเนินการ

  • โหลด Maps SDK สำหรับ iOS และไลบรารียูทิลิตี Google Maps SDK สำหรับ iOS
  • โหลดแผนที่
  • ใช้เครื่องหมาย เครื่องหมายที่กำหนดเอง และการจัดกลุ่มเครื่องหมาย
  • ทำงานร่วมกับระบบเหตุการณ์ของ Maps SDK สำหรับ iOS เพื่อรองรับการโต้ตอบของผู้ใช้
  • ควบคุมกล้องของแผนที่โดยใช้โปรแกรม
  • วาดในแผนที่

สิ่งที่คุณต้องมี

หากต้องการทำ Codelab นี้ให้เสร็จสมบูรณ์ คุณต้องมีบัญชี บริการ และเครื่องมือต่อไปนี้

  • Xcode 12.0 ขึ้นไปที่มี SDK เป้าหมายเป็น 12.0 ขึ้นไป
  • ติดตั้ง Cocoapods แล้ว
  • บัญชี Google Cloud Platform ที่เปิดใช้การเรียกเก็บเงินแล้ว (ดูขั้นตอนถัดไป)
  • โปรเจ็กต์ใน Cloud Console ที่เปิดใช้ Maps SDK สำหรับ iOS (ดูขั้นตอนถัดไป)

2. ตั้งค่า

สำหรับขั้นตอนการเปิดใช้ด้านล่าง คุณต้องเปิดใช้ Maps SDK สำหรับ iOS

ตั้งค่า Google Maps Platform

หากยังไม่มีบัญชี Google Cloud Platform และโปรเจ็กต์ที่เปิดใช้การเรียกเก็บเงิน โปรดดูคู่มือเริ่มต้นใช้งาน Google Maps Platform เพื่อสร้างบัญชีสำหรับการเรียกเก็บเงินและโปรเจ็กต์

  1. ใน Cloud Console ให้คลิกเมนูแบบเลื่อนลงของโปรเจ็กต์ แล้วเลือกโปรเจ็กต์ที่ต้องการใช้สำหรับ Codelab นี้

  1. เปิดใช้ Google Maps Platform APIs และ SDK ที่จำเป็นสำหรับ Codelab นี้ใน Google Cloud Marketplace โดยทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้
  2. สร้างคีย์ API ในหน้าข้อมูลเข้าสู่ระบบของ Cloud Console คุณสามารถทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้ คำขอทั้งหมดไปยัง Google Maps Platform ต้องใช้คีย์ API

คู่มือเริ่มใช้งานฉบับย่อ

เรามีโค้ดเริ่มต้นที่จะช่วยให้คุณเริ่มต้นใช้งานได้อย่างรวดเร็วที่สุด และช่วยให้คุณทำตาม Codelab นี้ได้

  1. โคลนที่เก็บหากคุณติดตั้ง git ไว้
git clone https://github.com/googlemaps/codelab-maps-platform-101-swift.git

หรือคลิกส่งโค้ดให้ฉันเพื่อดาวน์โหลดซอร์สโค้ด

  1. หลังจากดาวน์โหลดโค้ดแล้ว ให้เปิดโปรเจ็กต์ StarterApp ในไดเรกทอรี /starter โปรเจ็กต์นี้มีโครงสร้างไฟล์พื้นฐานที่คุณต้องใช้เพื่อทำ Codelab ให้เสร็จสมบูรณ์ ทุกอย่างที่คุณต้องใช้ในการทำงานจะอยู่ในไดเรกทอรี /starter/StarterApp

หากต้องการดูโค้ดโซลูชันแบบเต็มที่ทำงานอยู่ ให้ดูโค้ดที่เสร็จสมบูรณ์แล้วในไดเรกทอรี /solution/SolutionApp

3. ติดตั้ง Maps SDK สำหรับ iOS

ขั้นตอนแรกในการใช้ Maps SDK สำหรับ iOS คือการติดตั้งการอ้างอิงที่จำเป็น กระบวนการนี้มี 2 ขั้นตอน ได้แก่ การติดตั้ง Maps SDK สำหรับ iOS และ Maps SDK สำหรับ iOS Utility Library จากเครื่องมือจัดการทรัพยากร Dependency ของ Cocoapods และการระบุคีย์ API ให้กับ SDK

  1. เพิ่ม Maps SDK สำหรับ iOS และ Maps SDK สำหรับ iOS Utility Library ลงใน Podfile

Codelab นี้ใช้ทั้ง Maps SDK สำหรับ iOS ซึ่งมีฟังก์ชันหลักทั้งหมดของ Google Maps และ Maps iOS Utility Library ซึ่งมีเครื่องมือต่างๆ มากมายเพื่อเพิ่มประสิทธิภาพแผนที่ รวมถึงการจัดกลุ่มเครื่องหมาย

หากต้องการเริ่มต้น ให้เปิด Podfile ใน Xcode (หรือเครื่องมือแก้ไขข้อความที่คุณต้องการ) แล้วอัปเดตไฟล์ให้รวมทรัพยากร Dependency ของ Maps SDK สำหรับ iOS และไลบรารียูทิลิตีภายใต้ความคิดเห็น # Pods for StarterApp

pod 'GoogleMaps', '6.1.0'
pod 'Google-Maps-iOS-Utils', '3.4.0'

ดูเอกสารประกอบเวอร์ชันของ Maps SDK สำหรับ iOS เพื่อดู SDK เวอร์ชันล่าสุดและคำแนะนำในการบำรุงรักษา

Podfile ควรมีลักษณะดังนี้

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'

target 'StarterApp' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for StarterApp
  pod 'GoogleMaps', '6.1.0'
  pod 'Google-Maps-iOS-Utils', '3.4.0'
end
  1. ติดตั้ง Maps SDK สำหรับ iOS และพ็อดของ Maps SDK สำหรับ iOS Utility Library

หากต้องการติดตั้งการขึ้นต่อกัน ให้เรียกใช้ pod install ในไดเรกทอรี /starter จากบรรทัดคำสั่ง Cocoapods จะดาวน์โหลดการขึ้นต่อกันโดยอัตโนมัติและสร้าง StarterApp.xcworkspace

  1. เมื่อติดตั้งการขึ้นต่อกันแล้ว ให้เรียกใช้ open StarterApp.xcworkspace จากไดเรกทอรี /starter เพื่อเปิดไฟล์ใน Xcode จากนั้นเรียกใช้แอปในโปรแกรมจำลอง iPhone โดยกด Command+R หากตั้งค่าทุกอย่างถูกต้องแล้ว โปรแกรมจำลองจะเปิดขึ้นและแสดงหน้าจอสีดำ ไม่ต้องกังวล คุณยังไม่ได้สร้างอะไรเลย จึงเป็นเรื่องปกติ
  2. นำเข้า SDK ใน AppDelegate.swift

เมื่อติดตั้งการขึ้นต่อกันแล้ว ก็ถึงเวลาให้คีย์ API แก่ SDK ขั้นตอนแรกคือการนำเข้า Maps SDK สำหรับ iOS เป็นการขึ้นต่อกันโดยวางโค้ดต่อไปนี้ไว้ใต้import UIKitคำสั่งนำเข้า

import GoogleMaps
  1. ส่งคีย์ API ไปยัง iOS SDK โดยการเรียกใช้ provideAPIKey ใน GMSServices ใน application: didFinishLaunchingWithOptions:
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    // Override point for customization after application launch.
    GMSServices.provideAPIKey("YOUR_API_KEY")

    return true
  }

ตอนนี้ไฟล์ AppDelegate.swift ที่อัปเดตแล้วควรมีลักษณะดังนี้

import UIKit
import GoogleMaps

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    // Override point for customization after application launch.
    GMSServices.provideAPIKey("YOUR_API_KEY")

    return true
  }

}

แทนที่ YOUR_API_KEY ด้วยคีย์ API ที่คุณสร้างใน Cloud Console

ตอนนี้คุณได้ติดตั้งการขึ้นต่อกันและระบุคีย์ API แล้ว คุณก็พร้อมที่จะเริ่มเรียกใช้ Maps SDK สำหรับ iOS

4. แสดงแผนที่

ได้เวลาแสดงแผนที่แรกแล้ว

ส่วนที่ใช้บ่อยที่สุดของ Maps SDK สำหรับ iOS คือคลาส GMSMapView ซึ่งมีเมธอดมากมายที่ช่วยให้คุณสร้างและจัดการอินสแตนซ์ของแผนที่ได้ โดยมีวิธีการดังนี้

  1. เปิด ViewController.swift

นี่คือส่วนที่คุณจะทำงานที่เหลือสำหรับโค้ดแล็บนี้ โปรดสังเกตว่าระบบได้สร้างเหตุการณ์วงจรของ loadView และ viewDidLoad สำหรับตัวควบคุมมุมมองให้คุณแล้ว

  1. นำเข้า Maps SDK สำหรับ iOS โดยเพิ่มโค้ดนี้ที่ด้านบนของไฟล์
import GoogleMaps
  1. ประกาศViewControllerตัวแปรอินสแตนซ์เพื่อจัดเก็บ GMSMapView

อินสแตนซ์ของ GMSMapView คือออบเจ็กต์หลักที่คุณจะใช้ตลอดทั้งโค้ดแล็บนี้ และคุณจะอ้างอิงและดำเนินการกับออบเจ็กต์นี้จากเมธอดวงจรของตัวควบคุมมุมมองต่างๆ หากต้องการทำให้พร้อมใช้งาน ให้อัปเดตการติดตั้งใช้งานของ ViewController เพื่อประกาศตัวแปรอินสแตนซ์ที่จะจัดเก็บ

class ViewController: UIViewController {

  private var mapView: GMSMapView!

  ...
}
  1. ใน loadView ให้สร้างอินสแตนซ์ของ GMSCameraPosition

GMSCameraPosition กำหนดตำแหน่งศูนย์กลางของแผนที่และระดับการซูมที่จะแสดง โค้ดนี้เรียกใช้เมธอด cameraWithLatitude:longitude:zoom: เพื่อจัดกึ่งกลางแผนที่ในซิดนีย์ ออสเตรเลีย ที่ละติจูด -33.86 และลองจิจูด 151.20 โดยมีระดับการซูมเป็น 12

let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 12)
  1. ใน loadView ให้สร้างอินสแตนซ์ของ GMSMapView เพื่อสร้างอินสแตนซ์ของแผนที่

หากต้องการสร้างอินสแตนซ์แผนที่ใหม่ ให้เรียกใช้ GMSMapView(frame: CGRect, camera: GMSCameraPosition) โปรดสังเกตว่ามีการตั้งค่าเฟรมเป็น CGRect.zero ซึ่งเป็นตัวแปรส่วนกลางจากไลบรารี CGGeometry ของ iOS ที่ระบุเฟรมที่มีความกว้าง 0 ความสูง 0 ซึ่งอยู่ที่ตำแหน่ง (0,0) ภายในตัวควบคุมมุมมอง ระบบจะตั้งค่ากล้องเป็นตำแหน่งกล้องที่คุณเพิ่งสร้าง

จากนั้นตั้งค่ามุมมองรากของตัวควบคุมมุมมองเป็น mapView เพื่อแสดงแผนที่แบบเต็มหน้าจอ

    mapView = GMSMapView(frame: .zero, camera: camera)
    self.view = mapView
  1. ตั้งค่า GMSMapViewDelegate เป็นตัวควบคุมมุมมอง

เมื่อใช้งานแล้ว ตัวแทนมุมมองแผนที่จะช่วยให้คุณจัดการเหตุการณ์จากการโต้ตอบของผู้ใช้ในอินสแตนซ์ GMSMapView ซึ่งคุณจะต้องใช้ในภายหลัง

ก่อนอื่น ให้อัปเดตอินเทอร์เฟซของ ViewController ให้เป็นไปตามโปรโตคอลสำหรับ GMSMapViewDelegate:

class ViewController: UIViewController, GMSMapViewDelegate

จากนั้นเพิ่มบรรทัดต่อไปนี้ในฟังก์ชัน loadView เพื่อตั้งค่า GMSMapViewDelegate เป็น ViewController

    mapView.delegate = self

ตอนนี้ให้โหลดแอปในโปรแกรมจำลอง iOS (Command+R) อีกครั้ง แล้วแผนที่ควรจะปรากฏตามที่แสดงในภาพหน้าจอต่อไปนี้

แอป iOS แสดง Google Maps

รูปที่ 1. แอป iOS ที่แสดงแผนที่ Google

สรุปคือในขั้นตอนนี้ คุณได้สร้างอินสแตนซ์ของ GMSMapView เพื่อแสดงแผนที่ที่อยู่ตรงกลางเมืองซิดนีย์ ประเทศออสเตรเลีย

ตอนนี้ไฟล์ ViewController.swift ควรมีลักษณะดังนี้

import UIKit
import GoogleMaps

class ViewController: UIViewController, GMSMapViewDelegate {

  private var mapView: GMSMapView!

  override func loadView() {

    // Load the map at set latitude/longitude and zoom level
    let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 11)

    mapView = GMSMapView(frame: .zero, camera: camera)
    self.view = mapView
    mapView.delegate = self
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
  }

}

5. จัดรูปแบบแผนที่ (ไม่บังคับ)

คุณปรับแต่งสไตล์ของแผนที่ได้โดยใช้การจัดรูปแบบแผนที่ในระบบคลาวด์

สร้างรหัสแผนที่

หากยังไม่ได้สร้างรหัสแมปที่มีรูปแบบแผนที่เชื่อมโยงอยู่ โปรดดูคำแนะนำเกี่ยวกับรหัสแมปเพื่อทำตามขั้นตอนต่อไปนี้

  1. สร้างรหัสแผนที่
  2. เชื่อมโยงรหัสแผนที่กับรูปแบบแผนที่

เพิ่มรหัสแมปลงในแอป

หากต้องการใช้รหัสแผนที่ที่คุณสร้างในขั้นตอนก่อนหน้า ให้เปิดไฟล์ ViewController.swift และสร้างออบเจ็กต์ GMSMapID ภายในเมธอด loadView แล้วระบุรหัสแผนที่ จากนั้นแก้ไขGMSMapViewการเริ่มต้นGMSMapIDโดยระบุออบเจ็กต์GMSMapIDเป็นพารามิเตอร์

ViewController.swift

  override func loadView() {

    // Load the map at set latitude/longitude and zoom level
    let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 11)
    let mapID = GMSMapID(identifier: "YOUR_MAP_ID")

    mapView = GMSMapView(frame: .zero, mapID: mapID, camera: camera)
    self.view = mapView
    mapView.delegate = self
  }

เมื่อดำเนินการเสร็จแล้ว ให้เรียกใช้แอปเพื่อดูแผนที่ในรูปแบบที่คุณเลือก

6. เพิ่มเครื่องหมายลงในแผนที่

นักพัฒนาแอปทำสิ่งต่างๆ มากมายด้วย Maps SDK สำหรับ iOS แต่การวางเครื่องหมายบนแผนที่ได้รับความนิยมมากที่สุดอย่างแน่นอน เครื่องหมายจะแสดงจุดที่เฉพาะเจาะจงบนแผนที่ และเป็นองค์ประกอบ UI ทั่วไปสำหรับการจัดการการโต้ตอบของผู้ใช้ หากเคยใช้ Google Maps มาก่อน คุณอาจคุ้นเคยกับเครื่องหมายเริ่มต้นซึ่งมีลักษณะเหมือนหมุดสีแดงในรูปที่ 2

แผนที่ที่มีเครื่องหมายสีแดง

รูปที่ 2 แผนที่ที่มีเครื่องหมายสีแดง

ขั้นตอนนี้แสดงวิธีใช้คลาส GMSMarker เพื่อวางเครื่องหมายบนแผนที่

โปรดทราบว่าคุณจะวางเครื่องหมายบนแผนที่ไม่ได้จนกว่าจะโหลดแผนที่จากขั้นตอนก่อนหน้าในloadViewเหตุการณ์วงจรของ View Controller ดังนั้นให้ทำตามขั้นตอนเหล่านี้ในviewDidLoadเหตุการณ์วงจรของ View Controller ซึ่งจะเรียกใช้หลังจากโหลด View (และแผนที่) แล้ว

  1. กำหนดออบเจ็กต์ CLLocationCoordinate2D

CLLocationCoordinate2D คือโครงสร้างที่ไลบรารี CoreLocation ของ iOS จัดเตรียมไว้ ซึ่งกำหนดตำแหน่งทางภูมิศาสตร์ที่ละติจูดและลองจิจูดที่ตั้งไว้ หากต้องการเริ่มสร้างเครื่องหมายแรก ให้กำหนดออบเจ็กต์ CLLocationCoordinate2D และตั้งค่าละติจูดและลองจิจูดเป็นศูนย์กลางของแผนที่ ระบบจะเข้าถึงพิกัดของจุดกึ่งกลางของแผนที่จากมุมมองแผนที่โดยใช้พร็อพเพอร์ตี้ camera.target.latitude และ camera.target.longitude

    // Add a single marker with a custom icon
    let mapCenter = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude)
  1. สร้างอินสแตนซ์ของ GMSMarker

Maps SDK สำหรับ iOS มีคลาส GMSMarker แต่ละอินสแตนซ์ของ GMSMarker แสดงเครื่องหมายแต่ละรายการบนแผนที่ และสร้างขึ้นโดยการเรียก markerWithPosition: และส่งออบเจ็กต์ CLLocationCoordinate2D ไปยังออบเจ็กต์ดังกล่าวเพื่อบอก SDK ว่าจะวางเครื่องหมายไว้ที่ใดบนแผนที่

    let marker = GMSMarker(position: mapCenter)
  1. ตั้งค่าไอคอนเครื่องหมายที่กำหนดเอง

เครื่องหมายหมุดสีแดงเริ่มต้นสำหรับ Google Maps นั้นยอดเยี่ยม แต่การปรับแต่งแผนที่ก็ยอดเยี่ยมเช่นกัน โชคดีที่การใช้เครื่องหมายที่กำหนดเองนั้นทำได้ง่ายด้วย Maps SDK สำหรับ iOS โปรดทราบว่าโปรเจ็กต์ StarterApp มีรูปภาพชื่อ "custom_pin.png" ให้คุณใช้ แต่คุณจะใช้รูปภาพใดก็ได้ตามต้องการ

หากต้องการตั้งค่าเครื่องหมายที่กำหนดเอง ให้ตั้งค่าพร็อพเพอร์ตี้ icon ของเครื่องหมายเป็นอินสแตนซ์ของ UIImage

    marker.icon = UIImage(named: "custom_pin.png")
  1. แสดงเครื่องหมายในแผนที่

ระบบสร้างเครื่องหมายแล้ว แต่ยังไม่ได้แสดงบนแผนที่ โดยตั้งค่าพร็อพเพอร์ตี้ map ของอินสแตนซ์ GMSMarker เป็นอินสแตนซ์ของ GMSMapView

    marker.map = mapView

ตอนนี้ให้โหลดแอปซ้ำ แล้วคุณจะเห็นแผนที่แรกที่มีเครื่องหมายดังที่แสดงในรูปที่ 3

แอป iOS ที่แสดง Google Maps พร้อมเครื่องหมายสีแดงตรงกลาง

รูปที่ 3. แอป iOS ที่แสดง Google Maps พร้อมเครื่องหมายสีแดงตรงกลาง

สรุปคือ ในส่วนนี้ คุณได้สร้างอินสแตนซ์ของคลาส GMSMarker และนำไปใช้กับมุมมองแผนที่เพื่อแสดงเครื่องหมายบนแผนที่ เหตุการณ์วงจร viewDidLoad ที่อัปเดตแล้วใน ViewController.swift ควรมีลักษณะดังนี้

  override func viewDidLoad() {
    super.viewDidLoad()

    // Add a single marker with a custom icon
    let mapCenter = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude)
    let marker = GMSMarker(position: mapCenter)

    marker.icon = UIImage(named: "custom_pin.png")
    marker.map = mapView
  }

7. เปิดใช้การจัดกลุ่มเครื่องหมาย

หากใช้เครื่องหมายจำนวนมากหรือมีเครื่องหมายที่อยู่ใกล้กัน คุณอาจพบปัญหาที่เครื่องหมายซ้อนทับกันหรือปรากฏอยู่ใกล้กันมาก ซึ่งทำให้ผู้ใช้ได้รับประสบการณ์ที่ไม่ดี เช่น หากเครื่องหมาย 2 อันอยู่ใกล้กันมาก คุณอาจพบสถานการณ์ดังที่เห็นในรูปที่ 4

เครื่องหมาย 2 อันอยู่ใกล้กันมาก

รูปที่ 4 เครื่องหมาย 2 อันอยู่ใกล้กันมาก

การคลัสเตอร์เครื่องหมายจึงเข้ามามีบทบาทในจุดนี้ การจัดกลุ่มเครื่องหมายเป็นอีกฟีเจอร์ที่ใช้กันโดยทั่วไป ซึ่งจะจัดกลุ่มเครื่องหมายที่อยู่ใกล้เคียงเป็นไอคอนเดียวที่เปลี่ยนแปลงตามระดับการซูม ดังที่แสดงในรูปที่ 5

ตัวอย่างเครื่องหมายที่จัดกลุ่มเป็นไอคอนเดียว

รูปที่ 5 ตัวอย่างเครื่องหมายที่จัดกลุ่มเป็นไอคอนเดียว

อัลกอริทึมสำหรับการจัดกลุ่มเครื่องหมายจะแบ่งพื้นที่ที่มองเห็นได้ของแผนที่ออกเป็นตารางกริด จากนั้นจะจัดกลุ่มไอคอนที่อยู่ในเซลล์เดียวกัน ทีม Google Maps Platform ได้สร้างไลบรารียูทิลิตีแบบโอเพนซอร์สที่มีประโยชน์ชื่อว่า Google Maps SDK สำหรับ iOS Utility Library ซึ่งจะจัดการการจัดกลุ่มเครื่องหมายให้คุณโดยอัตโนมัติ รวมถึงสิ่งอื่นๆ อีกมากมาย อ่านเพิ่มเติมเกี่ยวกับการจัดกลุ่มเครื่องหมายในเอกสารประกอบของ Google Maps Platform หรือดูแหล่งที่มาของไลบรารียูทิลิตี iOS ใน GitHub

  1. เพิ่มเครื่องหมายลงในแผนที่

หากต้องการดูการจัดกลุ่มเครื่องหมายในการทำงาน คุณจะต้องมีเครื่องหมายจำนวนมากบนแผนที่ หากต้องการปรับปรุงกระบวนการนี้ ให้ใช้เครื่องมือสร้างเครื่องหมายที่อยู่ในโปรเจ็กต์เริ่มต้นใน MarkerGenerator.swift

หากต้องการเพิ่มเครื่องหมายตามจำนวนที่ระบุลงในแผนที่ ให้เรียกใช้ MarkerGenerator(near:count:).markerArray ในวงจรviewDidLoadของตัวควบคุมมุมมองใต้โค้ดจากขั้นตอนก่อนหน้า เมธอดนี้จะสร้างเครื่องหมายตามจำนวนที่ระบุใน count ในตำแหน่งแบบสุ่มรอบๆ พิกัดที่ระบุในออบเจ็กต์ CLLocationCoordinate2D ในกรณีนี้ คุณสามารถส่งตัวแปร mapCenter ที่สร้างไว้ก่อนหน้านี้ได้ ระบบจะแสดงผลเครื่องหมายใน [GMSMarker]

    // Generate many markers
    let markerArray = MarkerGenerator(near: mapCenter, count: 100).markerArray

คุณสามารถทดสอบลักษณะของเครื่องหมายจำนวนมากนี้ได้โดยเพิ่มบรรทัดต่อไปนี้หลังคำจำกัดความของ markerArray แล้วเรียกใช้แอป อย่าลืมแสดงความคิดเห็นในบรรทัดเหล่านี้ก่อนที่จะไปยังขั้นตอนถัดไป ซึ่งใช้ Marker Clusterer เพื่อจัดการการแสดงเครื่องหมายแทน

    // Comment the following code out if using the marker clusterer
    // to manage markers instead.
    for marker in markerArray {
      marker.map = mapView
    }
  1. นำเข้าไลบรารียูทิลิตีของ Google Maps SDK สำหรับ iOS

หากต้องการเพิ่มไลบรารียูทิลิตี Maps iOS เป็นทรัพยากร Dependency ในโปรเจ็กต์ ให้เพิ่มรายการนี้ลงในรายการทรัพยากร Dependency ที่ด้านบนของ ViewController.swift

import GoogleMapsUtils
  1. กำหนดค่าเครื่องหมายคลัสเตอร์

หากต้องการใช้ Marker Clusterer คุณต้องระบุ 3 สิ่งเพื่อกำหนดค่าวิธีการทำงาน ได้แก่ อัลกอริทึมการจัดกลุ่ม ตัวสร้างไอคอน และตัวแสดงผล อัลกอริทึมจะกำหนดลักษณะการทำงานของวิธีจัดกลุ่มเครื่องหมาย เช่น ระยะห่างระหว่างเครื่องหมายที่จะรวมไว้ในคลัสเตอร์เดียวกัน เครื่องมือสร้างไอคอนจะสร้างไอคอนคลัสเตอร์เพื่อใช้ในระดับการซูมต่างๆ ตัวแสดงผลจะจัดการการแสดงผลจริงของไอคอนคลัสเตอร์บนแผนที่

คุณเขียนทั้งหมดนี้ตั้งแต่ต้นได้หากต้องการ หรือคุณจะใช้ไลบรารียูทิลิตี iOS ของ Maps ซึ่งมีการติดตั้งใช้งานเริ่มต้นเพื่อทำให้กระบวนการเร็วขึ้นก็ได้ เพิ่มบรรทัดต่อไปนี้

    // Set up the cluster manager with a supplied icon generator and renderer.
    let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
    let iconGenerator = GMUDefaultClusterIconGenerator()
    let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
  1. สร้างอินสแตนซ์ของ GMUClusterManager

GMUClusterManager คือคลาสที่ใช้การจัดกลุ่มเครื่องหมายโดยใช้อัลกอริทึม ตัวสร้างไอคอน และตัวแสดงผลที่คุณระบุ หากต้องการสร้างตัวแสดงผลและทำให้พร้อมใช้งานในมุมมองแผนที่ ให้เพิ่มตัวแปรอินสแตนซ์ลงในViewControllerการติดตั้งใช้งานเพื่อจัดเก็บอินสแตนซ์ Cluster Manager ก่อน

class ViewController: UIViewController, GMSMapViewDelegate {

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

จากนั้นสร้างอินสแตนซ์ของ GMUClusterManager ในเหตุการณ์วงจรของ viewDidLoad โดยทำดังนี้

    clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
  1. เพิ่มเครื่องหมายและเรียกใช้เครื่องมือจัดกลุ่มเครื่องหมาย

เมื่อกำหนดค่าอินสแตนซ์ของ MarkerClusterer แล้ว ให้ส่งอาร์เรย์ของเครื่องหมายที่จะจัดกลุ่มไปยัง ClusterManager โดยเรียกใช้ add(items:) จากนั้นเรียกใช้ Clusterer โดยเรียกใช้ cluster

    clusterManager.setMapDelegate(self)
    clusterManager.add(markerArray)
    clusterManager.cluster()

โหลดแอปอีกครั้ง ตอนนี้คุณควรเห็นเครื่องหมายจำนวนมากที่จัดกลุ่มอย่างเรียบร้อยเหมือนตัวอย่างในรูปที่ 6 ลองเล่นกับระดับการซูมต่างๆ โดยการบีบและซูมบนแผนที่เพื่อดูว่ากลุ่มเครื่องหมายจะปรับเปลี่ยนตามการซูมเข้า/ออกอย่างไร

แอป iOS ที่มี Google Map และเครื่องหมายที่จัดกลุ่ม

รูปที่ 6 แอป iOS ที่มี Google Maps และเครื่องหมายที่จัดกลุ่ม

โดยสรุป ในขั้นตอนนี้ คุณได้กำหนดค่าอินสแตนซ์ของเครื่องหมายคลัสเตอร์จากไลบรารียูทิลิตีของ Google Maps SDK สำหรับ iOS แล้วใช้เพื่อจัดกลุ่มเครื่องหมาย 100 รายการบนแผนที่ ตอนนี้viewDidLoadเหตุการณ์วงจรลูกค้าใน ViewController.swift ควรมีลักษณะดังนี้

  override func viewDidLoad() {
    super.viewDidLoad()

    // Add a single marker with a custom icon
    let mapCenter = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude)
    let marker = GMSMarker(position: mapCenter)

    marker.icon = UIImage(named: "custom_pin.png")
    marker.map = mapView

    // Generate many markers
    let markerArray = MarkerGenerator(near: mapCenter, count: 100).markerArray
    // Comment the following code out if using the marker clusterer
    // to manage markers instead.
    //    for marker in markerArray {
    //      marker.map = mapView
    //    }

    // Set up the cluster manager with a supplied icon generator and renderer.
    let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
    let iconGenerator = GMUDefaultClusterIconGenerator()
    let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
    clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)

    clusterManager.setMapDelegate(self)
    clusterManager.add(markerArray)
    clusterManager.cluster()
  }

8. เพิ่มการโต้ตอบของผู้ใช้

ตอนนี้คุณมีแผนที่ที่ดูดีซึ่งแสดงเครื่องหมายและใช้การจัดกลุ่มเครื่องหมายแล้ว ในขั้นตอนนี้ คุณจะเพิ่มการจัดการเพิ่มเติมสำหรับการโต้ตอบของผู้ใช้โดยใช้ GMSMapViewDelegate ซึ่งคุณตั้งค่าไว้ใน ViewController ก่อนหน้านี้ เพื่อปรับปรุงประสบการณ์ของผู้ใช้ในแผนที่

Maps SDK สำหรับ iOS มีระบบเหตุการณ์ที่ครอบคลุมซึ่งใช้งานผ่านตัวแทนมุมมองแผนที่ ซึ่งรวมถึงตัวแฮนเดิลเหตุการณ์ที่ช่วยให้คุณเรียกใช้โค้ดได้เมื่อเกิดการโต้ตอบของผู้ใช้ต่างๆ ตัวอย่างเช่น ผู้มอบสิทธิ์ MapView มีเมธอดที่ช่วยให้คุณทริกเกอร์การเรียกใช้โค้ดสำหรับการโต้ตอบ เช่น ผู้ใช้คลิกที่แผนที่และเครื่องหมาย เลื่อนมุมมองของแผนที่ ซูมเข้าและออก และอื่นๆ

ในขั้นตอนนี้ คุณจะเลื่อนแผนที่โดยอัตโนมัติเพื่อจัดกึ่งกลางเครื่องหมายที่ผู้ใช้แตะ

  1. ติดตั้งใช้งาน Listener การแตะเครื่องหมาย

mapView(_:didTap:) จะเรียกใช้ทุกครั้งที่ผู้ใช้แตะเครื่องหมายใดเครื่องหมายหนึ่งที่คุณสร้างไว้ก่อนหน้านี้ และทุกครั้งที่ผู้ใช้แตะกลุ่มเครื่องหมาย (ภายในแล้ว กลุ่มเครื่องหมายจะได้รับการติดตั้งใช้งานเป็นอินสแตนซ์ของ GMSMarker)

หากต้องการใช้เครื่องมือตรวจหาเหตุการณ์ ให้เริ่มโดยการสร้าง Stub ไว้ที่ด้านล่างของ ViewController.swift ก่อนวงเล็บปีกกาปิด

  func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {

    return false
  }

โปรดสังเกตว่าเมธอดจะแสดงผล false การทำเช่นนี้จะบอกให้ iOS SDK ดำเนินการลักษณะการทำงานเริ่มต้นของ GMSMarker ต่อไป เช่น แสดงหน้าต่างข้อมูลหากมีการกำหนดค่าไว้ หลังจากเรียกใช้โค้ดตัวแฮนเดิลเหตุการณ์

  1. จัดการเหตุการณ์การแตะและเคลื่อนไหวกล้องเพื่อจัดกึ่งกลางแผนที่ใหม่เมื่อมีการแตะเครื่องหมายหรือกลุ่มเครื่องหมาย

เมื่อเรียกใช้ mapView(_:didTap:) จะส่งอินสแตนซ์ของ GMSMarker ที่แตะเพื่อให้คุณจัดการได้ในโค้ด คุณสามารถใช้อินสแตนซ์นี้เพื่อจัดกึ่งกลางแผนที่ใหม่ได้โดยเรียก animate(toLocation:) ในมุมมองแผนที่จากภายในตัวแฮนเดิลเหตุการณ์ และส่งตำแหน่งของอินสแตนซ์เครื่องหมายจากพร็อพเพอร์ตี้ position

    // Animate to the marker
    mapView.animate(toLocation: marker.position)
  1. ซูมเข้าคลัสเตอร์เครื่องหมายเมื่อมีการแตะ

รูปแบบ UX ที่พบบ่อยคือการซูมเข้าคลัสเตอร์เครื่องหมายเมื่อมีการแตะ ซึ่งช่วยให้ผู้ใช้ดูเครื่องหมายที่จัดกลุ่มได้เมื่อคลัสเตอร์ขยายที่ระดับการซูมต่ำ

ดังที่ได้กล่าวไว้ก่อนหน้านี้ ไอคอนคลัสเตอร์เครื่องหมายคือการใช้งาน GMSMarker จริงๆ ที่มีไอคอนที่กำหนดเอง แล้วคุณจะบอกได้อย่างไรว่ามีการแตะเครื่องหมายหรือคลัสเตอร์เครื่องหมาย เมื่อตัวจัดการการจัดกลุ่มเครื่องหมายสร้างไอคอนคลัสเตอร์ใหม่ ตัวจัดการจะใช้ตัวอย่างของ GMSMarker เพื่อให้เป็นไปตามโปรโตคอลที่เรียกว่า GMUCluster. คุณสามารถใช้เงื่อนไขเพื่อตรวจสอบว่าเครื่องหมายที่ส่งไปยังตัวแฮนเดิลเหตุการณ์เป็นไปตามโปรโตคอลนี้หรือไม่

เมื่อทราบโดยโปรแกรมว่ามีการแตะคลัสเตอร์แล้ว คุณจะเรียกใช้ animate(toZoom:) ในอินสแตนซ์ของมุมมองแผนที่และตั้งค่าระดับการซูมเป็นระดับการซูมปัจจุบันบวก 1 ได้ ระดับการซูมปัจจุบันจะอยู่ในอินสแตนซ์ mapView ในพร็อพเพอร์ตี้ camera.zoom

นอกจากนี้ โปรดสังเกตว่าโค้ดต่อไปนี้จะแสดงผลเป็น true ซึ่งจะบอกตัวแฮนเดิลเหตุการณ์ว่าคุณจัดการเหตุการณ์เสร็จแล้ว และไม่ต้องเรียกใช้โค้ดเพิ่มเติมในตัวแฮนเดิล เหตุผลหนึ่งที่ทำเช่นนี้ก็เพื่อป้องกันไม่ให้ออบเจ็กต์ GMSMarker พื้นฐานดำเนินการตามลักษณะการทำงานเริ่มต้นที่เหลือ เช่น การแสดงหน้าต่างข้อมูล ซึ่งไม่สมเหตุสมผลนักในกรณีที่แตะไอคอนคลัสเตอร์

    // If the tap was on a marker cluster, zoom in on the cluster
    if let _ = marker.userData as? GMUCluster {
      mapView.animate(toZoom: mapView.camera.zoom + 1)
      return true
    }

ตอนนี้ให้โหลดแอปซ้ำแล้วแตะเครื่องหมายและคลัสเตอร์เครื่องหมายบางรายการ เมื่อแตะองค์ประกอบใดองค์ประกอบหนึ่ง แผนที่จะปรับจุดศูนย์กลางใหม่ไปยังองค์ประกอบที่แตะ เมื่อแตะคลัสเตอร์เครื่องหมาย แผนที่จะซูมเข้า 1 ระดับ และคลัสเตอร์เครื่องหมายจะขยายเพื่อแสดงเครื่องหมายที่จัดกลุ่มอยู่ด้านล่าง

สรุปคือในขั้นตอนนี้ คุณได้ติดตั้งใช้งาน Listener การแตะเครื่องหมาย และจัดการเหตุการณ์เพื่อจัดกึ่งกลางองค์ประกอบที่แตะและซูมเข้าหากองค์ประกอบนั้นเป็นไอคอนคลัสเตอร์เครื่องหมาย

mapView(_:didTap:) ของคุณควรมีลักษณะดังนี้

  func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {

    // Animate to the marker
    mapView.animate(toLocation: marker.position)

    // If the tap was on a marker cluster, zoom in on the cluster
    if let _ = marker.userData as? GMUCluster {
      mapView.animate(toZoom: mapView.camera.zoom + 1)
      return true
    }

    return false
  }

9. วาดในแผนที่

จนถึงตอนนี้ คุณได้สร้างแผนที่ซิดนีย์ที่แสดงเครื่องหมายที่จุดแบบสุ่ม 100 จุดและจัดการการโต้ตอบของผู้ใช้ ในขั้นตอนสุดท้ายของ Codelab นี้ คุณจะใช้ฟีเจอร์การวาดของ Maps SDK สำหรับ iOS เพื่อเพิ่มฟีเจอร์ที่มีประโยชน์เพิ่มเติมลงในประสบการณ์การใช้งานแผนที่

สมมติว่าผู้ใช้ที่ต้องการสำรวจเมืองซิดนีย์จะใช้แผนที่นี้ ฟีเจอร์ที่มีประโยชน์คือการแสดงภาพรัศมีรอบเครื่องหมายเมื่อมีการคลิก ซึ่งจะช่วยให้ผู้ใช้เข้าใจได้อย่างรวดเร็วว่ามีจุดหมายปลายทางอื่นๆ อยู่ในระยะทางสั้นๆ จากเครื่องหมายที่คลิก

SDK สำหรับ iOS มีชุดฟังก์ชันสำหรับการวาดรูปร่างบนแผนที่ เช่น สี่เหลี่ยม รูปหลายเหลี่ยม เส้น และวงกลม ในขั้นตอนนี้ ให้แสดงวงกลมเพื่อแสดงรัศมี 800 เมตร (ประมาณครึ่งไมล์) รอบเครื่องหมายเมื่อมีการคลิก

  1. เพิ่มตัวแปรอินสแตนซ์ circle ลงในการติดตั้งใช้งาน ViewController

ตัวแปรอินสแตนซ์นี้ใช้เพื่อบันทึกวงกลมที่วาดล่าสุด เพื่อให้ทำลายวงกลมนั้นได้ก่อนที่จะวาดวงกลมอื่น เพราะหากทุกเครื่องหมายที่แตะมีวงกลมล้อมรอบ ก็คงไม่เป็นประโยชน์ต่อผู้ใช้และดูไม่ดี

โดยอัปเดตการติดตั้งใช้งาน ViewController ดังนี้

class ViewController: UIViewController, GMSMapViewDelegate {

  private var mapView: GMSMapView!
  private var clusterManager: GMUClusterManager!
  private var circle: GMSCircle? = nil
  ...
}
  1. วาดวงกลมเมื่อแตะเครื่องหมาย

ที่ด้านล่างของเมธอด mapView(_:didTap:) เหนือคำสั่ง return false ให้เพิ่มโค้ดที่แสดงที่นี่เพื่อสร้างอินสแตนซ์ของคลาส GMSCircle ของ iOS SDK เพื่อวาดวงกลมรัศมี 800 เมตรใหม่โดยเรียกใช้ GMSCircle(position:radius:) และส่งตำแหน่งของเครื่องหมายที่แตะไปให้เหมือนกับตอนที่คุณจัดกึ่งกลางแผนที่ใหม่

    // Draw a new circle around the tapped marker
    circle = GMSCircle(position: marker.position, radius: 800)
  1. จัดรูปแบบวงกลม

โดยค่าเริ่มต้น GMSCircle จะวาดวงกลมที่มีเส้นสีดำและสีเติมโปร่งใส วิธีนี้ใช้ได้สำหรับการแสดงรัศมี แต่ดูไม่ค่อยดีและมองเห็นได้ยาก จากนั้นกำหนดสีเติมให้กับวงกลมเพื่อปรับปรุงการจัดรูปแบบโดยกำหนด UIColor ให้กับพร็อพเพอร์ตี้ fillColor ของวงกลม โค้ดที่แสดงที่นี่จะเพิ่มการเติมสีเทาที่มีความโปร่งใส 50%

    circle?.fillColor = UIColor(red: 0.67, green: 0.67, blue: 0.67, alpha: 0.5)
  1. แสดงวงกลมบนแผนที่

เช่นเดียวกับตอนที่คุณสร้างเครื่องหมายก่อนหน้านี้ การสร้างอินสแตนซ์ของ GMSCircle ไม่ได้ทำให้เครื่องหมายปรากฏบนแผนที่ โดยกำหนดอินสแตนซ์มุมมองแผนที่ให้กับพร็อพเพอร์ตี้ map ของวงกลม

    circle?.map = mapView
  1. นำวงกลมที่แสดงผลก่อนหน้านี้ออก

ดังที่ได้กล่าวไว้ก่อนหน้านี้ การเพิ่มวงกลมลงในแผนที่เรื่อยๆ จะไม่เป็นประสบการณ์ของผู้ใช้ที่ดีนัก หากต้องการนำวงกลมที่แสดงผลโดยเหตุการณ์การแตะก่อนหน้าออก ให้ตั้งค่าพร็อพเพอร์ตี้ map ของ circle เป็น nil ที่ด้านบนของ mapView(_:didTap:)

    // Clear previous circles
    circle?.map = nil

โหลดแอปซ้ำแล้วแตะเครื่องหมาย คุณควรเห็นวงกลมใหม่วาดขึ้นทุกครั้งที่มีการแตะเครื่องหมาย และระบบจะนำวงกลมที่วาดก่อนหน้านี้ออกตามที่แสดงในรูปที่ 7

วงกลมที่วาดรอบเครื่องหมายที่แตะ

รูปที่ 7 วงกลมที่วาดรอบเครื่องหมายที่แตะ

สรุปคือในขั้นตอนนี้ คุณใช้คลาส GMSCircle เพื่อแสดงวงกลมทุกครั้งที่มีการแตะเครื่องหมาย

วิธี mapView(_:didTap:) ควรมีลักษณะดังนี้

  func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {

    // Clear previous circles
    circle?.map = nil

    // Animate to the marker
    mapView.animate(toLocation: marker.position)

    // If the tap was on a marker cluster, zoom in on the cluster
    if let _ = marker.userData as? GMUCluster {
      mapView.animate(toZoom: mapView.camera.zoom + 1)
      return true
    }

    // Draw a new circle around the tapped marker
    circle = GMSCircle(position: marker.position, radius: 800)
    circle?.fillColor = UIColor(red: 0.67, green: 0.67, blue: 0.67, alpha: 0.5)
    circle?.map = mapView
    return false
  }

10. ขอแสดงความยินดี

คุณสร้างแอป iOS ที่มี Google Maps แบบอินเทอร์แอกทีฟเรียบร้อยแล้ว

สิ่งที่คุณได้เรียนรู้

ขั้นตอนถัดไปคือ

  • สำรวจหรือ Fork ที่เก็บ maps-sdk-for-ios-samples GitHub ของตัวอย่างและเดโมเพื่อหาแรงบันดาลใจเพิ่มเติม
  • ดูข้อมูลจาก Codelab ของ Swift เพิ่มเติมสำหรับการสร้างแอป iOS ด้วย Google Maps Platform
  • ช่วยเราสร้างเนื้อหาที่เป็นประโยชน์ต่อคุณมากที่สุดโดยตอบแบบสำรวจต่อไปนี้

คุณอยากเห็น Codelab อื่นๆ แบบไหน

การแสดงข้อมูลเป็นภาพบนแผนที่ ข้อมูลเพิ่มเติมเกี่ยวกับการปรับแต่งรูปแบบของแผนที่ การสร้างการโต้ตอบ 3 มิติในแผนที่

หากไม่พบโค้ดแล็บที่คุณสนใจมากที่สุด ขอได้โดยแจ้งปัญหาใหม่ที่นี่