خدمة الارتفاع

نظرة عامة

توفر خدمة تحديد الارتفاع بيانات الارتفاع للمواقع الجغرافية على سطح الأرض، بما في ذلك مواقع العمق في قاع المحيط (التي تعرض قيمًا سالبة). في الحالات التي لا تملك فيها Google قياسات دقيقة للارتفاع في الموقع الجغرافي الدقيق الذي تطلبه، ستُجري الخدمة عملية استيفاء وتعرض قيمة متوسّطة باستخدام أقرب أربعة مواقع جغرافية.

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

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

الخطوات الأولى

قبل استخدام خدمة تحديد الارتفاع في Maps JavaScript API، تأكَّد أولاً من تفعيل Elevation API في Google Cloud Console، في المشروع نفسه الذي أعددته لـ Maps JavaScript API.

للاطّلاع على قائمة واجهات برمجة التطبيقات المفعّلة:

  1. انتقِل إلى Google Cloud Console.
  2. انقر على الزر اختيار مشروع ، ثم اختَر المشروع نفسه الذي أعددته لـ Maps JavaScript API وانقر على فتح.
  3. من قائمة واجهات برمجة التطبيقات في لوحة البيانات ، ابحث عن Elevation API.
  4. إذا ظهرت واجهة برمجة التطبيقات في القائمة، يعني ذلك أنّك جاهز. إذا لم تظهر واجهة برمجة التطبيقات، فعِّلها:
    1. في أعلى الصفحة، انقر على تفعيل واجهة برمجة التطبيقات لعرض علامة التبويب المكتبة. بدلاً من ذلك، من القائمة الجانبية اليسرى، حدد المكتبة.
    2. ابحث عن Elevation API، ثم اختَرها من قائمة النتائج.
    3. انقر على تفعيل. عند اكتمال العملية، تظهر Elevation API في قائمة واجهات برمجة التطبيقات على لوحة البيانات.

الأسعار والسياسات

الأسعار

للتعرّف على سياسات الأسعار والاستخدام لخدمة تحديد الارتفاع في JavaScript، يمكنك الاطّلاع على مقالة الاستخدام والفوترة في Elevation API.

السياسات

يجب أن يكون استخدام خدمة تحديد الارتفاع متوافقًا مع الـ سياسات الموضّحة في Elevation API.

طلبات تحديد الارتفاع

إنّ الوصول إلى خدمة تحديد الارتفاع غير متزامن، لأنّ Google Maps API تحتاج إلى إجراء طلب إلى خادم خارجي. لهذا السبب، عليك تمرير طريقة ردّ اتصال لتنفيذها عند اكتمال الطلب. يجب أن تعالج طريقة ردّ الاتصال هذه النتائج. يُرجى العِلم أنّ خدمة تحديد الارتفاع تعرض رمز حالة (ElevationStatus) ومصفوفة من كائنات ElevationResult منفصلة.

يتعامل ElevationService مع نوعَين من الطلبات:

  • طلبات المواقع الجغرافية المنفصلة والمستقلة باستخدام الـ getElevationForLocations() طريقة، التي يتم تمرير قائمة إليها تحتوي على موقع جغرافي واحد أو أكثر باستخدام الـ LocationElevationRequest كائن.
  • طلبات الارتفاع في سلسلة من النقاط المتصلة على طول مسار باستخدام الطريقة getElevationAlongPath()، التي يتم تمرير مجموعة مرتّبة من رؤوس المسار إليها ضمن كائن PathElevationRequest عند طلب الارتفاعات على طول المسارات، عليك أيضًا تمرير مَعلمة تشير إلى عدد العيّنات التي تريد أخذها على طول هذا المسار.

يجب أن تمرّر كل من هاتَين الطريقتَين أيضًا طريقة ردّ اتصال للتعامل مع كائنَي ElevationResult وElevationStatus المعروضَين.

طلبات تحديد الارتفاع في الموقع الجغرافي

يحتوي كائن LocationElevationRequest الحرفي على الحقل التالي:

{
  locations[]: LatLng
}

locations (مطلوب) يحدّد الموقع الجغرافي أو المواقع الجغرافية على الأرض التي سيتم عرض بيانات الارتفاع منها. تأخذ هذه المَعلمة مصفوفة من LatLngs.

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

طلبات تحديد الارتفاع في المسار الذي تم أخذ عيّنات منه

يحتوي كائن PathElevationRequest الحرفي على الحقول التالية:

{
  path[]: LatLng,
  samples: Number
}

نوضّح في ما يلي هذه الحقول:

  • path (مطلوب) يحدّد مسارًا على الأرض سيتم عرض بيانات الارتفاع له. تحدّد المَعلمة path مجموعة من زوجَين أو أكثر من الأزواج المرتّبة {خط العرض، خط الطول} باستخدام مصفوفة من كائنَين أو أكثر من كائنات LatLng.
  • samples (مطلوب) يحدّد عدد نقاط العيّنات على طول مسار سيتم عرض بيانات الارتفاع لها. تقسّم المَعلمة samples المحدّد path إلى مجموعة مرتّبة من النقاط المتساوية على طول المسار.

كما هو الحال مع طلبات تحديد المواقع الجغرافية، تحدّد المَعلمة path مجموعة من قيم خطوط الطول والعرض. على عكس طلب تحديد الموقع الجغرافي ، تحدّد path مجموعة مرتّبة من الرؤوس. بدلاً من عرض بيانات الارتفاع عند الرؤوس، يتم أخذ عيّنات من طلبات المسار على طول المسار، حيث تكون كل عيّنة متساوية المسافة عن الأخرى (بما في ذلك نقاط النهاية).

استجابات تحديد الارتفاع

لكل طلب صالح، ستعرض خدمة تحديد الارتفاع على دالة ردّ الاتصال المحدّدة مجموعة من ElevationResult الكائنات بالإضافة إلى كائن ElevationStatus.

حالات تحديد الارتفاع

يعرض كل طلب تحديد ارتفاع رمز ElevationStatus ضمن دالة ردّ الاتصال. سيحتوي رمز status code هذا على إحدى القيم التالية:

  • OK للإشارة إلى نجاح طلب الخدمة
  • INVALID_REQUEST للإشارة إلى أنّ طلب الخدمة غير صالح
  • OVER_QUERY_LIMIT للإشارة إلى أنّ مقدِّم الطلب قد تجاوز الحصة
  • REQUEST_DENIED للإشارة إلى أنّ الخدمة لم تُكمل الطلب، ومن المرجّح أنّ السبب هو مَعلمة غير صالحة
  • UNKNOWN_ERROR للإشارة إلى حدوث خطأ غير معروف

عليك التأكّد من نجاح دالة ردّ الاتصال من خلال فحص رمز الحالة هذا بحثًا عن OK.

نتائج تحديد الارتفاع

عند النجاح، سيحتوي وسيطة results في دالة ردّ الاتصال على مجموعة من كائنات ElevationResult تحتوي هذه الكائنات على العناصر التالية:

  • عنصر location (يحتوي على كائنات LatLng ) للموضع الذي يتم حساب بيانات الارتفاع له. يُرجى العِلم أنّه بالنسبة إلى طلبات المسار، ستحتوي مجموعة عناصر location على النقاط التي تم أخذ عيّنات منها على طول المسار.
  • عنصر elevation يشير إلى ارتفاع الموقع الجغرافي بالأمتار.
  • قيمة resolution تشير إلى الحد الأقصى للمسافة بين نقاط البيانات التي تم استيفاء الارتفاع منها، بالأمتار. لن تظهر هذه السمة إذا لم تكن الدقة معروفة. يُرجى العِلم أنّ بيانات الارتفاع تصبح أكثر خشونة (قيم resolution أكبر) عند تمرير نقاط متعدّدة. للحصول على قيمة الارتفاع الأكثر دقة لنقطة معيّنة، يجب الاستعلام عنها بشكل مستقل.

أمثلة على تحديد الارتفاع

يحوّل الرمز التالي نقرة على خريطة إلى طلب تحديد ارتفاع باستخدام الكائن LocationElevationRequest:

TypeScript

async function init(): Promise<void> {
    const [{ InfoWindow }, { ElevationService }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('elevation'),
    ]);

    const mapElement = document.querySelector('gmp-map')!;
    const innerMap = mapElement.innerMap;

    const elevator = new ElevationService();
    const infowindow = new InfoWindow();

    infowindow.open(innerMap);

    // Add a listener for the click event. Display the elevation for the LatLng of
    // the click inside the infowindow.
    innerMap.addListener('click', (event: google.maps.MapMouseEvent) => {
        displayLocationElevation(event.latLng!, elevator, infowindow, innerMap);
    });
}

function displayLocationElevation(
    location: google.maps.LatLng,
    elevator: google.maps.ElevationService,
    infowindow: google.maps.InfoWindow,
    map: google.maps.Map
) {
    // Format numeric values to two decimal places
    const formatter = new Intl.NumberFormat(undefined, {
        maximumFractionDigits: 2,
    });

    // Initiate the location request
    elevator
        .getElevationForLocations({
            locations: [location],
        })
        .then(({ results }) => {
            if (results[0]) {
                const { elevation, location: resultLocation } = results[0];
                infowindow.setPosition(resultLocation);
                infowindow.setContent(
                    `The elevation at ${String(resultLocation)} <br>is ${formatter.format(elevation)} meters.`
                );
            } else {
                infowindow.setPosition(location);
                infowindow.setContent('No results found');
            }

            infowindow.open(map);
        })
        .catch((e: unknown) => {
            infowindow.setContent(
                `Elevation service failed due to: ${String(e)}`
            );
        });
}

void init();

JavaScript

async function init() {
    const [{ InfoWindow }, { ElevationService }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('elevation'),
    ]);

    const mapElement = document.querySelector('gmp-map');
    const innerMap = mapElement.innerMap;

    const elevator = new ElevationService();
    const infowindow = new InfoWindow();

    infowindow.open(innerMap);

    // Add a listener for the click event. Display the elevation for the LatLng of
    // the click inside the infowindow.
    innerMap.addListener('click', (event) => {
        displayLocationElevation(event.latLng, elevator, infowindow, innerMap);
    });
}

function displayLocationElevation(location, elevator, infowindow, map) {
    // Format numeric values to two decimal places
    const formatter = new Intl.NumberFormat(undefined, {
        maximumFractionDigits: 2,
    });

    // Initiate the location request
    elevator
        .getElevationForLocations({
            locations: [location],
        })
        .then(({ results }) => {
            if (results[0]) {
                const { elevation, location: resultLocation } = results[0];
                infowindow.setPosition(resultLocation);
                infowindow.setContent(
                    `The elevation at ${String(resultLocation)} <br>is ${formatter.format(elevation)} meters.`
                );
            } else {
                infowindow.setPosition(location);
                infowindow.setContent('No results found');
            }

            infowindow.open(map);
        })
        .catch((e) => {
            infowindow.setContent(
                `Elevation service failed due to: ${String(e)}`
            );
        });
}

void init();
عرض المثال

ينشئ المثال التالي خطًا متعدد الأضلاع باستخدام مجموعة من الإحداثيات ويعرض بيانات الارتفاع على طول هذا المسار باستخدام الـ Google Visualization API. (عليك تحميل واجهة برمجة التطبيقات هذه باستخدام Google Common Loader.) يتم إنشاء طلب تحديد ارتفاع باستخدام PathElevationRequest:

TypeScript

// Load the Visualization API and the columnchart package.
// @ts-ignore TODO update to newest visualization library
google.load("visualization", "1", { packages: ["columnchart"] });

function initMap(): void {
  // The following path marks a path from Mt. Whitney, the highest point in the
  // continental United States to Badwater, Death Valley, the lowest point.
  const path = [
    { lat: 36.579, lng: -118.292 }, // Mt. Whitney
    { lat: 36.606, lng: -118.0638 }, // Lone Pine
    { lat: 36.433, lng: -117.951 }, // Owens Lake
    { lat: 36.588, lng: -116.943 }, // Beatty Junction
    { lat: 36.34, lng: -117.468 }, // Panama Mint Springs
    { lat: 36.24, lng: -116.832 },
  ]; // Badwater, Death Valley

  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 8,
      center: path[1],
      mapTypeId: "terrain",
    }
  );

  // Create an ElevationService.
  const elevator = new google.maps.ElevationService();

  // Draw the path, using the Visualization API and the Elevation service.
  displayPathElevation(path, elevator, map);
}

function displayPathElevation(
  path: google.maps.LatLngLiteral[],
  elevator: google.maps.ElevationService,
  map: google.maps.Map
) {
  // Display a polyline of the elevation path.
  new google.maps.Polyline({
    path: path,
    strokeColor: "#0000CC",
    strokeOpacity: 0.4,
    map: map,
  });

  // Create a PathElevationRequest object using this array.
  // Ask for 256 samples along that path.
  // Initiate the path request.
  elevator
    .getElevationAlongPath({
      path: path,
      samples: 256,
    })
    .then(plotElevation)
    .catch((e) => {
      const chartDiv = document.getElementById(
        "elevation_chart"
      ) as HTMLElement;

      // Show the error code inside the chartDiv.
      chartDiv.innerHTML = "Cannot show elevation: request failed because " + e;
    });
}

// Takes an array of ElevationResult objects, draws the path on the map
// and plots the elevation profile on a Visualization API ColumnChart.
function plotElevation({ results }: google.maps.PathElevationResponse) {
  const chartDiv = document.getElementById("elevation_chart") as HTMLElement;

  // Create a new chart in the elevation_chart DIV.
  const chart = new google.visualization.ColumnChart(chartDiv);

  // Extract the data from which to populate the chart.
  // Because the samples are equidistant, the 'Sample'
  // column here does double duty as distance along the
  // X axis.
  const data = new google.visualization.DataTable();

  data.addColumn("string", "Sample");
  data.addColumn("number", "Elevation");

  for (let i = 0; i < results.length; i++) {
    data.addRow(["", results[i].elevation]);
  }

  // Draw the chart using the data within its DIV.
  chart.draw(data, {
    height: 150,
    legend: "none",
    // @ts-ignore TODO update to newest visualization library
    titleY: "Elevation (m)",
  });
}

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

JavaScript

// Load the Visualization API and the columnchart package.
// @ts-ignore TODO update to newest visualization library
google.load("visualization", "1", { packages: ["columnchart"] });

function initMap() {
  // The following path marks a path from Mt. Whitney, the highest point in the
  // continental United States to Badwater, Death Valley, the lowest point.
  const path = [
    { lat: 36.579, lng: -118.292 }, // Mt. Whitney
    { lat: 36.606, lng: -118.0638 }, // Lone Pine
    { lat: 36.433, lng: -117.951 }, // Owens Lake
    { lat: 36.588, lng: -116.943 }, // Beatty Junction
    { lat: 36.34, lng: -117.468 }, // Panama Mint Springs
    { lat: 36.24, lng: -116.832 },
  ]; // Badwater, Death Valley
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 8,
    center: path[1],
    mapTypeId: "terrain",
  });
  // Create an ElevationService.
  const elevator = new google.maps.ElevationService();

  // Draw the path, using the Visualization API and the Elevation service.
  displayPathElevation(path, elevator, map);
}

function displayPathElevation(path, elevator, map) {
  // Display a polyline of the elevation path.
  new google.maps.Polyline({
    path: path,
    strokeColor: "#0000CC",
    strokeOpacity: 0.4,
    map: map,
  });
  // Create a PathElevationRequest object using this array.
  // Ask for 256 samples along that path.
  // Initiate the path request.
  elevator
    .getElevationAlongPath({
      path: path,
      samples: 256,
    })
    .then(plotElevation)
    .catch((e) => {
      const chartDiv = document.getElementById("elevation_chart");

      // Show the error code inside the chartDiv.
      chartDiv.innerHTML = "Cannot show elevation: request failed because " + e;
    });
}

// Takes an array of ElevationResult objects, draws the path on the map
// and plots the elevation profile on a Visualization API ColumnChart.
function plotElevation({ results }) {
  const chartDiv = document.getElementById("elevation_chart");
  // Create a new chart in the elevation_chart DIV.
  const chart = new google.visualization.ColumnChart(chartDiv);
  // Extract the data from which to populate the chart.
  // Because the samples are equidistant, the 'Sample'
  // column here does double duty as distance along the
  // X axis.
  const data = new google.visualization.DataTable();

  data.addColumn("string", "Sample");
  data.addColumn("number", "Elevation");

  for (let i = 0; i < results.length; i++) {
    data.addRow(["", results[i].elevation]);
  }

  // Draw the chart using the data within its DIV.
  chart.draw(data, {
    height: 150,
    legend: "none",
    // @ts-ignore TODO update to newest visualization library
    titleY: "Elevation (m)",
  });
}

window.initMap = initMap;
عرض المثال