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

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

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

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

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

แผนที่ 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
    • แผนที่ฐาน 45° จะแสดงที่ระดับการซูม 18 ขึ้นไป เว้นแต่จะตั้งค่า 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 ทิศทางด้วย กล่าวคือ คุณต้องกำหนดวิธีแปลจากพิกัด Earth (วัตถุ LatLng รายการ) ไปยังระบบพิกัดโลกของคลาส Projection และในทางกลับกันด้วย Google Maps ใช้เส้นโครงเมอร์เคเตอร์เพื่อสร้างแผนที่จากข้อมูลทางภูมิศาสตร์และแปลงเหตุการณ์บนแผนที่เป็นพิกัดทางภูมิศาสตร์ คุณรับการคาดการณ์นี้ได้โดยการเรียกใช้ getProjection() ใน Map (หรือประเภท MapType ฐานมาตรฐานใดก็ได้) สำหรับการใช้งานส่วนใหญ่ Projection มาตรฐานนี้จะเพียงพอแล้ว แต่คุณอาจกำหนดและใช้การคาดการณ์ที่กำหนดเองได้เช่นกัน

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

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

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

ประสานการแปลงโฉมใน การฉายภาพ

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

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

Google Maps มีสมมติฐานว่าเส้นโครงเป็นเส้นตรง

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

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

เส้นโครงแผนที่ไม่เพียงมีประโยชน์ในการกำหนดตำแหน่งของสถานที่หรือการวางซ้อนเท่านั้น แต่ยังใช้สำหรับการกำหนดตำแหน่งของชิ้นส่วนแผนที่ด้วยตัวเองอีกด้วย 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

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

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

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

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

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

let gallPetersMapType;

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

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

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

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

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

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

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

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

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

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

JavaScript

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

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

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

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

let gallPetersMapType;

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

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

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

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

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

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