שירות גובה

סקירה כללית

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

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

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

תחילת העבודה

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

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

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

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

תמחור

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

מדיניות

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

בקשות להעלאה

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

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

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

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

בקשות לגבי גובה מיקום

לביטוי לישויות אובייקט מסוג LocationElevationRequest יש את השדה הבא:

{
  locations[]: LatLng
}

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

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

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

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

{
  path[]: LatLng,
  samples: Number
}

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

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

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

תגובות לגובה

לכל בקשה תקינה, שירות Elevation יחזיר ל-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 }, // 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, 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 Visualization 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 }, // 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;
להצגת דוגמה

ניסיון של דוגמה