במסמך הזה מתוארים סוגי המפות שאפשר להציג באמצעות
JavaScript JavaScript API. ה-API משתמש באובייקט MapType
כדי להכיל מידע על המפות האלה. MapType
הוא ממשק שמגדיר את התצוגה והשימוש במשבצות מפה ואת התרגום של מערכות קואורדינטות מקואורדינטות מסך לקואורדינטות של העולם (במפה). כל MapType
צריך לכלול כמה שיטות לטיפול באחזור ובשחרור של אריחים, ובמאפיינים שמגדירים את ההתנהגות החזותית שלו.
העבודה הפנימית של סוגי מפות ב-Maps JavaScript API היא נושא מתקדם. רוב המפתחים יכולים להשתמש ב סוגי המפה הבסיסיים המצוינים למטה. עם זאת, אפשר גם לשנות את ההצגה של סוגי מפות קיימים באמצעות מפות מעוצבות או להגדיר אריחי מפה משלכם באמצעות סוגי מפות מותאמים אישית. כשמציינים סוגי מפות בהתאמה אישית, צריך להבין איך לשנות את רישום סוג המפה של המפה.
סוגי מפות בסיסיים
יש ארבעה סוגי מפות זמינות ב-JavaScript JavaScript API. בנוסף למשבצות המפה המוכרות "הצבעתי", ממשק ה-API של מפות Google JavaScript תומך גם בסוגי מפות אחרים.
סוגי המפות הבאים זמינים ב-JavaScript JavaScript API:
roadmap
מציג את תצוגת ברירת המחדל של מפת דרכים. זהו סוג המפה שמוגדר כברירת מחדל.- ב-
satellite
מוצגות תמונות לוויין של Google Earth. - ב-
hybrid
מוצג שילוב של תצוגות רגילות ותמונות לוויין. - אפליקציית
terrain
מציגה מפה פיזית על סמך פרטי פני השטח.
אפשר לשנות את סוג המפה המוגדר על ידי Map
על ידי הגדרת המאפיין mapTypeId
שלו, בתוך המבנה, על ידי הגדרת
אובייקט Map options
או על ידי קריאה ל-method
של setMapTypeId()
במפה. ברירת המחדל של המאפיין mapTypeID
היא roadmap
.
ההגדרה של mapTypeId
במהלך היצירה:
var myLatlng = new google.maps.LatLng(-34.397, 150.644); var mapOptions = { zoom: 8, center: myLatlng, mapTypeId: 'satellite' }; var map = new google.maps.Map(document.getElementById('map'), mapOptions);
שינוי mapTypeId
באופן דינמי:
map.setMapTypeId('terrain');
חשוב לדעת: לא ניתן להגדיר את סוג המפה של המפה ישירות, אלא להגדיר את mapTypeId
כדי להפנות אל MapType
באמצעות מזהה.
כדי להשתמש ב-API של JavaScript במפות, צריך להשתמש במרשם של סוגי מפות, כפי שמוסבר בהמשך.
תמונות ב-45°
ה-JavaScript של 'מפות' תומך בתמונות ב-45° מיוחדות במיקומים מסוימים. התמונות ברזולוציה גבוהה מספקות נקודת מבט לכל אחד מהכיוונים הקרדינליים (צפון, דרום, מזרח, מערב). התמונות האלה זמינות ברמות זום גבוהות יותר עבור סוגי המפות הנתמכים.
התמונה הבאה מציגה את נקודת המבט של ניו יורק ב-45°:
סוגי המפה satellite
ו-hybrid
תומכים בתמונות
ב-45°
ברמת זום גבוהה (12 ומעלה) כאשר היא זמינה. אם המשתמש יתקרב למיקום שבו קיימות תמונות כאלה, סוגי המפות האלה ישנו את התצוגות באופן אוטומטי באופן הבא:
- תמונות הלוויין או התמונות ההיברידיות יוחלפו בתמונות שיספקו פרספקטיבה של 45 מעלות, אבל הן באותו מיקום. כברירת מחדל, הצפיות האלה
מכוונות לצפון. אם המשתמש מקטין את התצוגה, תמונות הלוויין או ההיברידיות המוגדרות כברירת מחדל יופיעו שוב. ההתנהגות משתנה בהתאם לרמת המרחק מהתצוגה ולערך של
tilt
: - בין רמות זום 12 ו-18, המפה הבסיסית למטה (0°) מוצגת כברירת מחדל, אלא אם
tilt
מוגדר ל-45. - ברמות זום של 18 מעלות ומעלה, מפת הבסיס ב-45° מוצגת, אלא אם הערך של
tilt
מוגדר ל-0. - פקד הסיבוב הופך לגלוי. פקד הסיבוב מספק אפשרויות שמאפשרות למשתמש להחליף את מצב ההטיה ולסובב את התצוגה במרווחים של 90° בכל כיוון. כדי להסתיר את פקד הסיבוב, מגדירים את
rotateControl
לערךfalse
.
התרחקות מסוג מפה שמציגה תמונות ב-45° מבטלת את כל השינויים האלה, וכך יוצרת מחדש את סוגי המפה המקוריים.
הפעלה והשבתה של תמונות ב-45°
אפשר להשבית תמונות ב-45° באמצעות קריאה ל-setTilt(0)
באובייקט Map
. כדי להפעיל תמונות ב-45° לסוגי מפות נתמכים, יש להתקשר אל setTilt(45)
. השיטה getTilt()
של Map
תשקף תמיד את השיטה tilt
שמוצגת כרגע במפה. אם תגדיר tilt
במפה ולאחר מכן תסיר את tilt
(על ידי הקטנת המפה, לדוגמה), שיטת getTilt()
במפה תחזיר את הערך 0
.
חשוב: תמונות ב-45° נתמכות רק במפות רסטר. לא ניתן להשתמש בתמונות האלה במפות וקטוריות.
בדוגמה הבאה מוצגת תצוגה של 45° של העיר ניו יורק:
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { center: { lat: 40.76, lng: -73.983 }, zoom: 15, mapTypeId: "satellite", } ); map.setTilt(45); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 40.76, lng: -73.983 }, zoom: 15, mapTypeId: "satellite", }); map.setTilt(45); } window.initMap = initMap;
לדגימה
תמונות מסתובבות ב-45°
תמונות 45° כוללות אוסף של תמונות
לכל כיוון (בצפון, בדרום, במזרח, במערב). ברגע שהמפה שלך מציגה תמונות של 45°, אפשר לכוון אותה לכיוון אחד מהכיוונים הקרדינליים שלה. לשם כך, יש לקרוא לפונקציה setHeading()
באובייקט Map
ולהעביר ערך מספר שמשקף מצפון.
הדוגמה הבאה מציגה מפת אוויר ומסובבת את המפה אוטומטית כל 3 שניות לאחר לחיצה על הלחצן:
TypeScript
let map: google.maps.Map; function initMap(): void { map = new google.maps.Map(document.getElementById("map") as HTMLElement, { center: { lat: 40.76, lng: -73.983 }, zoom: 15, mapTypeId: "satellite", heading: 90, tilt: 45, }); // add listener to button document.getElementById("rotate")!.addEventListener("click", autoRotate); } function rotate90(): void { const heading = map.getHeading() || 0; map.setHeading(heading + 90); } function autoRotate(): void { // Determine if we're showing aerial imagery. if (map.getTilt() !== 0) { window.setInterval(rotate90, 3000); } } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
let map; function initMap() { map = new google.maps.Map(document.getElementById("map"), { center: { lat: 40.76, lng: -73.983 }, zoom: 15, mapTypeId: "satellite", heading: 90, tilt: 45, }); // add listener to button document.getElementById("rotate").addEventListener("click", autoRotate); } function rotate90() { const heading = map.getHeading() || 0; map.setHeading(heading + 90); } function autoRotate() { // Determine if we're showing aerial imagery. if (map.getTilt() !== 0) { window.setInterval(rotate90, 3000); } } window.initMap = initMap;
לדגימה
שינוי הרישום של סוג המפה
mapTypeId
של מפה הוא מזהה מחרוזת שמשמש לשיוך של MapType
לערך ייחודי. לכל אובייקט Map
יש
MapTypeRegistry
שמכיל את האוסף של
MapType
זמינים עבור המפה הזו. המרשם הזה
משמש לבחירת סוגי המפות שזמינים
בפקד MapType של המפה, לדוגמה.
אי אפשר לקרוא ישירות מהמרשם של סוג המפה. במקום זאת,
כדי לשנות את הרישום, צריך להוסיף סוגי מפות בהתאמה אישית ולשייך אותם
למזהה מחרוזת שתבחרו. לא ניתן לשנות או לשנות את סוגי המפה הבסיסיים (אם כי אפשר להסיר אותם מהמפה על ידי שינוי המראה של המפה המשויכת לכתובת mapTypeControlOptions
).
הקוד הבא מגדיר את המפה כך שיוצגו רק שני סוגי מפה ב-mapTypeControlOptions
של המפה, ומשנה את הרישום כדי להוסיף את השיוך למזהה הזה ליישום בפועל של הממשק MapType
.
// Modify the control to only display two maptypes, the // default ROADMAP and the custom 'mymap'. // Note that because this is an association, we // don't need to modify the MapTypeRegistry beforehand. var MY_MAPTYPE_ID = 'mymaps'; var mapOptions = { zoom: 12, center: brooklyn, mapTypeControlOptions: { mapTypeIds: ['roadmap', MY_MAPTYPE_ID] }, mapTypeId: MY_MAPTYPE_ID }; // Create our map. This creation will implicitly create a // map type registry. map = new google.maps.Map(document.getElementById('map'), mapOptions); // Create your custom map type using your own code. // (See below.) var myMapType = new MyMapType(); // Set the registry to associate 'mymap' with the // custom map type we created, and set the map to // show that map type. map.mapTypes.set(MY_MAPTYPE_ID, myMapType);
מפות מסוגננות
StyledMapType
מאפשר לך להתאים אישית את ההצגה של מפות הבסיס הרגילות של Google, ולשנות את התצוגה החזותית של רכיבים
כמו כבישים, פארקים ואזורים מובנים, כדי לשקף סגנון שונה מזה שמשמש
בסוג המפה שמוגדר כברירת המחדל.
למידע נוסף על StyledMapType
, אפשר לעיין במדריך למפות מעוצבות.
סוגים מותאמים אישית של מפות
ממשק ה-API של Maps JavaScript תומך בתצוגה ובניהול של סוגי מפות בהתאמה אישית, וכך מאפשר לך להטמיע תמונות מפה או שכבות-על של משבצות משלך.
קיימים מספר הטמעות אפשריות של סוגי מפות ב-Maps JavaScript API:
- קבוצות משבצות סטנדרטיות שכוללות תמונות שמשולבות בהן מפות קרטוגרפיות מלאות. קבוצות האריחים האלה
נקראות גם סוגי מפות בסיסיים. סוגי המפה האלה פועלים ומתנהגים כמו סוגי המפה הקיימים שמוגדרים כברירת מחדל:
roadmap
,satellite
,hybrid
ו-terrain
. אפשר להוסיף את סוג המפה המותאמת אישית למערךmapTypes
של המפה כדי לאפשר לממשק המשתמש ב-Maps JavaScript API להתייחס לסוג המפה המותאם אישית כאל סוג מפה רגיל (למשל, על ידי הכללתו בפקד של MapType). - שכבות-על של אריחי תמונה שמוצגות מעל סוגי מפת הבסיס הקיימת. באופן כללי, סוגי המפה האלה משמשים להרחבת סוג מפה קיים כדי להציג מידע נוסף, והם מוגבלים בדרך כלל למיקומים מסוימים או לרמות של זום. חשוב לזכור שהמשבצות האלה עשויות להיות שקופות ולאפשר לכם להוסיף תכונות למפות קיימות.
- סוגי מפות שאינם תמונות, שמאפשרים לך לטפל בתצוגה של פרטי המפה ברמה הבסיסית ביותר שלהם.
כל אחת מהאפשרויות האלה תלויה ביצירת מחלקה שמטמיעה את הממשק MapType
. בנוסף, במחלקה
ImageMapType
יש התנהגות מובנית שמאפשרת לפשט את היצירה של סוגי מפות.
הממשק של MapType
לפני שיוצרים קורסים שמטמיעים את MapType
,
חשוב להבין איך מפות Google קובעת
קואורדינטות ומחליטה אילו חלקים במפה להציג. צריך להטמיע לוגיקה דומה בכל סוג של מפה בסיסית או שכבת-על.
כדאי לקרוא את המדריך לקואורדינטות
של מפות ואריחים.
סוגי מפות מותאמים אישית חייבים להטמיע את הממשק MapType
. הממשק הזה מציין תכונות ושיטות
מסוימות שמאפשרות ל-API ליזום בקשות לסוגי המפה שלך
כשה-API קובע שהוא צריך להציג
אריחי מפה בתוך אזור התצוגה ורמת הזום הנוכחיים. אתם
מטפלים בבקשות האלה כדי להחליט איזה אריח לטעון.
הערה: כדי ליצור את הממשק הזה, אפשר ליצור כיתה משלך. לחלופין, אם יש לך תמונות תואמות, אפשר להשתמש במחלקה
ImageMapType
שכבר מטמיעה את הממשק הזה.
לכיתות המטמיעות את הממשק של MapType
נדרשת הגדרה ואכלוס את המאפיינים הבאים:
tileSize
(חובה) מציין את גודל המשבצת (מסוגgoogle.maps.Size
). הגדלים חייבים להיות מלבניים, אבל לא חייבים להיות ריבועיים.maxZoom
(חובה) מציינת את רמת הזום המקסימלית שבה יוצגו משבצות מסוג המפה הזה.minZoom
(אופציונלי) מציינת את רמת הזום המינימלית שבה יוצג אריח מהסוג הזה במפה. כברירת מחדל, הערך הזה הוא0
, ופירוש הדבר שלא קיימת רמה מינימלית של זום.name
(אופציונלי) מציין את השם עבור סוג המפה הזה. הנכס הזה נדרש רק אם ברצונך לבחור את סוג המפה הזה בתוך פקד של MapType. (ראו הוספתMapType
פקדים בהמשך).alt
(אופציונלי) מציין את הטקסט החלופי לסוג המפה הזה, שמוצג כטקסט מרחף. הנכס הזה נדרש רק אם ברצונך שניתן יהיה לבחור את סוג המפה הזה בפקד של MapType. (מידע נוסף זמין בקטע הוספתMapType
אמצעי בקרה בהמשך).
בנוסף, מחלקות שמטמיעות את הממשק של MapType
צריכות ליישם את השיטות הבאות:
-
מתבצעת קריאה ל-
getTile()
(חובה) בכל פעם שה-API קובע שהמפה צריכה להציג משבצות חדשות עבור אזור התצוגה הנתון. השיטהgetTile()
חייבת לכלול את החתימה הבאה:getTile(tileCoord:Point,zoom:number,ownerDocument:Document):Node
ה-API קובע אם להפעיל את הקריאה
getTile()
על סמך המאפייניםtileSize
,minZoom
ו-maxZoom
שלMapType
, לפי אזור התצוגה הנוכחי ורמת הזום של המפה. ה-handler של השיטה הזו צריך להחזיר רכיב HTML על סמך קואורדינטות שאותרו, רמת הזום ורכיב ה-DOM שבהם יש להוסיף את תמונת המשבצת. -
הפונקציה
releaseTile()
(אופציונלי) נקראת בכל פעם שה-API קובע שהמפה צריכה להסיר משבצת שהיא לא מופיעה בה. השיטה הזו חייבת לכלול את החתימה הבאה:releaseTile(tile:Node)
בדרך כלל יש לטפל בהסרה של רכיבים שצורפו למשבצות במפה, בנוסף למפה. לדוגמה, אם צירפת פונקציות מסוג listener של אירוע כדי למפות שכבות-על של משבצות, צריך להסיר אותן כאן.
השיטה getTile()
משמשת כבקר הראשי
שקובעת אילו משבצות ייטענו באזור תצוגה נתון.
סוגים בסיסיים של מפות
סוגי המפה שאתם יוצרים יכולים לעמוד בנפרד
או לשלב עם סוגי מפות אחרים כשכבות-על. סוגי המפה שעומדים בפני עצמם
נקראים סוגי מפות בסיסיים. מומלץ לאפשר ל-API לטפל ב-MapType
בהתאמה אישית, כמו בכל סוג אחר של מפת בסיס (ROADMAP
, TERRAIN
וכו'). כדי לעשות זאת, צריך להוסיף את
MapType
המותאם אישית
בנכס mapTypes
של Map
. הנכס הזה הוא מסוג MapTypeRegistry
.
הקוד הבא יוצר את הבסיס MapType
כדי להציג את הקואורדינטות של כרטיס המידע במפה, ומשרטט את קו המתאר של המשבצות:
TypeScript
/* * This demo demonstrates how to replace default map tiles with custom imagery. * In this case, the CoordMapType displays gray tiles annotated with the tile * coordinates. * * Try panning and zooming the map to see how the coordinates change. */ class CoordMapType { tileSize: google.maps.Size; maxZoom = 19; name = "Tile #s"; alt = "Tile Coordinate Map Type"; constructor(tileSize: google.maps.Size) { this.tileSize = tileSize; } getTile( coord: google.maps.Point, zoom: number, ownerDocument: Document ): HTMLElement { const div = ownerDocument.createElement("div"); div.innerHTML = String(coord); div.style.width = this.tileSize.width + "px"; div.style.height = this.tileSize.height + "px"; div.style.fontSize = "10"; div.style.borderStyle = "solid"; div.style.borderWidth = "1px"; div.style.borderColor = "#AAAAAA"; div.style.backgroundColor = "#E5E3DF"; return div; } releaseTile(tile: HTMLElement): void {} } function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 10, center: { lat: 41.85, lng: -87.65 }, streetViewControl: false, mapTypeId: "coordinate", mapTypeControlOptions: { mapTypeIds: ["coordinate", "roadmap"], style: google.maps.MapTypeControlStyle.DROPDOWN_MENU, }, } ); map.addListener("maptypeid_changed", () => { const showStreetViewControl = (map.getMapTypeId() as string) !== "coordinate"; map.setOptions({ streetViewControl: showStreetViewControl, }); }); // Now attach the coordinate map type to the map's registry. map.mapTypes.set( "coordinate", new CoordMapType(new google.maps.Size(256, 256)) ); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
/* * This demo demonstrates how to replace default map tiles with custom imagery. * In this case, the CoordMapType displays gray tiles annotated with the tile * coordinates. * * Try panning and zooming the map to see how the coordinates change. */ class CoordMapType { tileSize; maxZoom = 19; name = "Tile #s"; alt = "Tile Coordinate Map Type"; constructor(tileSize) { this.tileSize = tileSize; } getTile(coord, zoom, ownerDocument) { const div = ownerDocument.createElement("div"); div.innerHTML = String(coord); div.style.width = this.tileSize.width + "px"; div.style.height = this.tileSize.height + "px"; div.style.fontSize = "10"; div.style.borderStyle = "solid"; div.style.borderWidth = "1px"; div.style.borderColor = "#AAAAAA"; div.style.backgroundColor = "#E5E3DF"; return div; } releaseTile(tile) {} } function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 10, center: { lat: 41.85, lng: -87.65 }, streetViewControl: false, mapTypeId: "coordinate", mapTypeControlOptions: { mapTypeIds: ["coordinate", "roadmap"], style: google.maps.MapTypeControlStyle.DROPDOWN_MENU, }, }); map.addListener("maptypeid_changed", () => { const showStreetViewControl = map.getMapTypeId() !== "coordinate"; map.setOptions({ streetViewControl: showStreetViewControl, }); }); // Now attach the coordinate map type to the map's registry. map.mapTypes.set( "coordinate", new CoordMapType(new google.maps.Size(256, 256)), ); } window.initMap = initMap;
לדגימה
סוגים של מפת שכבת-על
חלק מסוגי המפות נועדו לפעול בנוסף לסוגי המפה הקיימים. בסוגים כאלה של מפות יכולים להיות שכבות שקופות שמצביעות על נקודות עניין או מציגות למשתמש נתונים נוספים.
במקרים כאלה, לא רוצים שסוג המפה ייחשב כישות נפרדת, אלא כשכבת-על.
אפשר לעשות זאת על ידי הוספה של סוג המפה ל-MapType
קיים ישירות באמצעות
המאפיין overlayMapTypes
של Map
. הנכס הזה מכיל MVCArray
מתוך MapType
כל סוגי המפות (בסיסי ושכבת-על) מעובדים בשכבת mapPane
. סוגים של מפת שכבת-על יוצגו מעל למפת הבסיס שאליה הם מצורפים, לפי הסדר שבו הם מופיעים במערך Map.overlayMapTypes
(שכבות-על עם ערכי אינדקס גבוהים יותר יוצגו לפני שכבות-על עם ערכי אינדקס נמוכים יותר).
הדוגמה הבאה זהה לדוגמה הקודמת, אלא שיצרנו שכבת-על של אריח MapType
מעל סוג המפה ROADMAP
:
TypeScript
/* * This demo illustrates the coordinate system used to display map tiles in the * API. * * Tiles in Google Maps are numbered from the same origin as that for * pixels. For Google's implementation of the Mercator projection, the origin * tile is always at the northwest corner of the map, with x values increasing * from west to east and y values increasing from north to south. * * Try panning and zooming the map to see how the coordinates change. */ class CoordMapType implements google.maps.MapType { tileSize: google.maps.Size; alt: string|null = null; maxZoom: number = 17; minZoom: number = 0; name: string|null = null; projection: google.maps.Projection|null = null; radius: number = 6378137; constructor(tileSize: google.maps.Size) { this.tileSize = tileSize; } getTile( coord: google.maps.Point, zoom: number, ownerDocument: Document ): HTMLElement { const div = ownerDocument.createElement("div"); div.innerHTML = String(coord); div.style.width = this.tileSize.width + "px"; div.style.height = this.tileSize.height + "px"; div.style.fontSize = "10"; div.style.borderStyle = "solid"; div.style.borderWidth = "1px"; div.style.borderColor = "#AAAAAA"; return div; } releaseTile(tile: Element): void {} } function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 10, center: { lat: 41.85, lng: -87.65 }, } ); // Insert this overlay map type as the first overlay map type at // position 0. Note that all overlay map types appear on top of // their parent base map. const coordMapType = new CoordMapType(new google.maps.Size(256, 256)) map.overlayMapTypes.insertAt( 0, coordMapType ); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
/* * This demo illustrates the coordinate system used to display map tiles in the * API. * * Tiles in Google Maps are numbered from the same origin as that for * pixels. For Google's implementation of the Mercator projection, the origin * tile is always at the northwest corner of the map, with x values increasing * from west to east and y values increasing from north to south. * * Try panning and zooming the map to see how the coordinates change. */ class CoordMapType { tileSize; alt = null; maxZoom = 17; minZoom = 0; name = null; projection = null; radius = 6378137; constructor(tileSize) { this.tileSize = tileSize; } getTile(coord, zoom, ownerDocument) { const div = ownerDocument.createElement("div"); div.innerHTML = String(coord); div.style.width = this.tileSize.width + "px"; div.style.height = this.tileSize.height + "px"; div.style.fontSize = "10"; div.style.borderStyle = "solid"; div.style.borderWidth = "1px"; div.style.borderColor = "#AAAAAA"; return div; } releaseTile(tile) {} } function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 10, center: { lat: 41.85, lng: -87.65 }, }); // Insert this overlay map type as the first overlay map type at // position 0. Note that all overlay map types appear on top of // their parent base map. const coordMapType = new CoordMapType(new google.maps.Size(256, 256)); map.overlayMapTypes.insertAt(0, coordMapType); } window.initMap = initMap;
לדגימה
סוגים של מפת תמונות
הטמעה של MapType
בתור סוג של מפה בסיסית
יכולה להיות משימה קשה שדורשת הרבה זמן. ה-API מספק מחלקה מיוחדת שמטמיעה את הממשק של MapType
, עבור סוגי המפות הנפוצים ביותר: סוגי מפות שמורכבים מכרטיסי מידע.
מחלקת ImageMapType
הזו נוצרה באמצעות מפרט אובייקט מסוג ImageMapTypeOptions
שמגדיר את המאפיינים הנדרשים הבאים:
tileSize
(חובה) מציין את גודל המשבצת (מסוגgoogle.maps.Size
). הגדלים חייבים להיות מלבניים, אבל לא חייבים להיות ריבועיים.- השדה
getTileUrl
(חובה) מציין את הפונקציה, שלרוב מסופקת כליטרל של פונקציה מוטבעת, כדי לטפל במשבצת של התמונה המתאימה על סמך קואורדינטות העולם ורמת הזום שסופקו.
הקוד הבא מטמיע ImageMapType
בסיסי באמצעות אריחי הירח של Google. הדוגמה משתמשת בפונקציית נורמליזציה כדי להבטיח שהאריחים יחזרו על ציר ה-X, אך לא לאורך ציר ה-y של המפה.
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { center: { lat: 0, lng: 0 }, zoom: 1, streetViewControl: false, mapTypeControlOptions: { mapTypeIds: ["moon"], }, } ); const moonMapType = new google.maps.ImageMapType({ getTileUrl: function (coord, zoom): string { const normalizedCoord = getNormalizedCoord(coord, zoom); if (!normalizedCoord) { return ""; } const bound = Math.pow(2, zoom); return ( "https://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw" + "/" + zoom + "/" + normalizedCoord.x + "/" + (bound - normalizedCoord.y - 1) + ".jpg" ); }, tileSize: new google.maps.Size(256, 256), maxZoom: 9, minZoom: 0, // @ts-ignore TODO 'radius' does not exist in type 'ImageMapTypeOptions' radius: 1738000, name: "Moon", }); map.mapTypes.set("moon", moonMapType); map.setMapTypeId("moon"); } // Normalizes the coords that tiles repeat across the x axis (horizontally) // like the standard Google map tiles. function getNormalizedCoord(coord, zoom) { const y = coord.y; let x = coord.x; // tile range in one direction range is dependent on zoom level // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc const tileRange = 1 << zoom; // don't repeat across y-axis (vertically) if (y < 0 || y >= tileRange) { return null; } // repeat across x-axis if (x < 0 || x >= tileRange) { x = ((x % tileRange) + tileRange) % tileRange; } return { x: x, y: y }; } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 0, lng: 0 }, zoom: 1, streetViewControl: false, mapTypeControlOptions: { mapTypeIds: ["moon"], }, }); const moonMapType = new google.maps.ImageMapType({ getTileUrl: function (coord, zoom) { const normalizedCoord = getNormalizedCoord(coord, zoom); if (!normalizedCoord) { return ""; } const bound = Math.pow(2, zoom); return ( "https://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw" + "/" + zoom + "/" + normalizedCoord.x + "/" + (bound - normalizedCoord.y - 1) + ".jpg" ); }, tileSize: new google.maps.Size(256, 256), maxZoom: 9, minZoom: 0, // @ts-ignore TODO 'radius' does not exist in type 'ImageMapTypeOptions' radius: 1738000, name: "Moon", }); map.mapTypes.set("moon", moonMapType); map.setMapTypeId("moon"); } // Normalizes the coords that tiles repeat across the x axis (horizontally) // like the standard Google map tiles. function getNormalizedCoord(coord, zoom) { const y = coord.y; let x = coord.x; // tile range in one direction range is dependent on zoom level // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc const tileRange = 1 << zoom; // don't repeat across y-axis (vertically) if (y < 0 || y >= tileRange) { return null; } // repeat across x-axis if (x < 0 || x >= tileRange) { x = ((x % tileRange) + tileRange) % tileRange; } return { x: x, y: y }; } window.initMap = initMap;
לדגימה
תחזיות
כדור הארץ הוא כדור תלת-ממדי (בערך) ואילו מפה היא משטח דו-מימדי שטוח. המפה שמופיעה ב-JavaScript של API של מפות Google, כמו כל מפה רגילה של כדור הארץ, היא הקרנה של כדור הארץ על פני שטח שטוח. במונחים הפשוטים ביותר, ניתן להגדיר תחזית כמיפוי של ערכי קווי אורך/רוחב לקואורדינטות במפה של הקרנה.
תחזיות ב-Maps JavaScript API חייבות להטמיע את
Projection
. הטמעת Projection
צריכה לספק מיפוי של מערכת קואורדינטות אחת
בלבד, וגם מיפוי דו-כיווני. כלומר, עליך
להגדיר איך לתרגם מהקואורדינטות של Earth (LatLng
אובייקטים)
למערכת הקואורדינטות של
עולם Projection
, ולהפך. אפליקציית מפות Google משתמשת
בתחזית של Mercator כדי ליצור את המפות
שלה מנתונים גיאוגרפיים ולהמיר אירועים במפה לקואורדינטות גיאוגרפיות. כדי להציג את התחזית הזו, יש להתקשר ל-getProjection()
ב-Map
(או בכל אחד מסוגי הבסיס הרגילים של MapType
). ברוב המקרים מספיק להשתמש בקובץ Projection
הסטנדרטי הזה, אבל אפשר גם להגדיר חיזויים מותאמים אישית ולהשתמש בהם.
הטמעת תחזית
כשמטמיעים תחזית מותאמת אישית, צריך להגדיר כמה דברים:
- הנוסחה למיפוי קואורדינטות של קווי אורך ורוחב לתוך מטוס קרקסי, ולהיפך. (הממשק של
Projection
תומך רק בטרנספורמציות לקואורדינטות רטרואקטיביות.) - גודל אריח הבסיס. כל האריחים חייבים להיות מלבניים.
- "הגודל העולמי" של מפה באמצעות אריח הבסיס שהוגדר ברמת הזום 0. חשוב לשים לב שבמפות שמכילות אריח אחד בזום 0, גודל העולם וגודל אריח הבסיס זהים.
תיאום שינויים בתחזיות
כל תחזית מספקת שתי שיטות שמתורגמות בין שתי מערכות הקואורדינטות האלה, כדי לאפשר לך להמיר בין קואורדינטות גיאוגרפיות לקואורדינטות:
- השיטה
Projection.fromLatLngToPoint()
ממירה ערךLatLng
לערך לקואורדינטות עולמיות. השיטה הזו משמשת למיקום שכבות-על במפה (ולמיקום המפה עצמה). - השיטה
Projection.fromPointToLatLng()
ממירה קואורדינטות בעולם לערךLatLng
. השיטה הזו משמשת להמרת אירועים כמו קליקים שמתרחשים במפה לקואורדינטות גיאוגרפיות.
מפות Google מניחה שהתחזיות הן רקטיות.
באופן כללי, אפשר להשתמש בתחזית לשני מקרים: כדי ליצור מפת העולם, או כדי ליצור מפה של אזור מקומי. במקרה הקודם, יש לוודא שה הקרנה שלך היא גם רצונית ורגילה בכל קווי האורך. חלק מההקרנות (במיוחד חרוטים) עשויות להיות 'רגילות באופן מקומי' (כלומר, מצפון) אבל סוטות מהצפון האמיתי. לדוגמה, ככל שהמפה במיקום קרוב יותר ביחס לקו אורך מסוים. יש לך אפשרות להשתמש בתחזית הזו באופן מקומי, אבל חשוב לזכור שהסבירות לכך היא לא מדויקת ושגיאות הטרנספורמציה יהפכו למעולות יותר מאורך ההפניות שסטית.
בחירת אריחי מפה בתחזיות
תחזיות לא משמשות רק לקביעת המיקומים של מיקומים או שכבות-על, אלא גם למיקום אריחי המפה עצמם.
ה-API של מפות Google מעבד מפות בסיסיות באמצעות ממשק של MapType
. צריך להצהיר על נכס projection
גם כדי לזהות את הקרנה של המפה וגם על שיטה getTile()
לאחזור
אריחי מפה על סמך
ערכי
קואורדינטות של משבצות. הקואורדינטות של המשבצות מבוססות על גודל המשבצות הבסיסי (שחייב להיות מלבני) וגם על 'הגודל של העולם' של המפה, שהוא גודל הפיקסלים של עולם המפה
ברמת הזום 0. (במפות שמכילות אריח אחד בזום 0, גודל המשבצת
וגודל העולם הם זהים).
הגודל של אריח הבסיס מוגדר בנכס tileSize
של MapType
. מגדירים את הגודל העולמי באופן לא מפורש
בשיטות fromLatLngToPoint()
ו-fromPointToLatLng()
של החיזוי.
בחירת התמונות תלויה בערכים המועברים האלה, ולכן
כדאי לתת שם לתמונות שניתן לבחור באופן פרוגרמטי בהתאם
לערכים שהועברו, כמו
map_zoom_tileX_tileY.png
.
בדוגמה הבאה מוגדרת ImageMapType
שימוש בתחזית
Gall-Peters:
TypeScript
// This example defines an image map type using the Gall-Peters // projection. // https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection function initMap(): void { // Create a map. Use the Gall-Peters map type. const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 0, center: { lat: 0, lng: 0 }, mapTypeControl: false, } ); initGallPeters(); map.mapTypes.set("gallPeters", gallPetersMapType); map.setMapTypeId("gallPeters"); // Show the lat and lng under the mouse cursor. const coordsDiv = document.getElementById("coords") as HTMLElement; map.controls[google.maps.ControlPosition.TOP_CENTER].push(coordsDiv); map.addListener("mousemove", (event: google.maps.MapMouseEvent) => { coordsDiv.textContent = "lat: " + Math.round(event.latLng!.lat()) + ", " + "lng: " + Math.round(event.latLng!.lng()); }); // Add some markers to the map. map.data.setStyle((feature) => { return { title: feature.getProperty("name"), optimized: false, }; }); map.data.addGeoJson(cities); } let gallPetersMapType; function initGallPeters() { const GALL_PETERS_RANGE_X = 800; const GALL_PETERS_RANGE_Y = 512; // Fetch Gall-Peters tiles stored locally on our server. gallPetersMapType = new google.maps.ImageMapType({ getTileUrl: function (coord, zoom) { const scale = 1 << zoom; // Wrap tiles horizontally. const x = ((coord.x % scale) + scale) % scale; // Don't wrap tiles vertically. const y = coord.y; if (y < 0 || y >= scale) return ""; return ( "https://developers.google.com/maps/documentation/" + "javascript/examples/full/images/gall-peters_" + zoom + "_" + x + "_" + y + ".png" ); }, tileSize: new google.maps.Size(GALL_PETERS_RANGE_X, GALL_PETERS_RANGE_Y), minZoom: 0, maxZoom: 1, name: "Gall-Peters", }); // Describe the Gall-Peters projection used by these tiles. gallPetersMapType.projection = { fromLatLngToPoint: function (latLng) { const latRadians = (latLng.lat() * Math.PI) / 180; return new google.maps.Point( GALL_PETERS_RANGE_X * (0.5 + latLng.lng() / 360), GALL_PETERS_RANGE_Y * (0.5 - 0.5 * Math.sin(latRadians)) ); }, fromPointToLatLng: function (point, noWrap) { const x = point.x / GALL_PETERS_RANGE_X; const y = Math.max(0, Math.min(1, point.y / GALL_PETERS_RANGE_Y)); return new google.maps.LatLng( (Math.asin(1 - 2 * y) * 180) / Math.PI, -180 + 360 * x, noWrap ); }, }; } // GeoJSON, describing the locations and names of some cities. const cities = { type: "FeatureCollection", features: [ { type: "Feature", geometry: { type: "Point", coordinates: [-87.65, 41.85] }, properties: { name: "Chicago" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-149.9, 61.218] }, properties: { name: "Anchorage" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-99.127, 19.427] }, properties: { name: "Mexico City" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-0.126, 51.5] }, properties: { name: "London" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [28.045, -26.201] }, properties: { name: "Johannesburg" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [15.322, -4.325] }, properties: { name: "Kinshasa" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [151.207, -33.867] }, properties: { name: "Sydney" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [0, 0] }, properties: { name: "0°N 0°E" }, }, ], }; declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// This example defines an image map type using the Gall-Peters // projection. // https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection function initMap() { // Create a map. Use the Gall-Peters map type. const map = new google.maps.Map(document.getElementById("map"), { zoom: 0, center: { lat: 0, lng: 0 }, mapTypeControl: false, }); initGallPeters(); map.mapTypes.set("gallPeters", gallPetersMapType); map.setMapTypeId("gallPeters"); // Show the lat and lng under the mouse cursor. const coordsDiv = document.getElementById("coords"); map.controls[google.maps.ControlPosition.TOP_CENTER].push(coordsDiv); map.addListener("mousemove", (event) => { coordsDiv.textContent = "lat: " + Math.round(event.latLng.lat()) + ", " + "lng: " + Math.round(event.latLng.lng()); }); // Add some markers to the map. map.data.setStyle((feature) => { return { title: feature.getProperty("name"), optimized: false, }; }); map.data.addGeoJson(cities); } let gallPetersMapType; function initGallPeters() { const GALL_PETERS_RANGE_X = 800; const GALL_PETERS_RANGE_Y = 512; // Fetch Gall-Peters tiles stored locally on our server. gallPetersMapType = new google.maps.ImageMapType({ getTileUrl: function (coord, zoom) { const scale = 1 << zoom; // Wrap tiles horizontally. const x = ((coord.x % scale) + scale) % scale; // Don't wrap tiles vertically. const y = coord.y; if (y < 0 || y >= scale) return ""; return ( "https://developers.google.com/maps/documentation/" + "javascript/examples/full/images/gall-peters_" + zoom + "_" + x + "_" + y + ".png" ); }, tileSize: new google.maps.Size(GALL_PETERS_RANGE_X, GALL_PETERS_RANGE_Y), minZoom: 0, maxZoom: 1, name: "Gall-Peters", }); // Describe the Gall-Peters projection used by these tiles. gallPetersMapType.projection = { fromLatLngToPoint: function (latLng) { const latRadians = (latLng.lat() * Math.PI) / 180; return new google.maps.Point( GALL_PETERS_RANGE_X * (0.5 + latLng.lng() / 360), GALL_PETERS_RANGE_Y * (0.5 - 0.5 * Math.sin(latRadians)), ); }, fromPointToLatLng: function (point, noWrap) { const x = point.x / GALL_PETERS_RANGE_X; const y = Math.max(0, Math.min(1, point.y / GALL_PETERS_RANGE_Y)); return new google.maps.LatLng( (Math.asin(1 - 2 * y) * 180) / Math.PI, -180 + 360 * x, noWrap, ); }, }; } // GeoJSON, describing the locations and names of some cities. const cities = { type: "FeatureCollection", features: [ { type: "Feature", geometry: { type: "Point", coordinates: [-87.65, 41.85] }, properties: { name: "Chicago" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-149.9, 61.218] }, properties: { name: "Anchorage" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-99.127, 19.427] }, properties: { name: "Mexico City" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [-0.126, 51.5] }, properties: { name: "London" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [28.045, -26.201] }, properties: { name: "Johannesburg" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [15.322, -4.325] }, properties: { name: "Kinshasa" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [151.207, -33.867] }, properties: { name: "Sydney" }, }, { type: "Feature", geometry: { type: "Point", coordinates: [0, 0] }, properties: { name: "0°N 0°E" }, }, ], }; window.initMap = initMap;