שירות גבהים

סקירה כללית

שירות הגובה מספק נתוני גובה לגבי מיקומים על פני כדור הארץ, כולל מיקומי עומק בקרקעית האוקיינוס (שמחזירים ערכים שליליים). במקרים שבהם ל-Google אין מדידות גובה מדויקות במיקום המדויק שביקשתם, השירות יבצע אינטרפולציה ויחזיר ערך ממוצע באמצעות ארבעת המיקומים הקרובים ביותר.

האובייקט ElevationService מספק ממשק פשוט לביצוע שאילתות על מיקומים בכדור הארץ כדי לקבל נתוני גובה. בנוסף, ניתן לבקש נתוני גובה שנדגמו לאורך נתיבים, וכך לחשב את שינויי הגובה המקבילים במסלולים. האובייקט ElevationService מתקשר עם שירות הגובה של ה-API של מפות Google, שמקבל בקשות להעלאה ומחזיר נתוני גובה.

בעזרת שירות הגובה, תוכלו לפתח אפליקציות לטיולים רגליים ולרכיבה על אופניים, אפליקציות למיקום מכשירים ניידים או אפליקציות סקרים ברזולוציה נמוכה.

תחילת העבודה

לפני השימוש בשירות גובה ב-API של JavaScript במפות Google, צריך קודם לוודא ש-Elevation API מופעל במסוף Google Cloud, באותו פרויקט שהגדרתם ל-Maps JavaScript API.

כדי לראות את רשימת ממשקי ה-API שמופעלים:

  1. נכנסים ל מסוף Google Cloud.
  2. לוחצים על הלחצן Select a project (בחירת פרויקט), בוחרים את הפרויקט שהגדרתם עבור Maps JavaScript API ולוחצים על Open.
  3. מחפשים את Elevation API ברשימת ממשקי ה-API במרכז הבקרה.
  4. אם ה-API מופיע ברשימה, אז הכול מוכן. אם ממשק ה-API לא מופיע ברשימה, מפעילים אותו:
    1. בחלק העליון של הדף, לוחצים על ENABLE API כדי להציג את הכרטיסייה Library. לחלופין, בתפריט מימין לוחצים על ספרייה.
    2. מחפשים את Elevation API ובוחרים אותו מרשימת התוצאות.
    3. בוחרים באפשרות הפעלה. בסיום התהליך, מופיע Elevation API ברשימת ממשקי ה-API במרכז הבקרה.

תמחור ומדיניות

תמחור

ב-16 ביולי 2018 נכנסה לתוקף תוכנית התמחור החדשה 'תשלום לפי שימוש' עבור מפות Google, מסלולים ומקומות. בקטע Usage and Billing ל-Elevation API אפשר לקרוא מידע נוסף על מגבלות התמחור והשימוש החדשות בשירות JavaScript Elevation API.

כללי מדיניות

השימוש בשירות גובה צריך להיות בהתאם למדיניות שמתוארת ב-Elevation API.

בקשות העלאה

הגישה לשירות הגובה היא אסינכרונית, מכיוון שה-API של מפות Google צריך לבצע קריאה לשרת חיצוני. לכן צריך להעביר שיטת callback כדי שהפעולות יבוצעו לאחר השלמת הבקשה. שיטת הקריאה החוזרת(callback) אמורה לעבד את התוצאות. הערה: שירות הגובה מחזיר קוד סטטוס (ElevationStatus) ומערך של אובייקטים נפרדים מסוג ElevationResult.

בElevationService מטפלים בשני סוגים של בקשות:

  • בקשות למיקומים נפרדים ונפרדים באמצעות method getElevationForLocations(), שאותה מעבירה רשימה של מיקום אחד או יותר באמצעות אובייקט LocationElevationRequest.
  • בקשות לגביית גובה בסדרה של נקודות מחוברות לאורך נתיב באמצעות השיטה getElevationAlongPath(), שמועברת קבוצה מסודרת של קודקודים בנתיב בתוך אובייקט PathElevationRequest. כשמבקשים נתוני גובה לאורך נתיבים, צריך גם להעביר פרמטר שמציין כמה דגימות אתם רוצים לקחת בנתיב הזה.

כל אחת מהשיטות האלה צריכה גם להעביר שיטת callback כדי לטפל באובייקטים ElevationResult ו-ElevationStatus שהוחזרו.

בקשות להעלאת נתוני מיקום

ליטרל של אובייקט LocationElevationRequest מכיל את השדה הבא:

{
  locations[]: LatLng
}

locations (חובה) מגדיר את המיקומים בכדור הארץ שמהם יש להחזיר נתוני גובה. הפרמטר הזה מקבל מערך של LatLngs.

אפשר להעביר כל מספר של קואורדינטות בתוך מערך, כל עוד לא חורגים ממכסות השירות. חשוב לשים לב שכשמעבירים מספר קואורדינטות, הדיוק של הנתונים שמוחזרים עשוי להיות ברזולוציה נמוכה יותר מזו כשמבקשים נתונים לקואורדינטה אחת.

בקשות לדוגמה לציון גובה נתיב

ליטרל של אובייקט PathElevationRequest מכיל את השדות הבאים:

{
  path[]: LatLng,
  samples: Number
}

השדות האלו מוסברים בהמשך:

  • path (חובה) מגדיר נתיב בכדור הארץ שעבורו מוחזרים נתוני גובה. הפרמטר path מגדיר קבוצה של שני צמדים או יותר של {קו רוחב, קו אורך}, עם מערך של שני אובייקטים או יותר מסוג LatLng.
  • samples (חובה) מציין את מספר הנקודות לדוגמה לאורך הנתיב שעבורן יש להחזיר נתוני גובה. הפרמטר samples מחלק את הערך הנתון ב-path לקבוצה מסודרת של נקודות הנמצאות במרחק שווה לאורך הנתיב.

כמו בבקשות מותאמות למיקום, הפרמטר path מציין קבוצה של ערכים של קווי אורך ורוחב. עם זאת, בשונה מבקשה תלוית מיקום, השדה path מציין קבוצה של קודקודים לפי סדר. במקום להציג נתוני גובה בקודקודים, הבקשות לנתיב נדגמים לאורך הנתיב, כשכל מדגם נמצא במרחק שווה זו מזו (כולל נקודות הקצה).

תגובות גובה

בכל בקשה חוקית, שירות הגובה יחזיר ל-callback המוגדר קבוצה של אובייקטים מסוג ElevationResult יחד עם אובייקט ElevationStatus.

סטטוסי גובה

כל בקשת העלאה מחזירה קוד ElevationStatus בתוך פונקציית הקריאה החוזרת שלה. הקוד status הזה יכיל אחד מהערכים הבאים:

  • OK שמציין שבקשת השירות בוצעה בהצלחה
  • INVALID_REQUEST שמציין שבקשת השירות הייתה שגויה
  • OVER_QUERY_LIMIT שמציין שמגיש הבקשה חרג מהמכסה
  • REQUEST_DENIED שמציין שהשירות לא השלים את הבקשה, כנראה בגלל שפרמטר לא חוקי
  • UNKNOWN_ERROR מציין שגיאה לא ידועה

יש לוודא שההתקשרות החוזרת הצליחה על ידי בדיקת קוד הסטטוס הזה עבור OK.

תוצאות של נתוני גובה

לאחר ביצוע הפעולה, הארגומנט results של פונקציית הקריאה החוזרת יכלול קבוצה של ElevationResult אובייקטים. האובייקטים האלה מכילים את הרכיבים הבאים:

  • רכיב location (המכיל LatLng אובייקטים) של המיקום שעבורו מחושבים נתוני הגובה. לתשומת ליבך בבקשות לנתיב, קבוצת רכיבי location תכלול את הנקודות שנדגמו לאורך הנתיב.
  • רכיב elevation שמציין את הגובה של המיקום במטרים.
  • ערך resolution, שמציין את המרחק המקסימלי בין נקודות נתונים שמהן גובה הגובה נקבע לפי אינטרפולציה, במטרים. המאפיין הזה יהיה חסר אם הרזולוציה לא ידועה. הערה: נתוני הגובה הופכים לגסים יותר (ערכי resolution גדולים יותר) כשמעבירים מספר נקודות. כדי לקבל את ערך הגובה המדויק ביותר של נקודה, צריך לשלוח שאילתה לגביה בנפרד.

דוגמאות לגובה

הקוד הבא מתרגם קליק על מפה לבקשת גובה באמצעות האובייקט LocationElevationRequest:

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 8,
      center: { lat: 63.333, lng: -150.5 }, // Denali.
      mapTypeId: "terrain",
    }
  );
  const elevator = new google.maps.ElevationService();
  const infowindow = new google.maps.InfoWindow({});

  infowindow.open(map);

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

function displayLocationElevation(
  location: google.maps.LatLng,
  elevator: google.maps.ElevationService,
  infowindow: google.maps.InfoWindow
) {
  // Initiate the location request
  elevator
    .getElevationForLocations({
      locations: [location],
    })
    .then(({ results }) => {
      infowindow.setPosition(location);

      // Retrieve the first result
      if (results[0]) {
        // Open the infowindow indicating the elevation at the clicked position.
        infowindow.setContent(
          "The elevation at this point <br>is " +
            results[0].elevation +
            " meters."
        );
      } else {
        infowindow.setContent("No results found");
      }
    })
    .catch((e) =>
      infowindow.setContent("Elevation service failed due to: " + e)
    );
}

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

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 8,
    center: { lat: 63.333, lng: -150.5 },
    mapTypeId: "terrain",
  });
  const elevator = new google.maps.ElevationService();
  const infowindow = new google.maps.InfoWindow({});

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

function displayLocationElevation(location, elevator, infowindow) {
  // Initiate the location request
  elevator
    .getElevationForLocations({
      locations: [location],
    })
    .then(({ results }) => {
      infowindow.setPosition(location);
      // Retrieve the first result
      if (results[0]) {
        // Open the infowindow indicating the elevation at the clicked position.
        infowindow.setContent(
          "The elevation at this point <br>is " +
            results[0].elevation +
            " meters.",
        );
      } else {
        infowindow.setContent("No results found");
      }
    })
    .catch((e) =>
      infowindow.setContent("Elevation service failed due to: " + e),
    );
}

window.initMap = initMap;
להצגת דוגמה

רוצה לנסות דוגמה?

הדוגמה הבאה יוצרת קו פוליגוני בהינתן קבוצה של קואורדינטות, ומציגה נתוני גובה לאורך הנתיב באמצעות Google Vision API. (עליכם לטעון את ה-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 },
    { lat: 36.606, lng: -118.0638 },
    { lat: 36.433, lng: -117.951 },
    { lat: 36.588, lng: -116.943 },
    { lat: 36.34, lng: -117.468 },
    { 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;
להצגת דוגמה

רוצה לנסות דוגמה?