เอกสารนี้อธิบายแผนที่ประเภทต่างๆ ที่คุณแสดงได้โดยใช้ 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 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° พิเศษสำหรับบางสถานที่ ภาพความละเอียดสูงนี้แสดงมุมมองภาพ 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;