انواع نقشه

پلتفرم را انتخاب کنید: Android iOS JavaScript

این سند انواع نقشه هایی را که می توانید با استفاده از Maps JavaScript API نمایش دهید، مورد بحث قرار می دهد. API از یک شی MapType برای نگهداری اطلاعات در مورد این نقشه ها استفاده می کند. MapType رابطی است که نمایش و استفاده از کاشی های نقشه و ترجمه سیستم های مختصات را از مختصات صفحه به مختصات جهانی (روی نقشه) تعریف می کند. هر MapType باید شامل چند روش برای رسیدگی به بازیابی و رهاسازی کاشی ها و ویژگی هایی باشد که رفتار بصری آن را مشخص می کند.

عملکرد داخلی انواع نقشه در Maps JavaScript API یک موضوع پیشرفته است. اکثر توسعه دهندگان می توانند از انواع نقشه های اصلی که در زیر ذکر شده است استفاده کنند. با این حال، همچنین می‌توانید ارائه انواع نقشه‌های موجود را با استفاده از Styled Maps تغییر دهید یا کاشی‌های نقشه خود را با استفاده از انواع نقشه سفارشی تعریف کنید. هنگام ارائه انواع نقشه های سفارشی، باید بدانید که چگونه رجیستری نوع نقشه نقشه را تغییر دهید.

انواع نقشه های اساسی

چهار نوع نقشه در Maps JavaScript API موجود است. علاوه بر کاشی های آشنای نقشه راه "نقاشی شده"، Maps JavaScript API از انواع دیگر نقشه ها نیز پشتیبانی می کند.

انواع نقشه های زیر در Maps JavaScript API موجود است:

  • roadmap نمای پیش فرض نقشه راه را نمایش می دهد. این نوع نقشه پیش فرض است.
  • satellite تصاویر ماهواره ای Google Earth را نمایش می دهد.
  • hybrid ترکیبی از نمای عادی و ماهواره ای را نمایش می دهد.
  • terrain یک نقشه فیزیکی را بر اساس اطلاعات زمین نمایش می دهد.

شما نوع نقشه مورد استفاده Map را با تنظیم ویژگی mapTypeId آن، یا در سازنده با تنظیم شی 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 با استفاده از یک شناسه تنظیم می کنید. Maps JavaScript API از یک رجیستری نوع نقشه، که در زیر توضیح داده شده است، برای مدیریت این مراجع استفاده می کند.

تصویر 45 درجه

Maps JavaScript API از تصاویر 45 درجه ویژه برای مکان‌های خاص پشتیبانی می‌کند. این تصاویر با وضوح بالا نماهای پرسپکتیو را به سمت هر یک از جهت های اصلی (شمال، جنوب، شرق، غرب) ارائه می دهد. این تصاویر در سطوح بزرگنمایی بالاتر برای انواع نقشه های پشتیبانی شده در دسترس هستند.

تصویر زیر نمای 45 درجه ای از شهر نیویورک را نشان می دهد:

انواع نقشه های satellite و hybrid از تصاویر 45 درجه در سطوح زوم بالا (12 و بیشتر) در صورت وجود پشتیبانی می کنند. اگر کاربر در مکانی بزرگنمایی کند که چنین تصاویری برای آن وجود دارد، این نوع نقشه ها به طور خودکار نماهای خود را به روش زیر تغییر می دهند:

  • تصاویر ماهواره‌ای یا ترکیبی با تصاویری جایگزین می‌شوند که پرسپکتیو 45 درجه را با مرکز مکان فعلی ارائه می‌دهند. به طور پیش فرض، چنین نماهایی به سمت شمال جهت گیری می شوند. اگر کاربر کوچک‌نمایی کند، تصاویر ماهواره‌ای یا ترکیبی پیش‌فرض دوباره ظاهر می‌شوند. این رفتار بسته به سطح زوم و مقدار tilt متفاوت است:
    • بین سطوح زوم 12 و 18، نقشه پایه از بالا به پایین (0 درجه) به طور پیش فرض نمایش داده می شود مگر اینکه tilt روی 45 تنظیم شده باشد.
    • در سطوح زوم 18 یا بیشتر، نقشه پایه 45 درجه نمایش داده می شود مگر اینکه tilt روی 0 تنظیم شده باشد.
  • کنترل چرخش قابل مشاهده می شود. کنترل چرخش گزینه هایی را ارائه می دهد که کاربر را قادر می سازد شیب را تغییر دهد و نما را با افزایش 90 درجه در هر جهت بچرخاند. برای پنهان کردن کنترل چرخش، rotateControl روی false قرار دهید.

بزرگنمایی از یک نوع نقشه که تصاویر 45 درجه را نشان می دهد، هر یک از این تغییرات را برمی گرداند و انواع نقشه اصلی را دوباره ایجاد می کند.

تصویر 45 درجه را فعال و غیرفعال کنید

می توانید با فراخوانی setTilt(0) روی شی Map تصویر 45 درجه را غیرفعال کنید. برای فعال کردن تصاویر 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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

مشاهده نمونه

چرخش 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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

مشاهده نمونه

رجیستری نوع نقشه را تغییر دهید

mapTypeId نقشه یک شناسه رشته ای است که برای مرتبط کردن MapType با یک مقدار منحصر به فرد استفاده می شود. هر شی Map یک MapTypeRegistry دارد که شامل مجموعه MapType های موجود برای آن نقشه است. از این رجیستری برای انتخاب انواع نقشه هایی که در کنترل MapType Maps موجود هستند، استفاده می شود.

شما مستقیماً از رجیستری نوع نقشه نمی خوانید. در عوض، رجیستری را با اضافه کردن انواع نقشه های سفارشی و مرتبط کردن آنها با یک شناسه رشته دلخواه تغییر می دهید. شما نمی توانید انواع اصلی نقشه را تغییر دهید یا تغییر دهید (البته می توانید با تغییر ظاهر نقشه 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 فقط بر نوع نقشه roadmap پیش فرض تأثیر می گذارد.

برای اطلاعات بیشتر در مورد StyledMapType ، به استفاده از اعلان‌های سبک JSON تعبیه‌شده مراجعه کنید.

انواع نقشه سفارشی

Maps JavaScript API از نمایش و مدیریت انواع نقشه‌های سفارشی پشتیبانی می‌کند و به شما امکان می‌دهد تصاویر نقشه یا پوشش‌های کاشی خود را پیاده‌سازی کنید.

چندین پیاده سازی ممکن از نوع نقشه در Maps JavaScript API وجود دارد:

  • مجموعه‌های کاشی استاندارد متشکل از تصاویری که در مجموع نقشه‌های کامل نقشه‌کشی را تشکیل می‌دهند. این مجموعه کاشی ها به عنوان انواع نقشه های پایه نیز شناخته می شوند. این انواع نقشه مانند انواع نقشه های پیش فرض موجود عمل می کنند و رفتار می کنند: roadmap ، satellite ، hybrid و terrain . می توانید نوع نقشه سفارشی خود را به آرایه mapTypes Map اضافه کنید تا به رابط کاربری در Maps JavaScript API اجازه دهید تا نوع نقشه سفارشی شما را به عنوان یک نوع نقشه استاندارد در نظر بگیرد (مثلاً با قرار دادن آن در کنترل MapType).
  • پوشش‌های کاشی تصویری که در بالای انواع نقشه پایه موجود نمایش داده می‌شوند. به طور کلی، این انواع نقشه برای تقویت یک نوع نقشه موجود برای نمایش اطلاعات اضافی استفاده می شود و اغلب به مکان های خاص و/یا سطوح زوم محدود می شود. توجه داشته باشید که این کاشی‌ها ممکن است شفاف باشند و به شما امکان می‌دهند ویژگی‌هایی را به نقشه‌های موجود اضافه کنید.
  • انواع نقشه های غیر تصویری، که به شما امکان می دهد نمایش اطلاعات نقشه را در اساسی ترین سطح آن دستکاری کنید.

هر یک از این گزینه ها متکی به ایجاد کلاسی است که رابط MapType را پیاده سازی می کند. علاوه بر این، کلاس ImageMapType برخی رفتارهای داخلی را برای ساده سازی ایجاد انواع نقشه های تصویری ارائه می دهد.

رابط MapType

قبل از ایجاد کلاس‌هایی که MapType را پیاده‌سازی می‌کنند، مهم است که بدانید Google Maps چگونه مختصات را تعیین می‌کند و تصمیم می‌گیرد کدام قسمت‌های نقشه را نشان دهد. شما باید منطق مشابهی را برای هر نوع نقشه پایه یا پوششی پیاده سازی کنید. راهنمای مختصات نقشه و کاشی را بخوانید.

انواع نقشه های سفارشی باید رابط MapType پیاده سازی کنند. این رابط ویژگی‌ها و روش‌های خاصی را مشخص می‌کند که به API اجازه می‌دهد زمانی که API تشخیص می‌دهد که باید کاشی‌های نقشه را در نمای فعلی و سطح زوم نمایش دهد، درخواست‌هایی را برای نوع(های) نقشه شما آغاز کند. شما با این درخواست ها تصمیم می گیرید کدام کاشی را بارگیری کنید.

توجه : می توانید کلاس خود را برای پیاده سازی این رابط ایجاد کنید. از طرف دیگر، اگر تصاویر سازگار دارید، می توانید از کلاس ImageMapType استفاده کنید که قبلاً این رابط را پیاده سازی می کند.

کلاس هایی که رابط MapType را پیاده سازی می کنند نیاز دارند که ویژگی های زیر را تعریف و پر کنید:

  • tileSize (الزامی) اندازه کاشی (از نوع google.maps.Size ) را مشخص می کند. اندازه ها باید مستطیل شکل باشند، اگرچه نیازی به مربع ندارند.
  • maxZoom (الزامی) حداکثر سطح بزرگنمایی را برای نمایش کاشی های این نوع نقشه مشخص می کند.
  • minZoom (اختیاری) حداقل سطح بزرگنمایی را برای نمایش کاشی از این نوع نقشه مشخص می کند. به طور پیش فرض، این مقدار 0 است که نشان می دهد حداقل سطح بزرگنمایی وجود ندارد.
  • name (اختیاری) نام این نوع نقشه را مشخص می کند. این ویژگی فقط در صورتی ضروری است که بخواهید این نوع نقشه در یک کنترل MapType قابل انتخاب باشد. ( گزینه های کنترل را ببینید.)
  • alt (اختیاری) متن جایگزین را برای این نوع نقشه مشخص می کند که به عنوان متن شناور نمایش داده می شود. این ویژگی فقط در صورتی ضروری است که بخواهید این نوع نقشه در یک کنترل MapType قابل انتخاب باشد. ( گزینه های کنترل را ببینید.)

علاوه بر این، کلاس هایی که رابط MapType را پیاده سازی می کنند، باید متدهای زیر را پیاده سازی کنند:

  • getTile() (الزامی) زمانی فراخوانی می شود که API تشخیص دهد که نقشه نیاز به نمایش کاشی های جدید برای نمای داده شده دارد. متد getTile() باید دارای امضای زیر باشد:

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

    API تعیین می کند که آیا نیاز به فراخوانی getTile() بر اساس ویژگی های tileSize ، minZoom ، و maxZoom MapType و نمای فعلی نقشه و سطح زوم است. کنترل‌کننده این روش باید یک عنصر HTML را با توجه به مختصات، سطح بزرگ‌نمایی و عنصر DOM برگرداند تا تصویر کاشی را به آن اضافه کند.

  • releaseTile() (اختیاری) زمانی فراخوانی می شود که API تشخیص دهد که نقشه باید یک کاشی را حذف کند زیرا از دید خارج می شود. این روش باید دارای امضای زیر باشد:

    releaseTile(tile:Node)

    شما معمولاً باید پس از اضافه شدن به نقشه، تمام عناصری را که به کاشی های نقشه متصل شده اند حذف کنید. برای مثال، اگر شنونده‌های رویداد را به همپوشانی‌های کاشی نقشه پیوست کرده‌اید، باید آنها را از اینجا حذف کنید.

متد getTile() به عنوان کنترل‌کننده اصلی برای تعیین اینکه کدام کاشی‌ها در یک Viewport بارگذاری شوند، عمل می‌کند.

انواع نقشه پایه

انواع نقشه‌هایی که به این روش می‌سازید ممکن است به تنهایی یا با دیگر انواع نقشه‌ها به عنوان همپوشانی ترکیب شوند. انواع نقشه های مستقل به عنوان انواع نقشه پایه شناخته می شوند. ممکن است بخواهید که 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;

جاوا اسکریپت

/*
 * 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;
مشاهده نمونه

Sample را امتحان کنید

انواع نقشه روکش

برخی از انواع نقشه برای کار بر روی انواع نقشه های موجود طراحی شده اند. این گونه نقشه ها ممکن است لایه های شفافی داشته باشند که نقاط مورد علاقه را نشان می دهد یا داده های اضافی را به کاربر نشان می دهد.

در این موارد، شما نمی خواهید که نوع نقشه به عنوان یک موجودیت جداگانه در نظر گرفته شود، بلکه به عنوان یک پوشش. می توانید این کار را با افزودن نوع نقشه به MapType موجود مستقیماً با استفاده از ویژگی overlayMapTypes Map انجام دهید. این ویژگی حاوی یک MVCArray از MapType s است. همه انواع نقشه (پایه و روکش) در لایه 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;

جاوا اسکریپت

/*
 * 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;
مشاهده نمونه

Sample را امتحان کنید

انواع نقشه های تصویری

پیاده سازی MapType برای عمل به عنوان یک نوع نقشه پایه می تواند یک کار وقت گیر و پر زحمت باشد. API کلاس خاصی را ارائه می‌کند که رابط MapType را برای رایج‌ترین انواع نقشه پیاده‌سازی می‌کند: انواع نقشه که از کاشی‌هایی تشکیل شده از فایل‌های تصویری منفرد تشکیل شده‌اند.

این کلاس، کلاس ImageMapType ، با استفاده از مشخصات شی ImageMapTypeOptions که ویژگی های مورد نیاز زیر را تعریف می کند، ساخته می شود:

  • tileSize (الزامی) اندازه کاشی (از نوع google.maps.Size ) را مشخص می کند. اندازه ها باید مستطیل شکل باشند، اگرچه نیازی به مربع ندارند.
  • getTileUrl (الزامی) تابعی را مشخص می‌کند که معمولاً به‌عنوان یک تابع درون خطی به صورت تحت اللفظی ارائه می‌شود، تا انتخاب کاشی تصویر مناسب را بر اساس مختصات جهان ارائه‌شده و سطح بزرگ‌نمایی انجام دهد.

کد زیر یک ImageMapType اولیه را با استفاده از کاشی های ماه گوگل پیاده سازی می کند. این مثال از یک تابع عادی سازی استفاده می کند تا اطمینان حاصل شود که کاشی ها در امتداد محور 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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

پیش بینی ها

زمین یک کره سه بعدی (تقریبا) است، در حالی که نقشه یک سطح دو بعدی صاف است. نقشه ای که در Maps JavaScript API مشاهده می کنید، مانند هر نقشه مسطحی از زمین، نمایش آن کره بر روی یک سطح صاف است. در ساده ترین عبارت، یک طرح ریزی را می توان به عنوان نگاشت مقادیر طول و عرض جغرافیایی به مختصات روی نقشه طرح ریزی تعریف کرد.

پیش‌بینی‌ها در Maps JavaScript API باید رابط Projection را پیاده‌سازی کنند. یک پیاده سازی Projection باید نه تنها یک نقشه برداری از یک سیستم مختصات به سیستم دیگر، بلکه یک نقشه برداری دو طرفه را نیز ارائه دهد. یعنی باید نحوه ترجمه از مختصات زمین (اشیاء LatLng ) به سیستم مختصات جهانی کلاس Projection و از سیستم مختصات جهان به مختصات زمین را تعریف کنید. Google Maps از طرح Mercator برای ایجاد نقشه های خود از داده های جغرافیایی و تبدیل رویدادهای روی نقشه به مختصات جغرافیایی استفاده می کند. شما می توانید با فراخوانی getProjection() روی Map (یا هر نوع از انواع MapType پایه استاندارد) این Projection را بدست آورید.

اجرای یک پروجکشن

هنگام اجرای یک طرح سفارشی، باید چند چیز را تعریف کنید:

  • فرمول های نگاشت مختصات طول و عرض جغرافیایی به یک صفحه دکارتی و فرمول های مربوطه برای نگاشت از صفحه دکارتی به مختصات طول و عرض جغرافیایی. (رابط Projection فقط از تبدیل به مختصات مستطیلی پشتیبانی می کند.)
  • اندازه کاشی پایه تمام کاشی ها باید مستطیل شکل باشند.
  • "اندازه جهانی" نقشه با استفاده از کاشی پایه در سطح زوم 0 تنظیم شده است. توجه داشته باشید که برای نقشه هایی که از یک کاشی با بزرگنمایی 0 تشکیل شده اند، اندازه جهانی و اندازه کاشی پایه یکسان است.

هماهنگی تحولات در پیش بینی ها

هر طرح دو روش را ارائه می دهد که بین این دو سیستم مختصات ترجمه می شود و به شما امکان می دهد بین مختصات جغرافیایی و جهانی تبدیل کنید:

  • متد Projection.fromLatLngToPoint() یک مقدار LatLng به یک مختصات جهانی تبدیل می کند. این روش برای قرار دادن همپوشانی ها روی نقشه (و موقعیت خود نقشه) استفاده می شود.
  • متد Projection.fromPointToLatLng() یک مختصات جهانی را به مقدار LatLng تبدیل می کند. این روش برای تبدیل رویدادهایی مانند کلیک هایی که روی نقشه اتفاق می افتد به مختصات جغرافیایی استفاده می شود.

نقشه های گوگل فرض می کند که پیش بینی ها مستطیل هستند.

به طور کلی، شما ممکن است از یک طرح برای دو مورد استفاده کنید: برای ایجاد یک نقشه از جهان، یا برای ایجاد یک نقشه از یک منطقه محلی. در حالت اول، باید اطمینان حاصل کنید که طرح شما در تمام طول‌های جغرافیایی مستطیل و نرمال است. برخی از برجستگی ها (به ویژه برآمدگی های مخروطی) ممکن است "به صورت محلی عادی" باشند (یعنی نقطه شمال) اما از شمال واقعی منحرف شوند. برای مثال، هر چه نقشه نسبت به طول جغرافیایی مرجع بیشتر قرار گیرد. شما ممکن است از چنین طرح ریزی به صورت محلی استفاده کنید، اما توجه داشته باشید که طرح ریزی لزوماً نادقیق است و خطاهای تبدیل ظاهراً هر چه از طول جغرافیایی مرجع منحرف می شوید بیشتر می شود.

انتخاب کاشی نقشه در پیش بینی ها

پیش بینی ها نه تنها برای تعیین موقعیت مکان ها یا پوشش ها، بلکه برای تعیین موقعیت خود کاشی های نقشه مفید هستند. Maps JavaScript API نقشه‌های پایه را با استفاده از رابط 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
const mapElement = document.querySelector("gmp-map") as google.maps.MapElement;
let innerMap;

async function initMap() {
  // Request the needed libraries.
  await google.maps.importLibrary("maps");

  // Create a map.
  innerMap = mapElement.innerMap;
  innerMap.setOptions({
    mapTypeControl: false,
  });

  // Set the Gall-Peters map type.
  initGallPeters();
  innerMap.mapTypes.set("gallPeters", gallPetersMapType);
  innerMap.setMapTypeId("gallPeters");

  // Show the lat and lng under the mouse cursor.
  const coordsDiv = document.getElementById("coords") as HTMLElement;

  innerMap.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.
  innerMap.data.setStyle((feature) => {
    return {
      title: feature.getProperty("name") as string,
      optimized: false,
    };
  });
  innerMap.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 (
        "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" },
    },
  ],
};

initMap();

جاوا اسکریپت

// This example defines an image map type using the Gall-Peters
// projection.
// https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection
const mapElement = document.querySelector("gmp-map");
let innerMap;
async function initMap() {
    // Request the needed libraries.
    await google.maps.importLibrary("maps");
    // Create a map.
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });
    // Set the Gall-Peters map type.
    initGallPeters();
    innerMap.mapTypes.set("gallPeters", gallPetersMapType);
    innerMap.setMapTypeId("gallPeters");
    // Show the lat and lng under the mouse cursor.
    const coordsDiv = document.getElementById("coords");
    innerMap.addListener("mousemove", (event) => {
        coordsDiv.textContent =
            "lat: " +
                Math.round(event.latLng.lat()) +
                ", " +
                "lng: " +
                Math.round(event.latLng.lng());
    });
    // Add some markers to the map.
    innerMap.data.setStyle((feature) => {
        return {
            title: feature.getProperty("name"),
            optimized: false,
        };
    });
    innerMap.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 ("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" },
        },
    ],
};
initMap();
مشاهده نمونه

Sample را امتحان کنید

،
پلتفرم را انتخاب کنید: Android iOS JavaScript

این سند انواع نقشه هایی را که می توانید با استفاده از Maps JavaScript API نمایش دهید، مورد بحث قرار می دهد. API از یک شی MapType برای نگهداری اطلاعات در مورد این نقشه ها استفاده می کند. MapType رابطی است که نمایش و استفاده از کاشی های نقشه و ترجمه سیستم های مختصات را از مختصات صفحه به مختصات جهانی (روی نقشه) تعریف می کند. هر MapType باید شامل چند روش برای رسیدگی به بازیابی و رهاسازی کاشی ها و ویژگی هایی باشد که رفتار بصری آن را مشخص می کند.

عملکرد داخلی انواع نقشه در Maps JavaScript API یک موضوع پیشرفته است. اکثر توسعه دهندگان می توانند از انواع نقشه های اصلی که در زیر ذکر شده است استفاده کنند. با این حال، همچنین می‌توانید ارائه انواع نقشه‌های موجود را با استفاده از Styled Maps تغییر دهید یا کاشی‌های نقشه خود را با استفاده از انواع نقشه سفارشی تعریف کنید. هنگام ارائه انواع نقشه های سفارشی، باید بدانید که چگونه رجیستری نوع نقشه نقشه را تغییر دهید.

انواع نقشه های اساسی

چهار نوع نقشه در Maps JavaScript API موجود است. علاوه بر کاشی های آشنای نقشه راه "نقاشی شده"، Maps JavaScript API از انواع دیگر نقشه ها نیز پشتیبانی می کند.

انواع نقشه های زیر در Maps JavaScript API موجود است:

  • roadmap نمای پیش فرض نقشه راه را نمایش می دهد. این نوع نقشه پیش فرض است.
  • satellite تصاویر ماهواره ای Google Earth را نمایش می دهد.
  • hybrid ترکیبی از نمای عادی و ماهواره ای را نمایش می دهد.
  • terrain یک نقشه فیزیکی را بر اساس اطلاعات زمین نمایش می دهد.

شما نوع نقشه مورد استفاده Map را با تنظیم ویژگی mapTypeId آن، یا در سازنده با تنظیم شی 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 با استفاده از یک شناسه تنظیم می کنید. Maps JavaScript API از یک رجیستری نوع نقشه، که در زیر توضیح داده شده است، برای مدیریت این مراجع استفاده می کند.

تصویر 45 درجه

Maps JavaScript API از تصاویر 45 درجه ویژه برای مکان‌های خاص پشتیبانی می‌کند. این تصاویر با وضوح بالا نماهای پرسپکتیو را به سمت هر یک از جهت های اصلی (شمال، جنوب، شرق، غرب) ارائه می دهد. این تصاویر در سطوح بزرگنمایی بالاتر برای انواع نقشه های پشتیبانی شده در دسترس هستند.

تصویر زیر نمای 45 درجه ای از شهر نیویورک را نشان می دهد:

انواع نقشه های satellite و hybrid از تصاویر 45 درجه در سطوح زوم بالا (12 و بیشتر) در صورت وجود پشتیبانی می کنند. اگر کاربر در مکانی بزرگنمایی کند که چنین تصاویری برای آن وجود دارد، این نوع نقشه ها به طور خودکار نماهای خود را به روش زیر تغییر می دهند:

  • تصاویر ماهواره‌ای یا ترکیبی با تصاویری جایگزین می‌شوند که پرسپکتیو 45 درجه را با مرکز مکان فعلی ارائه می‌دهند. به طور پیش فرض، چنین نماهایی به سمت شمال جهت گیری می شوند. اگر کاربر کوچک‌نمایی کند، تصاویر ماهواره‌ای یا ترکیبی پیش‌فرض دوباره ظاهر می‌شوند. این رفتار بسته به سطح زوم و مقدار tilt متفاوت است:
    • بین سطوح زوم 12 و 18، نقشه پایه از بالا به پایین (0 درجه) به طور پیش فرض نمایش داده می شود مگر اینکه tilt روی 45 تنظیم شده باشد.
    • در سطوح زوم 18 یا بیشتر، نقشه پایه 45 درجه نمایش داده می شود مگر اینکه tilt روی 0 تنظیم شده باشد.
  • کنترل چرخش قابل مشاهده می شود. کنترل چرخش گزینه هایی را ارائه می دهد که کاربر را قادر می سازد شیب را تغییر دهد و نما را با افزایش 90 درجه در هر جهت بچرخاند. برای پنهان کردن کنترل چرخش، rotateControl روی false قرار دهید.

بزرگنمایی از یک نوع نقشه که تصاویر 45 درجه را نشان می دهد، هر یک از این تغییرات را برمی گرداند و انواع نقشه اصلی را دوباره ایجاد می کند.

تصویر 45 درجه را فعال و غیرفعال کنید

می توانید با فراخوانی setTilt(0) روی شی Map تصویر 45 درجه را غیرفعال کنید. برای فعال کردن تصاویر 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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

مشاهده نمونه

چرخش 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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

مشاهده نمونه

رجیستری نوع نقشه را تغییر دهید

mapTypeId نقشه یک شناسه رشته ای است که برای مرتبط کردن MapType با یک مقدار منحصر به فرد استفاده می شود. هر شی Map یک MapTypeRegistry دارد که شامل مجموعه MapType های موجود برای آن نقشه است. از این رجیستری برای انتخاب انواع نقشه هایی که در کنترل MapType Maps موجود هستند، استفاده می شود.

شما مستقیماً از رجیستری نوع نقشه نمی خوانید. در عوض، رجیستری را با اضافه کردن انواع نقشه های سفارشی و مرتبط کردن آنها با یک شناسه رشته دلخواه تغییر می دهید. شما نمی توانید انواع اصلی نقشه را تغییر دهید یا تغییر دهید (البته می توانید با تغییر ظاهر نقشه 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 فقط بر نوع نقشه roadmap پیش فرض تأثیر می گذارد.

برای اطلاعات بیشتر در مورد StyledMapType ، به استفاده از اعلان‌های سبک JSON تعبیه‌شده مراجعه کنید.

انواع نقشه سفارشی

Maps JavaScript API از نمایش و مدیریت انواع نقشه‌های سفارشی پشتیبانی می‌کند و به شما امکان می‌دهد تصاویر نقشه یا پوشش‌های کاشی خود را پیاده‌سازی کنید.

چندین پیاده سازی ممکن از نوع نقشه در Maps JavaScript API وجود دارد:

  • مجموعه‌های کاشی استاندارد متشکل از تصاویری که در مجموع نقشه‌های کامل نقشه‌کشی را تشکیل می‌دهند. این مجموعه کاشی ها به عنوان انواع نقشه های پایه نیز شناخته می شوند. این انواع نقشه مانند انواع نقشه های پیش فرض موجود عمل می کنند و رفتار می کنند: roadmap ، satellite ، hybrid و terrain . می توانید نوع نقشه سفارشی خود را به آرایه mapTypes Map اضافه کنید تا به رابط کاربری در Maps JavaScript API اجازه دهید تا نوع نقشه سفارشی شما را به عنوان یک نوع نقشه استاندارد در نظر بگیرد (مثلاً با قرار دادن آن در کنترل MapType).
  • پوشش‌های کاشی تصویری که در بالای انواع نقشه پایه موجود نمایش داده می‌شوند. به طور کلی، این انواع نقشه برای تقویت یک نوع نقشه موجود برای نمایش اطلاعات اضافی استفاده می شود و اغلب به مکان های خاص و/یا سطوح زوم محدود می شود. توجه داشته باشید که این کاشی‌ها ممکن است شفاف باشند و به شما امکان می‌دهند ویژگی‌هایی را به نقشه‌های موجود اضافه کنید.
  • انواع نقشه های غیر تصویری، که به شما امکان می دهد نمایش اطلاعات نقشه را در اساسی ترین سطح آن دستکاری کنید.

هر یک از این گزینه ها متکی به ایجاد کلاسی است که رابط MapType را پیاده سازی می کند. علاوه بر این، کلاس ImageMapType برخی رفتارهای داخلی را برای ساده سازی ایجاد انواع نقشه های تصویری ارائه می دهد.

رابط MapType

قبل از ایجاد کلاس‌هایی که MapType را پیاده‌سازی می‌کنند، مهم است که بدانید Google Maps چگونه مختصات را تعیین می‌کند و تصمیم می‌گیرد کدام قسمت‌های نقشه را نشان دهد. شما باید منطق مشابهی را برای هر نوع نقشه پایه یا پوششی پیاده سازی کنید. راهنمای مختصات نقشه و کاشی را بخوانید.

انواع نقشه های سفارشی باید رابط MapType پیاده سازی کنند. این رابط ویژگی‌ها و روش‌های خاصی را مشخص می‌کند که به API اجازه می‌دهد زمانی که API تشخیص می‌دهد که باید کاشی‌های نقشه را در نمای فعلی و سطح زوم نمایش دهد، درخواست‌هایی را برای نوع(های) نقشه شما آغاز کند. شما با این درخواست ها تصمیم می گیرید کدام کاشی را بارگیری کنید.

توجه : می توانید کلاس خود را برای پیاده سازی این رابط ایجاد کنید. از طرف دیگر، اگر تصاویر سازگار دارید، می توانید از کلاس ImageMapType استفاده کنید که قبلاً این رابط را پیاده سازی می کند.

کلاس هایی که رابط MapType را پیاده سازی می کنند نیاز دارند که ویژگی های زیر را تعریف و پر کنید:

  • tileSize (الزامی) اندازه کاشی (از نوع google.maps.Size ) را مشخص می کند. اندازه ها باید مستطیل شکل باشند، اگرچه نیازی به مربع ندارند.
  • maxZoom (الزامی) حداکثر سطح بزرگنمایی را برای نمایش کاشی های این نوع نقشه مشخص می کند.
  • minZoom (اختیاری) حداقل سطح بزرگنمایی را برای نمایش کاشی از این نوع نقشه مشخص می کند. به طور پیش فرض، این مقدار 0 است که نشان می دهد حداقل سطح بزرگنمایی وجود ندارد.
  • name (اختیاری) نام این نوع نقشه را مشخص می کند. این ویژگی فقط در صورتی ضروری است که بخواهید این نوع نقشه در یک کنترل MapType قابل انتخاب باشد. ( گزینه های کنترل را ببینید.)
  • alt (اختیاری) متن جایگزین را برای این نوع نقشه مشخص می کند که به عنوان متن شناور نمایش داده می شود. این ویژگی فقط در صورتی ضروری است که بخواهید این نوع نقشه در یک کنترل MapType قابل انتخاب باشد. ( گزینه های کنترل را ببینید.)

علاوه بر این، کلاس هایی که رابط MapType را پیاده سازی می کنند، باید متدهای زیر را پیاده سازی کنند:

  • getTile() (الزامی) زمانی فراخوانی می شود که API تشخیص دهد که نقشه نیاز به نمایش کاشی های جدید برای نمای داده شده دارد. متد getTile() باید دارای امضای زیر باشد:

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

    API تعیین می کند که آیا نیاز به فراخوانی getTile() بر اساس ویژگی های tileSize ، minZoom ، و maxZoom MapType و نمای فعلی نقشه و سطح زوم است. کنترل‌کننده این روش باید یک عنصر HTML را با توجه به مختصات، سطح بزرگ‌نمایی و عنصر DOM برگرداند تا تصویر کاشی را به آن اضافه کند.

  • releaseTile() (اختیاری) زمانی فراخوانی می شود که API تشخیص دهد که نقشه باید یک کاشی را حذف کند زیرا از دید خارج می شود. این روش باید دارای امضای زیر باشد:

    releaseTile(tile:Node)

    شما معمولاً باید پس از اضافه شدن به نقشه، تمام عناصری را که به کاشی های نقشه متصل شده اند حذف کنید. برای مثال، اگر شنونده‌های رویداد را به همپوشانی‌های کاشی نقشه پیوست کرده‌اید، باید آنها را از اینجا حذف کنید.

متد getTile() به عنوان کنترل‌کننده اصلی برای تعیین اینکه کدام کاشی‌ها در یک Viewport بارگذاری شوند، عمل می‌کند.

انواع نقشه پایه

انواع نقشه‌هایی که به این روش می‌سازید ممکن است به تنهایی یا با دیگر انواع نقشه‌ها به عنوان همپوشانی ترکیب شوند. انواع نقشه های مستقل به عنوان انواع نقشه پایه شناخته می شوند. ممکن است بخواهید که 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;

جاوا اسکریپت

/*
 * 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;
مشاهده نمونه

Sample را امتحان کنید

انواع نقشه روکش

برخی از انواع نقشه برای کار بر روی انواع نقشه های موجود طراحی شده اند. این گونه نقشه ها ممکن است لایه های شفافی داشته باشند که نقاط مورد علاقه را نشان می دهد یا داده های اضافی را به کاربر نشان می دهد.

در این موارد، شما نمی خواهید که نوع نقشه به عنوان یک موجودیت جداگانه در نظر گرفته شود، بلکه به عنوان یک پوشش. می توانید این کار را با افزودن نوع نقشه به MapType موجود مستقیماً با استفاده از ویژگی overlayMapTypes Map انجام دهید. این ویژگی حاوی یک MVCArray از MapType s است. همه انواع نقشه (پایه و روکش) در لایه mapPane ارائه می شوند. Overlay map types will display on top of the base map they are attached to, in the order in which they appear in the Map.overlayMapTypes array (overlays with higher index values are displayed in front of overlays with lower index values).

The following example is identical to the previous one except that we've created a tile overlay MapType on top of the ROADMAP map type:

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;

جاوا اسکریپت

/*
 * 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;
مشاهده نمونه

Sample را امتحان کنید

Image Map Types

Implementing a MapType to act as a base map type can be a time-consuming and laborious task. The API provides a special class that implements the MapType interface for the most common map types: map types that consist of tiles made up of single image files.

This class, the ImageMapType class, is constructed using an ImageMapTypeOptions object specification defining the following required properties:

  • tileSize (required) specifies the size of the tile (of type google.maps.Size ). Sizes must be rectangular though they need not be square.
  • getTileUrl (required) specifies the function, usually provided as an inline function literal, to handle selection of the proper image tile based on supplied world coordinates and zoom level.

The following code implements a basic ImageMapType using Google's moon tiles. The example makes use of a normalization function to ensure that tiles repeat along the x-axis, but not along the y-axis of your map.

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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

پیش بینی ها

The Earth is a three-dimensional sphere (approximately), while a map is a flat two-dimensional surface. The map that you see within the Maps JavaScript API, like any flat map of the Earth, is a projection of that sphere onto a flat surface. In its simplest terms, a projection can be defined as a mapping of latitude/longitude values into coordinates on the projection's map.

Projections in the Maps JavaScript API must implement the Projection interface. A Projection implementation must provide not only a mapping from one coordinate system to another, but a bi-directional mapping. That is, you must define how to translate from Earth coordinates ( LatLng objects) to the Projection class's world coordinate system, and from the world coordinate system back to the Earth coordinates. Google Maps uses the Mercator projection to create its maps from geographic data and convert events on the map into geographic coordinates. You can obtain this projection by calling getProjection() on the Map (or any of the standard base MapType types.) For most uses, this standard Projection will suffice, but you may also define and use your own custom projections.

Implement a Projection

When implementing a custom projection, you will need to define a few things:

  • The formulae for mapping latitude and longitude coordinates into a Cartesian plane and the corresponding formulae for mapping from a Cartesian plane to latitude and longitude coordinates. (The Projection interface only supports transformations into rectilinear coordinates.)
  • The base tile size. All tiles must be rectangular.
  • The "world size" of a map using the base tile set at zoom level 0. Note that for maps consisting of one tile at zoom 0, the world size and base tile size are identical.

Coordinate Transformations in Projections

Each projection provides two methods which translate between these two coordinate systems, allowing you to convert between geographic and world coordinates:

  • The Projection.fromLatLngToPoint() method converts a LatLng value into a world coordinate. This method is used to position overlays on the map (and to position the map itself).
  • The Projection.fromPointToLatLng() method converts a world coordinate into a LatLng value. This method is used to convert events such as clicks that happen on the map into geographic coordinates.

Google Maps assumes that projections are rectilinear.

Generally, you may use a projection for two cases: to create a map of the world, or to create a map of a local area. In the former case, you should ensure that your projection is also rectilinear and normal at all longitudes. Some projections (especially conic projections) may be "locally normal" (ie point north) but deviate from true north; for example, the further the map is positioned relative to some reference longitude. You may use such a projection locally, but be aware that the projection is necessarily imprecise and transformation errors will become increasingly apparently the further away from the reference longitude you deviate.

Map Tile Selection in Projections

Projections are not only useful for determining the positions of locations or overlays, but for positioning the map tiles themselves. The Maps JavaScript API renders base maps using a MapType interface, which must declare both a projection property for identifying the map's projection and a getTile() method for retrieving map tiles based on tile coordinate values. Tile coordinates are based on both your basic tile size (which must be rectangular) and the "world size" of your map, which is the pixel size of your map world at zoom level 0. (For maps consisting of one tile at zoom 0, the tile size and world size are identical.)

You define the base tile size within your MapType 's tileSize property. You define the world size implicitly within your projection's fromLatLngToPoint() and fromPointToLatLng() methods.

Since image selection depends on these passed values, it is useful to name images that can be selected programmatically given those passed values, such as map _ zoom _ tileX _ tileY .png .

The following example defines an ImageMapType using the Gall-Peters projection:

TypeScript

// This example defines an image map type using the Gall-Peters
// projection.
// https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection
const mapElement = document.querySelector("gmp-map") as google.maps.MapElement;
let innerMap;

async function initMap() {
  // Request the needed libraries.
  await google.maps.importLibrary("maps");

  // Create a map.
  innerMap = mapElement.innerMap;
  innerMap.setOptions({
    mapTypeControl: false,
  });

  // Set the Gall-Peters map type.
  initGallPeters();
  innerMap.mapTypes.set("gallPeters", gallPetersMapType);
  innerMap.setMapTypeId("gallPeters");

  // Show the lat and lng under the mouse cursor.
  const coordsDiv = document.getElementById("coords") as HTMLElement;

  innerMap.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.
  innerMap.data.setStyle((feature) => {
    return {
      title: feature.getProperty("name") as string,
      optimized: false,
    };
  });
  innerMap.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 (
        "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" },
    },
  ],
};

initMap();

جاوا اسکریپت

// This example defines an image map type using the Gall-Peters
// projection.
// https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection
const mapElement = document.querySelector("gmp-map");
let innerMap;
async function initMap() {
    // Request the needed libraries.
    await google.maps.importLibrary("maps");
    // Create a map.
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });
    // Set the Gall-Peters map type.
    initGallPeters();
    innerMap.mapTypes.set("gallPeters", gallPetersMapType);
    innerMap.setMapTypeId("gallPeters");
    // Show the lat and lng under the mouse cursor.
    const coordsDiv = document.getElementById("coords");
    innerMap.addListener("mousemove", (event) => {
        coordsDiv.textContent =
            "lat: " +
                Math.round(event.latLng.lat()) +
                ", " +
                "lng: " +
                Math.round(event.latLng.lng());
    });
    // Add some markers to the map.
    innerMap.data.setStyle((feature) => {
        return {
            title: feature.getProperty("name"),
            optimized: false,
        };
    });
    innerMap.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 ("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" },
        },
    ],
};
initMap();
مشاهده نمونه

Sample را امتحان کنید

،
Select platform: Android iOS JavaScript

This document discusses the types of maps you can display using the Maps JavaScript API. The API uses a MapType object to hold information about these maps. A MapType is an interface that defines the display and usage of map tiles and the translation of coordinate systems from screen coordinates to world coordinates (on the map). Each MapType must contain a few methods to handle retrieval and release of tiles, and properties that define its visual behavior.

The inner workings of map types within the Maps JavaScript API is an advanced topic. Most developers can use the basic map types noted below. However, you can also modify the presentation of existing map types using Styled Maps or define your own map tiles using custom map types . When providing custom map types, you will need to understand how to modify the map's Map Type Registry .

Basic Map Types

There are four types of maps available within the Maps JavaScript API. In addition to the familiar "painted" road map tiles, the Maps JavaScript API also supports other maps types.

The following map types are available in the Maps JavaScript API:

  • roadmap displays the default road map view. This is the default map type.
  • satellite displays Google Earth satellite images.
  • hybrid displays a mixture of normal and satellite views.
  • terrain displays a physical map based on terrain information.

You modify the map type in use by the Map by setting its mapTypeId property, either within the constructor by setting its Map options object, or by calling the map's setMapTypeId() method. The mapTypeID property defaults to roadmap .

Setting the mapTypeId upon construction:

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);

Modifying the mapTypeId dynamically:

map.setMapTypeId('terrain');

Note that you don't actually set the map's map type directly, but instead set its mapTypeId to reference a MapType using an identifier. The Maps JavaScript API uses a map type registry, explained below, to manage these references.

45° Imagery

The Maps JavaScript API supports special 45° imagery for certain locations. This high-resolution imagery provides perspective views towards each of the cardinal direction (North, South, East, West). These images are available at higher zoom levels for supported map types.

The following image shows a 45° perspective view of New York City:

The satellite and hybrid map types support 45° imagery at high zoom levels (12 and greater) where available. If the user zooms into a location for which such imagery exists, these map types automatically alter their views in the following manner:

  • The satellite or hybrid imagery is replaced with imagery giving a 45° perspective, centered on the current location. By default, such views are oriented towards north. If the user zooms out, the default satellite or hybrid imagery appears again. The behavior varies depending on zoom level and the value of tilt :
    • Between zoom levels 12 and 18 the top-down basemap (0°) displays by default unless tilt is set to 45.
    • At zoom levels of 18 or greater the 45° basemap displays unless tilt is set to 0.
  • The rotate control becomes visible. The rotate control provides options that enable the user to toggle tilt, and to rotate the view in 90° increments in either direction. To hide the rotate control, set rotateControl to false .

Zooming out from a map type displaying 45° imagery reverts each of these changes, re-establishing the original map types.

Enable and Disable 45° Imagery

You can disable 45° imagery by calling setTilt(0) on the Map object. To enable 45° imagery for supported map types, call setTilt(45) . The Map 's getTilt() method will always reflect the current tilt being shown on the map; if you set a tilt on a map and then later remove that tilt (by zooming the map out, for example), the map's getTilt() method will return 0 .

Important: 45° imagery is only supported on raster maps; this imagery cannot be used with vector maps.

The following example displays a 45° view of New York City:

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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

View example .

Rotate 45° Imagery

The 45° imagery actually consists of a collection of images for each cardinal direction (North, South, East, West). Once your map is displaying 45° imagery, you can orient the imagery towards one of its cardinal directions by calling setHeading() on the Map object, passing a number value expressed as degrees from North.

The following example shows an aerial map and auto-rotates the map every 3 seconds when the button is clicked:

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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

View example .

Modify the Map Type Registry

A map's mapTypeId is a string identifier that is used to associate a MapType with a unique value. Each Map object maintains a MapTypeRegistry which contains the collection of available MapType s for that map. This registry is used to select the types of maps which are available in the Map's MapType control, for example.

You don't read directly from the map type registry. Instead, you modify the registry by adding custom map types and associating them with a string identifier of your choosing. You cannot modify or alter the basic map types (though you can remove them from the map by altering the appearance of the map's associated mapTypeControlOptions ).

The following code sets the map to show only two map types in the map's mapTypeControlOptions and modifies the registry to add the association with this identifier to the actual implementation of the MapType interface.

// 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);

Styled Maps

The StyledMapType lets you customize the presentation of the standard Google base maps, changing the visual display of such elements as roads, parks, and built-up areas to reflect a different style than that used in the default map type. The StyledMapType affects only the default roadmap map type.

For more information about the StyledMapType , see Using embedded JSON style declarations .

Custom Map Types

The Maps JavaScript API supports the display and management of custom map types, allowing you to implement your own map imagery or tile overlays.

Several possible map type implementations exist within the Maps JavaScript API:

  • Standard tile sets consisting of images which collectively constitute full cartographic maps. These tile sets are also known as base map types. These map types act and behave like the existing default map types: roadmap , satellite , hybrid and terrain . You can add your custom map type to a Map's mapTypes array to allow the UI within the Maps JavaScript API to treat your custom map type as a standard map type (by including it in the MapType control, for example).
  • Image tile overlays which display on top of existing base map types. Generally, these map types are used to augment an existing map type to display additional information and are often constrained to specific locations and/or zoom levels. Note that these tiles may be transparent, allowing you to add features to existing maps.
  • Non-image map types, which allow you to manipulate the display of map information at its most fundamental level.

Each of these options relies on creating a class that implements the MapType interface. Additionally, the ImageMapType class provides some built-in behavior to simplify the creation of imagery map types.

The MapType Interface

Before you create classes which implement MapType , it is important to understand how Google Maps determines coordinates and decides which parts of the map to show. You need to implement similar logic for any base or overlay map types. Read the guide to map and tile coordinates .

Custom map types must implement the MapType interface. This interface specifies certain properties and methods that allow the API to initiate requests to your map type(s) when the API determines that it needs to display map tiles within the current viewport and zoom level. You handle these requests to decide which tile to load.

Note : You may create your own class to implement this interface. Alternatively, if you have compatible imagery you can use the ImageMapType class which already implements this interface.

Classes implementing the MapType interface require that you define and populate the following properties:

  • tileSize (required) specifies the size of the tile (of type google.maps.Size ). Sizes must be rectangular though they need not be square.
  • maxZoom (required) specifies the maximum zoom level at which to display tiles of this map type.
  • minZoom (optional) specifies the minimum zoom level at which to display tile of this map type. By default, this value is 0 indicating that no minimum zoom level exists.
  • name (optional) specifies the name for this map type. This property is only necessary if you want this map type to be selectable within a MapType control. (See Control Options .)
  • alt (optional) specifies the alternate text for this map type, exhibited as hover text. This property is only necessary if you want this map type to be selectable within a MapType control. (See Control Options .)

Additionally, classes implementing the MapType interface need to implement the following methods:

  • getTile() (required) is called whenever the API determines that the map needs to display new tiles for the given viewport. The getTile() method must have the following signature:

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

    The API determines whether it needs to call getTile() based on the MapType 's tileSize , minZoom , and maxZoom properties and the map's current viewport and zoom level. The handler for this method should return an HTML element given a passed coordinate, zoom level, and DOM element on which to append the tile image.

  • releaseTile() (optional) is called whenever the API determines that the map needs to remove a tile as it falls out of view. This method must have the following signature:

    releaseTile(tile:Node)

    You typically should handle removal of any elements that were attached to the map tiles upon addition to the map. For example, if you attached event listeners to map tile overlays, you should remove them here.

The getTile() method acts as the main controller for determining which tiles to load within a given viewport.

Base Map Types

Map types which you construct in this manner may either stand alone or be combined with other map types as overlays. Standalone map types are known as base map types . You may want to have the API treat such custom MapType s as it would any other existing base map type ( ROADMAP , TERRAIN , etc.). To do so, add your custom MapType to the Map 's mapTypes property. This property is of type MapTypeRegistry .

The following code creates a base MapType to display a map's tile coordinates and draws an outline of the tiles:

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;

جاوا اسکریپت

/*
 * 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;
مشاهده نمونه

Sample را امتحان کنید

Overlay Map Types

Some map types are designed to work on top of existing map types. Such map types may have transparent layers indicating points of interest, or showing additional data to the user.

In these cases, you do not want the map type treated as a separate entity but as an overlay. You can do this by adding the map type to an existing MapType directly using the Map 's overlayMapTypes property. This property contains an MVCArray of MapType s. All map types (base and overlay) are rendered within the mapPane layer. Overlay map types will display on top of the base map they are attached to, in the order in which they appear in the Map.overlayMapTypes array (overlays with higher index values are displayed in front of overlays with lower index values).

The following example is identical to the previous one except that we've created a tile overlay MapType on top of the ROADMAP map type:

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;

جاوا اسکریپت

/*
 * 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;
مشاهده نمونه

Sample را امتحان کنید

Image Map Types

Implementing a MapType to act as a base map type can be a time-consuming and laborious task. The API provides a special class that implements the MapType interface for the most common map types: map types that consist of tiles made up of single image files.

This class, the ImageMapType class, is constructed using an ImageMapTypeOptions object specification defining the following required properties:

  • tileSize (required) specifies the size of the tile (of type google.maps.Size ). Sizes must be rectangular though they need not be square.
  • getTileUrl (required) specifies the function, usually provided as an inline function literal, to handle selection of the proper image tile based on supplied world coordinates and zoom level.

The following code implements a basic ImageMapType using Google's moon tiles. The example makes use of a normalization function to ensure that tiles repeat along the x-axis, but not along the y-axis of your map.

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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

پیش بینی ها

The Earth is a three-dimensional sphere (approximately), while a map is a flat two-dimensional surface. The map that you see within the Maps JavaScript API, like any flat map of the Earth, is a projection of that sphere onto a flat surface. In its simplest terms, a projection can be defined as a mapping of latitude/longitude values into coordinates on the projection's map.

Projections in the Maps JavaScript API must implement the Projection interface. A Projection implementation must provide not only a mapping from one coordinate system to another, but a bi-directional mapping. That is, you must define how to translate from Earth coordinates ( LatLng objects) to the Projection class's world coordinate system, and from the world coordinate system back to the Earth coordinates. Google Maps uses the Mercator projection to create its maps from geographic data and convert events on the map into geographic coordinates. You can obtain this projection by calling getProjection() on the Map (or any of the standard base MapType types.) For most uses, this standard Projection will suffice, but you may also define and use your own custom projections.

Implement a Projection

When implementing a custom projection, you will need to define a few things:

  • The formulae for mapping latitude and longitude coordinates into a Cartesian plane and the corresponding formulae for mapping from a Cartesian plane to latitude and longitude coordinates. (The Projection interface only supports transformations into rectilinear coordinates.)
  • The base tile size. All tiles must be rectangular.
  • The "world size" of a map using the base tile set at zoom level 0. Note that for maps consisting of one tile at zoom 0, the world size and base tile size are identical.

Coordinate Transformations in Projections

Each projection provides two methods which translate between these two coordinate systems, allowing you to convert between geographic and world coordinates:

  • The Projection.fromLatLngToPoint() method converts a LatLng value into a world coordinate. This method is used to position overlays on the map (and to position the map itself).
  • The Projection.fromPointToLatLng() method converts a world coordinate into a LatLng value. This method is used to convert events such as clicks that happen on the map into geographic coordinates.

Google Maps assumes that projections are rectilinear.

Generally, you may use a projection for two cases: to create a map of the world, or to create a map of a local area. In the former case, you should ensure that your projection is also rectilinear and normal at all longitudes. Some projections (especially conic projections) may be "locally normal" (ie point north) but deviate from true north; for example, the further the map is positioned relative to some reference longitude. You may use such a projection locally, but be aware that the projection is necessarily imprecise and transformation errors will become increasingly apparently the further away from the reference longitude you deviate.

Map Tile Selection in Projections

Projections are not only useful for determining the positions of locations or overlays, but for positioning the map tiles themselves. The Maps JavaScript API renders base maps using a MapType interface, which must declare both a projection property for identifying the map's projection and a getTile() method for retrieving map tiles based on tile coordinate values. Tile coordinates are based on both your basic tile size (which must be rectangular) and the "world size" of your map, which is the pixel size of your map world at zoom level 0. (For maps consisting of one tile at zoom 0, the tile size and world size are identical.)

You define the base tile size within your MapType 's tileSize property. You define the world size implicitly within your projection's fromLatLngToPoint() and fromPointToLatLng() methods.

Since image selection depends on these passed values, it is useful to name images that can be selected programmatically given those passed values, such as map _ zoom _ tileX _ tileY .png .

The following example defines an ImageMapType using the Gall-Peters projection:

TypeScript

// This example defines an image map type using the Gall-Peters
// projection.
// https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection
const mapElement = document.querySelector("gmp-map") as google.maps.MapElement;
let innerMap;

async function initMap() {
  // Request the needed libraries.
  await google.maps.importLibrary("maps");

  // Create a map.
  innerMap = mapElement.innerMap;
  innerMap.setOptions({
    mapTypeControl: false,
  });

  // Set the Gall-Peters map type.
  initGallPeters();
  innerMap.mapTypes.set("gallPeters", gallPetersMapType);
  innerMap.setMapTypeId("gallPeters");

  // Show the lat and lng under the mouse cursor.
  const coordsDiv = document.getElementById("coords") as HTMLElement;

  innerMap.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.
  innerMap.data.setStyle((feature) => {
    return {
      title: feature.getProperty("name") as string,
      optimized: false,
    };
  });
  innerMap.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 (
        "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" },
    },
  ],
};

initMap();

جاوا اسکریپت

// This example defines an image map type using the Gall-Peters
// projection.
// https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection
const mapElement = document.querySelector("gmp-map");
let innerMap;
async function initMap() {
    // Request the needed libraries.
    await google.maps.importLibrary("maps");
    // Create a map.
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });
    // Set the Gall-Peters map type.
    initGallPeters();
    innerMap.mapTypes.set("gallPeters", gallPetersMapType);
    innerMap.setMapTypeId("gallPeters");
    // Show the lat and lng under the mouse cursor.
    const coordsDiv = document.getElementById("coords");
    innerMap.addListener("mousemove", (event) => {
        coordsDiv.textContent =
            "lat: " +
                Math.round(event.latLng.lat()) +
                ", " +
                "lng: " +
                Math.round(event.latLng.lng());
    });
    // Add some markers to the map.
    innerMap.data.setStyle((feature) => {
        return {
            title: feature.getProperty("name"),
            optimized: false,
        };
    });
    innerMap.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 ("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" },
        },
    ],
};
initMap();
مشاهده نمونه

Sample را امتحان کنید

،
Select platform: Android iOS JavaScript

This document discusses the types of maps you can display using the Maps JavaScript API. The API uses a MapType object to hold information about these maps. A MapType is an interface that defines the display and usage of map tiles and the translation of coordinate systems from screen coordinates to world coordinates (on the map). Each MapType must contain a few methods to handle retrieval and release of tiles, and properties that define its visual behavior.

The inner workings of map types within the Maps JavaScript API is an advanced topic. Most developers can use the basic map types noted below. However, you can also modify the presentation of existing map types using Styled Maps or define your own map tiles using custom map types . When providing custom map types, you will need to understand how to modify the map's Map Type Registry .

Basic Map Types

There are four types of maps available within the Maps JavaScript API. In addition to the familiar "painted" road map tiles, the Maps JavaScript API also supports other maps types.

The following map types are available in the Maps JavaScript API:

  • roadmap displays the default road map view. This is the default map type.
  • satellite displays Google Earth satellite images.
  • hybrid displays a mixture of normal and satellite views.
  • terrain displays a physical map based on terrain information.

You modify the map type in use by the Map by setting its mapTypeId property, either within the constructor by setting its Map options object, or by calling the map's setMapTypeId() method. The mapTypeID property defaults to roadmap .

Setting the mapTypeId upon construction:

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);

Modifying the mapTypeId dynamically:

map.setMapTypeId('terrain');

Note that you don't actually set the map's map type directly, but instead set its mapTypeId to reference a MapType using an identifier. The Maps JavaScript API uses a map type registry, explained below, to manage these references.

45° Imagery

The Maps JavaScript API supports special 45° imagery for certain locations. This high-resolution imagery provides perspective views towards each of the cardinal direction (North, South, East, West). These images are available at higher zoom levels for supported map types.

The following image shows a 45° perspective view of New York City:

The satellite and hybrid map types support 45° imagery at high zoom levels (12 and greater) where available. If the user zooms into a location for which such imagery exists, these map types automatically alter their views in the following manner:

  • The satellite or hybrid imagery is replaced with imagery giving a 45° perspective, centered on the current location. By default, such views are oriented towards north. If the user zooms out, the default satellite or hybrid imagery appears again. The behavior varies depending on zoom level and the value of tilt :
    • Between zoom levels 12 and 18 the top-down basemap (0°) displays by default unless tilt is set to 45.
    • At zoom levels of 18 or greater the 45° basemap displays unless tilt is set to 0.
  • The rotate control becomes visible. The rotate control provides options that enable the user to toggle tilt, and to rotate the view in 90° increments in either direction. To hide the rotate control, set rotateControl to false .

Zooming out from a map type displaying 45° imagery reverts each of these changes, re-establishing the original map types.

Enable and Disable 45° Imagery

You can disable 45° imagery by calling setTilt(0) on the Map object. To enable 45° imagery for supported map types, call setTilt(45) . The Map 's getTilt() method will always reflect the current tilt being shown on the map; if you set a tilt on a map and then later remove that tilt (by zooming the map out, for example), the map's getTilt() method will return 0 .

Important: 45° imagery is only supported on raster maps; this imagery cannot be used with vector maps.

The following example displays a 45° view of New York City:

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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

View example .

Rotate 45° Imagery

The 45° imagery actually consists of a collection of images for each cardinal direction (North, South, East, West). Once your map is displaying 45° imagery, you can orient the imagery towards one of its cardinal directions by calling setHeading() on the Map object, passing a number value expressed as degrees from North.

The following example shows an aerial map and auto-rotates the map every 3 seconds when the button is clicked:

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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

View example .

Modify the Map Type Registry

A map's mapTypeId is a string identifier that is used to associate a MapType with a unique value. Each Map object maintains a MapTypeRegistry which contains the collection of available MapType s for that map. This registry is used to select the types of maps which are available in the Map's MapType control, for example.

You don't read directly from the map type registry. Instead, you modify the registry by adding custom map types and associating them with a string identifier of your choosing. You cannot modify or alter the basic map types (though you can remove them from the map by altering the appearance of the map's associated mapTypeControlOptions ).

The following code sets the map to show only two map types in the map's mapTypeControlOptions and modifies the registry to add the association with this identifier to the actual implementation of the MapType interface.

// 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);

Styled Maps

The StyledMapType lets you customize the presentation of the standard Google base maps, changing the visual display of such elements as roads, parks, and built-up areas to reflect a different style than that used in the default map type. The StyledMapType affects only the default roadmap map type.

For more information about the StyledMapType , see Using embedded JSON style declarations .

Custom Map Types

The Maps JavaScript API supports the display and management of custom map types, allowing you to implement your own map imagery or tile overlays.

Several possible map type implementations exist within the Maps JavaScript API:

  • Standard tile sets consisting of images which collectively constitute full cartographic maps. These tile sets are also known as base map types. These map types act and behave like the existing default map types: roadmap , satellite , hybrid and terrain . You can add your custom map type to a Map's mapTypes array to allow the UI within the Maps JavaScript API to treat your custom map type as a standard map type (by including it in the MapType control, for example).
  • Image tile overlays which display on top of existing base map types. Generally, these map types are used to augment an existing map type to display additional information and are often constrained to specific locations and/or zoom levels. Note that these tiles may be transparent, allowing you to add features to existing maps.
  • Non-image map types, which allow you to manipulate the display of map information at its most fundamental level.

Each of these options relies on creating a class that implements the MapType interface. Additionally, the ImageMapType class provides some built-in behavior to simplify the creation of imagery map types.

The MapType Interface

Before you create classes which implement MapType , it is important to understand how Google Maps determines coordinates and decides which parts of the map to show. You need to implement similar logic for any base or overlay map types. Read the guide to map and tile coordinates .

Custom map types must implement the MapType interface. This interface specifies certain properties and methods that allow the API to initiate requests to your map type(s) when the API determines that it needs to display map tiles within the current viewport and zoom level. You handle these requests to decide which tile to load.

Note : You may create your own class to implement this interface. Alternatively, if you have compatible imagery you can use the ImageMapType class which already implements this interface.

Classes implementing the MapType interface require that you define and populate the following properties:

  • tileSize (required) specifies the size of the tile (of type google.maps.Size ). Sizes must be rectangular though they need not be square.
  • maxZoom (required) specifies the maximum zoom level at which to display tiles of this map type.
  • minZoom (optional) specifies the minimum zoom level at which to display tile of this map type. By default, this value is 0 indicating that no minimum zoom level exists.
  • name (optional) specifies the name for this map type. This property is only necessary if you want this map type to be selectable within a MapType control. (See Control Options .)
  • alt (optional) specifies the alternate text for this map type, exhibited as hover text. This property is only necessary if you want this map type to be selectable within a MapType control. (See Control Options .)

Additionally, classes implementing the MapType interface need to implement the following methods:

  • getTile() (required) is called whenever the API determines that the map needs to display new tiles for the given viewport. The getTile() method must have the following signature:

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

    The API determines whether it needs to call getTile() based on the MapType 's tileSize , minZoom , and maxZoom properties and the map's current viewport and zoom level. The handler for this method should return an HTML element given a passed coordinate, zoom level, and DOM element on which to append the tile image.

  • releaseTile() (optional) is called whenever the API determines that the map needs to remove a tile as it falls out of view. This method must have the following signature:

    releaseTile(tile:Node)

    You typically should handle removal of any elements that were attached to the map tiles upon addition to the map. For example, if you attached event listeners to map tile overlays, you should remove them here.

The getTile() method acts as the main controller for determining which tiles to load within a given viewport.

Base Map Types

Map types which you construct in this manner may either stand alone or be combined with other map types as overlays. Standalone map types are known as base map types . You may want to have the API treat such custom MapType s as it would any other existing base map type ( ROADMAP , TERRAIN , etc.). To do so, add your custom MapType to the Map 's mapTypes property. This property is of type MapTypeRegistry .

The following code creates a base MapType to display a map's tile coordinates and draws an outline of the tiles:

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;

جاوا اسکریپت

/*
 * 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;
مشاهده نمونه

Sample را امتحان کنید

Overlay Map Types

Some map types are designed to work on top of existing map types. Such map types may have transparent layers indicating points of interest, or showing additional data to the user.

In these cases, you do not want the map type treated as a separate entity but as an overlay. You can do this by adding the map type to an existing MapType directly using the Map 's overlayMapTypes property. This property contains an MVCArray of MapType s. All map types (base and overlay) are rendered within the mapPane layer. Overlay map types will display on top of the base map they are attached to, in the order in which they appear in the Map.overlayMapTypes array (overlays with higher index values are displayed in front of overlays with lower index values).

The following example is identical to the previous one except that we've created a tile overlay MapType on top of the ROADMAP map type:

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;

جاوا اسکریپت

/*
 * 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;
مشاهده نمونه

Sample را امتحان کنید

Image Map Types

Implementing a MapType to act as a base map type can be a time-consuming and laborious task. The API provides a special class that implements the MapType interface for the most common map types: map types that consist of tiles made up of single image files.

This class, the ImageMapType class, is constructed using an ImageMapTypeOptions object specification defining the following required properties:

  • tileSize (required) specifies the size of the tile (of type google.maps.Size ). Sizes must be rectangular though they need not be square.
  • getTileUrl (required) specifies the function, usually provided as an inline function literal, to handle selection of the proper image tile based on supplied world coordinates and zoom level.

The following code implements a basic ImageMapType using Google's moon tiles. The example makes use of a normalization function to ensure that tiles repeat along the x-axis, but not along the y-axis of your map.

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;

جاوا اسکریپت

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;
مشاهده نمونه

Sample را امتحان کنید

پیش بینی ها

The Earth is a three-dimensional sphere (approximately), while a map is a flat two-dimensional surface. The map that you see within the Maps JavaScript API, like any flat map of the Earth, is a projection of that sphere onto a flat surface. In its simplest terms, a projection can be defined as a mapping of latitude/longitude values into coordinates on the projection's map.

Projections in the Maps JavaScript API must implement the Projection interface. A Projection implementation must provide not only a mapping from one coordinate system to another, but a bi-directional mapping. That is, you must define how to translate from Earth coordinates ( LatLng objects) to the Projection class's world coordinate system, and from the world coordinate system back to the Earth coordinates. Google Maps uses the Mercator projection to create its maps from geographic data and convert events on the map into geographic coordinates. You can obtain this projection by calling getProjection() on the Map (or any of the standard base MapType types.) For most uses, this standard Projection will suffice, but you may also define and use your own custom projections.

Implement a Projection

When implementing a custom projection, you will need to define a few things:

  • The formulae for mapping latitude and longitude coordinates into a Cartesian plane and the corresponding formulae for mapping from a Cartesian plane to latitude and longitude coordinates. (The Projection interface only supports transformations into rectilinear coordinates.)
  • The base tile size. All tiles must be rectangular.
  • The "world size" of a map using the base tile set at zoom level 0. Note that for maps consisting of one tile at zoom 0, the world size and base tile size are identical.

Coordinate Transformations in Projections

Each projection provides two methods which translate between these two coordinate systems, allowing you to convert between geographic and world coordinates:

  • The Projection.fromLatLngToPoint() method converts a LatLng value into a world coordinate. This method is used to position overlays on the map (and to position the map itself).
  • The Projection.fromPointToLatLng() method converts a world coordinate into a LatLng value. This method is used to convert events such as clicks that happen on the map into geographic coordinates.

Google Maps assumes that projections are rectilinear.

Generally, you may use a projection for two cases: to create a map of the world, or to create a map of a local area. In the former case, you should ensure that your projection is also rectilinear and normal at all longitudes. Some projections (especially conic projections) may be "locally normal" (ie point north) but deviate from true north; for example, the further the map is positioned relative to some reference longitude. You may use such a projection locally, but be aware that the projection is necessarily imprecise and transformation errors will become increasingly apparently the further away from the reference longitude you deviate.

Map Tile Selection in Projections

Projections are not only useful for determining the positions of locations or overlays, but for positioning the map tiles themselves. The Maps JavaScript API renders base maps using a MapType interface, which must declare both a projection property for identifying the map's projection and a getTile() method for retrieving map tiles based on tile coordinate values. Tile coordinates are based on both your basic tile size (which must be rectangular) and the "world size" of your map, which is the pixel size of your map world at zoom level 0. (For maps consisting of one tile at zoom 0, the tile size and world size are identical.)

You define the base tile size within your MapType 's tileSize property. You define the world size implicitly within your projection's fromLatLngToPoint() and fromPointToLatLng() methods.

Since image selection depends on these passed values, it is useful to name images that can be selected programmatically given those passed values, such as map _ zoom _ tileX _ tileY .png .

The following example defines an ImageMapType using the Gall-Peters projection:

TypeScript

// This example defines an image map type using the Gall-Peters
// projection.
// https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection
const mapElement = document.querySelector("gmp-map") as google.maps.MapElement;
let innerMap;

async function initMap() {
  // Request the needed libraries.
  await google.maps.importLibrary("maps");

  // Create a map.
  innerMap = mapElement.innerMap;
  innerMap.setOptions({
    mapTypeControl: false,
  });

  // Set the Gall-Peters map type.
  initGallPeters();
  innerMap.mapTypes.set("gallPeters", gallPetersMapType);
  innerMap.setMapTypeId("gallPeters");

  // Show the lat and lng under the mouse cursor.
  const coordsDiv = document.getElementById("coords") as HTMLElement;

  innerMap.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.
  innerMap.data.setStyle((feature) => {
    return {
      title: feature.getProperty("name") as string,
      optimized: false,
    };
  });
  innerMap.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 (
        "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" },
    },
  ],
};

initMap();

جاوا اسکریپت

// This example defines an image map type using the Gall-Peters
// projection.
// https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection
const mapElement = document.querySelector("gmp-map");
let innerMap;
async function initMap() {
    // Request the needed libraries.
    await google.maps.importLibrary("maps");
    // Create a map.
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });
    // Set the Gall-Peters map type.
    initGallPeters();
    innerMap.mapTypes.set("gallPeters", gallPetersMapType);
    innerMap.setMapTypeId("gallPeters");
    // Show the lat and lng under the mouse cursor.
    const coordsDiv = document.getElementById("coords");
    innerMap.addListener("mousemove", (event) => {
        coordsDiv.textContent =
            "lat: " +
                Math.round(event.latLng.lat()) +
                ", " +
                "lng: " +
                Math.round(event.latLng.lng());
    });
    // Add some markers to the map.
    innerMap.data.setStyle((feature) => {
        return {
            title: feature.getProperty("name"),
            optimized: false,
        };
    });
    innerMap.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 ("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" },
        },
    ],
};
initMap();
مشاهده نمونه

Sample را امتحان کنید