ภาพรวม
แนวคิดในเอกสารนี้หมายถึงฟีเจอร์ที่มีให้บริการในไลบรารี google.maps.geometry
เท่านั้น ระบบจะไม่โหลดไลบรารีนี้โดยค่าเริ่มต้นเมื่อคุณโหลด Maps JavaScript API แต่ต้องระบุอย่างชัดเจนผ่านการใช้พารามิเตอร์ libraries
บูตสแตรป ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมของไลบรารี
ไลบรารีเรขาคณิตของ Maps JavaScript API มีฟังก์ชันยูทิลิตีสำหรับการคำนวณข้อมูลเรขาคณิตบนพื้นผิวโลก โดยไลบรารีนี้มีเนมสเปซ 3 รายการ ได้แก่
spherical
มียูทิลิตีเรขาคณิตทรงกลมที่ช่วยให้คุณคำนวณมุม ระยะทาง และพื้นที่จากละติจูดและลองจิจูดได้encoding
มียูทิลิตีสำหรับการเข้ารหัสและถอดรหัสเส้นทางแบบ Polyline ตามอัลกอริทึม Polyline ที่เข้ารหัสpoly
มีฟังก์ชันยูทิลิตีสําหรับการคํานวณที่เกี่ยวข้องกับรูปหลายเหลี่ยมและรูปหลายเส้น
ไลบรารี google.maps.geometry
ไม่มีคลาสใดๆ แต่มีเมธอดแบบคงที่ในเนมสเปซข้างต้น
แนวคิดเรขาคณิตทรงกลม
รูปภาพภายใน Maps JavaScript API เป็นแบบ 2 มิติและ "แบน" แต่โลกเป็นรูปทรง 3 มิติ และมักได้รับการประมาณว่าเป็นทรงกลมแบบ Oblate Spheroid หรือทรงกลมมากกว่า ใน Maps API เราใช้ทรงกลม และเพื่อแสดงภาพโลกบนพื้นผิว 2 มิติที่ราบเรียบ เช่น หน้าจอคอมพิวเตอร์ Maps API จะใช้ การฉายภาพ
ในการแสดงผล 2 มิติ บางครั้งลักษณะที่ปรากฏอาจทำให้เข้าใจผิด เนื่องจากต้องมีการบิดเบือนบางอย่างในการฉายแผนที่ เรขาคณิตแบบยุคลิดแบบง่ายจึงมักใช้ไม่ได้ เช่น ระยะทางที่สั้นที่สุดระหว่าง 2 จุดบนทรงกลมไม่ใช่เส้นตรง แต่เป็นเส้นรอบโลก (เส้นบอกทางประเภทหนึ่ง) และมุมที่ประกอบกันเป็นสามเหลี่ยมบนพื้นผิวทรงกลมจะมีค่ารวมมากกว่า 180 องศา
ความแตกต่างเหล่านี้ทำให้ฟังก์ชันเชิงเรขาคณิตบนทรงกลม (หรือบนภาพโปรเจ็กชัน) ต้องใช้เรขาคณิตทรงกลมเพื่อคำนวณองค์ประกอบต่างๆ เช่น ระยะทาง ทิศทาง และพื้นที่ ยูทิลิตีสำหรับคำนวณรูปเรขาคณิตทรงกลมเหล่านี้อยู่ในเนมสเปซ google.maps.geometry.spherical
ของ Maps API เนมสเปซนี้มีเมธอดแบบคงที่สําหรับคํานวณค่าสเกลาร์จากพิกัดทรงกลม (ละติจูดและลองจิจูด)
ฟังก์ชันระยะทางและพื้นที่
ระยะทางระหว่าง 2 จุดคือความยาวของเส้นทางที่สั้นที่สุดระหว่างจุดเหล่านั้น เส้นทางที่สั้นที่สุดนี้เรียกว่าเส้น geodesic ในทรงกลม เส้น geodesic ทั้งหมดจะเป็นส่วนของเส้นรอบโลก หากต้องการคํานวณระยะทางนี้ ให้เรียกใช้ computeDistanceBetween()
โดยส่งLatLng
2 รายการ
คุณอาจใช้
computeLength()
แทนเพื่อคํานวณความยาวของเส้นทางหนึ่งๆ หากมีสถานที่ตั้งหลายแห่ง
ผลลัพธ์ระยะทางจะแสดงเป็นเมตร
หากต้องการคํานวณพื้นที่ (เป็นตารางเมตร) ของพื้นที่รูปหลายเหลี่ยม ให้เรียกใช้ computeArea()
โดยส่งอาร์เรย์ของออบเจ็กต์ LatLng
ที่กําหนดลูปปิด
ฟังก์ชันการนําทาง
เมื่อนำทางบนทรงกลม ทิศทางคือมุมของทิศทางจากจุดอ้างอิงที่คงที่ ซึ่งมักจะเป็นทิศเหนือจริง ใน Google Maps API ทิศทางจะกำหนดเป็นองศาจากทิศเหนือจริง โดยระบบจะวัดทิศทางตามเข็มนาฬิกาจากทิศเหนือจริง (0 องศา) คุณสามารถคํานวณทิศทางนี้ระหว่างสถานที่ 2 แห่งด้วยเมธอด computeHeading()
โดยส่งออบเจ็กต์ from
และ to
LatLng
2 รายการ
เมื่อทราบทิศทาง ตำแหน่งต้นทาง และระยะทาง (เป็นเมตร) ที่จะเดินทาง คุณจะคำนวณพิกัดปลายทางได้โดยใช้ computeOffset()
เมื่อทราบออบเจ็กต์ LatLng
2 รายการและค่าระหว่าง 0 ถึง 1 คุณยังคำนวณปลายทางระหว่างออบเจ็กต์เหล่านั้นได้โดยใช้เมธอด interpolate()
ซึ่งจะทำการประมาณเชิงเส้นทรงกลมระหว่างสถานที่ตั้ง 2 แห่ง โดยค่าที่ระบุคือระยะทางส่วนที่เป็นเศษที่จะเดินทางไปตามเส้นทางจากต้นทางไปยังปลายทาง
ตัวอย่างต่อไปนี้จะสร้างเส้นประกอบ 2 เส้นเมื่อคุณคลิก 2 จุดบนแผนที่ ซึ่งก็คือเส้น geodesic เส้นหนึ่งและเส้น "ตรง" เส้นหนึ่งที่เชื่อมต่อ 2 ตำแหน่งเข้าด้วยกัน และคำนวณทิศทางการเดินทางระหว่าง 2 จุด
TypeScript
// This example requires the Geometry library. Include the libraries=geometry // parameter when you first load the API. For example: // <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"> let marker1: google.maps.Marker, marker2: google.maps.Marker; let poly: google.maps.Polyline, geodesicPoly: google.maps.Polyline; function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 4, center: { lat: 34, lng: -40.605 }, } ); map.controls[google.maps.ControlPosition.TOP_CENTER].push( document.getElementById("info") as HTMLElement ); marker1 = new google.maps.Marker({ map, draggable: true, position: { lat: 40.714, lng: -74.006 }, }); marker2 = new google.maps.Marker({ map, draggable: true, position: { lat: 48.857, lng: 2.352 }, }); const bounds = new google.maps.LatLngBounds( marker1.getPosition() as google.maps.LatLng, marker2.getPosition() as google.maps.LatLng ); map.fitBounds(bounds); google.maps.event.addListener(marker1, "position_changed", update); google.maps.event.addListener(marker2, "position_changed", update); poly = new google.maps.Polyline({ strokeColor: "#FF0000", strokeOpacity: 1.0, strokeWeight: 3, map: map, }); geodesicPoly = new google.maps.Polyline({ strokeColor: "#CC0099", strokeOpacity: 1.0, strokeWeight: 3, geodesic: true, map: map, }); update(); } function update() { const path = [ marker1.getPosition() as google.maps.LatLng, marker2.getPosition() as google.maps.LatLng, ]; poly.setPath(path); geodesicPoly.setPath(path); const heading = google.maps.geometry.spherical.computeHeading( path[0], path[1] ); (document.getElementById("heading") as HTMLInputElement).value = String(heading); (document.getElementById("origin") as HTMLInputElement).value = String( path[0] ); (document.getElementById("destination") as HTMLInputElement).value = String( path[1] ); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// This example requires the Geometry library. Include the libraries=geometry // parameter when you first load the API. For example: // <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"> let marker1, marker2; let poly, geodesicPoly; function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: { lat: 34, lng: -40.605 }, }); map.controls[google.maps.ControlPosition.TOP_CENTER].push( document.getElementById("info"), ); marker1 = new google.maps.Marker({ map, draggable: true, position: { lat: 40.714, lng: -74.006 }, }); marker2 = new google.maps.Marker({ map, draggable: true, position: { lat: 48.857, lng: 2.352 }, }); const bounds = new google.maps.LatLngBounds( marker1.getPosition(), marker2.getPosition(), ); map.fitBounds(bounds); google.maps.event.addListener(marker1, "position_changed", update); google.maps.event.addListener(marker2, "position_changed", update); poly = new google.maps.Polyline({ strokeColor: "#FF0000", strokeOpacity: 1.0, strokeWeight: 3, map: map, }); geodesicPoly = new google.maps.Polyline({ strokeColor: "#CC0099", strokeOpacity: 1.0, strokeWeight: 3, geodesic: true, map: map, }); update(); } function update() { const path = [marker1.getPosition(), marker2.getPosition()]; poly.setPath(path); geodesicPoly.setPath(path); const heading = google.maps.geometry.spherical.computeHeading( path[0], path[1], ); document.getElementById("heading").value = String(heading); document.getElementById("origin").value = String(path[0]); document.getElementById("destination").value = String(path[1]); } window.initMap = initMap;
ลองใช้ตัวอย่าง
วิธีการเข้ารหัส
เส้นทางภายใน Maps JavaScript API มักระบุเป็นArray
ของออบเจ็กต์ LatLng
อย่างไรก็ตาม การส่งผ่านอาร์เรย์ดังกล่าวมักจะมีขนาดใหญ่ คุณอาจใช้อัลกอริทึมการเข้ารหัส Polyline ของ Google เพื่อบีบอัดเส้นทางหนึ่งๆ แทน ซึ่งคุณจะถอดรหัสได้ภายหลัง
ไลบรารี geometry
มีเนมสเปซ encoding
สำหรับยูทิลิตีในการเข้ารหัสและถอดรหัสเส้นประกอบ
เมธอดแบบคงที่ encodePath()
จะเข้ารหัสเส้นทางที่ระบุ
คุณสามารถส่งอาร์เรย์ของ LatLng
หรือ MVCArray
(ซึ่ง Polyline.getPath()
จะแสดงผล)
หากต้องการถอดรหัสเส้นทางที่เข้ารหัส ให้เรียกใช้ decodePath()
โดยส่งสตริงที่เข้ารหัสไปยังเมธอด
ตัวอย่างต่อไปนี้แสดงแผนที่ของเมืองอ็อกซ์ฟอร์ด รัฐมิสซิสซิปปี การคลิกแผนที่จะเพิ่มจุดลงในเส้นประกอบ เมื่อสร้างเส้นประกอบแล้ว การโค้ดจะปรากฏอยู่ด้านล่าง
TypeScript
// This example requires the Geometry library. Include the libraries=geometry // parameter when you first load the API. For example: // <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"> function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 14, center: { lat: 34.366, lng: -89.519 }, } ); const poly = new google.maps.Polyline({ strokeColor: "#000000", strokeOpacity: 1, strokeWeight: 3, map: map, }); // Add a listener for the click event google.maps.event.addListener(map, "click", (event) => { addLatLngToPoly(event.latLng, poly); }); } /** * Handles click events on a map, and adds a new point to the Polyline. * Updates the encoding text area with the path's encoded values. */ function addLatLngToPoly( latLng: google.maps.LatLng, poly: google.maps.Polyline ) { const path = poly.getPath(); // Because path is an MVCArray, we can simply append a new coordinate // and it will automatically appear path.push(latLng); // Update the text field to display the polyline encodings const encodeString = google.maps.geometry.encoding.encodePath(path); if (encodeString) { (document.getElementById("encoded-polyline") as HTMLInputElement).value = encodeString; } } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// This example requires the Geometry library. Include the libraries=geometry // parameter when you first load the API. For example: // <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"> function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 14, center: { lat: 34.366, lng: -89.519 }, }); const poly = new google.maps.Polyline({ strokeColor: "#000000", strokeOpacity: 1, strokeWeight: 3, map: map, }); // Add a listener for the click event google.maps.event.addListener(map, "click", (event) => { addLatLngToPoly(event.latLng, poly); }); } /** * Handles click events on a map, and adds a new point to the Polyline. * Updates the encoding text area with the path's encoded values. */ function addLatLngToPoly(latLng, poly) { const path = poly.getPath(); // Because path is an MVCArray, we can simply append a new coordinate // and it will automatically appear path.push(latLng); // Update the text field to display the polyline encodings const encodeString = google.maps.geometry.encoding.encodePath(path); if (encodeString) { document.getElementById("encoded-polyline").value = encodeString; } } window.initMap = initMap;
ลองใช้ตัวอย่าง
ฟังก์ชันรูปหลายเหลี่ยมและเส้นประกอบ
เนมสเปซ poly
ของไลบรารีเรขาคณิตมีฟังก์ชันยูทิลิตีที่ระบุว่าจุดหนึ่งๆ อยู่ภายในหรือใกล้กับรูปหลายเหลี่ยมหรือเส้นประกอบหรือไม่
containsLocation()
containsLocation(point:LatLng, polygon:Polygon)
หากต้องการดูว่าจุดหนึ่งๆ อยู่ในรูปหลายเหลี่ยมหรือไม่ ให้ส่งจุดและรูปหลายเหลี่ยมไปยัง google.maps.geometry.poly.containsLocation()
ฟังก์ชันจะแสดงผลเป็น "จริง" หากจุดอยู่ภายในหรือบนขอบของรูปหลายเหลี่ยม
โค้ดต่อไปนี้จะเขียน "จริง" ลงในคอนโซลเบราว์เซอร์หากการคลิกของผู้ใช้อยู่ภายในสามเหลี่ยมที่กําหนดไว้ ไม่เช่นนั้นก็จะเขียน "เท็จ"
function initialize() { var mapOptions = { zoom: 5, center: new google.maps.LatLng(24.886, -70.269), mapTypeId: 'terrain' }; var map = new google.maps.Map(document.getElementById('map'), mapOptions); var bermudaTriangle = new google.maps.Polygon({ paths: [ new google.maps.LatLng(25.774, -80.190), new google.maps.LatLng(18.466, -66.118), new google.maps.LatLng(32.321, -64.757) ] }); google.maps.event.addListener(map, 'click', function(event) { console.log(google.maps.geometry.poly.containsLocation(event.latLng, bermudaTriangle)); }); } google.maps.event.addDomListener(window, 'load', initialize);
รหัสเวอร์ชันอื่นของโค้ดนี้จะวาดรูปสามเหลี่ยมสีน้ำเงินบนแผนที่หากการคลิกอยู่ภายในสามเหลี่ยมเบอร์มิวดา และวาดวงกลมสีแดงหากไม่ใช่
isLocationOnEdge()
isLocationOnEdge(point:LatLng, poly:Polygon|Polyline, tolerance?:number)
หากต้องการตรวจสอบว่าจุดหนึ่งๆ อยู่ในหรือใกล้กับเส้นประกอบ หรืออยู่ในหรือใกล้กับขอบของรูปหลายเหลี่ยม ให้ส่งจุด เส้นประกอบ/รูปหลายเหลี่ยม และค่าความคลาดเคลื่อนเป็นองศา (ไม่บังคับ) ไปยัง google.maps.geometry.poly.isLocationOnEdge()
ฟังก์ชันจะแสดงผลเป็น "จริง" หากระยะทางระหว่างจุดนั้นกับจุดที่ใกล้ที่สุดบนเส้นหรือขอบอยู่ภายในความคลาดเคลื่อนที่กำหนด ค่าความคลาดเคลื่อนเริ่มต้นคือ 10-9 องศา
function initialize() { var myPosition = new google.maps.LatLng(46.0, -125.9); var mapOptions = { zoom: 5, center: myPosition, mapTypeId: 'terrain' }; var map = new google.maps.Map(document.getElementById('map'), mapOptions); var cascadiaFault = new google.maps.Polyline({ path: [ new google.maps.LatLng(49.95, -128.1), new google.maps.LatLng(46.26, -126.3), new google.maps.LatLng(40.3, -125.4) ] }); cascadiaFault.setMap(map); if (google.maps.geometry.poly.isLocationOnEdge(myPosition, cascadiaFault, 10e-1)) { alert("Relocate!"); } } google.maps.event.addDomListener(window, 'load', initialize);