عناصر الخريطة الاتجاهية

اختيار النظام الأساسي: Android iOS JavaScript

عرض نموذج

توفّر Maps JavaScript API طريقتَين مختلفتَين لتنفيذ الخريطة: النقطية والمتجهة. تحمِّل الخريطة النقطية الخريطة كشبكة من مربّعات صور نقطية تستند إلى وحدات البكسل، وتنشئها منصة خرائط Google من جهة الخادم، ثم يتم عرضها على تطبيق الويب. تتألف الخريطة المتجهة من مربّعات تستند إلى المتجهات، ويتم رسمها في مدّة التحميل من جهة العميل باستخدام WebGL، وهي تكنولوجيا ويب تسمح للمتصفّح بالوصول إلى وحدة معالجة الرسومات (GPU) على جهاز المستخدم لعرض الرسومات الثنائية والثلاثية الأبعاد.

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

البدء في استخدام الخرائط المتجهة

الإمالة والتدوير

يمكنك ضبط الإمالة والتدوير (الاتجاه) على الخريطة المتجهة من خلال تضمين سمتَي heading وtilt عند تهيئة الخريطة، و من خلال استدعاء الطريقتَين setTilt وsetHeading على الخريطة. يضيف المثال التالي بعض الأزرار إلى الخريطة التي تعرض ضبط الإمالة والاتجاه بشكل آلي بزيادات قدرها 20 درجة.

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: {
        lat: 37.7893719,
        lng: -122.3942,
      },
      zoom: 16,
      heading: 320,
      tilt: 47.5,
      mapId: "90f87356969d889c",
    }
  );

  const buttons: [string, string, number, google.maps.ControlPosition][] = [
    ["Rotate Left", "rotate", 20, google.maps.ControlPosition.LEFT_CENTER],
    ["Rotate Right", "rotate", -20, google.maps.ControlPosition.RIGHT_CENTER],
    ["Tilt Down", "tilt", 20, google.maps.ControlPosition.TOP_CENTER],
    ["Tilt Up", "tilt", -20, google.maps.ControlPosition.BOTTOM_CENTER],
  ];

  buttons.forEach(([text, mode, amount, position]) => {
    const controlDiv = document.createElement("div");
    const controlUI = document.createElement("button");

    controlUI.classList.add("ui-button");
    controlUI.innerText = `${text}`;
    controlUI.addEventListener("click", () => {
      adjustMap(mode, amount);
    });
    controlDiv.appendChild(controlUI);
    map.controls[position].push(controlDiv);
  });

  const adjustMap = function (mode: string, amount: number) {
    switch (mode) {
      case "tilt":
        map.setTilt(map.getTilt()! + amount);
        break;
      case "rotate":
        map.setHeading(map.getHeading()! + amount);
        break;
      default:
        break;
    }
  };
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: {
      lat: 37.7893719,
      lng: -122.3942,
    },
    zoom: 16,
    heading: 320,
    tilt: 47.5,
    mapId: "90f87356969d889c",
  });
  const buttons = [
    ["Rotate Left", "rotate", 20, google.maps.ControlPosition.LEFT_CENTER],
    ["Rotate Right", "rotate", -20, google.maps.ControlPosition.RIGHT_CENTER],
    ["Tilt Down", "tilt", 20, google.maps.ControlPosition.TOP_CENTER],
    ["Tilt Up", "tilt", -20, google.maps.ControlPosition.BOTTOM_CENTER],
  ];

  buttons.forEach(([text, mode, amount, position]) => {
    const controlDiv = document.createElement("div");
    const controlUI = document.createElement("button");

    controlUI.classList.add("ui-button");
    controlUI.innerText = `${text}`;
    controlUI.addEventListener("click", () => {
      adjustMap(mode, amount);
    });
    controlDiv.appendChild(controlUI);
    map.controls[position].push(controlDiv);
  });

  const adjustMap = function (mode, amount) {
    switch (mode) {
      case "tilt":
        map.setTilt(map.getTilt() + amount);
        break;
      case "rotate":
        map.setHeading(map.getHeading() + amount);
        break;
      default:
        break;
    }
  };
}

window.initMap = initMap;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.ui-button {
  background-color: #fff;
  border: 0;
  border-radius: 2px;
  box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3);
  margin: 10px;
  padding: 0 0.5em;
  font: 400 18px Roboto, Arial, sans-serif;
  overflow: hidden;
  height: 40px;
  cursor: pointer;
}
.ui-button:hover {
  background: rgb(235, 235, 235);
}

HTML

<html>
  <head>
    <title>Tilt and Rotation</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>

استخدام إيماءات الماوس ولوحة المفاتيح

إذا تم تفعيل تفاعلات المستخدم مع الإمالة والتدوير (الاتجاه) (إما بشكل آلي أو في Google Cloud Console)، يمكن للمستخدمين ضبط الإمالة والتدوير باستخدام الماوس ولوحة المفاتيح:

  • باستخدام الماوس، اضغط مع الاستمرار على مفتاح Shift، ثم اسحب الماوس للأعلى والأسفل لضبط الإمالة، ولليمين واليسار لضبط الاتجاه.
  • باستخدام لوحة المفاتيح، اضغط مع الاستمرار على مفتاح Shift، ثم استخدِم مفتاحَي السهمين للأعلى والأسفل لضبط الإمالة، ومفتاحَي السهمين لليمين واليسار لضبط الاتجاه.

ضبط الإمالة والاتجاه بشكل آلي

استخدِم الطريقتَين setTilt() وsetHeading() لضبط الإمالة والاتجاه بشكل آلي على خريطة متجهة. الاتجاه هو اتجاه الكاميرا بالدرجات في اتجاه عقارب الساعة بدءًا من الشمال، لذا سيؤدي map.setHeading(90) إلى تدوير الخريطة بحيث يكون الشرق متجهًا للأعلى. يتم قياس زاوية الإمالة من السمت، لذا يشير map.setTilt(0) إلى النظر مباشرةً للأسفل، بينما سيؤدي map.setTilt(45) إلى عرض مائل.

  • استدعِ setTilt() لضبط زاوية إمالة الخريطة. استخدِم getTilt() للحصول على قيمة الإمالة الحالية.
  • استدعِ setHeading() لضبط اتجاه الخريطة. استخدِم getHeading() للحصول على قيمة الاتجاه الحالية.

لتغيير مركز الخريطة مع الاحتفاظ بالإمالة والاتجاه، استخدِم map.setCenter() أو map.panBy().

يُرجى العِلم أنّ نطاق الزوايا التي يمكن استخدامها يختلف حسب مستوى التكبير أو التصغير الحالي. ويتم تثبيت القيم التي تخرج عن هذا النطاق ضمن النطاق المسموح به.

يمكنك أيضًا استخدام طريقة moveCamera لتغيير الاتجاه والإمالة والمركز والتكبير أو التصغير بشكل آلي. مزيد من المعلومات.

التأثير في الطرق الأخرى

عند تطبيق الإمالة أو التدوير على الخريطة، يتأثر سلوك الطرق الأخرى في Maps JavaScript API:

  • تعرض map.getBounds() دائمًا أصغر مربّع إحاطة يتضمّن المنطقة المرئية، وعند تطبيق الإمالة، قد تمثّل الحدود المعروضة منطقة أكبر من المنطقة المرئية لإطار عرض الخريطة.
  • ستعيد map.fitBounds() ضبط الإمالة والاتجاه إلى الصفر قبل ضبط الحدود.
  • ستعيد map.panToBounds() ضبط الإمالة والاتجاه إلى الصفر قبل تحريك الحدود.
  • تقبل map.setTilt() أي قيمة، ولكنها تحدّ من الحد الأقصى للإمالة استنادًا إلى مستوى التكبير أو التصغير الحالي للخريطة.
  • تقبل map.setHeading() أي قيمة، وستعدّلها لتناسب النطاق [0, 360].

التحكّم في الكاميرا

استخدِم الدالة map.moveCamera() لتعديل أي مجموعة من خصائص الكاميرا في آنٍ واحد. تقبل map.moveCamera() مَعلمة واحدة تحتوي على جميع خصائص الكاميرا المطلوب تعديلها. يوضّح المثال التالي استدعاء map.moveCamera() لضبط center وzoom وheading وtilt في آنٍ واحد:

map.moveCamera({
  center: new google.maps.LatLng(37.7893719, -122.3942),
  zoom: 16,
  heading: 320,
  tilt: 47.5
});

يمكنك تحريك خصائص الكاميرا من خلال استدعاء map.moveCamera() باستخدام حلقة رسوم متحركة، كما هو موضّح هنا:

const degreesPerSecond = 3;

function animateCamera(time) {
  // Update the heading, leave everything else as-is.
  map.moveCamera({
    heading: (time / 1000) * degreesPerSecond
  });

  requestAnimationFrame(animateCamera);
}

// Start the animation.
requestAnimationFrame(animateCamera);

موضع الكاميرا

يتم تصميم طريقة عرض الخريطة على أنّها كاميرا تنظر إلى أسفل على مستوى مسطّح. يتم تحديد موضع الكاميرا (وبالتالي عرض الخريطة) من خلال الخصائص التالية: الهدف (موقع خط العرض/خط الطول)، والاتجاه، والإمالة، والتكبير أو التصغير.

مخطّط خصائص الكاميرا

الهدف (الموقع الجغرافي)

الهدف من الكاميرا هو موقع مركز الخريطة، ويتم تحديده كإحداثيات خط العرض وخط الطول.

يمكن أن يتراوح خط العرض بين ‎-85 و‎85 درجة، بما في ذلك هاتان القيمتان. وسيتم تثبيت القيم الأعلى أو الأدنى من هذا النطاق على أقرب قيمة ضمن هذا النطاق. على سبيل المثال، سيؤدي تحديد خط عرض يبلغ 100 إلى ضبط القيمة على 85. يتراوح خط الطول بين ‎-180 و‎180 درجة، بما في ذلك هاتان القيمتان. وسيتم تضمين القيم الأعلى أو الأدنى من هذا النطاق بحيث تقع ضمن النطاق (‎-180، 180). على سبيل المثال، سيتم تضمين القيم 480 و840 و1200 جميعها في 120 درجة.

الاتجاه

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

يعني الاتجاه 0 أنّ الجزء العلوي من الخريطة يشير إلى الشمال الحقيقي. وتعني قيمة الاتجاه 90 أنّ الجزء العلوي من الخريطة يشير إلى الشرق تمامًا (90 درجة على البوصلة). وتعني القيمة 180 أنّ الجزء العلوي من الخريطة يشير إلى الجنوب تمامًا.

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

الإمالة (زاوية العرض)

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

في الصور أدناه، تبلغ زاوية العرض 0 درجة. تعرض الصورة الأولى رسمًا تخطيطيًا لذلك، حيث يمثّل الموضع 1 موضع الكاميرا، ويمثّل الموضع 2 موضع الخريطة الحالي. وتظهر الخريطة الناتجة أدناه.

لقطة شاشة لخريطة مع كاميرا موضوعة بزاوية عرض 0 درجة، ومستوى تكبير 18
الخريطة المعروضة بزاوية العرض التلقائية للكاميرا
مخطّط يوضّح الموضع التلقائي للكاميرا، مباشرةً فوق موضع الخريطة، بزاوية 0 درجة
زاوية العرض التلقائية للكاميرا.

في الصور أدناه، تبلغ زاوية العرض 45 درجة. يُرجى العِلم أنّ الكاميرا تتحرّك في منتصف قوس بين الأعلى مباشرةً (0 درجة) والأرض (90 درجة)، إلى الموضع 3. لا تزال الكاميرا تشير إلى نقطة مركز الخريطة، ولكن المنطقة التي يمثّلها الخط في الموضع 4 أصبحت مرئية الآن.

لقطة شاشة لخريطة مع كاميرا موضوعة بزاوية عرض 45 درجة، ومستوى تكبير 18
الخريطة المعروضة بزاوية عرض تبلغ 45 درجة.
مخطّط يوضّح زاوية عرض الكاميرا المضبوطة على 45 درجة، مع ضبط مستوى التكبير/التصغير على 18.
زاوية عرض الكاميرا تبلغ 45 درجة

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

Zoom

يحدّد مستوى التكبير أو التصغير للكاميرا مقياس الخريطة. عند مستويات التكبير أو التصغير الأكبر، يمكن رؤية المزيد من التفاصيل على الشاشة، بينما يمكن رؤية المزيد من العالم على الشاشة عند مستويات التكبير أو التصغير الأصغر.

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

  • 1: العالم
  • 5: اليابسة/القارة
  • 10: المدينة
  • 15: الشوارع
  • 20: المباني
تعرض الصور التالية المظهر المرئي لمستويات التكبير أو التصغير المختلفة:
لقطة شاشة لخريطة بمستوى تكبير/تصغير 5
خريطة بمستوى التكبير أو التصغير 5.
لقطة شاشة لخريطة بمستوى تكبير/تصغير 15
خريطة بمستوى التكبير أو التصغير 15.
لقطة شاشة لخريطة بمستوى تكبير/تصغير 20
خريطة بمستوى التكبير أو التصغير 20.

التكبير أو التصغير الجزئي

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

يوضّح المثال التالي تفعيل التكبير أو التصغير الجزئي عند تهيئة الخريطة:

map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: -34.397, lng: 150.644},
  zoom: 8,
  isFractionalZoomEnabled: true
});

يمكنك أيضًا تفعيل التكبير أو التصغير الجزئي وإيقافه من خلال ضبط خيار الخريطة isFractionalZoomEnabled كما هو موضّح هنا:

// Using map.set
map.set('isFractionalZoomEnabled', true);

// Using map.setOptions
map.setOptions({isFractionalZoomEnabled: true});

يمكنك ضبط مستمع لرصد ما إذا كان التكبير أو التصغير الجزئي مفعّلاً، ويكون ذلك مفيدًا بشكل خاص إذا لم تضبط isFractionalZoomEnabled بشكل صريح على true أو false. يتحقّق رمز المثال التالي مما إذا كان التكبير أو التصغير الجزئي مفعّلاً:

map.addListener('isfractionalzoomenabled_changed', () => {
  const isFractionalZoomEnabled = map.get('isFractionalZoomEnabled');
  if (isFractionalZoomEnabled === false) {
    console.log('not using fractional zoom');
  } else if (isFractionalZoomEnabled === true) {
    console.log('using fractional zoom');
  } else {
    console.log('map not done initializing yet');
  }
});