Geometry Library

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

ภาพรวม

แนวคิดในเอกสารนี้อ้างอิงถึงฟีเจอร์ที่มีเฉพาะในไลบรารี 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 ดังนี้