เอกสารนี้จะกล่าวถึงประเภทของแผนที่ที่คุณแสดงได้โดยใช้ 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 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)
เมธอด Map
's getTilt()
จะแสดง 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
จะมีผลกับroadmap
ประเภทแผนที่เริ่มต้นเท่านั้น
ดูข้อมูลเพิ่มเติมเกี่ยวกับ StyledMapType
ได้ที่
การใช้ประกาศรูปแบบ JSON แบบฝัง
ประเภทแผนที่ที่กำหนดเอง
Maps JavaScript API รองรับการแสดง และการจัดการประเภทแผนที่ที่กำหนดเอง ซึ่งช่วยให้คุณใช้ ภาพแผนที่หรือการวางซ้อนไทล์ของคุณเองได้
Maps JavaScript API มีการใช้งานประเภทแผนที่ที่เป็นไปได้หลายแบบ ดังนี้
- ชุดไทล์มาตรฐานที่ประกอบด้วยรูปภาพซึ่ง
รวมกันเป็นแผนที่แบบคาร์โทกราฟีที่สมบูรณ์ ชุดไทล์เหล่านี้เรียกอีกอย่างว่าประเภทแผนที่ฐาน แผนที่ประเภทเหล่านี้
จะทำงานและมีลักษณะเหมือนกับประเภทแผนที่เริ่มต้นที่มีอยู่ ได้แก่
roadmap
,satellite
,hybrid
และterrain
คุณเพิ่มประเภทแผนที่ที่กำหนดเองลงในอาร์เรย์mapTypes
ของ Map เพื่อให้ 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()
หรือไม่ โดยอิงตามพร็อพเพอร์ตี้MapType
ของtileSize
minZoom
และmaxZoom
รวมถึงวิวพอร์ตปัจจุบันและระดับการซูมของแผนที่ แฮนเดิล สำหรับเมธอดนี้ควรแสดงผลองค์ประกอบ HTML เมื่อได้รับพิกัดที่ส่งมา ระดับการซูม และองค์ประกอบ DOM ที่จะต่อท้ายรูปภาพไทล์ -
releaseTile()
(ไม่บังคับ) จะเรียกใช้เมื่อใดก็ตามที่ API พิจารณาว่าแผนที่ต้องนำไทล์ออกเนื่องจากอยู่นอกมุมมอง เมธอดนี้ต้องมีลายเซ็นต่อไปนี้releaseTile(tile:Node)
โดยปกติแล้ว คุณควรจัดการการนำองค์ประกอบใดๆ ออก ที่แนบมากับไทล์แผนที่เมื่อเพิ่มลงในแผนที่ เช่น หากคุณแนบ Listener เหตุการณ์กับโอเวอร์เลย์ไทล์แผนที่ คุณควรนำออกที่นี่
getTile()
เมธอดทำหน้าที่เป็นตัวควบคุมหลักสำหรับ
การกำหนดว่าจะโหลดไทล์ใดภายในวิวพอร์ตที่กำหนด
ประเภทแผนที่ฐาน
แผนที่ประเภทต่างๆ ที่คุณสร้างขึ้นในลักษณะนี้อาจอยู่
แยกกันหรือรวมกับแผนที่ประเภทอื่นๆ เป็นภาพซ้อนทับก็ได้ ประเภทแผนที่แบบสแตนด์อโลนเรียกว่าประเภทแผนที่ฐาน คุณอาจต้องการให้ API
ถือว่า MapType
ที่กำหนดเองดังกล่าวเป็นประเภทแผนที่ฐานอื่นๆ ที่มีอยู่ (ROADMAP
, TERRAIN
ฯลฯ) หากต้องการทำเช่นนั้น ให้เพิ่ม MapType
ที่กำหนดเองลงในพร็อพเพอร์ตี้ของ Map
mapTypes
พร็อพเพอร์ตี้นี้เป็นประเภท
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;
ลองใช้ตัวอย่าง
การคาดการณ์
โลกเป็นทรงกลมสามมิติ (โดยประมาณ) ในขณะที่แผนที่เป็นพื้นผิวแบนราบสองมิติ แผนที่ที่คุณเห็นใน Maps JavaScript API เช่น แผนที่แบบ 2 มิติของโลก เป็นการฉายภาพของทรงกลมนั้นลงบนพื้นผิวระนาบ ในแง่ง่ายๆ การฉายภาพคือการแมปค่าละติจูด/ลองจิจูดเป็นพิกัดบนแผนที่ของการฉายภาพ
การฉายใน Maps JavaScript API ต้องใช้Projection
อินเทอร์เฟซ การติดตั้งใช้งาน Projection
ต้องไม่เพียงแต่ให้การแมปจากระบบพิกัดหนึ่งไปยังอีกระบบหนึ่ง แต่ยังต้องให้การแมปแบบ 2 ทางด้วย
กล่าวคือ คุณต้อง
กำหนดวิธีแปลงจากพิกัดโลก (ออบเจ็กต์ LatLng
)
เป็นระบบพิกัดโลกของคลาส Projection
และจากระบบพิกัดโลกกลับไปเป็นพิกัดโลก
Google Maps ใช้การฉายภาพแบบเมอร์เคเตอร์เพื่อสร้างแผนที่จากข้อมูลทางภูมิศาสตร์และแปลงเหตุการณ์บนแผนที่เป็นพิกัดทางภูมิศาสตร์ คุณขอรับการคาดการณ์นี้ได้โดย
โทรหา getProjection()
ใน Map
(หรือฐานมาตรฐานประเภทใดก็ได้ MapType
) สำหรับการใช้งานส่วนใหญ่
Projection
มาตรฐานนี้ก็เพียงพอแล้ว แต่คุณยัง
กำหนดและใช้การฉายภาพที่กำหนดเองได้ด้วย
ใช้การฉายภาพ
เมื่อใช้การฉายภาพที่กำหนดเอง คุณจะต้องกำหนดสิ่งต่อไปนี้
- สูตรสำหรับการแมปพิกัดละติจูดและลองจิจูดลงใน
ระนาบคาร์ทีเซียน และสูตรที่เกี่ยวข้องสำหรับการแมปจากระนาบคาร์ทีเซียนไปยังพิกัดละติจูด
และลองจิจูด (
Projection
อินเทอร์เฟซ รองรับเฉพาะการแปลงเป็นพิกัดเส้นตรง) - ขนาดไทล์ฐาน ไทล์ทั้งหมดต้องเป็นสี่เหลี่ยมผืนผ้า
- "ขนาดโลก" ของแผนที่ที่ใช้ชุดไทล์ฐานที่ระดับการซูม 0 โปรดทราบว่าสำหรับแผนที่ที่ประกอบด้วยไทล์ 1 ไทล์ที่ระดับการซูม 0 ขนาดโลก และขนาดไทล์ฐานจะเหมือนกัน
ประสานงานการเปลี่ยนรูปแบบใน การคาดการณ์
การฉายภาพแต่ละแบบมี 2 วิธีที่แปลงระหว่างระบบพิกัด 2 ระบบนี้ เพื่อให้คุณแปลงระหว่างพิกัดทางภูมิศาสตร์กับ พิกัดโลกได้
- เมธอด
Projection.fromLatLngToPoint()
จะแปลงค่าLatLng
เป็นพิกัดโลก วิธีนี้ใช้เพื่อ วางซ้อนบนแผนที่ (และวางตำแหน่งแผนที่เอง) - เมธอด
Projection.fromPointToLatLng()
จะแปลง พิกัดโลกเป็นค่าLatLng
เมธอดนี้ใช้เพื่อแปลงเหตุการณ์ เช่น การคลิกที่เกิดขึ้นบนแผนที่ ให้เป็นพิกัดทางภูมิศาสตร์
Google Maps ถือว่าการฉายภาพเป็นเส้นตรง
โดยทั่วไป คุณอาจใช้การฉายภาพใน 2 กรณี ได้แก่ เพื่อสร้างแผนที่โลก หรือเพื่อสร้างแผนที่ของพื้นที่ท้องถิ่น ในกรณีแรก คุณควรตรวจสอบว่าการฉายภาพเป็นแบบเส้นตรงและปกติ ที่ลองจิจูดทั้งหมดด้วย การฉายภาพบางอย่าง (โดยเฉพาะการฉายภาพแบบกรวย) อาจ "ปกติในพื้นที่" (เช่น ชี้ไปทางเหนือ) แต่เบี่ยงเบนจากทิศเหนือจริง เช่น ยิ่งวางแผนที่ให้ห่างจากลองจิจูดอ้างอิงมากเท่าใด การเบี่ยงเบนก็จะยิ่งมากขึ้น คุณอาจใช้การฉายภาพดังกล่าวในเครื่อง แต่โปรดทราบว่าการฉายภาพนั้นไม่แม่นยำและข้อผิดพลาดในการแปลงจะเห็นได้ชัดเจนมากขึ้นเมื่อคุณเบี่ยงเบนไปจากลองจิจูดอ้างอิง
การเลือกไทล์แผนที่ในการคาดการณ์
การฉายภาพไม่เพียงมีประโยชน์ในการกำหนดตำแหน่งของ
สถานที่หรือภาพซ้อนทับ แต่ยังใช้ในการกำหนดตำแหน่งของไทล์แผนที่ด้วย
Maps JavaScript API แสดงผลแผนที่ฐานโดยใช้MapType
อินเทอร์เฟซ ซึ่งต้องประกาศทั้งพร็อพเพอร์ตี้ projection
สำหรับ
ระบุการฉายภาพของแผนที่และเมธอด getTile()
สำหรับการดึงข้อมูลไทล์แผนที่ตามค่าพิกัด
ไทล์ พิกัดไทล์จะอิงตาม
ทั้งขนาดไทล์พื้นฐาน (ซึ่งต้องเป็นรูปสี่เหลี่ยมผืนผ้า) และ "ขนาดโลก"
ของแผนที่ ซึ่งคือขนาดพิกเซลของโลกแผนที่ที่ระดับการซูม 0 (สำหรับแผนที่ที่ประกอบด้วยไทล์ 1 ไทล์ที่ระดับการซูม 0 ขนาดไทล์และขนาดโลกจะเหมือนกัน)
คุณกำหนดขนาดไทล์ฐานภายในพร็อพเพอร์ตี้ MapType
ของ
tileSize
คุณกำหนดขนาดโลกโดยนัย
ภายในเมธอด 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;