ห้องสมุดเรขาคณิต

  1. ภาพรวม
  2. แนวคิดเรขาคณิตแบบทรงกลม
    1. ฟังก์ชันระยะทางและพื้นที่
    2. ฟังก์ชันการนำทาง
  3. การเข้ารหัสเรขาคณิต
  4. ฟังก์ชันรูปหลายเหลี่ยมและรูปหลายเหลี่ยม
    1. containsLocation()
    2. isLocationOnEdge()

ภาพรวม

แนวคิดในเอกสารนี้อ้างถึงฟีเจอร์ที่มีให้ใช้งานภายในไลบรารี google.maps.geometry เท่านั้น ระบบจะไม่โหลดไลบรารีนี้โดยค่าเริ่มต้นเมื่อโหลด JavaScript API ของ Maps แต่ต้องระบุอย่างชัดแจ้งผ่านการใช้พารามิเตอร์ Bootstrap ของ libraries ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมของห้องสมุด

ไลบรารีเรขาคณิตของ Maps JavaScript API มีฟังก์ชันที่เ��็นประโยชน์สำหรับการคำนวณข้อมูลเรขาคณิตบนพื้นผิวโลก ไลบรารีดังกล่าวมีเนมสเปซ 3 รายการ ได้แก่

  • spherical มียูทิลิตีเรขาคณิตทรงกลมที่ช่วยคุณคำนวณมุม ระยะทาง และพื้นที่จากละติจูดและลองจิจูดได้
  • encoding มียูทิลิตีสำหรับการเข้ารหัสและถอดรหัสเส้นทางโพลีไลน์ตามอัลกอริทึม Polyline ที่เข้ารหัส
  • poly มีฟังก์ชันยูทิลิตีสำหรับการคำนวณที่เกี่ยวข้องกับรูปหลายเหลี่ยมและโพลีไลน์

ไลบรารี google.maps.geometry ไม่มีคลาสใดๆ แต่ไลบรารีมีเมธอดแบบคงที่ในเนมสเปซด้านบน

แนวคิดเรขาคณิตแบบทรงกลม

ภาพใน Maps JavaScript API เป็นแบบ 2 มิติ และเป็นแบบ "แบน" อย่างไรก็ตาม โลกเป็น 3 มิติและมักมีค่าประมาณของ สเฟียร์ทรงกลม ขึ้นไปเป็นทรงกลม ภายในแผนที่ 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 2 รายการและ to LatLng ออบเจ็กต์

เมื่อมีส่วนหัวเฉพาะ ตำแหน่งต้นทาง และระยะทางในการเดินทาง (เป็นเมตร) คุณจะคำนวณพิกัดจุดหมายได้โดยใช้ computeOffset()

เมื่อ��ิ��า������จากออบเจ็กต์ LatLng 2 รายการและค่าระหว่าง 0 ถึง 1 คุณอาจคำนวณปลายทางระหว่างวัตถุเหล่านั้นโดยใช้เมธอด interpolate() ซึ่งแสดงการประมาณค่าเชิงเส้นแบบทรงกลมระหว่างตำแหน่งทั้ง 2 แห่ง โดยค่าจะแสดงระยะทางเป็นเศษส่วนที่จะเดินทางตามเส้นทางจากต้นทางไปยังปลายทาง

ตัวอย่างต่อไปนี้จะสร้างเส้นประกอบ 2 เส้นเมื่อคุณคลิกจุด 2 จุดบนแผนที่ — เส้นเรขาคณิต 1 เส้นและเส้น "ตรง" 1 เส้นที่เชื่อมระหว่างตำแหน่งทั้งสอง และคำนวณหัวข้อสำหรับการเดินทางระหว่าง 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, polygon:Polygon)

หากต้องการดูว่าจุดที่กำหนดอยู่ภายในรูปหลายเหลี่ยมหรือไม่ ให้ส่งจุดและรูปหลายเหลี่ยมไปยัง google.maps.geometry.poly.containsLocation() ฟังก์ชันจะแสดงผลค่า "จริง" หากจุดอยู่ภายในรูปหลายเหลี่ยมหรือขอบของจุด

โค้ดต่อไปนี้จะเขียนเป็น "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);