إضافة خريطة Google إلى تطبيق React

1. قبل البدء

في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كل ما تحتاج إليه للبدء في استخدام مكتبة vis.gl/react-google-map لخدمة Google Maps JavaScript API، والتي تتيح لك إضافة خريطة من Google إلى تطبيق React. ستتعرّف على كيفية إعداد المكتبة وتحميل Maps JavaScript API وعرض أول خريطة والعمل مع العلامات وتجميع العلامات ورسم الأشكال على الخريطة والتعامل مع تفاعلات المستخدمين.

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

  • معرفة أساسية بلغات JavaScript وHTML وCSS

ما ستتعلمه

  • كيفية بدء استخدام مكتبة vis.gl/react-google-map في "منصة خرائط Google"
  • كيفية تحميل Maps JavaScript API بشكل تعريفي
  • كيفية تحميل خريطة في تطبيق React
  • كيفية استخدام العلامات والعلامات المخصّصة وتجميع العلامات
  • كيفية استخدام نظام الأحداث في Maps JavaScript API لتوفير تفاعل المستخدم
  • كيفية التحكّم في الخريطة بشكل ديناميكي
  • كيفية الرسم على الخريطة

ما تحتاج إليه

  • حساب على Google Cloud تم تفعيل الفوترة فيه
  • مفتاح Google Maps Platform API مع تفعيل Maps JavaScript API
  • Node.js مثبَّت على جهاز الكمبيوتر
  • محرّر نصوص أو بيئة تطوير متكاملة (IDE) من اختيارك
  • مكتبة vis.gl/react-google-map لواجهة Google Maps JavaScript API
  • مكتبة googlemaps/markerclusterer

إعداد Google Maps Platform

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

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

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

2. طريقة الإعداد

تنزيل مشروع البداية

لتنزيل نموذج مشروع البداية ورمز الحلّ، اتّبِع الخطوات التالية:

  1. نزِّل مستودع GitHub أو أنشئ نسخة منه. يقع مشروع البداية في الدليل /starter ويتضمّن بنية الملف الأساسية التي تحتاج إليها لإكمال الدرس العملي. يمكنك إنجاز جميع أعمالك في الدليل /starter/src.
git clone https://github.com/googlemaps-samples/codelab-maps-platform-101-react-js.git

بدلاً من ذلك، انقر على هذا الزر لتنزيل الرمز المصدر.

  1. انتقِل إلى الدليل /starter وثبِّت npm. يؤدي ذلك إلى تثبيت جميع العناصر التابعة اللازمة والمدرَجة في الملف package.json.
cd starter && npm install
  1. أثناء البقاء في دليل /starter، اتّبِع الخطوات التالية:
npm start

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

  1. إذا كنت تريد تنفيذ رمز الحل الكامل، انتقِل إلى الدليل /solution وأكمِل خطوات الإعداد نفسها.

3- تحميل Maps JavaScript API

أساس استخدام "منصة خرائط Google" على الويب هو Maps JavaScript API. توفّر واجهة برمجة التطبيقات هذه واجهة JavaScript لاستخدام جميع ميزات "منصة خرائط Google"، بما في ذلك الخريطة والعلامات وأدوات الرسم وخدمات "منصة خرائط Google" الأخرى، مثل Places.

لتحميل Maps JavaScript API باستخدام إطار عمل React، عليك استخدام المكوّن APIProvider الذي يشكّل جزءًا من مكتبة vis.gl/react-google-map. يمكن إضافة هذا المكوّن على أي مستوى من التطبيق، عادةً في مكان ما في الأعلى، ويعرض جميع المكوّنات الفرعية بدون تعديل. بالإضافة إلى معالجة تحميل Maps JavaScript API، يوفّر أيضًا معلومات السياق ووظائف المكوّنات وخطافات المكتبة الأخرى. يتم تضمين APIProvider في مكتبة vis.gl/react-google-map، لذا تم تثبيته عند تنفيذ npm install في وقت سابق.

لاستخدام مكوّن APIProvider، اتّبِع الخطوات التالية:

  1. افتح ملف /src/app.tsx. هذا الملف هو المكان الذي ستنفّذ فيه جميع المهام المطلوبة في هذا الدرس البرمجي.
  2. في أعلى الملف، استورِد الفئة APIProvider من مكتبة @vis.gl/react-google-maps:
import {APIProvider} from '@vis.gl/react-google-maps';
  1. في تعريف الدالة App، اضبط المَعلمة apiKey الخاصة بالمكوّن APIProvider باستخدام مفتاح واجهة برمجة التطبيقات الذي تم إنشاؤه في الخطوة السابقة والخاصية onLoad باستخدام رسالة سجلّ وحدة التحكّم:
<APIProvider apiKey={'Your API key here'} onLoad={() => console.log('Maps API has loaded.')}>

يتضمّن المكوّن APIProvider سلسلة من السمات التي تحدّد خيارات مختلفة لتحميل Maps JavaScript API، بما في ذلك مفتاح واجهة برمجة التطبيقات في Google Maps Platform، وإصدار واجهة برمجة التطبيقات الذي تريد تحميله، وأي مكتبات إضافية توفّرها Maps JavaScript API وتريد تحميلها.

مفتاح Google Maps API هو السمة الوحيدة المطلوبة لكي تعمل APIProvider، وقد أدرجنا السمة onLoad لأغراض توضيحية. لمزيد من المعلومات، يُرجى الاطّلاع على مكوّن <APIProvider>.

يجب أن يظهر ملف app.tsx على النحو التالي:

import React from 'react';
import {createRoot} from "react-dom/client";
import {APIProvider} from '@vis.gl/react-google-maps';

const App = () => (
 <APIProvider apiKey={'Your API key here'} onLoad={() => console.log('Maps API has loaded.')}>
   <h1>Hello, world!</h1>
 </APIProvider>
);

const root = createRoot(document.getElementById('app'));
root.render(<App />);

export default App;

في حال نجاح كل شيء، من المفترض أن ترى العبارة console.log في وحدة تحكّم المتصفّح. بعد تحميل Maps JavaScript API، يمكنك عرض الخريطة الديناميكية في الخطوة التالية.

4. عرض خريطة

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

الجزء الأكثر استخدامًا في Maps JavaScript API هو google.maps.Map، وهو الفئة التي تتيح لك إنشاء مثيلات الخرائط ومعالجتها. تغلّف مكتبة vis.gl/react-google-map هذه الفئة في المكوّن Map. أولاً، استورِد الصفين Map وMapCameraChangedEvent.

import {APIProvider, Map, MapCameraChangedEvent} from '@vis.gl/react-google-maps';

يتيح المكوّن Map مجموعة متنوعة من الإعدادات المختلفة للخريطة. في هذا الدرس العملي، ستستخدم الإعدادات التالية:

  • defaultCenter، التي تحدّد خط العرض وخط الطول لمركز الخريطة.
  • defaultZoom، الذي يضبط مستوى التكبير أو التصغير الأولي للخريطة.
  • لعرض خريطة، ضَع الرمز التالي ضمن علامتَي APIProvider لتوسيط الخريطة على "سيدني"، أستراليا، ومنحها مستوى تكبير 13، وهو مستوى التكبير المناسب لعرض وسط المدينة:
 <Map
      defaultZoom={13}
      defaultCenter={ { lat: -33.860664, lng: 151.208138 } }
      onCameraChanged={ (ev: MapCameraChangedEvent) =>
        console.log('camera changed:', ev.detail.center, 'zoom:', ev.detail.zoom)
      }>
</Map>

من المفترض أن تظهر لك الآن خريطة سيدني في المتصفّح:

761c8c51c6631174.png

للتلخيص، في هذا القسم، عرضتَ خريطة باستخدام مكوّن <Map> وضبطتَ حالتها الأولية باستخدام السمات. استخدمت أيضًا الأحداث لتسجيل وقت تغيير الكاميرا.

يجب أن يبدو ملف app.tsx على النحو التالي:

import React from 'react';
import {createRoot} from "react-dom/client";
import {APIProvider, Map, MapCameraChangedEvent} from '@vis.gl/react-google-maps';

const App = () => (
 <APIProvider apiKey={'Your API key here'} onLoad={() => console.log('Maps API has loaded.')}>
   <Map
      defaultZoom={13}
      defaultCenter={ { lat: -33.860664, lng: 151.208138 } }
      onCameraChanged={ (ev: MapCameraChangedEvent) =>
        console.log('camera changed:', ev.detail.center, 'zoom:', ev.detail.zoom)
      }>
   </Map>
 </APIProvider>
);

const root = createRoot(document.getElementById('app'));
root.render(<App />);

export default App;

5- إضافة تصميم الخرائط باستخدام السحابة الإلكترونية

يجب توفير رقم تعريف خريطة لاستخدام "محدّدات المواقع المتقدّمة" التي تستخدمها لوضع علامات على نقاط الاهتمام في خريطة سيدني. يُستخدَم معرّف الخريطة أيضًا لتصميم الخرائط باستخدام السحابة الإلكترونية.

يمكنك تخصيص نمط الخريطة باستخدام تصميم الخرائط باستخدام السحابة الإلكترونية.

إنشاء رقم تعريف خريطة

إذا لم يسبق لك إنشاء معرّف خريطة مرتبط بنمط خريطة، يمكنك الاطّلاع على دليل معرّفات الخرائط لإكمال الخطوات التالية:

  1. أنشئ معرّف خريطة.
  2. ربط رقم تعريف خريطة بنمط خريطة

لاستخدام معرّف الخريطة الذي أنشأته، اضبط السمة mapId للمكوّن <Map>:

<Map
    defaultZoom={13}
    defaultCenter={ { lat: -33.860664, lng: 151.208138 } }
    mapId='DEMO_MAP_ID'
    onCameraChanged={ (ev: MapCameraChangedEvent) =>
        console.log('camera changed:', ev.detail.center, 'zoom:', ev.detail.zoom)
    }>
</Map>

من المفترض أن يظهر لك النمط الذي اخترته على الخريطة.

6. إضافة علامات إلى الخريطة

هناك العديد من الإجراءات التي ينفّذها المطوّرون باستخدام Maps JavaScript API، ولكن وضع العلامات على الخريطة هو بالتأكيد الأكثر شيوعًا. تتيح لك العلامات عرض نقاط معيّنة على الخريطة، وهي عنصر شائع في واجهة المستخدم للتعامل مع تفاعل المستخدم. إذا سبق لك استخدام "خرائط Google"، من المحتمل أنّك على دراية بالعلامة التلقائية التي تبدو على النحو التالي:

d9a6513b82a2f1e1.png

لاستخدام مكوّن AdvancedMarker لوضع علامات على الخريطة، اتّبِع الخطوات التالية:

  1. أنشئ قائمة بالكائنات لتمثيل نقاط الاهتمام في منطقة "سيدني"، وضَعها أسفل عمليات الاستيراد مباشرةً، خارج تعريف App:
type Poi ={ key: string, location: google.maps.LatLngLiteral }
const locations: Poi[] = [
  {key: 'operaHouse', location: { lat: -33.8567844, lng: 151.213108  }},
  {key: 'tarongaZoo', location: { lat: -33.8472767, lng: 151.2188164 }},
  {key: 'manlyBeach', location: { lat: -33.8209738, lng: 151.2563253 }},
  {key: 'hyderPark', location: { lat: -33.8690081, lng: 151.2052393 }},
  {key: 'theRocks', location: { lat: -33.8587568, lng: 151.2058246 }},
  {key: 'circularQuay', location: { lat: -33.858761, lng: 151.2055688 }},
  {key: 'harbourBridge', location: { lat: -33.852228, lng: 151.2038374 }},
  {key: 'kingsCross', location: { lat: -33.8737375, lng: 151.222569 }},
  {key: 'botanicGardens', location: { lat: -33.864167, lng: 151.216387 }},
  {key: 'museumOfSydney', location: { lat: -33.8636005, lng: 151.2092542 }},
  {key: 'maritimeMuseum', location: { lat: -33.869395, lng: 151.198648 }},
  {key: 'kingStreetWharf', location: { lat: -33.8665445, lng: 151.1989808 }},
  {key: 'aquarium', location: { lat: -33.869627, lng: 151.202146 }},
  {key: 'darlingHarbour', location: { lat: -33.87488, lng: 151.1987113 }},
  {key: 'barangaroo', location: { lat: - 33.8605523, lng: 151.1972205 }},
];

const App = () => (
  ...
);
  1. يمكنك تخصيص الدبابيس باستخدام العنصر <Pin> باتّباع الخطوات التالية:
<Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
  1. أنشئ مكوّنًا مخصّصًا لعرض قائمتك باستخدام "علامات متقدّمة"، وضَع هذا المكوّن أسفل تعريف App:
const App = () => (
  ...
);

const PoiMarkers = (props: {pois: Poi[]}) => {
  return (
    <>
      {props.pois.map( (poi: Poi) => (
        <AdvancedMarker
          key={poi.key}
          position={poi.location}>
        <Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
        </AdvancedMarker>
      ))}
    </>
  );
};
  1. أضِف المكوّن PoiMarkers كعنصر ثانوي للمكوّن Map:
<Map
  ... map properties ...
>
  <PoiMarkers pois={locations} />
</Map>
  1. أخيرًا، أضِف Pin وAdvancedMarker إلى عمليات الاستيراد.
import {
  APIProvider,
  Map,
  AdvancedMarker,
  MapCameraChangedEvent,
  Pin
} from '@vis.gl/react-google-maps';

من المفترض أن تظهر لك "علامات متقدمة" مخصّصة على الخريطة:

98d12a994e12a2c1.png

7. تفعيل تجميع العلامات

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

98d12a994e12a2c1.png

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

3da24a6b737fe499.png

تقسّم خوارزمية تجميع العلامات المنطقة المرئية من الخريطة إلى شبكة، ثم تجمع الرموز التي تقع في الخلية نفسها. لحسن الحظ، لا داعي للقلق بشأن أي من ذلك لأنّ فريق Google Maps Platform أنشأ مكتبة أدوات مساعدة مفيدة ومفتوحة المصدر باسم MarkerClustererPlus تنفّذ كل ذلك تلقائيًا. يمكنك الاطّلاع على رمز المصدر لمكتبة MarkerClustererPlus على GitHub.

لتفعيل تجميع العلامات، اتّبِع الخطوات التالية:

  1. في أعلى ملف app.tsx، لنعدّل ونضيف إلى عمليات استيراد المكتبة والأنواع المتوافقة.
import React, {useEffect, useState, useRef, useCallback} from 'react';
import {createRoot} from "react-dom/client";
import {
    APIProvider,
    Map,
    AdvancedMarker,
    MapCameraChangedEvent,
    useMap,
    Pin
  } from '@vis.gl/react-google-maps';
  import {MarkerClusterer} from '@googlemaps/markerclusterer';
  import type {Marker} from '@googlemaps/markerclusterer';

بالنسبة إلى مشروع النموذج لهذا الدرس البرمجي، تم تضمين مكتبة الأداة MarkerClustererPlus في التبعيات المحدّدة في ملف package.json، لذا سبق لك تثبيتها عند تنفيذ npm install في بداية هذا الدرس البرمجي.

  1. أنشئ متغيرات لعنصر MarkerClusterer والعناصر الداعمة في مكوّن PoiMarkers.

تحتاج إلى نسخة من الخريطة لإعداد MarkerClusterer. احصل على هذا المثال من خطاف useMap():

const map = useMap();
  1. إنشاء قائمة بالعلامات المخزّنة في متغيّر حالة:
const [markers, setMarkers] = useState<{[key: string]: Marker}>({});
  1. تخزين أداة التجميع كمرجع:
const clusterer = useRef<MarkerClusterer | null>(null);
  1. في مكوّن PoiMarkers أيضًا، أنشئ مثيلاً من MarkerClusterer ومرِّر إليه مثيل Map حيث تريد عرض مجموعات العلامات:
 useEffect(() => {
    if (!map) return;
    if (!clusterer.current) {
      clusterer.current = new MarkerClusterer({map});
    }
  }, [map]);
  1. أنشئ تأثيرًا يعدّل أداة التجميع عند تغيير قائمة العلامات:
useEffect(() => {
    clusterer.current?.clearMarkers();
    clusterer.current?.addMarkers(Object.values(markers));
  }, [markers]);
  1. أنشئ دالة لإنشاء مراجع للعلامات الجديدة:
const setMarkerRef = (marker: Marker | null, key: string) => {
    if (marker && markers[key]) return;
    if (!marker && !markers[key]) return;

    setMarkers(prev => {
      if (marker) {
        return {...prev, [key]: marker};
      } else {
        const newMarkers = {...prev};
        delete newMarkers[key];
        return newMarkers;
      }
    });
  };
  1. استخدِم هذه الطريقة في العنصر AdvancedMarker لإنشاء مرجع لكل علامة.
<AdvancedMarker
  key={poi.key}
  position={poi.location}
  ref={marker => setMarkerRef(marker, poi.key)}
  >
    <Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
</AdvancedMarker>

من المفترض أن تظهر لك الآن مجموعات من العلامات على خريطتك:

3da24a6b737fe499.png

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

d5e75480e9abd3c7.png

باختصار، في هذا القسم، استوردت مكتبة الأدوات المساعدة MarkerClustererPlus المفتوحة المصدر واستخدمتها لإنشاء مثيل من MarkerClusterer، والذي عمل، بمساعدة حالة React والمراجع، على تجميع العلامات التي أنشأتها في الخطوة السابقة تلقائيًا.

يجب أن يبدو مكوّن PoiMarkers على النحو التالي:

const PoiMarkers = (props: { pois: Poi[] }) => {
  const map = useMap();
  const [markers, setMarkers] = useState<{[key: string]: Marker}>({});
  const clusterer = useRef<MarkerClusterer | null>(null);

  // Initialize MarkerClusterer, if the map has changed
  useEffect(() => {
    if (!map) return;
    if (!clusterer.current) {
      clusterer.current = new MarkerClusterer({map});
    }
  }, [map]);

  // Update markers, if the markers array has changed
  useEffect(() => {
    clusterer.current?.clearMarkers();
    clusterer.current?.addMarkers(Object.values(markers));
  }, [markers]);

  const setMarkerRef = (marker: Marker | null, key: string) => {
    if (marker && markers[key]) return;
    if (!marker && !markers[key]) return;

    setMarkers(prev => {
      if (marker) {
        return {...prev, [key]: marker};
      } else {
        const newMarkers = {...prev};
        delete newMarkers[key];
        return newMarkers;
      }
    });
  };

  return (
    <>
      {props.pois.map( (poi: Poi) => (
        <AdvancedMarker
          key={poi.key}
          position={poi.location}
          ref={marker => setMarkerRef(marker, poi.key)}
          >
            <Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
        </AdvancedMarker>
      ))}
    </>
  );
};

بعد ذلك، ستتعرّف على كيفية التعامل مع تفاعل المستخدمين.

8. إضافة تفاعل المستخدم

أصبحت لديك الآن خريطة رائعة المظهر تعرض بعض الوجهات السياحية الأكثر رواجًا في سيدني. في هذا القسم، ستضيف بعض الإجراءات الإضافية للتعامل مع تفاعلات المستخدمين مع نظام الأحداث في Maps JavaScript API من أجل تحسين تجربة المستخدم في الخريطة.

توفّر Maps JavaScript API نظام أحداث شاملاً يستخدم معالجات أحداث JavaScript للسماح لك بالتعامل مع تفاعلات المستخدمين المختلفة في الرمز. على سبيل المثال، يمكنك إنشاء أدوات معالجة الأحداث لتفعيل تنفيذ الرمز البرمجي للتفاعلات، مثل نقر المستخدم على الخريطة والعلامات، وتحريك عرض الخريطة، والتكبير والتصغير، وغير ذلك.

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

  1. أنشِئ دالة ردّ اتصال لمعالج click.

في المكوّن PoiMarkers، حدِّد معالج click باستخدام useCallback() في React.

يتم تشغيل الحدث click عندما ينقر المستخدم على علامة أو يلمسها، ويعرض الحدث كعنصر JSON يتضمّن معلومات عن عنصر واجهة المستخدم الذي تم النقر عليه. لتحسين تجربة المستخدم على الخريطة، يمكنك التعامل مع الحدث click واستخدام العنصر LatLng الخاص به للحصول على خطوط الطول والعرض للعلامة التي تم النقر عليها.

بعد الحصول على خطوط الطول والعرض، مرِّرها إلى الدالة panTo() المضمّنة في مثيل Map لكي يتم تحريك الخريطة بسلاسة لإعادة توسيطها على العلامة التي تم النقر عليها من خلال إضافة ما يلي في دالة رد الاتصال لمعالج الحدث:

const PoiMarkers = (props: { pois: Poi[] }) => {
...
const handleClick = useCallback((ev: google.maps.MapMouseEvent) => {
    if(!map) return;
    if(!ev.latLng) return;
    console.log('marker clicked:', ev.latLng.toString());
    map.panTo(ev.latLng);
  });
...
};
  1. عيِّن معالِجات click للعلامات.

تعرض عناصر AdvancedMarker في مكتبة vis.gl/react-google-map سمتَين مفيدتَين للتعامل مع النقرات:

  • clickable: إذا كانت القيمة صحيحة، سيكون AdvancedMarker قابلاً للنقر وسيؤدي إلى تشغيل الحدث gmp-click، وسيكون تفاعليًا لأغراض تسهيل الاستخدام. على سبيل المثال، ستتيح التنقّل باستخدام لوحة المفاتيح ومفاتيح الأسهم.
  • onClick: دالّة ردّ الاتصال التي سيتم استدعاؤها عند وقوع حدث click.
  1. عدِّل عملية العرض PoiMarkers لتعيين معالج click لكل علامة:
return (
    <>
      {props.pois.map( (poi: Poi) => (
        <AdvancedMarker
          ... other properties ...
          clickable={true}
          onClick={handleClick}
          >
           ...
        </AdvancedMarker>
      ))}
    </>
  );
  1. انتقِل إلى المتصفّح وانقر على العلامات. من المفترض أن يتم تحريك الخريطة تلقائيًا لإعادة توسيطها عند النقر على محدّد.

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

يتبقّى لك خطوة واحدة فقط. بعد ذلك، يمكنك تحسين تجربة المستخدم على الخريطة بشكل أكبر باستخدام ميزات الرسم في Maps JavaScript API.

9- الرسم على الخريطة

حتى الآن، أنشأت خريطة لمدينة سيدني تعرض علامات للوجهات السياحية الشهيرة وتتعامل مع تفاعل المستخدم. في الخطوة الأخيرة من هذا الدرس التطبيقي، ستستخدم ميزات الرسم في Maps JavaScript API لإضافة ميزة مفيدة أخرى إلى تجربة الخريطة.

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

تتضمّن Maps JavaScript API مجموعة من الدوال لرسم الأشكال على الخريطة، مثل المربّعات والمضلّعات والخطوط والدوائر. تتيح لك مكتبة vis.gl/react-google-map إمكانية استخدام هذه الميزات في React.

بعد ذلك، يمكنك عرض دائرة لتوضيح نطاق جغرافي يبلغ 800 متر (حوالي نصف ميل) حول علامة عند النقر عليها.

يحتوي مستودع الرموز البرمجية المبدئية على مكوّن مخصّص لعنصر circle. يمكنك العثور عليه في ملف src/components/circle.tsx.

للسماح للمستخدمين بالرسم على الخريطة، اتّبِع الخطوات التالية:

  1. عدِّل عمليات الاستيراد لتضمين مكوّن الدائرة المقدَّم.
import {Circle} from './components/circle'
  1. أنشئ متغيّر حالة لمركز الدائرة.

التقط حالة مركز الدائرة في مكوّن PoiMarkers. يمكنك ضبط الحالة الأولية على القيمة null، والاستفادة من حقيقة أنّه لن يتم عرض دائرة ما لم يكن لديها موقع جغرافي صالح في المركز (ونصف قطر).

const PoiMarkers = (props: { pois: Poi[] }) => {
...
  const [circleCenter, setCircleCenter] = useState(null)
...
};
  1. تعديل مركز الدائرة عند معالجة حدث click

استدعِ الدالة setCircleCenter مع الموقع الجغرافي الذي تم العثور عليه في عنصر الحدث:

const handleClick = useCallback((ev: google.maps.MapMouseEvent) => {
    ...
    setCircleCenter(ev.latLng);
  });

تمنحك دوال الرسم في Maps JavaScript API مجموعة كبيرة من الخيارات حول كيفية ظهور عنصر مرسوم على الخريطة. لعرض نصف قطر دائري، اضبط خصائص عنصر الدائرة، مثل اللون ووزن الحد، ومكان توسيط الدائرة ونصف قطرها.

  1. أضِف دائرة إلى عملية العرض واربط مركزها بمتغيّر الحالة. يجب أن يبدو العرض على النحو التالي:
return (
    <>
      <Circle
          radius={800}
          center={circleCenter}
          strokeColor={'#0c4cb3'}
          strokeOpacity={1}
          strokeWeight={3}
          fillColor={'#3b82f6'}
          fillOpacity={0.3}
        />
      {props.pois.map( (poi: Poi) => (
        <AdvancedMarker
          key={poi.key}
          position={poi.location}
          ref={marker => setMarkerRef(marker, poi.key)}
          clickable={true}
          onClick={handleClick}
          >
            <Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
        </AdvancedMarker>
      ))}
    </>
  );
};

أكملت الخطوات بنجاح انتقِل إلى المتصفّح وانقر على أحد العلامات. من المفترض أن يظهر نصف قطر دائري حوله:

d243587f4a9ec4a6.png

10. تهانينا

لقد أنشأت تطبيق الويب الأول باستخدام مكتبة vis.gl/react-google-map لمنصة "خرائط Google"، بما في ذلك تحميل Maps JavaScript API، وتحميل خريطة، والعمل مع العلامات، والتحكّم في الخريطة والرسم عليها، وإضافة تفاعل المستخدم.

للاطّلاع على الرمز البرمجي المكتمل، راجِع الدليل /solutions.

مزيد من المعلومات