ב-Maps JavaScript API יש שתי הטמעות שונות של המפה: רסטר ווקטור. במפה רסטר, המפה נטענת כמרשת של משבצות של תמונות רסטר שמבוססות על פיקסלים, שנוצרות בצד השרת של פלטפורמת מפות Google ולאחר מכן מוצגות באפליקציית האינטרנט. המפה וקטורית מורכבת ממשבצות שמבוססות על וקטורים, שנוצרות בזמן הטעינה בצד הלקוח באמצעות WebGL, טכנולוגיית אינטרנט שמאפשרת לדפדפן לגשת ל-GPU במכשיר של המשתמש כדי ליצור גרפיקה דו-ממדית ותלת-ממדית.
מפת הוקטורים היא אותה מפת Google שהמשתמשים מכירים, והיא מציעה כמה יתרונות על פני מפת האריחים בריזולוציית רסטר שמוגדרת כברירת מחדל. היתרונות העיקריים הם חדות התמונות שמבוססות על וקטורים והוספת בניינים תלת-ממדיים ברמות זום מקרובות. המפה הוקטורית תומכת בתכונות הבאות:
- שליטה פרוגרמטית בנטייה ובכיוון
- בקרה משופרת על המצלמה
- זום חלקי לשינוי חלק יותר של מרחק התצוגה
במפות שנטענות באמצעות רכיב
div
ו-JavaScript, סוג העיבוד שמוגדר כברירת מחדל הואgoogle.maps.RenderingType.RASTER
.במפות שנטענות באמצעות הרכיב
gmp-map
, סוג העיבוד שמוגדר כברירת מחדל הואgoogle.maps.RenderingType.VECTOR
, עם בקרת הטיה וכיוון מופעלת.
הטיה וסיבוב
כדי להגדיר את ההטיה והסיבוב (הכיוון) במפת הווקטורים, צריך לכלול את המאפיינים 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>
ניסיון של דוגמה
שימוש בתנועות של עכבר ומקלדת
אם הפעלתם את האינטראקציות של המשתמשים עם הטיה ועם סיבוב (כיוון), הם יוכלו לשנות את הטיה ואת הסיבוב באמצעות העכבר והמקלדת:
- בעזרת העכבר, לוחצים לחיצה ארוכה על מקש 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);
מיקום המצלמה
תצוגת המפה מודללת כמצלמה שמביטה למטה על מישור שטוח. המיקום של המצלמה (ולכן הרינדור של המפה) מצוין באמצעות המאפיינים הבאים: target (מיקום קו רוחב/קו אורך), bearing, tilt ו-zoom.
יעד (מיקום)
יעד המצלמה הוא המיקום של מרכז המפה, שמצוין כקואורדינטות של רוחב וקו אורך.
קו הרוחב יכול להיות בין 85 מעלות ל-85 מעלות, כולל. ערכים מעל או מתחת לטווח הזה יוצמדו לערך הקרוב ביותר בטווח הזה. לדוגמה, ציון קו רוחב של 100 יגרום להגדרת הערך כ-85. הערך של קו האורך נע בין 180- ל-180, כולל. ערכים מעל או מתחת לטווח הזה יעברו עיגול כך שייכללו בטווח (-180, 180). לדוגמה, הערכים 480, 840 ו-1,200 יעברו גלילה ל-120 מעלות.כיוון (כיוון)
כיוון המצלמה מציין את כיוון המצפן, שנמדד בזוויות מצפון אמיתי, בהתאם לקצה העליון של המפה. אם מציירים קו אנכי ממרכז המפה לקצה העליון שלה, כיוון הצפון תואם לכיוון המצלמה (שנמדד בפרוגרסיות) ביחס לצפון האמיתי.
כיוון של 0 מציין שהחלק העליון של המפה מצביע על צפון אמיתי. כשהערך של כיוון המצפן הוא 90, החלק העליון של המפה מצביע לכיוון מזרח (90 מעלות במצפן). ערך של 180 מציין שהחלק העליון של המפה מצביע ישירות דרומה.
באמצעות Maps API אפשר לשנות את הכיוון של המפה. לדוגמה, אנשים שנוסעים ברכב בדרך כלל מסובבים את מפת הכבישים כך שתתאים לכיוון הנסיעה שלהם, ואילו מטיילים שמשתמשים במפה ובמצפן בדרך כלל מסובבים את המפה כך שקו אנכי יצביע לכיוון צפון.
הטיה (זווית צפייה)
ההטיה מגדירה את מיקום המצלמה על קשת ישירות מעל מיקום מרכז המפה, ומחושבת בזוויות מהנאדיר (הכיוון שמצביע ישירות מתחת למצלמה). ערך 0 תואם למצלמה שמכוונת ישירות למטה. ערכים גדולים מ-0 מתאימים למצלמה שמשויכת לזווית מסוימת ביחס לאופק. כשמשנים את זווית התצוגה, המפה מוצגת בתצוגת תלת-ממד, שבה תכונות שנמצאות רחוק נראות קטנות יותר ותכונות שנמצאות קרוב נראות גדולות יותר. האיורים הבאים מדגימים זאת.
בתמונות הבאות, זווית הצפייה היא 0 מעלות. בתמונה הראשונה מוצגת תרשים של המצב הזה: המיקום 1 הוא מיקום המצלמה, והמיקום 2 הוא המיקום הנוכחי במפה. המפה שנוצרה מוצגת מתחת.
בתמונות הבאות, זווית הצפייה היא 45 מעלות. שימו לב שהמצלמה נעה למחצית קשת בין מיקום ישר מעל הראש (0 מעלות) לבין מיקום על הקרקע (90 מעלות), למיקום 3. המצלמה עדיין מכוונת לנקודת המרכז של המפה, אבל האזור שמיוצג על ידי הקו במיקום 4 גלוי עכשיו.
המפה בצילום המסך הזה עדיין ממוקמת באותה נקודה כמו במפה המקורית, אבל תכונות נוספות הופיעו בחלק העליון של המפה. ככל שהזווית גדלה מעבר ל-45 מעלות, האובייקטים שבין המצלמה לבין מיקום המפה נראים גדולים יותר באופן יחסי, ואילו האובייקטים שמעבר למיקום המפה נראים קטנים יותר באופן יחסי, וכך נוצר אפקט תלת-ממדי.
שינוי מרחק התצוגה
רמת הזום של המצלמה קובעת את קנה המידה של המפה. ברמות זום גדולות יותר אפשר לראות יותר פרטים במסך, וברמות זום קטנות יותר אפשר לראות יותר מהעולם במסך.
רמת הזום לא חייבת להיות מספר שלם. טווח רמות הזום המותרות במפה תלוי בכמה גורמים, כולל היעד, סוג המפה וגודל המסך. כל מספר מחוץ לטווח יומיר לערך החוקי הקרוב ביותר, שיכול להיות רמת הזום המינימלית או רמת הזום המקסימלית. ברשימה הבאה מפורטת רמת הפירוט המשוערת שאפשר לראות בכל רמת זום:
- 1: עולם
- 5: יבשת
- 10: עיר
- 15: רחובות
- 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');
}
});