إضافة خريطة إلى تطبيق iOS (Swift)

1. قبل البدء

يعرض لك هذا الدرس التطبيقي كيفية بدء استخدام "منصة خرائط Google" لإنشاء تطبيقات iOS في Swift. يجب إنشاء تطبيق iOS لتنفيذ ما يلي:

  • لتحميل حزمة تطوير البرامج (SDK) لخدمة "خرائط Google" لنظام التشغيل iOS وحزمة تطوير برامج "خرائط Google" لمكتبة أدوات مساعدة iOS.
  • لعرض خريطة متمركزة في سيدني، أستراليا.
  • تعرض محدّدات الموقع المخصّصة لـ 100 نقطة حول سيدني.
  • لتنفيذ تجميع العلامات.
  • يمكّن تفاعل المستخدم الذي يعيد توسيط الدائرة ويرسمها على الخريطة عند النقر على العلامة.

خريطة محدّدة بعلامات في تطبيق iOS

المتطلّبات الأساسية

  • معرفة أساسية بتطوير Swift وiOS.

ما ستتعرَّف عليه

  • تحميل حزمة تطوير البرامج (SDK) لخدمة "خرائط Google" لنظام التشغيل iOS وحزمة تطوير برامج "خرائط Google" لمنصّة خدمات iOS.
  • جارٍ تحميل خريطة.
  • استخدام العلامات والعلامات المخصصة وتجميع العلامات.
  • استخدام حزمة تطوير البرامج (SDK) لتطبيق "خرائط Google" لنظام التشغيل iOS لتوفير تفاعل المستخدم.
  • التحكم في كاميرا الخريطة آليًا
  • الرسم على الخريطة

الأشياء التي تحتاج إليها

لإكمال الدرس التطبيقي حول الترميز، يجب توفّر الحسابات والخدمات والأدوات التالية:

  • الإصدار 12.0 من Xcode أو إصدار أحدث مع SDK المستهدف الإصدار 12.0 أو إصدار أحدث.
  • تم تثبيت Cocoapods.
  • حساب Google Cloud Platform تم تفعيل الفوترة به (راجِع الخطوة التالية).
  • مشروع في Cloud Console تم تفعيل "SDK للخرائط" لنظام التشغيل iOS (راجِع الخطوة التالية).

2. الإعداد

بالنسبة إلى خطوة التفعيل أدناه، عليك تفعيل حزمة تطوير البرامج (SDK) لتطبيق "خرائط Google" لنظام التشغيل iOS.

إعداد "منصة خرائط Google"

إذا لم يكن لديك حساب على Google Cloud Platform ومشروع تم تفعيل الفوترة فيه، يُرجى الاطّلاع على دليل بدء استخدام "منصة خرائط Google" لإنشاء حساب فوترة ومشروع.

  1. في Cloud Console، انقر على القائمة المنسدلة للمشروع واختَر المشروع الذي تريد استخدامه لهذا الدرس التطبيقي.

  1. فعِّل واجهات برمجة تطبيقات ومنصة SDK لمنصة "خرائط Google" المطلوبة لهذا الدرس التطبيقي في Google Cloud Marketplace. ولإجراء ذلك، اتّبِع الخطوات الواردة في هذا الفيديو أو هذه المستندات.
  2. يمكنك إنشاء مفتاح واجهة برمجة تطبيقات في صفحة بيانات الاعتماد في Cloud Console. يمكنك اتّباع الخطوات الواردة في هذا الفيديو أو هذه المستندات. تتطلب جميع الطلبات إلى "منصة خرائط Google" مفتاح واجهة برمجة تطبيقات.

البدء السريع

لمساعدتك في البدء في أسرع وقت ممكن، إليك بعض رموز البدء لمساعدتك في متابعة هذا الدرس التطبيقي حول الترميز.

  1. إنشاء نسخة طبق الأصل من المستودع في حال تثبيت git.
git clone https://github.com/googlemaps/codelab-maps-platform-101-swift.git

أو بدلاً من ذلك، انقر على إعطائي الرمز لتنزيل رمز المصدر.

  1. بعد تنزيل الرمز، افتح مشروع StarterApp في الدليل /starter. يتضمّن هذا المشروع بنية الملفات الأساسية التي تحتاجها لإكمال الدرس التطبيقي حول الترميز. ستجد كل ما تحتاج إليه للعمل في دليل /starter/StarterApp.

وللاطّلاع على رمز الحل الكامل قيد التشغيل، اعرض الرمز المكتمل في الدليل /solution/SolutionApp.

3- تثبيت "حزمة تطوير البرامج (SDK)" لخدمة "خرائط Google" لنظام التشغيل iOS

تتمثل الخطوة الأولى لاستخدام حزمة تطوير البرامج (SDK) لتطبيق "خرائط Google" لنظام التشغيل iOS في تثبيت العناصر المرتبطة المطلوبة. وهناك خطوتان لإجراء هذه العملية: تثبيت حزمة تطوير البرامج (SDK) لخدمة "خرائط Google" لنظام التشغيل iOS وحزمة تطوير البرامج (SDK) لخدمة "خرائط Google" لنظام التشغيل iOS المساعدة من مدير الاعتمادية في Cocoapods، وتقديم مفتاح واجهة برمجة التطبيقات إلى حزمة تطوير البرامج (SDK).

  1. أضِف حزمة تطوير البرامج (SDK) لخدمة "خرائط Google" لنظام التشغيل iOS وحزمة تطوير البرامج (SDK) لخدمة "خرائط Google" لنظام التشغيل iOS Utility إلى Podfile.

يستخدم هذا الدرس التطبيقي كلًا من SDK للخرائط في نظام التشغيل iOS، والذي يقدم جميع الوظائف الأساسية لخدمة "خرائط Google" ومكتبة الأدوات في iOS، والتي توفّر مجموعة متنوعة من الأدوات المساعدة لإثراء خريطتك، بما في ذلك تجميع العلامات.

للبدء، في Xcode (أو محرر النصوص المفضل لديك)، افتح Podfile وعدِّل الملف لتضمين حِزم تطوير البرامج (SDK) لتطبيق "خرائط Google" لنظام التشغيل iOS وتبعيات مكتبة الأدوات المساعدة ضمن التعليق # Pods for StarterApp:

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

تحقّق من مستندات إصدارات حزمة تطوير البرامج (SDK) لخدمة "خرائط Google" لنظام التشغيل 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. ثبِّت تطبيق حزمة تطوير البرامج (SDK) لخدمة "خرائط Google" لنظام التشغيل iOS وحزمة تطوير البرامج (SDK) لخدمة "خرائط Google" لنظام التشغيل iOS للمكتبة.

لتثبيت التبعيات، شغِّل pod install في الدليل /starter من سطر الأوامر. يعمل Cocoapods على تنزيل الارتباطات تلقائيًا وإنشاء StarterApp.xcworkspace.

  1. بعد تثبيت العناصر التابعة لك، يمكنك تشغيل open StarterApp.xcworkspace من الدليل /starter لفتح الملف في Xcode، ثم تشغيل التطبيق في محاكي iPhone بالضغط على Command+R. إذا تم إعداد كل شيء بشكل صحيح، سيتم تشغيل المحاكي وعرض شاشة سوداء. لا داعي للقلق، فلم يتم إنشاء أي شيء بعد، لذلك يعد هذا أمرًا متوقعًا.
  2. استورِد حزمة تطوير البرامج (SDK) في AppDelegate.swift.

الآن بعد أن تم تثبيت تبعياتك، حان وقت تقديم مفتاح واجهة برمجة التطبيقات إلى حزمة تطوير البرامج (SDK). تتمثل الخطوة الأولى في استيراد حزمة تطوير البرامج (SDK) لتطبيق "خرائط Google" لنظام التشغيل iOS اعتمادية من خلال وضع ما يلي أسفل عبارة استيراد import UIKit:

import GoogleMaps
  1. تمرير مفتاح واجهة برمجة التطبيقات إلى حزمة تطوير البرامج (SDK) لنظام التشغيل iOS من خلال الاتصال بـ 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 بمفتاح واجهة برمجة التطبيقات الذي أنشأته في Cloud Console.

الآن وقد تم تثبيت تبعياتك وتوفير مفتاح واجهة برمجة التطبيقات، أنت على استعداد لبدء إجراء مكالمات إلى SDK للخرائط لنظام التشغيل iOS.

4. عرض خريطة

حان وقت عرض خريطتك الأولى.

ويُعد الجزء GMSMapView من الجزء الأكثر استخدامًا في SDK للخرائط لنظام التشغيل iOS، والذي يوفر العديد من الطرق التي تتيح لك إنشاء مثيلات الخرائط ومعالجتها. إليك كيفية إجراء ذلك.

  1. فتح ViewController.swift

هذا هو الجزء الذي سيتم فيه إكمال العمل المتبقي من هذا الدرس التطبيقي حول الترميز. لاحظ أنه تمت إزالة بعض مراحل نشاط loadView وviewDidLoad لوحدة التحكم في الملف الشخصي من قبل.

  1. يمكنك استيراد حزمة تطوير البرامج (SDK) لتطبيق "خرائط Google" لنظام التشغيل 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)، ويجب أن تظهر الخريطة كما هو موضح في الشكل 1.

تطبيق iOS يعرض "خرائط Google"

الشكل 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 وضمن طريقة loadView، أنشئ كائن GMSMapID وقدّم رقم تعريف الخريطة إليه. بعد ذلك، عدِّل مثيل GMSMapView من خلال تقديم الكائن 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- إضافة علامات إلى الخريطة

هناك العديد من الأمور التي ينفذها مطوّرو البرامج باستخدام حزمة تطوير البرامج (SDK) لتطبيق "خرائط Google" لنظام التشغيل iOS، إلا أن وضع العلامات على الخريطة هو الأكثر رواجًا بكل تأكيد. تعرض العلامات نقاطًا محددة على الخريطة، وتُعتبر عنصرًا شائعًا في واجهة المستخدم للتعامل مع المستخدم. إذا كنت قد استخدمت "خرائط Google" من قبل، ربما تكون على دراية بالعلامة التلقائية، التي تبدو كدبابيس حمراء في الشكل 2:

خريطة محدّدة بعلامات حمراء

الشكل 2. خريطة باستخدام علامات حمراء.

توضّح هذه الخطوة كيفية استخدام الفئة GMSMarker لوضع العلامات على الخريطة.

تجدر الإشارة إلى أنّه لا يمكن وضع العلامات على الخريطة إلا بعد تحميل الخريطة من الخطوة السابقة في حدث دورة الحياة لـ loadView في وحدة التحكّم في العرض، لذلك أكمِل هذه الخطوات في حدث مراحل نشاط viewDidLoad، والذي يتم طلبه بعد تحميل العرض (والخريطة).

  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.

توفر حزمة تطوير البرامج (SDK) لتطبيق"خرائط Google"لنظام التشغيل iOS الصف GMSMarker. يمثل كل مثيل GMSMarker علامة خاصة على الخريطة ويتم إنشاؤه عن طريق استدعاء markerWithPosition: وتمرير كائن CLLocationCoordinate2D لإعلام حزمة تطوير البرامج (SDK) بمكان وضع العلامة على الخريطة.

    let marker = GMSMarker(position: mapCenter)
  1. إعداد رمز علامة مخصّصة

محدِّد الدبوس الأحمر التلقائي في "خرائط Google" رائع، لذلك يتم تخصيص خريطتك. لحسن الحظ، استخدام العلامة المخصصة سهل جدًا مع SDK للخرائط لنظام التشغيل iOS. يُرجى ملاحظة أن مشروع StarterApp يتضمن صورة باسم "custom_pin.png&#39؛ لك حتى تستخدمها، ولكن يمكنك استخدام أي صورة تريدها.

لضبط العلامة المخصّصة، اضبط الخاصية icon للعلامة على مثيل UIImage.

    marker.icon = UIImage(named: "custom_pin.png")
  1. عرض محدّد الموقع على الخريطة.

تم إنشاء محدّد موقعك، ولكنه ليس على الخريطة بعد. لتنفيذ ذلك، اضبط السمة map للمثيل GMSMarker على مثيل GMSMapView.

    marker.map = mapView

الآن أعد تحميل التطبيق وتمكّن من بدء تشغيل الخريطة الأولى باستخدام محدّد كما هو موضح في الشكل 3.

تطبيق iOS يعرض خريطة Google مع علامة حمراء في الوسط

الشكل 3. تطبيق iOS وهو يعرض "خرائط Google" مع علامة حمراء في الوسط.

خلاصة الملخّص، في هذا القسم، أنشأت مثيلاً لصف GMSماركر وطبّقته على وضع الخريطة لعرض محدّد على الخريطة. من المفترض أن يظهر الآن حدث مراحل نشاط مراحل العرض المعدَّلة في 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- تفعيل تجميع العلامات

إذا كنت تستخدم الكثير من العلامات، أو إذا كانت لديك علامات قريبة من بعضها البعض، قد تواجه مشكلة عندما تتداخل العلامات أو تظهر مزدحمًا معًا، مما يؤدي إلى تجربة سيئة للمستخدم. على سبيل المثال، إذا كان هناك محدّدَين قريبَين جدًا من بعضهما، قد ينتهي بك الأمر كما هو موضّح في الشكل 4:

هناك علامتان قريبتان جدًا من بعضهما

الشكل 4. هناك محدّدَان قريبان جدًا من بعضهما.

وهنا يأتي دور تجميع العلامات. ميزة تجميع العلامات هي ميزة أخرى يتم تنفيذها بشكل عام، وهي تجمّع العلامات القريبة في رمز واحد يتغير استنادًا إلى مستوى التكبير أو التصغير، كما هو موضح في الشكل 5:

مثال لعلامات تم تجميعها في رمز واحد

الشكل 5. مثال للعلامات التي تم تجميعها في رمز واحد.

تقسِّم خوارزمية تجميع العلامات المنطقة المرئية من الخريطة إلى شبكة، ثم تجمّع الرموز في الخلية نفسها. أنشأ فريق "منصة خرائط Google" مكتبة برامج مساعدة مفتوحة المصدر تُسمى "حزمة تطوير البرامج (SDK) لخدمة "خرائط Google"" لنظام التشغيل iOS، وتتولى هذه الأداة، من بين أمور أخرى، معالجة تجميع العلامات من أجلك تلقائيًا. اقرأ المزيد عن تجميع العلامات في وثائق منصة خرائط Google، أو تحقق من مصدر مكتبة أدوات 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، ثم تشغيل التطبيق. تأكد من إضافة تعليق لهذه الأسطر قبل الانتقال إلى الخطوات التالية، والتي تستخدم مجموعة العلامات لإدارة عرض العلامات بدلاً من ذلك:

    // Comment the following code out if using the marker clusterer
    // to manage markers instead.
    for marker in markerArray {
      marker.map = mapView
    }
  1. استيراد حزمة تطوير البرامج (SDK) لتطبيق "خرائط Google" لمكتب خدمات iOS.

لإضافة مكتبة أدوات iOS في"خرائط Google"باعتبارها اعتمادية على مشروعك، أضِف هذه القائمة إلى قائمة التبعيات في أعلى ViewController.swift:

import GoogleMapsUtils
  1. اضبط أداة تجميع العلامات.

لاستخدام أداة تجميع العلامات، يجب تقديم ثلاثة عناصر لضبط آلية العمل: خوارزمية تجميع ومنشئ رموز وعارض. تحدد الخوارزمية سلوك كيفية تجميع العلامات، مثل المسافة بين العلامات المطلوب تضمينها في المجموعة نفسها. يوفر منشئ الرموز رموز المجموعات لاستخدامها في مستويات تكبير/تصغير مختلفة. يتعامل العارض مع العرض الفعلي لرموز المجموعات على الخريطة.

يمكنك كتابة كل هذه المعلومات من البداية إذا كنت تفضّل ذلك، ولكن توفر مكتبة برامج الخدمات في نظام التشغيل iOS عمليات تنفيذ تلقائية لتسهيل العملية. إضافة هذا:

    // 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 لتخزين مثيل مدير المجموعة:

class ViewController: UIViewController, GMSMapViewDelegate {

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

بعد ذلك، أنشئ مثيل GMUClusterManager في حدث مراحل نشاط viewDidLoad:

    clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
  1. إضافة العلامات وتشغيل مجمِّع العلامات.

الآن بعد أن تم إعداد مثيل أداة تصنيف العلامات، عليك تمرير مدير المجموعة مصفوفة من العلامات التي سيتم تجميعها من خلال الاتصال بـ add(items:)، ثم تشغيل هذه المجموعة من خلال استدعاء cluster.

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

أعد تحميل تطبيقك، ومن المفترض أن يظهر لك الآن الكثير من العلامات التي تم تجميعها بشكل جيد، كما هو موضّح في المثال 6 في الشكل 6. واصِل اللعب بمستويات تكبير وتصغير مختلفة من خلال التكبير والتصغير على الشاشة والتكبير أو التصغير، لرؤية مجموعات العلامات تتكيف مع تكبير/تصغير.

تطبيق iOS مزوّد بخريطة Google وعلامات محدّدة

الشكل 6. تطبيق iOS مزوّد بتطبيق "خرائط Google" وعلامات مجمّعة.

خلاصة القول، في هذه الخطوة، هيأتَ مثيلًا لأداة تجميع العلامات من حزمة تطوير البرامج (SDK) لتطبيق "خرائط Google" لمكتب خدمات 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، والتي حددتها على وحدة التحكُّم في العرض سابقًا، لتحسين تجربة المستخدِم لخريطتك.

توفر حزمة تطوير البرامج (SDK) لتطبيق "خرائط Google" لنظام التشغيل iOS نظامًا شاملاً للأحداث يتم تنفيذه من خلال مفوّض عرض الخريطة، والذي يتضمّن معالجات الأحداث التي تتيح لك تنفيذ الرمز عند حدوث تفاعلات مختلفة للمستخدم. على سبيل المثال، يتضمن مفوَّض MapView طرقًا تتيح لك تنفيذ الرمز للتفاعلات، مثل نقر المستخدم على الخريطة والعلامات، وتكبير عرض الخريطة، وتكبيرها وتصغيرها، والمزيد.

في هذه الخطوة، يمكنك تدوير الخريطة آليًا لتوسيطها على أي محدّد ينقر عليه المستخدم.

  1. تنفيذ المستمع على النقر على محدّد الموقع.

يتم استدعاء mapView(_:didTap:) في أي وقت ينقر فيه المستخدم على إحدى العلامات التي أنشأتها سابقًا، وعندما ينقر المستخدم على مجموعة علامات (يتم تنفيذ مجموعات العلامات داخليًا كمثال GMSMarker).

لتنفيذ أداة معالجة الحدث، ابدأ بوضعها في أسفل ViewController.swift قبل القوس المجعد الختامي.

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

    return false
  }

يُرجى العِلم بأنّ الطريقة تعرض false. يؤدي ذلك إلى إبلاغ حزمة تطوير البرامج (SDK) لنظام التشغيل iOS بمواصلة تنفيذ وظيفة GMSMarker التلقائية، مثل عرض نافذة معلومات في حال ضبطها، بعد تنفيذ رمز معالج الأحداث.

  1. يمكنك معالجة حدث النقر وتحريك الكاميرا لتصغير الخريطة عند النقر على محدِّد موقع أو مجموعة علامات.

عند الاتصال، يمرّر mapView(_:didTap:) مثيل GMSMarker الذي تم النقر عليه حتى تتمكن من التعامل معه في الرمز. ويمكنك استخدام هذا المثيل في إعادة ضبط الخريطة من خلال استدعاء الدالة animate(toLocation:) في وضع الخريطة من داخل معالج الحدث، وتمريره موضع مثيل العلامة من الموقع الإلكتروني position.

    // Animate to the marker
    mapView.animate(toLocation: marker.position)
  1. تكبير مجموعة علامات عند النقر عليها

يتمثل نمط المستخدم الشائع في تكبير مجموعات العلامات عند النقر عليها. ويسمح هذا للمستخدمين بعرض العلامات المجمّعة، أثناء توسيع المجموعة عند مستويات تكبير/تصغير أقل.

كما أشرنا سلفًا، رمز مجموعة العلامات هو تنفيذ GMSMarker مع رمز مخصص. كيف يمكنك معرفة ما إذا تم النقر على علامة أو مجموعة علامات؟ عندما ينشئ مدير أداة تجميع العلامات رمز مجموعة جديد، ينفِّذ مثيل GMSMarker للتوافق مع بروتوكول يُسمى GMUCluster.. ويمكنك استخدام شرطي للتحقق مما إذا كانت العلامة التي يتم تمريرها إلى معالج الأحداث تتوافق مع هذا البروتوكول أم لا.

بعد أن تعرف آليًا أنه تم النقر على مجموعة، يمكنك استدعاء الدالة animate(toZoom:) على مثيل عرض الخريطة وضبط التكبير/التصغير على مستوى التكبير أو التصغير الحالي بالإضافة إلى واحد. يتوفّر مستوى التكبير أو التصغير الحالي في مثيل 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
    }

أعِد تحميل التطبيق الآن وانقر على بعض العلامات ومجموعات المجموعات. عند النقر على أي منهما، سيتم تحديث الخريطة على العنصر الذي تم النقر عليه. عند النقر على مجموعة علامات، سيتم أيضًا تكبير الخريطة على مستوى واحد، وسيتم توسيع مجموعة العلامات لإظهار العلامات التي تم تجميعها أدناه.

باختصار، في هذه الخطوة، تكون قد نفّذت أداة معالجة النقر على محدّد الموقع، وعالجت الحدث على أحدث عنصر تم النقر عليه وتكبيره إذا كان هذا العنصر هو رمز مجموعة محدّد الموقع.

ستظهر طريقة 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 نقطة عشوائية وتتعامل مع تفاعل المستخدم. بالنسبة إلى الخطوة الأخيرة من هذا الدرس التطبيقي حول الترميز، يمكنك استخدام ميزات الرسم في "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 لحزمة تطوير البرامج (SDK) لنظام التشغيل iOS لنظام التشغيل iOS&#39؛ لرسم دائرة نصف قطر جديدة 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-sdk-for-ios-samples GitHub للنماذج والعروض التوضيحية للحصول على مزيد من الإلهام
  • تعلّم من المزيد من مختبرات Swift لتصميم تطبيقات iOS باستخدام نظام خرائط Google الأساسي
  • يُرجى مساعدتنا في إنشاء المحتوى الذي قد تجده أكثر فائدة من خلال الإجابة عن السؤال التالي:

ما هي الدروس التطبيقية الأخرى حول الترميز التي تريد الاطّلاع عليها؟

التمثيل البصري للبيانات على الخرائط مزيد من المعلومات عن تخصيص نمط خرائطي إنشاء التفاعلات الثلاثية الأبعاد في الخرائط

هل الدرس التطبيقي حول الترميز الذي تريده غير مدرج أعلاه؟ طلب حلول للمشكلة الجديدة هنا