Thêm bản đồ vào ứng dụng iOS (Objective-C)

1. Trước khi bắt đầu

Bản tóm tắt

Trong lớp học lập trình này, bạn sẽ tìm hiểu mọi thứ cần thiết để bắt đầu sử dụng Google Maps Platform nhằm tạo ứng dụng iOS bằng Objective-C. Bạn sẽ tìm hiểu tất cả những kiến thức cơ bản, từ cách thiết lập đến tải SDK Bản đồ dành cho iOS, hiển thị bản đồ đầu tiên, làm việc với các điểm đánh dấu và cụm điểm đánh dấu, vẽ trên bản đồ và xử lý hoạt động tương tác của người dùng.

Sản phẩm bạn sẽ tạo ra

342520482a888519.png

Trong lớp học lập trình này, bạn sẽ tạo một ứng dụng iOS có các chức năng sau:

  • Tải Maps SDK cho iOS và Maps SDK cho Thư viện tiện ích iOS
  • Hiển thị bản đồ có tâm là Sydney, Úc
  • Hiển thị các điểm đánh dấu tuỳ chỉnh cho 100 điểm xung quanh Sydney
  • Triển khai tính năng phân cụm điểm đánh dấu
  • Cho phép người dùng tương tác bằng cách đặt lại tâm và vẽ một vòng tròn trên bản đồ khi nhấp vào một điểm đánh dấu

Kiến thức bạn sẽ học được

  • Bắt đầu sử dụng Nền tảng Google Maps
  • Tải Maps SDK cho iOS và Thư viện tiện ích Google Maps SDK cho iOS
  • Tải bản đồ
  • Sử dụng điểm đánh dấu, điểm đánh dấu tuỳ chỉnh và tính năng phân cụm điểm đánh dấu
  • Làm việc với hệ thống sự kiện Maps SDK cho iOS để cung cấp hoạt động tương tác của người dùng
  • Kiểm soát bản đồ theo phương thức lập trình
  • Vẽ trên bản đồ

Điều kiện tiên quyết

Bạn cần làm quen với các mục bên dưới để hoàn tất lớp học lập trình này. Nếu bạn đã quen với việc sử dụng Nền tảng Google Maps, hãy chuyển đến lớp học lập trình!

Các sản phẩm bắt buộc của Nền tảng Google Maps

Trong lớp học lập trình này, bạn sẽ sử dụng các sản phẩm sau đây của Nền tảng Google Maps:

  • SDK Maps dành cho iOS
  • Thư viện tiện ích Google Maps SDK cho iOS

Bắt đầu sử dụng Nền tảng Google Maps

Nếu bạn chưa từng sử dụng Nền tảng Google Maps, hãy làm theo hướng dẫn Bắt đầu sử dụng Nền tảng Google Maps hoặc xem danh sách phát Bắt đầu sử dụng Nền tảng Google Maps để hoàn tất các bước sau:

  1. Tạo tài khoản thanh toán.
  2. Tạo dự án.
  3. Bật các API và SDK của Nền tảng Google Maps (được liệt kê trong phần trước).
  4. Tạo khoá API.

Các yêu cầu khác đối với lớp học lập trình này

Để hoàn tất lớp học lập trình này, bạn cần có các tài khoản, dịch vụ và công cụ sau:

  • Tài khoản Google Cloud Platform có bật tính năng thanh toán
  • Khoá Google Maps Platform API có Maps SDK dành cho iOS được bật
  • Kiến thức cơ bản về Objective-C
  • Xcode 12.0 với SDK mục tiêu là 12.0 trở lên

2. Bắt đầu thiết lập

Đối với bước bật bên dưới, bạn cần bật Maps SDK dành cho iOS.

Thiết lập Nền tảng Google Maps

Nếu bạn chưa có tài khoản Google Cloud Platform và dự án có bật tính năng thanh toán, vui lòng xem hướng dẫn Bắt đầu sử dụng Google Maps Platform để tạo tài khoản thanh toán và dự án.

  1. Trong Cloud Console, hãy nhấp vào trình đơn thả xuống dự án rồi chọn dự án mà bạn muốn sử dụng cho lớp học lập trình này.

  1. Bật các API và SDK của Google Maps Platform cần thiết cho lớp học lập trình này trong Google Cloud Marketplace. Để làm như vậy, hãy làm theo các bước trong video này hoặc tài liệu này.
  2. Tạo khoá API trong trang Thông tin xác thực của Cloud Console. Bạn có thể làm theo các bước trong video này hoặc tài liệu này. Tất cả các yêu cầu gửi đến Nền tảng Google Maps đều cần có khoá API.

Thiết lập mẫu dự án dành cho người mới bắt đầu

Trước khi bắt đầu lớp học lập trình này, hãy làm như sau để tải mẫu dự án khởi đầu cũng như mã giải pháp hoàn chỉnh xuống:

  1. Tải xuống hoặc phân nhánh kho lưu trữ GitHub cho lớp học lập trình này tại https://github.com/googlecodelabs/maps-platform-101-objc.

Dự án StarterApp nằm trong thư mục /starter và có cấu trúc tệp cơ bản mà bạn sẽ cần để hoàn thành lớp học lập trình. Mọi thứ bạn cần để làm việc đều nằm trong thư mục /starter/StarterApp.

Nếu muốn xem đoạn mã giải pháp đầy đủ đang chạy, bạn có thể hoàn tất các bước thiết lập ở trên và xem giải pháp trong thư mục /solution/SolutionApp.

3. Cài đặt Maps SDK cho iOS

Bước đầu tiên để sử dụng Maps SDK cho iOS là cài đặt các phần phụ thuộc cần thiết. Quy trình này có 2 bước: cài đặt Maps SDK cho iOS và Thư viện tiện ích Maps SDK cho iOS từ trình quản lý phần phụ thuộc Cocoapods, đồng thời cung cấp khoá API cho SDK.

  1. Thêm Maps SDK cho iOS và Maps SDK cho Thư viện tiện ích iOS vào Podfile.

Trong lớp học lập trình này, bạn sẽ sử dụng cả Maps SDK cho iOS (cung cấp tất cả chức năng cốt lõi của Google Maps) và Maps iOS Utility Library (cung cấp nhiều tiện ích để làm phong phú bản đồ của bạn, bao gồm cả tính năng phân cụm điểm đánh dấu).

Để bắt đầu, trong Xcode (hoặc trình chỉnh sửa văn bản mà bạn muốn), hãy mở Pods > Podfile rồi cập nhật tệp này để thêm các phần phụ thuộc Maps SDK cho iOS và Thư viện tiện ích trong use_frameworks!:

pod 'GoogleMaps'
pod 'Google-Maps-iOS-Utils'
  1. Cài đặt các pod Maps SDK cho iOS và Maps SDK cho iOS Utility Library.

Để cài đặt các phần phụ thuộc, hãy chạy pod install trong thư mục /starter qua dòng lệnh. Cocoapods sẽ tự động tải các phần phụ thuộc xuống, cũng như tạo StarterApp.xcworkspace. 3. Sau khi bạn cài đặt các phần phụ thuộc, hãy mở StarterApp.xcworkspace trong Xcode, sau đó chạy ứng dụng trong trình mô phỏng iPhone bằng cách nhấn Command+R. Nếu bạn thiết lập đúng mọi thứ, trình mô phỏng sẽ khởi chạy và cho thấy một màn hình đen. Đừng lo lắng, bạn chưa tạo bất cứ thứ gì nên việc này là bình thường! 4. Nhập SDK trong AppDelegate.h.

Sau khi cài đặt các phần phụ thuộc, bạn cần cung cấp khoá API cho SDK. Bước đầu tiên là nhập Maps SDK cho iOS dưới dạng một phần phụ thuộc bằng cách đặt nội dung sau đây bên dưới câu lệnh nhập #import "AppDelegate.h":

@import GoogleMaps;
  1. Bên dưới câu lệnh nhập SDK iOS, hãy khai báo một hằng số NSString có giá trị được đặt thành khoá API của bạn:
static NSString *const kMapsAPIKey = @"YOUR API KEY";
  1. Truyền khoá API đến iOS SDK bằng cách gọi provideAPIKey trên GMSServices trong application: didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GMSServices provideAPIKey:kMapsAPIKey];
  return YES;
}

Tệp AppDelegate.m mới cập nhật của bạn giờ đây sẽ có dạng như sau:

#import "AppDelegate.h"
@import GoogleMaps;

static NSString *const kMapsAPIKey = @"YOUR API KEY";

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GMSServices provideAPIKey:kMapsAPIKey];
  return YES;
}
@end

Podfile của bạn sẽ có dạng như sau:

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

target 'StarterApp' do
  use_frameworks!

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

end

Sau khi cài đặt các phần phụ thuộc và cung cấp khoá API, bạn đã sẵn sàng bắt đầu gọi Maps SDK cho iOS.

4. Hiển thị bản đồ

Đã đến lúc hiển thị bản đồ đầu tiên của bạn!

Phần thường dùng nhất của Maps SDK cho iOS là lớp GMSMapView. Lớp này cung cấp nhiều phương thức cho phép bạn tạo và thao tác với các thực thể bản đồ. Sau đây là cách thực hiện.

  1. Mở ViewController.m.

Đây là nơi bạn sẽ thực hiện tất cả các công việc còn lại cho lớp học lập trình này. Bạn sẽ thấy các sự kiện trong vòng đời loadViewviewDidLoad cho trình điều khiển khung hiển thị đã được tạo sẵn cho bạn. 2. Nhập Maps SDK cho iOS bằng cách thêm nội dung sau vào đầu tệp:

@import GoogleMaps;
  1. Khai báo một biến thực thể ViewController để lưu trữ GMSMapView.

Phiên bản GMSMapView là đối tượng chính mà bạn sẽ làm việc trong suốt lớp học lập trình này, đồng thời bạn sẽ tham chiếu và thao tác trên đối tượng này từ nhiều phương thức trong vòng đời của bộ điều khiển thành phần hiển thị. Để cung cấp dữ liệu này, hãy cập nhật cách triển khai ViewController để khai báo một biến thực thể nhằm lưu trữ dữ liệu:

@implementation ViewController {
  GMSMapView *_mapView;
}
  1. Trong loadView, hãy tạo một thực thể của GMSCameraPosition.

GMSCameraPosition xác định vị trí bản đồ sẽ được căn giữa và mức thu phóng sẽ hiển thị. Đoạn mã này gọi phương thức cameraWithLatitude:longitude:zoom: để đặt bản đồ ở giữa Sydney, Úc, ở vĩ độ -33,86 và kinh độ 151,20, với mức thu phóng là 12:

GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.86 longitude:151.20 zoom:12];
  1. Trong loadView, hãy tạo một thực thể của GMSMapView để khởi tạo bản đồ.

Để tạo một phiên bản bản đồ mới, hãy gọi mapWithFrame:camera:. Lưu ý cách khung được đặt thành CGRectZero. Đây là một biến toàn cục trong thư viện CGGeometry của iOS, chỉ định một khung có chiều rộng bằng 0, chiều cao bằng 0, nằm ở vị trí (0,0) bên trong trình xem. Máy ảnh được đặt ở vị trí máy ảnh mà bạn vừa tạo.

Để thực sự hiển thị bản đồ, tiếp theo, bạn sẽ đặt khung hiển thị gốc của trình điều khiển khung hiển thị thành _mapview. Thao tác này sẽ khiến bản đồ hiển thị ở chế độ toàn màn hình.

_mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
self.view = _mapView;
  1. Đặt GMSMapViewDelegate thành bộ điều khiển chế độ xem.

Khi được triển khai, uỷ quyền chế độ xem bản đồ cho phép bạn xử lý các sự kiện từ lượt tương tác của người dùng trên thực thể GMSMapView mà bạn sẽ cần trong các bước sau.

Trước tiên, hãy cập nhật giao diện của ViewController để tuân thủ giao thức cho GMSMapViewDelegate:

@interface ViewController ()<GMSMapViewDelegate>

Tiếp theo, hãy thêm nội dung sau để đặt GMSMapViewDelegate thành ViewController.

_mapView.delegate = self;

Bây giờ, hãy tải lại ứng dụng trong trình mô phỏng iOS (Command+R) và bản đồ sẽ xuất hiện!

2e6ebac422323aa6.png

Tóm lại, trong bước này, bạn đã tạo một thực thể của GMSMapView để hiển thị một bản đồ tập trung vào thành phố Sydney, Úc.

Bây giờ, tệp ViewController.m của bạn sẽ có dạng như sau:

#import "ViewController.h"
#import "LocationGenerator.h"
@import GoogleMaps;

@interface ViewController ()<GMSMapViewDelegate>
@end

@implementation ViewController {
  GMSMapView *_mapView;
}

- (void)loadView {
  [super loadView];
  GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.86 longitude:151.20 zoom:12];
  _mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
  self.view = _mapView;
  _mapView.delegate = self;
}

5. Định kiểu bản đồ dựa trên đám mây (Không bắt buộc)

Bạn có thể tuỳ chỉnh kiểu bản đồ bằng tính năng Định kiểu bản đồ dựa trên đám mây.

Tạo mã bản đồ

Nếu bạn chưa tạo mã bản đồ có kiểu bản đồ được liên kết, hãy xem hướng dẫn về Mã bản đồ để hoàn tất các bước sau:

  1. Tạo mã bản đồ.
  2. Liên kết mã bản đồ với kiểu bản đồ.

Thêm Mã bản đồ vào ứng dụng

Để sử dụng mã bản đồ mà bạn đã tạo ở bước trước, hãy mở tệp ViewController.m và trong phương thức loadView, hãy tạo một đối tượng GMSMapID rồi cung cấp mã bản đồ cho đối tượng đó. Tiếp theo, hãy sửa đổi quá trình khởi tạo GMSMapView bằng cách cung cấp đối tượng GMSMapID làm tham số.

ViewController.m

- (void)loadView {
    GMSMapID *mapID = [[GMSMapID alloc] initWithIdentifier:@"YOUR_MAP_ID"];
    _mapView = [GMSMapView mapWithFrame:CGRectZero mapID:mapID camera:camera];
    // ...
}

Sau khi hoàn tất, hãy chạy ứng dụng để xem bản đồ theo kiểu mà bạn đã chọn!

6. Thêm điểm đánh dấu vào bản đồ

Có rất nhiều việc mà nhà phát triển có thể làm với Maps SDK cho iOS, nhưng đặt điểm đánh dấu trên bản đồ chắc chắn là việc phổ biến nhất. Các điểm đánh dấu cho phép bạn hiện các điểm cụ thể trên bản đồ và là một phần tử phổ biến trên giao diện người dùng để xử lý hoạt động tương tác của người dùng. Nếu đã từng sử dụng Google Maps, có lẽ bạn đã quen thuộc với điểm đánh dấu mặc định có dạng như sau:

590815267846f166.png

Trong bước này, bạn sẽ tìm hiểu cách sử dụng lớp GMSMarker để đặt điểm đánh dấu trên bản đồ.

Xin lưu ý rằng bạn không thể đặt điểm đánh dấu trên bản đồ cho đến khi bản đồ được tải từ bước trước đó trong sự kiện vòng đời loadView của trình điều khiển chế độ xem. Vì vậy, bạn sẽ hoàn tất các bước này trong sự kiện vòng đời viewDidLoad. Sự kiện này được gọi sau khi chế độ xem (và bản đồ) được tải.

  1. Xác định một đối tượng CLLocationCoordinate2D.

CLLocationCoordinate2D là một cấu trúc do thư viện CoreLocation của iOS cung cấp, xác định một vị trí địa lý ở một vĩ độ và kinh độ nhất định. Để bắt đầu tạo điểm đánh dấu đầu tiên, hãy xác định một đối tượng CLLocationCoordinate2D và đặt vĩ độ cũng như kinh độ ở tâm bản đồ. Bạn có thể truy cập vào toạ độ của tâm bản đồ từ khung hiển thị bản đồ bằng cách sử dụng các thuộc tính camera.target.latitudecamera.target.longitude.

CLLocationCoordinate2D mapCenter = CLLocationCoordinate2DMake(_mapView.camera.target.latitude, _mapView.camera.target.longitude);
  1. Tạo một thực thể của GMSMarker.

Maps SDK dành cho iOS cung cấp lớp GMSMarker. Mỗi phiên bản của GMSMarker đại diện cho một điểm đánh dấu riêng lẻ trên bản đồ và được tạo bằng cách gọi markerWithPosition: rồi truyền cho phiên bản đó một đối tượng CLLocationCoordinate2D để cho SDK biết vị trí đặt điểm đánh dấu trên bản đồ.

GMSMarker *marker = [GMSMarker markerWithPosition:mapCenter];
  1. Đặt biểu tượng điểm đánh dấu tuỳ chỉnh.

Điểm đánh dấu ghim màu đỏ mặc định của Google Maps rất hữu ích, nhưng việc tuỳ chỉnh bản đồ cũng vậy! Rất may là bạn có thể dễ dàng sử dụng điểm đánh dấu tuỳ chỉnh bằng Maps SDK cho iOS. Bạn sẽ thấy rằng dự án StarterApp có một hình ảnh tên là "custom_pin.png" để bạn sử dụng, nhưng bạn có thể dùng bất kỳ hình ảnh nào bạn muốn.

Để đặt điểm đánh dấu tuỳ chỉnh, hãy đặt thuộc tính icon của điểm đánh dấu thành một thực thể của UIImage.

marker.icon = [UIImage imageNamed:@"custom_pin.png"];
  1. Kết xuất điểm đánh dấu vào bản đồ.

Điểm đánh dấu của bạn đã được tạo, nhưng bạn sẽ nhận thấy điểm đánh dấu đó không xuất hiện trên bản đồ. Để thực hiện việc này, hãy đặt thuộc tính map của thực thể GMSMarker thành một thực thể của GMSMapView.

marker.map = _mapView;

Bây giờ, hãy tải lại ứng dụng và xem bản đồ đầu tiên của bạn có một điểm đánh dấu!

a4ea8724f8c5ba20.png

Tóm lại, trong phần này, bạn đã tạo một thực thể của lớp GMSMarker và áp dụng thực thể đó vào khung hiển thị bản đồ để hiển thị một điểm đánh dấu trên bản đồ. Sự kiện vòng đời viewDidLoad được cập nhật trong ViewController.m hiện sẽ có dạng như sau:

- (void)viewDidLoad {
  [super viewDidLoad];

  CLLocationCoordinate2D mapCenter = CLLocationCoordinate2DMake(_mapView.camera.target.latitude, _mapView.camera.target.longitude);
  GMSMarker *marker = [GMSMarker markerWithPosition:mapCenter];
  marker.icon = [UIImage imageNamed:@"custom_pin.png"];
  marker.map = _mapView;
}

7. Bật tính năng Nhóm điểm đánh dấu

Khi sử dụng nhiều điểm đánh dấu hoặc các điểm đánh dấu ở gần nhau, bạn có thể gặp phải vấn đề là các điểm đánh dấu chồng lên nhau hoặc xuất hiện quá dày đặc, gây ra trải nghiệm người dùng kém. Ví dụ: nếu hai điểm đánh dấu ở rất gần nhau, bạn có thể gặp phải trường hợp như sau:

6e39736160c6bce4.png

Đây là lúc bạn cần đến tính năng nhóm điểm đánh dấu. Nhóm điểm đánh dấu là một tính năng khác thường được triển khai, giúp nhóm các điểm đánh dấu lân cận thành một biểu tượng duy nhất thay đổi tuỳ theo mức thu phóng, chẳng hạn như:

4abb38cd97cab3f1.png

Thuật toán phân cụm điểm đánh dấu chia khu vực hiển thị của bản đồ thành một lưới, sau đó phân cụm các biểu tượng nằm trong cùng một ô. May mắn là bạn không phải lo lắng về bất kỳ điều nào trong số đó, vì nhóm Nền tảng Google Maps đã tạo ra một thư viện tiện ích nguồn mở hữu ích có tên là Thư viện tiện ích SDK Google Maps cho iOS. Thư viện này, trong số nhiều thư viện khác, sẽ tự động xử lý việc phân cụm điểm đánh dấu cho bạn. Bạn có thể đọc thêm về tính năng nhóm điểm đánh dấu trong tài liệu của Nền tảng Google Maps hoặc xem nguồn của Thư viện tiện ích iOS trên GitHub.

  1. Thêm nhiều điểm đánh dấu khác vào bản đồ.

Để xem tính năng nhóm điểm đánh dấu hoạt động, bạn cần có nhiều điểm đánh dấu trên bản đồ. Để giúp bạn dễ dàng thực hiện việc này, chúng tôi cung cấp một trình tạo điểm đánh dấu thuận tiện trong dự án khởi đầu ở LocationGenerator.m.

Để thêm nhiều điểm đánh dấu vào bản đồ tuỳ ý, bạn chỉ cần gọi generateMarkersNear:count: trong vòng đời viewDidLoad của trình điều khiển chế độ xem bên dưới mã từ bước trước. Phương thức này tạo số lượng điểm đánh dấu được chỉ định trong count tại các vị trí ngẫu nhiên xung quanh toạ độ được chỉ định trong một đối tượng CLLocationCoordinate2D. Trong trường hợp này, bạn chỉ cần truyền biến mapCenter mà bạn đã tạo trước đó. Các điểm đánh dấu được trả về trong một NSArray.

NSArray<GMSMarker *> *markerArray = [LocationGenerator generateMarkersNear:mapCenter count:100];
  1. Nhập Thư viện tiện ích Google Maps SDK cho iOS.

Để thêm thư viện tiện ích Maps iOS làm phần phụ thuộc vào dự án, hãy thêm nội dung sau vào danh sách phần phụ thuộc ở đầu ViewController.m:

@import GoogleMapsUtils;
  1. Định cấu hình trình phân cụm điểm đánh dấu.

Để sử dụng trình nhóm điểm đánh dấu, bạn cần cung cấp 3 thành phần để định cấu hình cách hoạt động của trình nhóm điểm đánh dấu: một thuật toán phân cụm, một trình tạo biểu tượng và một trình kết xuất. Thuật toán này xác định hành vi của cách các điểm đánh dấu được nhóm lại, chẳng hạn như khoảng cách giữa các điểm đánh dấu để đưa vào cùng một cụm. Trình tạo biểu tượng cung cấp các biểu tượng cụm sẽ được dùng ở nhiều mức thu phóng. Trình kết xuất xử lý hoạt động kết xuất thực tế của các biểu tượng cụm trên bản đồ.

Bạn có thể viết tất cả những nội dung này từ đầu nếu muốn, nhưng thư viện tiện ích Maps iOS cung cấp các phương thức triển khai mặc định để giúp quy trình này trở nên dễ dàng. Chỉ cần thêm nội dung sau:

id<GMUClusterAlgorithm> algorithm = [[GMUNonHierarchicalDistanceBasedAlgorithm alloc] init];

id<GMUClusterIconGenerator> clusterIconGenerator = [[GMUDefaultClusterIconGenerator alloc] init];

id<GMUClusterRenderer> renderer = [[GMUDefaultClusterRenderer alloc] initWithMapView:_mapView clusterIconGenerator:clusterIconGenerator];
  1. Tạo một thực thể của GMUClusterManager.

GMUClusterManager là lớp triển khai tính năng nhóm điểm đánh dấu, sử dụng thuật toán, trình tạo biểu tượng và trình kết xuất do bạn chỉ định. Để tạo trình kết xuất và cung cấp trình kết xuất cho khung hiển thị bản đồ, trước tiên, hãy thêm một biến thực thể vào quá trình triển khai ViewController để lưu trữ thực thể trình quản lý cụm:

@implementation ViewController {
  GMSMapView *_mapView;
  GMUClusterManager *_clusterManager;
}

Tiếp theo, hãy tạo thực thể của GMUClusterManager trong sự kiện vòng đời viewDidLoad:

_clusterManager = [[GMUClusterManager alloc] initWithMap:_mapView algorithm:algorithm renderer:renderer];
  1. Thêm các điểm đánh dấu và chạy trình phân cụm điểm đánh dấu.

Giờ đây, khi bạn đã định cấu hình phiên bản nhóm điểm đánh dấu, tất cả những gì bạn phải làm là truyền cho trình quản lý nhóm mảng điểm đánh dấu cần được nhóm bằng cách gọi addItems:, sau đó chạy trình nhóm bằng cách gọi cluster.

[_clusterManager addItems:markerArray];
[_clusterManager cluster];

Tải lại ứng dụng, giờ đây bạn sẽ thấy rất nhiều điểm đánh dấu được nhóm lại với nhau một cách gọn gàng. Hãy thử các mức thu phóng khác nhau bằng cách chụm và thu phóng trên bản đồ để xem các cụm điểm đánh dấu thích ứng khi bạn phóng to/thu nhỏ.

c49383b07752bfc4.png

Tóm lại, trong bước này, bạn đã định cấu hình một phiên bản của trình phân cụm điểm đánh dấu từ Thư viện tiện ích Google Maps SDK cho iOS, sau đó dùng phiên bản này để phân cụm 100 điểm đánh dấu trên bản đồ. Sự kiện vòng đời viewDidLoad trong ViewController.m hiện sẽ có dạng như sau:

- (void)viewDidLoad {
  [super viewDidLoad];

  CLLocationCoordinate2D mapCenter = CLLocationCoordinate2DMake(_mapView.camera.target.latitude,
                                                                _mapView.camera.target.longitude);
  GMSMarker *marker = [GMSMarker markerWithPosition:mapCenter];
  marker.icon = [UIImage imageNamed:@"custom_pin.png"];
  marker.map = _mapView;
  NSArray<GMSMarker *> *markerArray = [LocationGenerator generateMarkersNear:mapCenter count:100];

  id<GMUClusterAlgorithm> algorithm = [[GMUNonHierarchicalDistanceBasedAlgorithm alloc] init];
  id<GMUClusterIconGenerator> clusterIconGenerator = [[GMUDefaultClusterIconGenerator alloc] init];
  id<GMUClusterRenderer> renderer = [[GMUDefaultClusterRenderer alloc] initWithMapView:_mapView clusterIconGenerator:clusterIconGenerator];
  _clusterManager = [[GMUClusterManager alloc] initWithMap:_mapView algorithm:algorithm renderer:renderer];

  [_clusterManager addItems:markerArray];
  [_clusterManager cluster];
}

8. Thêm hoạt động tương tác của người dùng

Giờ đây, bạn đã có một bản đồ trông rất đẹp, hiển thị các điểm đánh dấu và sử dụng tính năng nhóm điểm đánh dấu. Trong bước này, bạn sẽ thêm một số thao tác xử lý bổ sung đối với các hoạt động tương tác của người dùng bằng cách sử dụng GMSMapViewDelegate (bạn đã đặt thành bộ điều khiển khung hiển thị trước đó) để cải thiện trải nghiệm người dùng trên bản đồ.

Maps SDK for iOS cung cấp một hệ thống sự kiện toàn diện được triển khai thông qua uỷ quyền chế độ xem bản đồ, bao gồm cả trình xử lý sự kiện cho phép bạn thực thi mã khi nhiều hoạt động tương tác của người dùng xảy ra. Ví dụ: uỷ quyền mapview bao gồm các phương thức cho phép bạn kích hoạt quá trình thực thi mã cho các hoạt động tương tác như người dùng nhấp vào bản đồ và điểm đánh dấu, kéo khung hiển thị của bản đồ, thu phóng và nhiều hoạt động khác.

Trong bước này, bạn sẽ lập trình để bản đồ di chuyển đến vị trí trung tâm của bất kỳ điểm đánh dấu nào mà người dùng nhấn vào.

  1. Triển khai trình nghe lượt nhấn vào điểm đánh dấu.

mapView:didTapMarker được gọi bất cứ khi nào người dùng nhấn vào một trong các điểm đánh dấu mà bạn đã tạo trước đó, cũng như bất cứ khi nào người dùng nhấn vào một nhóm điểm đánh dấu (về bản chất, nhóm điểm đánh dấu được triển khai dưới dạng một phiên bản của GMSMarker).

Để triển khai trình nghe sự kiện, hãy bắt đầu bằng cách tạo một chương trình khung ở cuối ViewController.m trước câu lệnh end.

Bạn sẽ nhận thấy rằng phương thức này đang trả về NO. Thao tác này yêu cầu iOS SDK tiếp tục thực thi chức năng GMSMarker mặc định, chẳng hạn như hiện cửa sổ thông tin (nếu được định cấu hình) sau khi thực thi mã trình xử lý sự kiện của bạn.

- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {

  return NO;
}
  1. Xử lý sự kiện nhấn và tạo ảnh động cho camera để căn giữa lại bản đồ khi người dùng nhấn vào một điểm đánh dấu hoặc cụm điểm đánh dấu.

Khi được gọi, mapView:didTapMarker sẽ truyền thực thể của GMSMarker đã được nhấn, cho phép bạn xử lý thực thể đó trong mã của mình. Bạn có thể dùng thực thể này để đặt lại tâm bản đồ bằng cách gọi animateToLocation: trên khung hiển thị bản đồ từ bên trong trình xử lý sự kiện và truyền cho khung hiển thị này vị trí của thực thể điểm đánh dấu (có trong thuộc tính position).

[_mapView animateToLocation:marker.position];
  1. Phóng to một nhóm điểm đánh dấu khi nhóm đó được nhấn.

Một mẫu hình phổ biến về trải nghiệm người dùng là phóng to các cụm điểm đánh dấu khi người dùng nhấn vào. Điều này cho phép người dùng xem các điểm đánh dấu được phân cụm, vì cụm sẽ mở rộng ở mức thu phóng thấp hơn.

Như đã lưu ý trước đó, biểu tượng cụm điểm đánh dấu thực ra chỉ là một cách triển khai GMSMarker bằng biểu tượng tuỳ chỉnh. Vậy làm sao bạn có thể biết người dùng đã nhấn vào một điểm đánh dấu hay một cụm điểm đánh dấu? Khi trình quản lý nhóm điểm đánh dấu tạo một biểu tượng nhóm mới, trình quản lý này sẽ triển khai phiên bản GMSMarker để tuân thủ một giao thức có tên là GMUCluster. Bạn có thể dùng một điều kiện để kiểm tra xem điểm đánh dấu được truyền vào trình xử lý sự kiện có tuân thủ giao thức này hay không.

Sau khi biết theo phương thức lập trình rằng một cụm đã được nhấn, bạn có thể gọi animateToZoom: trên thực thể khung hiển thị bản đồ và đặt mức thu phóng thành mức thu phóng hiện tại cộng thêm một. Mức thu phóng hiện tại có trong thực thể chế độ xem bản đồ trong thuộc tính camera.zoom.

Ngoài ra, hãy lưu ý cách đoạn mã dưới đây trả về YES. Điều này cho trình xử lý sự kiện biết rằng bạn đã hoàn tất việc xử lý sự kiện và không thực thi thêm mã nào trong trình xử lý. Một trong những lý do để làm việc này là ngăn đối tượng GMSMarker cơ bản thực thi phần còn lại của hành vi mặc định, chẳng hạn như hiện cửa sổ thông tin. Điều này sẽ không có nhiều ý nghĩa trong trường hợp nhấn vào biểu tượng cụm.

if ([marker.userData conformsToProtocol:@protocol(GMUCluster)]) {
    [_mapView animateToZoom:_mapView.camera.zoom +1];
    return YES;
}

Bây giờ, hãy tải lại ứng dụng rồi nhấn vào một số điểm đánh dấu và cụm điểm đánh dấu. Khi bạn nhấn vào một trong hai, bản đồ sẽ căn giữa lại vào phần tử bạn nhấn. Khi bạn nhấn vào một cụm điểm đánh dấu, bản đồ cũng sẽ phóng to thêm một cấp và cụm điểm đánh dấu sẽ mở rộng để cho thấy các điểm đánh dấu được nhóm bên dưới.

Tóm lại, trong bước này, bạn đã triển khai trình nghe thao tác nhấn vào điểm đánh dấu và xử lý sự kiện để lấy lại tâm cho phần tử được nhấn, đồng thời phóng to nếu phần tử đó là biểu tượng nhóm điểm đánh dấu.

Phương thức mapView:didTapMarker của bạn sẽ có dạng như sau:

- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
  [_mapView animateToLocation:marker.position];

  if ([marker.userData conformsToProtocol:@protocol(GMUCluster)]) {
    [_mapView animateToZoom:_mapView.camera.zoom +1];
    return YES;
  }

  return NO;
}

9. Vẽ trên bản đồ

Cho đến nay, bạn đã tạo một bản đồ Sydney có các điểm đánh dấu tại 100 điểm ngẫu nhiên và xử lý hoạt động tương tác của người dùng. Trong bước cuối cùng của lớp học lập trình này, bạn sẽ sử dụng các tính năng vẽ của Maps SDK cho iOS để thêm một tính năng hữu ích khác vào trải nghiệm bản đồ của mình.

Hãy tưởng tượng rằng bản đồ này sẽ được những người dùng muốn khám phá thành phố Sydney sử dụng. Một tính năng hữu ích là hình dung bán kính xung quanh một điểm đánh dấu khi người dùng nhấp vào điểm đó. Điều này sẽ giúp người dùng dễ dàng biết được những điểm đến khác nằm trong khoảng cách đi bộ dễ dàng từ điểm đánh dấu đã nhấp.

SDK iOS bao gồm một bộ hàm để vẽ các hình dạng trên bản đồ, chẳng hạn như hình vuông, đa giác, đường kẻ và hình tròn. Tiếp theo, bạn sẽ kết xuất một vòng tròn để hiện bán kính 800 mét (khoảng nửa dặm) xung quanh một điểm đánh dấu khi người dùng nhấp vào điểm đó.

  1. Thêm một biến thực thể _circ vào quá trình triển khai ViewController.

Biến thực thể này sẽ được dùng để lưu vòng tròn được vẽ gần đây nhất, để có thể huỷ vòng tròn đó trước khi vẽ một vòng tròn khác. Sau tất cả, việc này sẽ không hữu ích cho người dùng và trông khá xấu nếu mọi điểm đánh dấu được nhấn đều có một vòng tròn vẽ xung quanh!

Để làm việc này, hãy cập nhật cách triển khai ViewController như sau:

@implementation ViewController {
  GMSMapView *_mapView;
  GMUClusterManager *_clusterManager;
  GMSCircle *_circ;
}
  1. Vẽ vòng tròn khi người dùng nhấn vào một điểm đánh dấu.

Ở cuối phương thức mapView:didTapMarker, hãy thêm mã sau để tạo một thực thể của lớp GMSCircle trong iOS SDK nhằm vẽ một vòng tròn bán kính 800 mét mới bằng cách gọi circleWithPosition:radius: và truyền cho vòng tròn này vị trí của điểm đánh dấu được nhấn, giống như bạn đã làm ở trên khi căn giữa lại bản đồ.

_circ = [GMSCircle circleWithPosition:marker.position radius:800];
  1. Tạo kiểu cho vòng tròn.

Theo mặc định, GMSCircle vẽ một vòng tròn có nét vẽ màu đen và màu tô trong suốt. Cách này sẽ hoạt động để cho thấy bán kính, nhưng trông không đẹp mắt và hơi khó nhìn. Tiếp theo, hãy tô màu cho vòng tròn để cải thiện kiểu dáng bằng cách chỉ định một UIColor cho thuộc tính fillColor của vòng tròn. Đoạn mã sau đây sẽ thêm một màu xám có độ trong suốt 50%:

_circ.fillColor = [UIColor colorWithRed: 0.67 green: 0.67 blue: 0.67 alpha: 0.5];
  1. Kết xuất hình tròn trên bản đồ.

Giống như khi bạn tạo điểm đánh dấu trước đó, bạn sẽ nhận thấy rằng việc chỉ tạo một thực thể của GMSCircle không làm cho thực thể đó xuất hiện trên bản đồ. Để thực hiện việc này, bạn chỉ cần chỉ định thực thể khung hiển thị bản đồ cho thuộc tính map của hình tròn.

_circ.map = _mapView;
  1. Xoá mọi vòng tròn đã kết xuất trước đó.

Như đã lưu ý trước đó, việc chỉ tiếp tục thêm các vòng tròn vào bản đồ sẽ không mang lại trải nghiệm người dùng tốt. Để xoá vòng tròn do một sự kiện nhấn trước đó kết xuất, hãy đặt thuộc tính map của _circ thành nil ở đầu mapView:didTapMarker.

_circ.map = nil;

Tải lại ứng dụng rồi nhấn vào một điểm đánh dấu. Bạn sẽ thấy một hình tròn mới được vẽ bất cứ khi nào một điểm đánh dấu được nhấn và mọi hình tròn đã hiển thị trước đó sẽ bị xoá.

342520482a888519.png

Tóm lại, trong bước này, bạn đã sử dụng lớp GMSCircle để kết xuất một hình tròn bất cứ khi nào một điểm đánh dấu được nhấn.

Phương thức mapView:didTapMarker của bạn sẽ có dạng như sau:

- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
  _circ.map = nil;
  [_mapView animateToLocation:marker.position];

  if ([marker.userData conformsToProtocol:@protocol(GMUCluster)]) {
    [_mapView animateToZoom:_mapView.camera.zoom +1];
    return YES;
  }

  _circ = [GMSCircle circleWithPosition:marker.position radius:800];
  _circ.fillColor = [UIColor colorWithRed: 0.67 green: 0.67 blue: 0.67 alpha: 0.5];
  _circ.map = _mapView;
  return NO;
}

10. Xin chúc mừng

Bạn đã tạo thành công ứng dụng iOS đầu tiên bằng Nền tảng Google Maps, bao gồm cả việc tải Maps SDK cho iOS, tải bản đồ, làm việc với các điểm đánh dấu, kiểm soát và vẽ trên bản đồ, cũng như thêm hoạt động tương tác của người dùng.

Để xem mã nguồn hoàn chỉnh, hãy xem dự án đã hoàn tất trong thư mục /solution.

Tiếp theo là gì?

Trong lớp học lập trình này, chúng ta chỉ đề cập đến những kiến thức cơ bản về những việc bạn có thể làm với Maps SDK cho iOS. Tiếp theo, hãy thử thêm một số tính năng sau vào bản đồ:

  • Thay đổi loại bản đồ để hiển thị bản đồ vệ tinh, bản đồ kết hợp và bản đồ địa hình.
  • Tuỳ chỉnh các tương tác khác của người dùng, chẳng hạn như các chế độ thu phóng và điều khiển bản đồ.
  • Thêm cửa sổ thông tin để hiển thị thông tin khi người dùng nhấp vào điểm đánh dấu.
  • Hãy xem Places SDK cho iOS để thêm các tính năng và dữ liệu phong phú về địa điểm của Nền tảng Google Maps vào ứng dụng của bạn.

Để tiếp tục tìm hiểu thêm về những cách bạn có thể sử dụng Nền tảng Google Maps trên web, hãy xem các đường liên kết sau: