ประเภทแผนที่

เลือกแพลตฟอร์ม: Android iOS JavaScript

เอกสารนี้จะกล่าวถึงประเภทแผนที่ที่คุณแสดงได้โดยใช้ Maps JavaScript API API ใช้ออบเจ็กต์ MapType เพื่อเก็บข้อมูลเกี่ยวกับแผนที่เหล่านี้ MapType เป็นอินเทอร์เฟซที่กำหนดการแสดงผลและการใช้ชิ้นส่วนแผนที่และการแปลระบบพิกัดจากพิกัดของหน้าจอเป็นพิกัดโลก (บนแผนที่) MapType แต่ละรายการต้องมีวิธีการ 2-3 วิธีในการจัดการการดึงข้อมูลและการเผยแพร่การ์ด และพร็อพเพอร์ตี้ที่กำหนดลักษณะการทำงานของการ์ด

การทำงานภายในของแผนที่ประเภทต่างๆ ภายใน Maps JavaScript API เป็นหัวข้อขั้นสูง นักพัฒนาซอฟต์แวร์ส่วนใหญ่สามารถใช้ ประเภทแผนที่พื้นฐานที่ระบุไว้ด้านล่าง อย่างไรก็ตาม คุณยังสามารถแก้ไขการนำเสนอแผนที่ประเภทต่างๆ ที่มีอยู่โดยใช้แผนที่ที่มีการจัดรูปแบบ หรือกำหนดชิ้นส่วนแผนที่ของคุณเองได้โดยใช้ประเภทแผนที่ที่กำหนดเอง เมื่อระบุประเภทแผนที่ที่กำหนดเอง คุณจะต้องเข้าใจวิธีแก้ไขรีจิสทรีประเภทแผนที่ของแผนที่

ประเภทแผนที่พื้นฐาน

แผนที่ใน Maps JavaScript API มี 4 ประเภท นอกเหนือจากชิ้นส่วนแผนที่ถนนแบบ "ลงสี" ที่คุ้นเคยแล้ว 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°

คุณปิดใช้ภาพ 45° ได้โดยเรียกใช้ setTilt(0) บนออบเจ็กต์ Map หากต้องการเปิดภาพ 45° สำหรับประเภทแผนที่ที่รองรับ โปรดโทร setTilt(45) เมธอด getTilt() ของ Map จะแสดง tilt ปัจจุบันที่แสดงอยู่ในแผนที่เสมอ หากคุณตั้งค่า tilt บนแผนที่แล้วลบ tilt นั้นในภายหลัง (เช่น เมื่อซูมแผนที่ออก) เมธอด getTilt() ของแผนที่จะแสดงผลเป็น 0

สิ่งสำคัญ: ภาพ 45° ได้รับการสนับสนุนเฉพาะบนแผนที่แรสเตอร์เท่านั้น ภาพนี้ไม่สามารถใช้กับแผนที่เวกเตอร์ได้

ตัวอย่างต่อไปนี้แสดงมุมมอง 45° ของนครนิวยอร์ก

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: { lat: 40.76, lng: -73.983 },
      zoom: 15,
      mapTypeId: "satellite",
    }
  );

  map.setTilt(45);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.76, lng: -73.983 },
    zoom: 15,
    mapTypeId: "satellite",
  });

  map.setTilt(45);
}

window.initMap = initMap;
ดูตัวอย่าง

ลองใช้ตัวอย่าง

ดูตัวอย่าง

กำลังหมุนภาพ 45°

ภาพ 45° ประกอบด้วยคอลเล็กชันรูปภาพของผู้นำแต่ละด้าน (เหนือ ใต้ ตะวันออก ตะวันตก) เมื่อแผนที่แสดงภาพ 45° คุณสามารถจัดแนวภาพไปยังหนึ่งในเส้นทางที่สำคัญ โดยเรียก setHeading() บนวัตถุ Map โดยส่งผ่านค่าตัวเลขที่แสดงเป็นองศาจากทิศเหนือ

ตัวอย่างต่อไปนี้แสดงแผนที่ทางอากาศและหมุนแผนที่อัตโนมัติทุกๆ 3 วินาทีเมื่อมีการคลิกปุ่ม

TypeScript

let map: google.maps.Map;

function initMap(): void {
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    center: { lat: 40.76, lng: -73.983 },
    zoom: 15,
    mapTypeId: "satellite",
    heading: 90,
    tilt: 45,
  });

  // add listener to button
  document.getElementById("rotate")!.addEventListener("click", autoRotate);
}

function rotate90(): void {
  const heading = map.getHeading() || 0;

  map.setHeading(heading + 90);
}

function autoRotate(): void {
  // Determine if we're showing aerial imagery.
  if (map.getTilt() !== 0) {
    window.setInterval(rotate90, 3000);
  }
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

let map;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.76, lng: -73.983 },
    zoom: 15,
    mapTypeId: "satellite",
    heading: 90,
    tilt: 45,
  });
  // add listener to button
  document.getElementById("rotate").addEventListener("click", autoRotate);
}

function rotate90() {
  const heading = map.getHeading() || 0;

  map.setHeading(heading + 90);
}

function autoRotate() {
  // Determine if we're showing aerial imagery.
  if (map.getTilt() !== 0) {
    window.setInterval(rotate90, 3000);
  }
}

window.initMap = initMap;
ดูตัวอย่าง

ลองใช้ตัวอย่าง

ดูตัวอย่าง

การแก้ไขรีจิสทรีประเภทแผนที่

mapTypeId ของแผนที่เป็นตัวระบุสตริงที่ใช้ในการเชื่อมโยง MapType กับค่าที่ไม่ซ้ำกัน ออบเจ็กต์ Map แต่ละรายการจะมี MapTypeRegistry ซึ่งมีคอลเล็กชันของ MapType ที่ใช้ได้สำหรับแผนที่นั้น รีจิสทรีนี้ใช้สำหรับเลือกประเภทของแผนที่ที่มีให้ใช้งานในการควบคุม MapType ของแผนที่ เป็นต้น

คุณไม่ได้อ่านจากรีจิสทรีประเภทแผนที่โดยตรง แต่จะแก้ไขรีจิสทรีโดยเพิ่มประเภทแผนที่ที่กำหนดเองและเชื่อมโยงประเภทกับตัวระบุสตริงที่คุณเลือก คุณไม่สามารถแก้ไขหรือปรับเปลี่ยนประเภทแผนที่พื้นฐานได้ (แต่สามารถนำออกจากแผนที่โดยการแก้ไขลักษณะที่ปรากฏของ mapTypeControlOptions ที่เชื่อมโยงกับแผนที่)

รหัสต่อไปนี้กำหนดให้แผนที่แสดงแผนที่เพียง 2 ประเภทใน 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 โปรดดูคู่มือแผนที่ที่มีการจัดรูปแบบ

ประเภทแผนที่ที่กำหนดเอง

Maps JavaScript API รองรับการแสดงและการจัดการแผนที่ประเภทต่างๆ ที่กำหนดเอง ซึ่งจะช่วยให้คุณนำภาพแผนที่หรือชิ้นส่วนแผนที่ของคุณเองมาใช้ได้

อาจมีการใช้งานแผนที่หลายประเภทที่เป็นไปได้ใน Maps JavaScript API ดังนี้

  • ชุดชิ้นส่วนมาตรฐานที่ประกอบด้วยรูปภาพที่ประกอบขึ้นเป็นแผนที่แผนที่ฉบับเต็มทั้งหมด ชุดชิ้นส่วนเหล่านี้เรียกอีกอย่างว่าแผนที่ประเภทฐาน แผนที่ประเภทเหล่านี้ทำงานและมีลักษณะคล้ายกับแผนที่ประเภทเริ่มต้นที่มีอยู่ ได้แก่ roadmap, satellite, hybrid และ terrain คุณเพิ่มประเภทแผนที่ที่กำหนดเองลงในอาร์เรย์ mapTypes ของแผนที่เพื่อให้ UI ภายใน Maps JavaScript API จัดการประเภทแผนที่ที่กำหนดเองเป็นประเภทแผนที่มาตรฐานได้ (เช่น โดยรวมไว้ในตัวควบคุม MapType เป็นต้น)
  • การวางซ้อนชิ้นส่วนภาพซึ่งแสดงทับประเภทแผนที่ฐานที่มีอยู่ โดยทั่วไป แผนที่ประเภทเหล่านี้จะใช้เพื่อขยายประเภทแผนที่ที่มีอยู่ให้แสดงข้อมูลเพิ่มเติม และมักจะจำกัดไว้เฉพาะตำแหน่งและ/หรือระดับการซูมที่เฉพาะเจาะจง โปรดทราบว่าชิ้นส่วนแผนที่เหล่านี้อาจเป็นแบบโปร่งใส ซึ่งช่วยให้คุณเพิ่มจุดสนใจในแผนที่ที่มีอยู่ได้
  • แผนที่ประเภทที่ไม่ใช่รูปภาพ ซึ่งให้คุณจัดการการแสดงข้อมูลแผนที่ในระดับพื้นฐานที่สุด

ตัวเลือกแต่ละรายการเหล่านี้ขึ้นอยู่กับการสร้างคลาสที่ใช้อินเทอร์เฟซ MapType นอกจากนี้ คลาส ImageMapType ยังมีลักษณะการทำงานบางอย่างในตัว เพื่อให้การสร้างประเภทแผนที่ภาพง่ายขึ้น

อินเทอร์เฟซของ MapType

ก่อนที่จะสร้างชั้นเรียนที่ใช้ MapType คุณควรทำความเข้าใจวิธีที่ Google Maps ระบุพิกัดและตัดสินใจว่าจะแสดงส่วนใดของแผนที่ คุณต้องใช้ตรรกะที่คล้ายกันกับแผนที่ฐานหรือซ้อนทับทุกประเภท อ่านคู่มือเกี่ยวกับพิกัดของแผนที่และแผนที่ย่อย

ประเภทแผนที่ที่กำหนดเองต้องใช้อินเทอร์เฟซ MapType อินเทอร์เฟซนี้ระบุพร็อพเพอร์ตี้และเมธอดบางอย่างที่อนุญาตให้ API เริ่มคำขอไปยังประเภทแผนที่ของคุณเมื่อ API ระบุว่าจำเป็นต้องแสดงชิ้นส่วนแผนที่ภายในวิวพอร์ตและระดับการซูมปัจจุบัน คุณจัดการคำขอเหล่านี้เพื่อตัดสินใจว่าจะโหลดการ์ดใด

หมายเหตุ: คุณสร้างชั้นเรียนของคุณเองเพื่อใช้อินเทอร์เฟซนี้ได้ หรือหากคุณมีรูปภาพที่เข้ากันได้ คุณสามารถใช้คลาส ImageMapType ที่ใช้งานอินเทอร์เฟซนี้อยู่แล้ว

ชั้นเรียนที่ใช้อินเทอร์เฟซ MapType กำหนดให้คุณต้องกำหนดและป้อนข้อมูลพร็อพเพอร์ตี้ต่อไปนี้

  • tileSize (ต้องระบุ) ระบุขนาดของชิ้นส่วน (ประเภท google.maps.Size) ขนาดต้องเป็นรูปสี่เหลี่ยมผืนผ้าแต่ไม่จำเป็นต้องเป็นรูปสี่เหลี่ยมจัตุรัส
  • maxZoom (จำเป็น) ระบุระดับการซูมสูงสุดที่จะแสดงชิ้นส่วนแผนที่ประเภทนี้
  • minZoom (ไม่บังคับ) ระบุระดับการซูมขั้นต่ำที่จะแสดงชิ้นส่วนแผนที่ประเภทนี้ โดยค่าเริ่มต้น ค่านี้คือ 0 ซึ่งบ่งชี้ว่าไม่มีระดับการซูมขั้นต่ำ
  • name (ไม่บังคับ) ระบุชื่อของแผนที่ประเภทนี้ พร็อพเพอร์ตี้นี้มีความจำเป็นต่อเมื่อคุณต้องการให้ระบบเลือกประเภทแผนที่นี้ ภายในตัวควบคุม MapType ได้ (โปรดดู การเพิ่มตัวควบคุม MapType ด้านล่าง)
  • alt (ไม่บังคับ) ระบุข้อความแสดงแทนสำหรับแผนที่ประเภทนี้ ซึ่งแสดงเป็นข้อความที่แสดงเมื่อเลื่อนเมาส์ผ่าน พร็อพเพอร์ตี้นี้มีความจำเป็นต่อเมื่อคุณต้องการให้ระบบเลือกประเภทแผนที่นี้ภายในตัวควบคุม MapType ได้ (โปรดดูการเพิ่มตัวควบคุม MapType ด้านล่าง)

นอกจากนี้ คลาสที่ใช้อินเทอร์เฟซ MapType จะต้องติดตั้งใช้งานเมธอดต่อไปนี้

  • ระบบจะเรียกใช้ getTile() (ต้องระบุ) ทุกครั้งที่ API ระบุว่าแผนที่จำเป็นต้องแสดงไทล์ใหม่สำหรับวิวพอร์ตที่ระบุ เมธอด getTile() ต้องมีลายเซ็นต่อไปนี้

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

    API จะระบุว่าต้องเรียกใช้ getTile() หรือไม่ตามพร็อพเพอร์ตี้ tileSize, minZoom และ maxZoom ของ MapType รวมถึงระดับวิวพอร์ตและระดับการซูมปัจจุบันของแผนที่ ตัวแฮนเดิลสำหรับเมธอดนี้ควรแสดงผลองค์ประกอบ HTML ที่ระบุพิกัดที่ส่งผ่าน ระดับการซูม และองค์ประกอบ DOM ที่จะผนวกรูปภาพชิ้นส่วน

  • ระบบจะเรียก releaseTile() (ไม่บังคับ) ทุกครั้งที่ API ระบุว่าแผนที่จำเป็นต้องนำการ์ดออกเมื่อแผนที่หลุดออกมา เมธอดนี้ต้องมีลายเซ็นต่อไปนี้

    releaseTile(tile:Node)

    โดยทั่วไปแล้วคุณควรจัดการการลบองค์ประกอบที่แนบอยู่กับชิ้นส่วนแผนที่นอกเหนือจากแผนที่ ตัวอย่างเช่น หากคุณแนบ Listener เหตุการณ์กับการวางซ้อนของชิ้นส่วนแผนที่ คุณควรนำ Listener เหตุการณ์ออกจากที่นี่

เมธอด getTile() จะทําหน้าที่เป็นตัวควบคุมหลักสําหรับกําหนดว่าไทล์ใดจะโหลดภายในวิวพอร์ตหนึ่งๆ

ประเภทแผนที่ฐาน

แผนที่ประเภทที่คุณสร้างในลักษณะนี้อาจแยกเป็นอิสระหรือรวมกับแผนที่ประเภทอื่นๆ เป็นการวางซ้อน ประเภทแผนที่แบบสแตนด์อโลนเรียกว่าประเภทแผนที่ฐาน คุณอาจต้องการให้ API ดำเนินการกับ MapType ที่กำหนดเองดังกล่าวเหมือนกับแผนที่ฐานประเภทอื่นๆ ที่มีอยู่ (ROADMAP, TERRAIN ฯลฯ) โดยเพิ่ม MapType ที่กําหนดเองลงในพร็อพเพอร์ตี้ mapTypes ของ Map พร็อพเพอร์ตี้นี้เป็นประเภท MapTypeRegistry

โค้ดต่อไปนี้จะสร้าง MapType ฐานเพื่อแสดงพิกัดของชิ้นส่วนแผนที่ และวาดโครงร่างของชิ้นส่วนแผนที่

TypeScript

/*
 * This demo demonstrates how to replace default map tiles with custom imagery.
 * In this case, the CoordMapType displays gray tiles annotated with the tile
 * coordinates.
 *
 * Try panning and zooming the map to see how the coordinates change.
 */

class CoordMapType {
  tileSize: google.maps.Size;
  maxZoom = 19;
  name = "Tile #s";
  alt = "Tile Coordinate Map Type";

  constructor(tileSize: google.maps.Size) {
    this.tileSize = tileSize;
  }

  getTile(
    coord: google.maps.Point,
    zoom: number,
    ownerDocument: Document
  ): HTMLElement {
    const div = ownerDocument.createElement("div");

    div.innerHTML = String(coord);
    div.style.width = this.tileSize.width + "px";
    div.style.height = this.tileSize.height + "px";
    div.style.fontSize = "10";
    div.style.borderStyle = "solid";
    div.style.borderWidth = "1px";
    div.style.borderColor = "#AAAAAA";
    div.style.backgroundColor = "#E5E3DF";
    return div;
  }

  releaseTile(tile: HTMLElement): void {}
}

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 10,
      center: { lat: 41.85, lng: -87.65 },
      streetViewControl: false,
      mapTypeId: "coordinate",
      mapTypeControlOptions: {
        mapTypeIds: ["coordinate", "roadmap"],
        style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
      },
    }
  );

  map.addListener("maptypeid_changed", () => {
    const showStreetViewControl =
      (map.getMapTypeId() as string) !== "coordinate";

    map.setOptions({
      streetViewControl: showStreetViewControl,
    });
  });

  // Now attach the coordinate map type to the map's registry.
  map.mapTypes.set(
    "coordinate",
    new CoordMapType(new google.maps.Size(256, 256))
  );
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

/*
 * This demo demonstrates how to replace default map tiles with custom imagery.
 * In this case, the CoordMapType displays gray tiles annotated with the tile
 * coordinates.
 *
 * Try panning and zooming the map to see how the coordinates change.
 */
class CoordMapType {
  tileSize;
  maxZoom = 19;
  name = "Tile #s";
  alt = "Tile Coordinate Map Type";
  constructor(tileSize) {
    this.tileSize = tileSize;
  }
  getTile(coord, zoom, ownerDocument) {
    const div = ownerDocument.createElement("div");

    div.innerHTML = String(coord);
    div.style.width = this.tileSize.width + "px";
    div.style.height = this.tileSize.height + "px";
    div.style.fontSize = "10";
    div.style.borderStyle = "solid";
    div.style.borderWidth = "1px";
    div.style.borderColor = "#AAAAAA";
    div.style.backgroundColor = "#E5E3DF";
    return div;
  }
  releaseTile(tile) {}
}

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 10,
    center: { lat: 41.85, lng: -87.65 },
    streetViewControl: false,
    mapTypeId: "coordinate",
    mapTypeControlOptions: {
      mapTypeIds: ["coordinate", "roadmap"],
      style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
    },
  });

  map.addListener("maptypeid_changed", () => {
    const showStreetViewControl = map.getMapTypeId() !== "coordinate";

    map.setOptions({
      streetViewControl: showStreetViewControl,
    });
  });
  // Now attach the coordinate map type to the map's registry.
  map.mapTypes.set(
    "coordinate",
    new CoordMapType(new google.maps.Size(256, 256)),
  );
}

window.initMap = initMap;
ดูตัวอย่าง

ลองใช้ตัวอย่าง

ประเภทแผนที่ซ้อนทับ

แผนที่บางประเภทได้รับการออกแบบมาให้ทำงานที่ด้านบนของแผนที่บางประเภทที่มีอยู่ แผนที่ประเภทดังกล่าวอาจมีเลเยอร์โปร่งใสที่ระบุจุดที่น่าสนใจ หรือแสดงข้อมูลเพิ่มเติมแก่ผู้ใช้

ในกรณีเหล่านี้ คุณไม่ต้องการให้ระบบถือว่าแผนที่เป็นเอนทิตีแยกต่างหาก แต่เป็นการวางซ้อน ซึ่งทำได้โดยการเพิ่มประเภทแผนที่ลงใน MapType ที่มีอยู่โดยตรงโดยใช้พร็อพเพอร์ตี้ overlayMapTypes ของ Map พร็อพเพอร์ตี้นี้มี MVCArray เป็น MapType แผนที่ทุกประเภท (ฐานและการวางซ้อน) จะแสดงผลภายในเลเยอร์ mapPane ประเภทแผนที่ซ้อนทับจะแสดงที่ด้านบนของแผนที่ฐานที่แนบอยู่ โดยเรียงลำดับตามการปรากฏในอาร์เรย์ Map.overlayMapTypes (การวางซ้อนที่มีค่าดัชนีที่สูงกว่าจะแสดงหน้าโฆษณาซ้อนทับที่มีค่าดัชนีต่ำกว่า)

ตัวอย่างต่อไปนี้เหมือนกับภาพก่อนหน้า เว้นแต่ว่าเราได้สร้างการวางซ้อนของชิ้นส่วนแผนที่ MapType ที่ด้านบนของแผนที่ประเภท ROADMAP

TypeScript

/*
 * This demo illustrates the coordinate system used to display map tiles in the
 * API.
 *
 * Tiles in Google Maps are numbered from the same origin as that for
 * pixels. For Google's implementation of the Mercator projection, the origin
 * tile is always at the northwest corner of the map, with x values increasing
 * from west to east and y values increasing from north to south.
 *
 * Try panning and zooming the map to see how the coordinates change.
 */

class CoordMapType implements google.maps.MapType {
  tileSize: google.maps.Size;
  alt: string|null = null;
  maxZoom: number = 17;
  minZoom: number = 0;
  name: string|null = null;
  projection: google.maps.Projection|null = null;
  radius: number = 6378137;

  constructor(tileSize: google.maps.Size) {
    this.tileSize = tileSize;
  }
  getTile(
    coord: google.maps.Point,
    zoom: number,
    ownerDocument: Document
  ): HTMLElement {
    const div = ownerDocument.createElement("div");

    div.innerHTML = String(coord);
    div.style.width = this.tileSize.width + "px";
    div.style.height = this.tileSize.height + "px";
    div.style.fontSize = "10";
    div.style.borderStyle = "solid";
    div.style.borderWidth = "1px";
    div.style.borderColor = "#AAAAAA";
    return div;
  }
  releaseTile(tile: Element): void {}
}

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 10,
      center: { lat: 41.85, lng: -87.65 },
    }
  );

  // Insert this overlay map type as the first overlay map type at
  // position 0. Note that all overlay map types appear on top of
  // their parent base map.
  const coordMapType = new CoordMapType(new google.maps.Size(256, 256))
  map.overlayMapTypes.insertAt(
    0,
    coordMapType
  );
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

/*
 * This demo illustrates the coordinate system used to display map tiles in the
 * API.
 *
 * Tiles in Google Maps are numbered from the same origin as that for
 * pixels. For Google's implementation of the Mercator projection, the origin
 * tile is always at the northwest corner of the map, with x values increasing
 * from west to east and y values increasing from north to south.
 *
 * Try panning and zooming the map to see how the coordinates change.
 */
class CoordMapType {
  tileSize;
  alt = null;
  maxZoom = 17;
  minZoom = 0;
  name = null;
  projection = null;
  radius = 6378137;
  constructor(tileSize) {
    this.tileSize = tileSize;
  }
  getTile(coord, zoom, ownerDocument) {
    const div = ownerDocument.createElement("div");

    div.innerHTML = String(coord);
    div.style.width = this.tileSize.width + "px";
    div.style.height = this.tileSize.height + "px";
    div.style.fontSize = "10";
    div.style.borderStyle = "solid";
    div.style.borderWidth = "1px";
    div.style.borderColor = "#AAAAAA";
    return div;
  }
  releaseTile(tile) {}
}

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 10,
    center: { lat: 41.85, lng: -87.65 },
  });
  // Insert this overlay map type as the first overlay map type at
  // position 0. Note that all overlay map types appear on top of
  // their parent base map.
  const coordMapType = new CoordMapType(new google.maps.Size(256, 256));

  map.overlayMapTypes.insertAt(0, coordMapType);
}

window.initMap = initMap;
ดูตัวอย่าง

ลองใช้ตัวอย่าง

ประเภทการแมปภาพ

การนำ MapType ไปใช้เป็นแผนที่ฐานอาจกินเวลามากและต้องใช้แรงงานอย่างมาก API มีคลาสพิเศษที่ใช้อินเทอร์เฟซ MapType สำหรับประเภทแผนที่ที่พบบ่อยที่สุด ซึ่งได้แก่ ประเภทแผนที่ที่ประกอบด้วยชิ้นส่วนต่างๆ ซึ่งประกอบด้วยไฟล์ภาพเดียว

คลาส ImageMapType นี้สร้างขึ้นโดยใช้ข้อมูลจำเพาะของออบเจ็กต์ ImageMapTypeOptions ที่กำหนดพร็อพเพอร์ตี้ที่จำเป็นต่อไปนี้

  • tileSize (ต้องระบุ) ระบุขนาดของชิ้นส่วน (ประเภท google.maps.Size) ขนาดต้องเป็นรูปสี่เหลี่ยมผืนผ้าแต่ไม่จำเป็นต้องเป็นรูปสี่เหลี่ยมจัตุรัส
  • getTileUrl (ต้องระบุ) ระบุฟังก์ชัน ซึ่งโดยปกติจะเป็นฟังก์ชันลิเทอรัลของฟังก์ชันในบรรทัด เพื่อจัดการการเลือกชิ้นส่วนรูปภาพที่เหมาะสมตามพิกัดโลกและระดับการซูมที่ให้ไว้

โค้ดต่อไปนี้จะใช้ ImageMapType พื้นฐานโดยใช้ชิ้นส่วนดวงจันทร์ของ Google ตัวอย่างนี้ใช้ฟังก์ชันการทำให้เป็นมาตรฐานเพื่อให้แน่ใจว่าชิ้นส่วนเกิดขึ้นซ้ำตามแกน x แต่ไม่ใช่ตามแกน y ของแผนที่

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: { lat: 0, lng: 0 },
      zoom: 1,
      streetViewControl: false,
      mapTypeControlOptions: {
        mapTypeIds: ["moon"],
      },
    }
  );

  const moonMapType = new google.maps.ImageMapType({
    getTileUrl: function (coord, zoom): string {
      const normalizedCoord = getNormalizedCoord(coord, zoom);

      if (!normalizedCoord) {
        return "";
      }

      const bound = Math.pow(2, zoom);
      return (
        "https://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw" +
        "/" +
        zoom +
        "/" +
        normalizedCoord.x +
        "/" +
        (bound - normalizedCoord.y - 1) +
        ".jpg"
      );
    },
    tileSize: new google.maps.Size(256, 256),
    maxZoom: 9,
    minZoom: 0,
    // @ts-ignore TODO 'radius' does not exist in type 'ImageMapTypeOptions'
    radius: 1738000,
    name: "Moon",
  });

  map.mapTypes.set("moon", moonMapType);
  map.setMapTypeId("moon");
}

// Normalizes the coords that tiles repeat across the x axis (horizontally)
// like the standard Google map tiles.
function getNormalizedCoord(coord, zoom) {
  const y = coord.y;
  let x = coord.x;

  // tile range in one direction range is dependent on zoom level
  // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc
  const tileRange = 1 << zoom;

  // don't repeat across y-axis (vertically)
  if (y < 0 || y >= tileRange) {
    return null;
  }

  // repeat across x-axis
  if (x < 0 || x >= tileRange) {
    x = ((x % tileRange) + tileRange) % tileRange;
  }

  return { x: x, y: y };
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 0, lng: 0 },
    zoom: 1,
    streetViewControl: false,
    mapTypeControlOptions: {
      mapTypeIds: ["moon"],
    },
  });
  const moonMapType = new google.maps.ImageMapType({
    getTileUrl: function (coord, zoom) {
      const normalizedCoord = getNormalizedCoord(coord, zoom);

      if (!normalizedCoord) {
        return "";
      }

      const bound = Math.pow(2, zoom);
      return (
        "https://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw" +
        "/" +
        zoom +
        "/" +
        normalizedCoord.x +
        "/" +
        (bound - normalizedCoord.y - 1) +
        ".jpg"
      );
    },
    tileSize: new google.maps.Size(256, 256),
    maxZoom: 9,
    minZoom: 0,
    // @ts-ignore TODO 'radius' does not exist in type 'ImageMapTypeOptions'
    radius: 1738000,
    name: "Moon",
  });

  map.mapTypes.set("moon", moonMapType);
  map.setMapTypeId("moon");
}

// Normalizes the coords that tiles repeat across the x axis (horizontally)
// like the standard Google map tiles.
function getNormalizedCoord(coord, zoom) {
  const y = coord.y;
  let x = coord.x;
  // tile range in one direction range is dependent on zoom level
  // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc
  const tileRange = 1 << zoom;

  // don't repeat across y-axis (vertically)
  if (y < 0 || y >= tileRange) {
    return null;
  }

  // repeat across x-axis
  if (x < 0 || x >= tileRange) {
    x = ((x % tileRange) + tileRange) % tileRange;
  }
  return { x: x, y: y };
}

window.initMap = initMap;
ดูตัวอย่าง

ลองใช้ตัวอย่าง

การคาดการณ์

โลกเป็นทรงกลม 3 มิติ (โดยประมาณ) ส่วนแผนที่พื้นราบ 2 มิติ แผนที่ที่คุณเห็นภายใน Maps JavaScript API เป็นแบบเดียวกับแผนที่แผ่นราบในโลก คือเส้นโครงของทรงกลมนั้นบนพื้นผิวราบเรียบ กล่าวอย่างง่ายที่สุดคือ การฉายภาพสามารถกำหนดเป็นการแมปค่าละติจูด/ลองจิจูดลงในพิกัดบนแผนที่ของการฉายภาพ

การคาดการณ์ใน Maps JavaScript API ต้องใช้อินเทอร์เฟซ Projection การใช้งาน Projection ไม่ใช่แค่การแมปจากระบบพิกัดหนึ่งไปยังอีกระบบหนึ่งเท่านั้น แต่รวมถึงการแมปแบบ 2 ทิศทางด้วย กล่าวคือ คุณต้องกำหนดวิธีแปลจากพิกัดโลก (วัตถุ LatLng) เป็นระบบพิกัดโลกของคลาส Projection และในทางกลับกันด้วย Google Maps ใช้เส้นโครงเมอร์เคเตอร์เพื่อสร้างแผนที่จากข้อมูลทางภูมิศาสตร์และแปลงเหตุการณ์ต่างๆ บนแผนที่เป็นพิกัดทางภูมิศาสตร์ คุณดูการคาดการณ์นี้ได้โดยเรียกใช้ getProjection() ใน Map (หรือประเภทฐาน MapType แบบมาตรฐานใดก็ได้) สำหรับการใช้งานส่วนใหญ่ Projection มาตรฐานนี้ก็เพียงพอแล้ว แต่คุณกำหนดและใช้การคาดการณ์ที่กำหนดเองได้ด้วย

การใช้การคาดการณ์

เมื่อใช้การฉายภาพที่กำหนดเอง คุณจะต้องกำหนดสิ่งต่อไปนี้

  • สูตรในการแมปพิกัดละติจูดและลองจิจูดลงในระนาบคาร์ทีเซียนและพิกัดละติจูดและลองจิจูดบนระนาบคาร์ทีเซียน (อินเทอร์เฟซ Projection รองรับเฉพาะการแปลงเป็นพิกัดเชิงเส้นเท่านั้น)
  • ขนาดการ์ดฐาน ชิ้นส่วนทั้งหมดต้องเป็นรูปสี่เหลี่ยมผืนผ้า
  • "ขนาดโลก" ของแผนที่ที่ใช้ชุดชิ้นส่วนพื้นฐานที่ระดับการซูม 0 โปรดทราบว่าสำหรับแผนที่ที่มี 1 ไทล์ที่การซูม 0 ขนาดโลกและขนาดชิ้นส่วนฐานจะเท่ากัน

ประสานงานการเปลี่ยนรูปแบบในการคาดการณ์

การฉายภาพแต่ละครั้งเป็นวิธี 2 วิธีในการแปลงระหว่างระบบพิกัด 2 ระบบนี้ ซึ่งช่วยให้คุณแปลงพิกัดทางภูมิศาสตร์กับพิกัดโลกได้ ดังนี้

  • เมธอด Projection.fromLatLngToPoint() จะแปลงค่า LatLng เป็นพิกัดโลก วิธีนี้ใช้เพื่อวางตำแหน่งการวางซ้อนบนแผนที่ (และเพื่อกำหนดตำแหน่งแผนที่)
  • เมธอด Projection.fromPointToLatLng() จะแปลงพิกัดโลกเป็นค่า LatLng วิธีการนี้ใช้เพื่อแปลงเหตุการณ์อย่างเช่นการคลิกที่เกิดขึ้นบนแผนที่เป็นข้อมูลพิกัดทางภูมิศาสตร์

Google Maps จะถือว่าเส้นโครงเป็นเส้นตรง

โดยทั่วไปแล้ว คุณอาจใช้เส้นโครงใน 2 กรณี ได้แก่ การสร้างแผนที่โลก หรือการสร้างแผนที่ของท้องถิ่น ในกรณีแรก คุณควรตรวจสอบว่าการฉายภาพเป็นเส้นตรงและปกติที่ลองจิจูดทั้งหมด เส้นโครงบางอย่าง (โดยเฉพาะเส้นโครงรูปกรวย) อาจเป็นแบบ "ปกติทั่วไป" (เช่น ชี้ขึ้นเหนือ) แต่เบี่ยงเบนจากทิศเหนือจริง ตัวอย่างเช่น ยิ่งแผนที่อยู่ไกลออกไปเมื่อเทียบกับลองจิจูดอ้างอิงบางส่วน คุณอาจใช้การฉายภาพดังกล่าวภายในเครื่องได้ แต่โปรดทราบว่าการฉายภาพนั้นอาจไม่แม่นยำเสมอไป และข้อผิดพลาดในการเปลี่ยนรูปแบบจะเห็นได้ชัดมากขึ้นเรื่อยๆ ยิ่งห่างจาก ลองจิจูดอ้างอิงที่คุณเบี่ยงเบนไป

การเลือกชิ้นส่วนแผนที่ในเส้นโครง

เส้นโครงแผนที่ไม่เพียงมีประโยชน์ในการกำหนดตำแหน่งของสถานที่หรือการวางซ้อนเท่านั้น แต่ยังมีประโยชน์ในการระบุตำแหน่งตัวชิ้นส่วนแผนที่ด้วย Maps JavaScript API จะแสดงผลแผนที่ฐานโดยใช้อินเทอร์เฟซ MapType ซึ่งต้องประกาศทั้งพร็อพเพอร์ตี้ projection สำหรับการระบุการฉายภาพของแผนที่ และวิธี getTile() ในการเรียกชิ้นส่วนแผนที่ตามค่าพิกัดของไทล์ พิกัดของชิ้นส่วนขึ้นอยู่กับทั้งขนาดชิ้นส่วนพื้นฐาน (ซึ่งต้องเป็นสี่เหลี่ยมผืนผ้า) และ "ขนาดโลก" ของแผนที่ ซึ่งเป็นขนาดพิกเซลของโลกในแผนที่ของคุณที่ระดับการซูม 0 (สำหรับแผนที่ที่มี 1 ไทล์ที่การซูม 0 นั้น ขนาดของชิ้นส่วนและขนาดโลกจะเท่ากัน)

คุณกําหนดขนาดชิ้นส่วนฐานภายในพร็อพเพอร์ตี้ tileSize ของ MapType คุณกำหนดขนาดโลกโดยปริยายภายในเมธอด fromLatLngToPoint() และ fromPointToLatLng() ของการคาดการณ์

เนื่องจากการเลือกรูปภาพขึ้นอยู่กับค่าที่ส่งผ่านเหล่านี้ จึงมีประโยชน์ในการตั้งชื่อรูปภาพที่จะเลือกแบบเป็นโปรแกรมได้ด้วยค่าที่ส่งผ่านดังกล่าว เช่น map_zoom_tileX_tileY.png

ตัวอย่างต่อไปนี้กำหนด ImageMapType โดยใช้การฉายภาพ Gall-Peters

TypeScript

// This example defines an image map type using the Gall-Peters
// projection.
// https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection

function initMap(): void {
  // Create a map. Use the Gall-Peters map type.
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 0,
      center: { lat: 0, lng: 0 },
      mapTypeControl: false,
    }
  );

  initGallPeters();
  map.mapTypes.set("gallPeters", gallPetersMapType);
  map.setMapTypeId("gallPeters");

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

  map.controls[google.maps.ControlPosition.TOP_CENTER].push(coordsDiv);
  map.addListener("mousemove", (event: google.maps.MapMouseEvent) => {
    coordsDiv.textContent =
      "lat: " +
      Math.round(event.latLng!.lat()) +
      ", " +
      "lng: " +
      Math.round(event.latLng!.lng());
  });

  // Add some markers to the map.
  map.data.setStyle((feature) => {
    return {
      title: feature.getProperty("name") as string,
      optimized: false,
    };
  });
  map.data.addGeoJson(cities);
}

let gallPetersMapType;

function initGallPeters() {
  const GALL_PETERS_RANGE_X = 800;
  const GALL_PETERS_RANGE_Y = 512;

  // Fetch Gall-Peters tiles stored locally on our server.
  gallPetersMapType = new google.maps.ImageMapType({
    getTileUrl: function (coord, zoom) {
      const scale = 1 << zoom;

      // Wrap tiles horizontally.
      const x = ((coord.x % scale) + scale) % scale;

      // Don't wrap tiles vertically.
      const y = coord.y;

      if (y < 0 || y >= scale) return "";

      return (
        "https://developers.google.com/maps/documentation/" +
        "javascript/examples/full/images/gall-peters_" +
        zoom +
        "_" +
        x +
        "_" +
        y +
        ".png"
      );
    },
    tileSize: new google.maps.Size(GALL_PETERS_RANGE_X, GALL_PETERS_RANGE_Y),
    minZoom: 0,
    maxZoom: 1,
    name: "Gall-Peters",
  });

  // Describe the Gall-Peters projection used by these tiles.
  gallPetersMapType.projection = {
    fromLatLngToPoint: function (latLng) {
      const latRadians = (latLng.lat() * Math.PI) / 180;
      return new google.maps.Point(
        GALL_PETERS_RANGE_X * (0.5 + latLng.lng() / 360),
        GALL_PETERS_RANGE_Y * (0.5 - 0.5 * Math.sin(latRadians))
      );
    },
    fromPointToLatLng: function (point, noWrap) {
      const x = point.x / GALL_PETERS_RANGE_X;
      const y = Math.max(0, Math.min(1, point.y / GALL_PETERS_RANGE_Y));

      return new google.maps.LatLng(
        (Math.asin(1 - 2 * y) * 180) / Math.PI,
        -180 + 360 * x,
        noWrap
      );
    },
  };
}

// GeoJSON, describing the locations and names of some cities.
const cities = {
  type: "FeatureCollection",
  features: [
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-87.65, 41.85] },
      properties: { name: "Chicago" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-149.9, 61.218] },
      properties: { name: "Anchorage" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-99.127, 19.427] },
      properties: { name: "Mexico City" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-0.126, 51.5] },
      properties: { name: "London" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [28.045, -26.201] },
      properties: { name: "Johannesburg" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [15.322, -4.325] },
      properties: { name: "Kinshasa" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [151.207, -33.867] },
      properties: { name: "Sydney" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [0, 0] },
      properties: { name: "0°N 0°E" },
    },
  ],
};

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example defines an image map type using the Gall-Peters
// projection.
// https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection
function initMap() {
  // Create a map. Use the Gall-Peters map type.
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 0,
    center: { lat: 0, lng: 0 },
    mapTypeControl: false,
  });

  initGallPeters();
  map.mapTypes.set("gallPeters", gallPetersMapType);
  map.setMapTypeId("gallPeters");

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

  map.controls[google.maps.ControlPosition.TOP_CENTER].push(coordsDiv);
  map.addListener("mousemove", (event) => {
    coordsDiv.textContent =
      "lat: " +
      Math.round(event.latLng.lat()) +
      ", " +
      "lng: " +
      Math.round(event.latLng.lng());
  });
  // Add some markers to the map.
  map.data.setStyle((feature) => {
    return {
      title: feature.getProperty("name"),
      optimized: false,
    };
  });
  map.data.addGeoJson(cities);
}

let gallPetersMapType;

function initGallPeters() {
  const GALL_PETERS_RANGE_X = 800;
  const GALL_PETERS_RANGE_Y = 512;

  // Fetch Gall-Peters tiles stored locally on our server.
  gallPetersMapType = new google.maps.ImageMapType({
    getTileUrl: function (coord, zoom) {
      const scale = 1 << zoom;
      // Wrap tiles horizontally.
      const x = ((coord.x % scale) + scale) % scale;
      // Don't wrap tiles vertically.
      const y = coord.y;

      if (y < 0 || y >= scale) return "";
      return (
        "https://developers.google.com/maps/documentation/" +
        "javascript/examples/full/images/gall-peters_" +
        zoom +
        "_" +
        x +
        "_" +
        y +
        ".png"
      );
    },
    tileSize: new google.maps.Size(GALL_PETERS_RANGE_X, GALL_PETERS_RANGE_Y),
    minZoom: 0,
    maxZoom: 1,
    name: "Gall-Peters",
  });
  // Describe the Gall-Peters projection used by these tiles.
  gallPetersMapType.projection = {
    fromLatLngToPoint: function (latLng) {
      const latRadians = (latLng.lat() * Math.PI) / 180;
      return new google.maps.Point(
        GALL_PETERS_RANGE_X * (0.5 + latLng.lng() / 360),
        GALL_PETERS_RANGE_Y * (0.5 - 0.5 * Math.sin(latRadians)),
      );
    },
    fromPointToLatLng: function (point, noWrap) {
      const x = point.x / GALL_PETERS_RANGE_X;
      const y = Math.max(0, Math.min(1, point.y / GALL_PETERS_RANGE_Y));
      return new google.maps.LatLng(
        (Math.asin(1 - 2 * y) * 180) / Math.PI,
        -180 + 360 * x,
        noWrap,
      );
    },
  };
}

// GeoJSON, describing the locations and names of some cities.
const cities = {
  type: "FeatureCollection",
  features: [
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-87.65, 41.85] },
      properties: { name: "Chicago" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-149.9, 61.218] },
      properties: { name: "Anchorage" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-99.127, 19.427] },
      properties: { name: "Mexico City" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-0.126, 51.5] },
      properties: { name: "London" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [28.045, -26.201] },
      properties: { name: "Johannesburg" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [15.322, -4.325] },
      properties: { name: "Kinshasa" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [151.207, -33.867] },
      properties: { name: "Sydney" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [0, 0] },
      properties: { name: "0°N 0°E" },
    },
  ],
};

window.initMap = initMap;
ดูตัวอย่าง

ลองใช้ตัวอย่าง