סוגי מפות

בחירת פלטפורמה: Android iOS JavaScript

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

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

סוגי מפה בסיסיים

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

סוגי המפות הבאים זמינים ב-Maps JavaScript API:

  • roadmap מציג את תצוגת ברירת המחדל של מפת הדרכים. הזה הוא סוג המפה שמוגדר כברירת מחדל.
  • satellite מציג את הלוויין של Google Earth תמונות.
  • ב-hybrid מוצג שילוב של נתונים רגילים ולוויין צפיות.
  • ב-terrain מוצגת מפה פיזית על סמך פני השטח מידע.

אפשר לשנות את סוג המפה שבו נעשה שימוש על ידי Map על ידי הגדרת מאפיין mapTypeId, בתוך ה-constructor דרך ההגדרה באובייקט Map options שלו, או על ידי קריאה אמצעי תשלום 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 של מפות Google משתמש במרשם סוגי מפה, כדי לנהל את ההפניות האלה.

תמונות ב-45°

ה-JavaScript API של מפות Google תומך בתמונות מיוחדות ב-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, אפשר לעיין במדריך של מפות מעוצבות.

סוגי מפה מותאמים אישית

ה-JavaScript API של מפות Google תומך בתצוגה וניהול של סוגי מפות מותאמים אישית, כדי שתוכלו להטמיע תמונות מפה או שכבות-על של משבצות.

קיימים כמה הטמעות אפשריות של סוגי מפה JavaScript API של מפות Google:

  • ערכות אריחים רגילות שמכילות תמונות יחד מרכיבים מפות קרטוגרפיות מלאות. המשבצת הזו נקראים גם סוגי מפות בסיס. סוגי המפות האלה פועלות ומתנהגות כמו סוגי המפות הקיימים שמוגדרים כברירת מחדל: roadmap, satellite hybrid וגם terrain. אפשר להוסיף סוג מפה מותאם אישית למערך mapTypes של מפה כדי מאפשרים לממשק המשתמש בתוך API JavaScript של מפות Google להתייחס לסוג המפה המותאמת אישית כאל סוג מפה סטנדרטי (על ידי הכללתו ב-MapType שליטה, למשל).
  • שכבות-על של משבצת תמונה שמוצגות מעל הסוגים הקיימים של המפה הבסיסית. בדרך כלל, סוגי המפות האלה משמשת להרחבת סוג מפה קיים כדי להציג מידע, ולעיתים קרובות הם מוגבלים למיקומים ספציפיים ו/או רמות הזום. חשוב לזכור שהמשבצות האלה עשויות להיות שקופות. וכך להוסיף תכונות למפות קיימות.
  • סוגים של מפות שאינן תמונות, שמאפשרות לבצע מניפולציה להצגת המידע במפה ברמה הבסיסית ביותר שלו.

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

הממשק של MapType

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

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

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

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

  • tileSize (חובה) מציין את גודל המשבצת (מסוג google.maps.Size). המידות חייבות להיות מלבניות למרות שהן לא חייבות להיות ריבועיות.
  • maxZoom (חובה) מציין את מרחק התצוגה המקסימלי הרמה שבה יוצגו משבצות מסוג המפה הזה.
  • minZoom (אופציונלי) מציין את מרחק התצוגה המינימלי הרמה שבה יוצג אריח מסוג המפה הזה. כברירת מחדל, הערך הוא 0, שמציין שאין ערך מינימלי קיימת רמת זום.
  • name (אופציונלי) מציין את שם המפה הזו מהסוג הזה. הנכס הזה נחוץ רק אם רוצים את סוג המפה הזה ניתנים לבחירה בתוך פקד MapType. (ראו הוספת MapType פקדים למטה.)
  • alt (אופציונלי) מציין את הטקסט החלופי סוג המפה, מוצג כטקסט מרחף. הנכס הזה נדרש רק אם רוצים שניתן יהיה לבחור את סוג המפה הזה בפקד MapType. (ראו הוספת פקדים של MapType) below.)

בנוסף, מחלקות שמטמיעות את הממשק של MapType תצטרכו להטמיע את השיטות הבאות:

  • מתבצעת קריאה אל getTile() (חובה) בכל פעם שה-API קובע שהמפה צריכה להציג משבצות חדשות עבור אזור התצוגה. ה-method getTile() חייבת לכלול את הפרטים הבאים חתימה:

    getTile(tileCoord:Point,zoom:number,ownerDocument:Document):Node

    ה-API קובע אם הוא צריך לקרוא ל-getTile() על סמך tileSize של MapType, minZoom, maxZoom ואת אזור התצוגה ורמת הזום הנוכחיים של המפה. הגורם המטפל לשיטה הזו אמור להחזיר רכיב HTML בהינתן קואורדינטה שהועברה, רמת הזום, ואת רכיב ה-DOM שאליו צריך לצרף את תמונת המשבצת.

  • תתבצע קריאה אל releaseTile() (אופציונלי) בכל פעם שה-API קובע שהמפה צריכה להסיר משבצת כשהיא נופלת מהתצוגה. השיטה הזו חייבת לכלול את החתימה הבאה:

    releaseTile(tile:Node)

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

ה-method getTile() משמשת כבקר הראשי עבור שקובעים אילו משבצות ייטענו בתוך אזור תצוגה נתון.

סוגים של מפה בסיסית

סוגי המפות שאתם בונים באופן הזה עשויים לעמוד בלבד או להיות משולבות עם סוגי מפות אחרים כשכבות-על. מיקום מודעה עצמאי סוגי המפות נקראים סוגי מפות בסיסיות. אולי כדאי להשתמש ב-API מתייחסים למאפייני MapType מותאמים אישית כאלה כמו לכל הגדרה קיימת אחרת סוג המפה הבסיסית (ROADMAP, TERRAIN וכו'). לבצע לכן צריך להוסיף את MapType המותאם אישית לMap נכס mapTypes. הנכס הזה הוא מסוג 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 אבל לא לאורך ציר ה-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 היא שהתחזיות הן ליניאריות.

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

בחירת אריחי מפה בהקרנות

התחזיות לא עוזרות רק לקביעת המיקומים של מיקומים או שכבות-על, אבל לצורך מיקום קטעי המפה עצמם. ממשק JavaScript API של מפות Google מעבד מפות בסיסיות באמצעות MapType של הממשק, שחייב להצהיר גם על המאפיין projection של זיהוי ההיטל של המפה ו-getTile() לאחזור קטעי מפה על סמך אריח קואורדינטות. קואורדינטות של משבצות מבוססות על גם את גודל האריח הבסיסי (שחייב להיות מלבני) וגם את size" של המפה, שהוא גודל הפיקסלים של עולם המפה ברמת זום 0. (במפות שמורכבות מאריח אחד עם מרחק של 0, האריח הגודל והגודל העולמיים זהים).

אתם מגדירים את הגודל של אריח הבסיס בתוך MapType נכס tileSize. אתם מגדירים את גודל העולם באופן מרומז בטווח fromLatLngToPoint() של התחזית ו-fromPointToLatLng().

בחירת התמונה תלויה בערכים האלה, ולכן היא שימושית לתת שמות לתמונות שאפשר לבחור באופן פרוגרמטי, של הערכים שמועברים, כמו map_zoom_tileX_tileY.png

בדוגמה הבאה מוגדר ImageMapType באמצעות תחזית גל-פיטרס:

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") as string,
      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;
להצגת דוגמה

כדאי לנסות דוגמה