برنامه نویسی 442 بازدید

یکی از جالب‌ترین کارهایی که در زمان توسعه اپلیکیشن‌ها می‌توان انجام داد، استفاده از گوگل مپ در اپلیکیشن ری اکت است. نکته جالب اینجا است که این فرایند بسیار ساده و جذاب است. در این راهنما با روش انجام این کار آشنا خواهیم شد.

گوگل مپ در اپلیکیشن ری اکت

برای قرار دادن نقشه گوگل در یک اپلیکیشن ری‌اکت نیاز به کتابخانه‌ای به نام Google Maps React (+) داریم. برای نصب این کتابخانه در محیط ترمینال به محل پروژه رفته و دستور زیر را وارد نمایید:

npm install --save google-maps-react

ایجاد یک فایل پیکربندی

ابتدا یک فایل به نام config.js ایجاد می‌کنیم که شامل مختصات طول و عرض جغرافیایی، سطح بزرگنمایی و کلید API نقشه گوگل و موارد دیگر است. این کلید برای استفاده از نقشه‌های گوگل ضروری است.

export default {
    zoomLevel: 16,
    latitudeForFocusingMap: 51.4934,
    longitudeForFocusingMap: 0.0098,
    markerLongitude: 51.4934,
    markerLatitude: 0.0098,
    apiKey: 'your api key',
    useDefaultUI: false,
    googleMapsMarkerIcon: 'marker icon link'
};

اگر می‌خواهید کل پروژه را در یک مکان عمومی ارسال کنید، باید این فایل و به طور خاص apiKey را پنهان کنید. اگر می‌خواهید آن را به گیت ارسال کنید، کافی است فایل config.js را به فایل gitignore. خود اضافه کنید.

  1. zoomLevel سطح بزرگنمایی اولیه در زمان بارگذاری نقشه را تعیین می‌کند.
  2. latitudeForFocusingMap و longitudeForFocusingMap محل اولیه‌ای که نقشه در زمان بارگذاری نشان می‌دهد را تعیین می‌کنند.
  3. markerLongitude و markerLatitude مکان نشانگر را روی نقشه تعیین می‌کنند.
  4. apiKey همان کلید دسترسی و استفاده از سرویس گوگل مپ است که باید از افراد دیگر پنهان باشد.
  5. useDefaultUI تنظیمات دکمه‌های پیرامون نقشه است. این دکمه‌ها می‌توانند شامل سطح بزرگنمایی، دکمه fullScreenMode، دکمه Satellite و Map و دکمه تماس 360 درجه باشند. زمانی که این مشخصه مقدار False داشته باشد، این دکمه‌های پیش‌فرض پنهان می‌شوند، اما مقدار پیش‌فرض آن True است.
  6. googleMapsMarkerIcon تصویر آیکون نشانگر روی نقشه است. به صورت پیش‌فرض از یک نشانگر قرمز استفاده می‌شود.

ایجاد googleMapsMarkerIcon اصلی

فایل کامپوننت نقشه ما به صورت زیر است:

import React, { useState } from 'react';
import { Map, GoogleApiWrapper } from 'google-maps-react';
import mapStyles from './mapStyle';
import config from '../../../../../config';

function MapComponent(props) {
  const [zoomLevel, setZoomLevel] = useState(config.zoomLevel)
  const [lat, setLat] = useState(config.lat || 51.4934);
  const [lng, setLng] = useState(config.lng || 0.0098);
  
  return (
    <div className='map'>
      <Map
        google={props.google}
        zoom={zoomLevel}
        styles={mapStyles}
        disableDefaultUI={config.useDefaultUI}
        initialCenter={{
          lat,
          lng
        }}
      >
        <Marker
          position={{ lat: config.latitudeForMarker, lng: config.longitudeForMarker }}
          icon={config.googleMapsMarkerIcon}
        />
      </Map>
    </div>
  );
};

export default GoogleApiWrapper({ apiKey: config.apiKey })(MapComponent);

در خطوط 7 تا 9، ‌برخی پیکربندی‌ها تعیین شده‌اند و سپس به نقشه ارسال می‌شوند. امکان ارسال مستقیم این مشخصات از پیکربندی نیز وجود دارد، ‌اما به جهت ایجاد انعطاف‌پذیری بیشتر در کاربردهای آتی بهتر است مانند این مثال ارائه شده عمل کنید.

نکته: شما می‌بایست پارامترهای lat و lon پیش‌فرض را تعیین کنید، زیرا اگر این کار را نکنید، نقشه هیچ چیز نمایش نمی‌دهد.

Marker کامپوننت نشانگر روی نقشه است. به این کامپوننت یک جفت مختصات و آیکون نشانگر (اختیاری) می‌دهیم تا روی نقشه نمایش یابد. می‌توانید نشانگرهای زیادی را به صورت فرزند به کامپوننت Map ارسال کنید.

علاوه بر نشانگرها می‌توان Infowindows نیز اضافه کرد که برخی اطلاعات را در زمان کلیک روی نواحی خاص نقشه ارائه می‌کنند.

import React, { useState } from 'react';
import { Map, GoogleApiWrapper } from 'google-maps-react';
import mapStyles from './mapStyle';
import config from '../../../../../config';

function MapComponent(props) {
  const [zoomLevel, setZoomLevel] = useState(config.zoomLevel);
  const [lat, setLat] = useState(config.lat || 51.4934);
  const [lng, setLng] = useState(config.lng || 0.0098);
  const [state, setState] = useState({
    activeMarker: {},
    showingInfoWindow: false,
    text: ''
  });
  
  const onMarkerClick = (props, marker) => {
    setState({
      ...state,
      activeMarker: marker,
      showingInfoWindow: true,
      text: marker.text || ''
    });
  };

  const onInfoWindowClose = () => {
    setState({
      activeMarker: null,
      showingInfoWindow: false
    });
  }
  
  return (
    <div className='map'>
      <Map
        google={props.google}
        zoom={zoomLevel}
        styles={mapStyles}
        disableDefaultUI={config.useDefaultUI}
        initialCenter={{
          lat,
          lng
        }}
      >
        <Marker
          position={{ lat: config.latitudeForMarker, lng: config.longitudeForMarker }}
          icon={config.googleMapsMarkerIcon}
          onClick={onMarkerClick}
          text='some text'
        />
        <InfoWindow
          marker={state.activeMarker}
          onClose={onInfoWindowClose}
          visible={state.showingInfoWindow}>
          <div>
            <p>{state.text}</p>
          </div>
        </InfoWindow>
      </Map>
    </div>
  );
};

export default GoogleApiWrapper({ apiKey: config.apiKey })(MapComponent);

در کد فوق دو متد به صورت onMarkerClick و onInfoWindowClose وجود دارند. زمانی که کاربر روی Marker کلیک کند، ‌متد onMarkerClick را فراخوانی می‌کنیم. این متد متنی که باید روی infoWindow نمایش یابد و مرجع نشانگر را دریافت کرده و آن را روی حالت تنظیم می‌کند. همچنین امکان نمایش infoWindow را از طریق تعیین مقدار showingInfoWindow: true فراهم می‌سازد.

اگر کاربر به نشانگر دیگری سوئیچ کند یا روی دکمه بستن در infoWindow فعال کلیک نماید، در این صورت متد onInfoWindowClose عمل کرده و infoWindow فعال را می‌بندد.

ایجاد استایل سفارشی

چنان که در بخش قبل دیدید، mapStyles را ایمپورت کرده و زیر پارامتر styles به نقشه ارسال کردیم. این یک استایل سفارشی برای نقشه است که می‌توانید مورد استفاده قرار دهید:

گوگل مپ در اپلیکیشن ری اکت

فایل mapStyles ما به صورت زیر است:

const mapStyles = [
  {
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#1d2c4d"
      }
    ]
  },
  {
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#8ec3b9"
      }
    ]
  },
  {
    "elementType": "labels.text.stroke",
    "stylers": [
      {
        "color": "#1a3646"
      }
    ]
  },
  {
    "featureType": "administrative.country",
    "elementType": "geometry.stroke",
    "stylers": [
      {
        "color": "#4b6878"
      }
    ]
  },
  {
    "featureType": "administrative.land_parcel",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#64779e"
      }
    ]
  },
  {
    "featureType": "administrative.province",
    "elementType": "geometry.stroke",
    "stylers": [
      {
        "color": "#4b6878"
      }
    ]
  },
  {
    "featureType": "landscape.man_made",
    "elementType": "geometry.stroke",
    "stylers": [
      {
        "color": "#334e87"
      }
    ]
  },
  {
    "featureType": "landscape.natural",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#023e58"
      }
    ]
  },
  {
    "featureType": "poi",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#283d6a"
      }
    ]
  },
  {
    "featureType": "poi",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#6f9ba5"
      }
    ]
  },
  {
    "featureType": "poi",
    "elementType": "labels.text.stroke",
    "stylers": [
      {
        "color": "#1d2c4d"
      }
    ]
  },
  {
    "featureType": "poi.park",
    "elementType": "geometry.fill",
    "stylers": [
      {
        "color": "#023e58"
      }
    ]
  },
  {
    "featureType": "poi.park",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#3C7680"
      }
    ]
  },
  {
    "featureType": "road",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#304a7d"
      }
    ]
  },
  {
    "featureType": "road",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#98a5be"
      }
    ]
  },
  {
    "featureType": "road",
    "elementType": "labels.text.stroke",
    "stylers": [
      {
        "color": "#1d2c4d"
      }
    ]
  },
  {
    "featureType": "road.highway",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#2c6675"
      }
    ]
  },
  {
    "featureType": "road.highway",
    "elementType": "geometry.stroke",
    "stylers": [
      {
        "color": "#255763"
      }
    ]
  },
  {
    "featureType": "road.highway",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#b0d5ce"
      }
    ]
  },
  {
    "featureType": "road.highway",
    "elementType": "labels.text.stroke",
    "stylers": [
      {
        "color": "#023e58"
      }
    ]
  },
  {
    "featureType": "transit",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#98a5be"
      }
    ]
  },
  {
    "featureType": "transit",
    "elementType": "labels.text.stroke",
    "stylers": [
      {
        "color": "#1d2c4d"
      }
    ]
  },
  {
    "featureType": "transit.line",
    "elementType": "geometry.fill",
    "stylers": [
      {
        "color": "#283d6a"
      }
    ]
  },
  {
    "featureType": "transit.station",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#3a4762"
      }
    ]
  },
  {
    "featureType": "water",
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#0e1626"
      }
    ]
  },
  {
    "featureType": "water",
    "elementType": "labels.text.fill",
    "stylers": [
      {
        "color": "#4e6d70"
      }
    ]
  }
];

export default mapStyles;

در واقع این فایل صرفاً از کد JSON تشکیل یافته است. شما می‌توانید در این صفحه (+) آن را سفارشی‌سازی کنید و استایل منحصربه‌فرد خود را برای نقشه به دست بیاورید. بدین ترتیب به پایان این راهنما می‌رسیم.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای 0 نفر
آیا این مطلب برای شما مفید بود؟
شما قبلا رای داده‌اید!
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.

«میثم لطفی» در رشته‌های ریاضیات کاربردی و مهندسی کامپیوتر به تحصیل پرداخته و شیفته فناوری است. وی در حال حاضر علاوه بر پیگیری علاقه‌مندی‌هایش در رشته‌های برنامه‌نویسی، کپی‌رایتینگ و محتوای چندرسانه‌ای، در زمینه نگارش مقالاتی با محوریت نرم‌افزار با مجله فرادرس همکاری دارد.

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *