เอกสารนี้อธิบายแผนที่ประเภทต่างๆ ที่คุณแสดงได้โดยใช้ Maps JavaScript API API ใช้ออบเจ็กต์ MapType
เพื่อเก็บข้อมูลเกี่ยวกับแผนที่เหล่านี้ MapType
คืออินเทอร์เฟซที่กําหนดการแสดงผลและการใช้ชิ้นส่วนแผนที่ รวมถึงการเปลี่ยนระบบพิกัดจากพิกัดหน้าจอเป็นพิกัดโลก (บนแผนที่) MapType
แต่ละรายการต้องมีวิธีจัดการการเรียกข้อมูลและการปล่อยข้อมูลไทล์ และพร็อพเพอร์ตี้ที่กําหนดลักษณะการมองเห็น
วิธีการทํางานภายในของแผนที่แต่ละประเภทภายใน Maps JavaScript API เป็นหัวข้อขั้นสูง นักพัฒนาแอปส่วนใหญ่สามารถใช้ ประเภทแผนที่พื้นฐานที่ระบุไว้ด้านล่าง อย่างไรก็ตาม คุณยังแก้ไขการแสดงแผนที่ประเภทที่มีอยู่ได้โดยใช้แผนที่ที่มีสไตล์ หรือกำหนดชิ้นส่วนแผนที่ของคุณเองโดยใช้แผนที่ประเภทที่กำหนดเอง เมื่อระบุประเภทแผนที่ที่กำหนดเอง คุณจะต้องเข้าใจวิธีแก้ไขรีจิสทรีประเภทแผนที่ของแผนที่
ประเภทแผนที่พื้นฐาน
Maps JavaScript API มีแผนที่ 4 ประเภท นอกจากไทล์แผนที่ถนน "ภาพวาด" ที่คุ้นเคยแล้ว Maps JavaScript API ยังรองรับแผนที่ประเภทอื่นๆ ด้วย
แผนที่ประเภทต่อไปนี้มีให้บริการใน Maps JavaScript API
roadmap
แสดงมุมมองแผนภูมิเริ่มต้น ซึ่งเป็นแผนที่ประเภทเริ่มต้นsatellite
แสดงภาพถ่ายดาวเทียมของ Google Earthhybrid
แสดงมุมมองแบบปกติและมุมมองดาวเทียมผสมกัน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° แบบพิเศษสำหรับบางสถานที่ ภาพความละเอียดสูงนี้แสดงมุมมองภาพเปอร์สเปคทีฟไปยังทิศหลักแต่ละทิศ (เหนือ ใต้ ตะวันออก ตะวันตก) รูปภาพเหล่านี้จะแสดงในระดับการซูมสูงขึ้นสำหรับแผนที่ที่รองรับ
รูปภาพต่อไปนี้แสดงมุมมองภาพ 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;