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

เลือกแพลตฟอร์ม 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 นั้นภายในเครื่องมือสร้างโดยการตั้งค่าออบเจ็กต์ 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° พิเศษสำหรับบางสถานที่ ภาพความละเอียดสูงนี้แสดงมุมมองภาพ 4 ทิศ (เหนือ ใต้ ตะวันออก ตะวันตก) รูปภาพเหล่านี้จะแสดงในระดับการซูมสูงขึ้นสำหรับแผนที่ที่รองรับ

รูปภาพต่อไปนี้แสดงมุมมองภาพ 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 ได้ที่การใช้ประกาศสไตล์ JSON ที่ฝัง

เพื่อหลีกเลี่ยงความขัดแย้งที่อาจเกิดขึ้น

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

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 (ดูตัวเลือกการควบคุม)
  • 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)

    โดยทั่วไปแล้วคุณควรจัดการการลบองค์ประกอบที่แนบอยู่กับชิ้นส่วนแผนที่นอกเหนือจากแผนที่ เช่น หากคุณแนบ 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 พื้นฐานโดยใช้ไทล์ Moon ของ 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 ใช้การฉายภาพ Mercator เพื่อสร้างแผนที่จากข้อมูลทางภูมิศาสตร์และแปลงเหตุการณ์บนแผนที่เป็นพิกัดทางภูมิศาสตร์ คุณดูการคาดการณ์นี้ได้โดยการเรียกใช้ 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;
ดูตัวอย่าง

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