ภาพรวม
แนวคิดในเอกสารนี้อ้างอิงถึงฟีเจอร์ที่มีเฉพาะในไลบรารี google.maps.geometry เท่านั้น ระบบจะไม่โหลดไลบรารีนี้โดยค่าเริ่มต้นเมื่อคุณโหลด Maps JavaScript API แต่ต้องระบุอย่างชัดเจนผ่านการใช้พารามิเตอร์บูตสแตรป libraries ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมของไลบรารี
ไลบรารีเรขาคณิตของ Maps JavaScript API มีฟังก์ชันยูทิลิตีสำหรับการคำนวณข้อมูลเรขาคณิตบนพื้นผิวโลก ไลบรารีประกอบด้วยเนมสเปซ 3 รายการ ได้แก่
sphericalมียูทิลิตีเรขาคณิตทรงกลมที่ช่วยให้คุณคำนวณมุม ระยะทาง และพื้นที่จากละติจูดและลองจิจูดได้encodingมียูทิลิตีสำหรับการเข้ารหัสและถอดรหัสเส้นทางเส้นประกอบตามอัลกอริทึมเส้นประกอบที่เข้ารหัสpolyมีฟังก์ชันยูทิลิตีสำหรับการคำนวณที่เกี่ยวข้องกับรูปหลายเหลี่ยมและเส้นประกอบ
ไลบรารี google.maps.geometry ไม่มีคลาสใดๆ แต่ไลบรารีจะมีเมธอดแบบคงที่ในเนมสเปซข้างต้น
แนวคิดเรขาคณิตทรงกลม
รูปภาพภายใน Maps JavaScript API เป็นแบบ 2 มิติและ "แบน" อย่างไรก็ตาม โลกเป็นแบบ 3 มิติ และมักจะประมาณเป็นทรงกลมแบนหรือทรงกลมมากกว่า ภายใน Maps API เราใช้ทรงกลม และเพื่อแสดงโลกบนพื้นผิวเรียบ 2 มิติ เช่น หน้าจอคอมพิวเตอร์ Maps API จะใช้ การฉายภาพ
ในการฉายภาพ 2 มิติ บางครั้งรูปลักษณ์อาจหลอกตาได้ เนื่องจากการฉายแผนที่จำเป็นต้องมีการบิดเบือนบางอย่าง เรขาคณิตแบบยุคลิดอย่างง่ายจึงมักใช้ไม่ได้ ตัวอย่างเช่น ระยะทางที่สั้นที่สุดระหว่างจุด 2 จุดบนทรงกลมไม่ใช่เส้นตรง แต่เป็นวงกลมใหญ่ (ประเภทหนึ่งของจีโอเดสิก) และมุมที่ประกอบกันเป็นสามเหลี่ยมบนพื้นผิวของทรงกลมรวมกันได้มากกว่า 180 องศา
เนื่องจากความแตกต่างเหล่านี้ ฟังก์ชันทางเรขาคณิตบนทรงกลม (หรือบนการฉายภาพ) จึงจำเป็นต้องใช้เรขาคณิตทรงกลมเพื่อคำนวณโครงสร้างต่างๆ เช่น ระยะทาง ทิศทาง และพื้นที่ ยูทิลิตีในการคำนวณโครงสร้างทางเรขาคณิตทรงกลมเหล่านี้มีอยู่ในเนมสเปซ google.maps.geometry.spherical ของ Maps API เนมสเปซนี้มีเมธอดแบบคงที่สำหรับการคำนวณค่าสเกลาร์จากพิกัดทรงกลม (ละติจูดและลองจิจูด)
ฟังก์ชันระยะทางและพื้นที่
ระยะห่างระหว่างจุด 2 จุดคือความยาวของเส้นทางที่สั้นที่สุดระหว่างจุดทั้งสอง เส้นทางที่สั้นที่สุดนี้เรียกว่าจีโอเดสิก บนทรงกลม เส้นจีโอเดสิกทั้งหมดคือ
ส่วนของวงกลมใหญ่ หากต้องการคำนวณระยะทางนี้ ให้เรียกใช้ 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 แห่ง และคำนวณทิศทางสำหรับการเดินทางระหว่างจุด 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 อย่างไรก็ตาม การส่งอาร์เรย์ดังกล่าวไปมามักจะยุ่งยาก คุณอาจใช้อัลกอริทึมการเข้ารหัสเส้นประกอบของ 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|LatLngLiteral, polygon:Polygon|Circle|CircleLiteral)
หากต้องการดูว่าจุดที่ระบุอยู่ภายในรูปหลายเหลี่ยมหรือวงกลมหรือไม่ ให้ส่งจุดและ
google.maps.Polygon,
google.maps.Circle
หรือ
google.maps.CircleLiteral
ไปยัง
google.maps.geometry.poly.containsLocation()
ฟังก์ชันจะแสดงผล true หากจุดอยู่ภายในรูปร่างหรืออยู่บนขอบ
โค้ดต่อไปนี้จะเขียน "true" ลงในคอนโซลเบราว์เซอร์หากการคลิกของผู้ใช้อยู่ภายในสามเหลี่ยมที่กำหนดไว้ ไม่เช่นนั้นจะเขียน "false"
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);
การตรวจสอบเขตพื้นที่เสมือนและรัศมีของโซนปลอดภัย
หากต้องการตรวจสอบว่าพิกัดแบบเรียลไทม์ (เช่น ตำแหน่งของยานพาหนะ ชิ้นงาน หรือผู้ใช้) อยู่ภายในเขตพื้นที่เสมือนหรือขอบเขตโซนปลอดภัยบนแผนที่หรือไม่ ให้รวมรูปร่างแผนที่เข้ากับไลบรารี geometry ดังนี้
- เขตพื้นที่เสมือนแบบวงกลม (การตรวจสอบรัศมี): วาดขอบเขตด้วย
google.maps.Circle(หรือกำหนดgoogle.maps.CircleLiteral) แล้วส่งพิกัดเป้าหมายและวงกลมไปยังgoogle.maps.geometry.poly.containsLocation()หากต้องการระยะทางเป็นเมตรจากCircle.getCenter()ด้วย ให้ส่งพิกัดเป้าหมายและจุดศูนย์กลางไปยังgoogle.maps.geometry.spherical.computeDistanceBetween() - เขตพื้นที่เสมือนรูปหลายเหลี่ยม: วาดเส้นรอบรูปด้วย
google.maps.Polygonแล้วส่งพิกัดเป้าหมายและรูปหลายเหลี่ยมไปยังgoogle.maps.geometry.poly.containsLocation()