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

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

ภาพรวม

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

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

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

ไลบรารี google.maps.geometry ไม่มี ชั้นเรียน แต่ไลบรารีมีวิธีแบบคงที่ข้างต้น เนมสเปซ

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

ภาพใน Maps JavaScript API เป็นแบบ 2 มิติ และ "แฟลต" อย่างไรก็ตาม โลกเป็น 3 มิติ และ ประมาณว่า สฟิอรอยด์แบบสับปะรด หรือมากกว่าเป็นทรงกลม ภายในแผนที่ API เราใช้ทรงกลม และเพื่อ แสดงแทนโลกบนพื้นผิวราบเรียบ 2 มิติ เช่น หน้าจอคอมพิวเตอร์ของคุณ Maps API ใช้ การฉายภาพ

ในการคาดการณ์แบบ 2 มิติ บางครั้งการปรากฏตัวอาจหลอกลวงได้ เนื่องจากเส้นโครงแผนที่จำเป็นต้องบิดเบี้ยว เรียบง่าย เรขาคณิตแบบยุคลิดมักจะไม่เกี่ยวข้อง เช่น ระยะทางที่สั้นที่สุด ระหว่างจุด 2 จุดบนทรงกลมไม่เป็นเส้นตรง แต่เป็นวงกลมที่ยิ่งใหญ่ (เป็นรูปเรขาคณิตประเภทหนึ่ง) และมุมที่ประกอบกันขึ้นเป็นรูปสามเหลี่ยมบนพื้นผิวนั้น ของทรงกลมรวมกันแล้วเกิน 180 องศา

และเนื่องจากความแตกต่างเหล่านี้ ฟังก์ชันเรขาคณิตในทรงกลม (หรือบนรูปทรงกลม การคาดการณ์) จำเป็นต้องมีการใช้ เรขาคณิตทรงกลม เพื่อคำนวณสิ่งปลูกสร้างต่างๆ เช่น ระยะทาง ทิศทาง และพื้นที่ สาธารณูปโภคสำหรับ คำนวณว่าโครงสร้างเรขาคณิตทรงกลมเหล่านี้มีอยู่ในแผนที่ เนมสเปซ google.maps.geometry.spherical ของ API เนมสเปซนี้ มอบวิธีการแบบคงที่สำหรับการคำนวณค่าสเกลาร์จากพิกัดทรงกลม (ละติจูดและลองจิจูด)

ฟังก์ชันระยะทางและพื้นที่

ระยะทางระหว่างจุด 2 จุดคือความยาวของเส้นทางที่สั้นที่สุดระหว่าง ให้พวกเขา เส้นทางที่สั้นที่สุดนี้เรียกว่าเส้นธรณี ในทรงกลมทรงกลมทั้งหมด ส่วนของวงกลมที่ยิ่งใหญ่ ในการคำนวณระยะทางนี้ เรียก computeDistanceBetween(), ส่ง 2, LatLng ออบเจ็กต์

คุณอาจใช้ แทน computeLength() เพื่อคำนวณความยาว ของเส้นทางที่กำหนด หากคุณมีหลายตำแหน่ง

ผลการวัดระยะทางแสดงเป็นหน่วยเมตร

หากต้องการคำนวณพื้นที่ (เป็นตารางเมตร) ของพื้นที่รูปหลายเหลี่ยม โปรดเรียก computeArea() ส่งอาร์เรย์ของออบเจ็กต์ LatLng รายการ ซึ่งเป็นการกำหนดลูปปิด

เมื่อนำทางไปบนทรงกลม ส่วนหัวคือมุมของทิศทาง จากจุดอ้างอิงคงที่ ซึ่งโดยปกติจะเป็นทิศเหนือจริง ใน Google Maps API ส่วนหัวจะกำหนดเป็นองศาจากทิศเหนือจริง โดยมีการวัดส่วนหัว ตามเข็มนาฬิกาจากทิศเหนือจริง (0 องศา) คุณอาจประมวลผลส่วนหัวนี้ระหว่าง 2 แห่งที่มี computeHeading(), ส่ง 2 from และ to LatLng ออบเจ็กต์

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

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

ตัวอย่างต่อไปนี้สร้างเส้นประกอบ 2 เส้นเมื่อคุณคลิกจุด 2 จุด บนแผนที่ — รูปธรณีรูป 1 รูปและรูป "ตรง" 1 รูป เส้นเชื่อมถนน 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 รายการ แต่การขับไปรอบๆ อาร์เรย์ดังกล่าวมักมีขนาดใหญ่ คุณสามารถใช้ เส้นประกอบ อัลกอริทึมการเข้ารหัสเพื่อบีบอัดเส้นทางที่ระบุ ซึ่งคุณสามารถทำได้ในภายหลัง ขยายขนาดผ่านการถอดรหัส

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" ลงในคอนโซลของเบราว์เซอร์เมื่อผู้ใช้คลิก อยู่ภายในสามเหลี่ยมที่กำหนด มิเช่นนั้น จะเขียนเป็น "เท็จ"

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);