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

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

عرض عيّنة

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

الخريطة الاتجاهية هي خريطة 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');
  }
});