Thư viện hình học

  1. Tổng quan
  2. Khái niệm hình học hình cầu
    1. Hàm khoảng cách và hàm diện tích
    2. Hàm điều hướng
  3. Mã hoá hình học
  4. Hàm đa giác và hàm nhiều đường
    1. containsLocation()
    2. isLocationOnEdge()

Tổng quan

Các khái niệm trong tài liệu này chỉ đề cập đến các tính năng có trong thư viện google.maps.geometry. Chiến dịch này thư viện không được tải theo mặc định khi bạn tải API JavaScript của Maps nhưng phải được chỉ định rõ ràng thông qua việc sử dụng libraries tham số tự khởi động. Để biết thêm thông tin, hãy xem Tổng quan về thư viện.

Thư viện hình học Maps JavaScript API cung cấp tiện ích các hàm để tính toán dữ liệu hình học trên bề mặt của Earth. Thư viện này bao gồm 3 không gian tên:

  • spherical chứa các tiện ích hình cầu cho phép bạn tính toán góc, khoảng cách và diện tích so với vĩ độ và kinh độ.
  • encoding chứa các tiện ích để mã hoá và giải mã đường dẫn nhiều đường theo mã Thuật toán đa dòng.
  • poly chứa các hàm hiệu dụng để tính toán liên quan đến đa giác và hình nhiều đường.

Thư viện google.maps.geometry không chứa bất kỳ các lớp; thay vào đó, thư viện này chứa các phương thức tĩnh ở trên không gian tên.

Khái niệm về hình cầu

Các hình ảnh trong API JavaScript của Maps là hai chiều và "phẳng". Tuy nhiên, Trái Đất có tính ba chiều và thường được tính gần đúng hình cầu nhân tạo hoặc nhiều hơn dưới dạng hình cầu. Trong API Maps, chúng tôi sử dụng hình cầu và để mô tả Trái Đất trên một mặt phẳng hai chiều, chẳng hạn như màn hình máy tính của bạn — API Maps sử dụng phép chiếu.

Trong các phép chiếu 2D, hình ảnh xuất hiện đôi khi có thể gây nhầm lẫn. Do phép chiếu bản đồ nhất thiết yêu cầu một chút biến dạng, nên đơn giản Hình học Euclidian thường không áp dụng được. Ví dụ: khoảng cách ngắn nhất giữa hai điểm trên một hình cầu không phải là một đường thẳng mà là một đường tròn lớn (một loại đường trắc địa) và các góc tạo thành một hình tam giác trên bề mặt tổng của hình cầu cộng lại bằng 180 độ.

Do những khác biệt này, các hàm hình học trên một hình cầu (hoặc trên phép chiếu) cần sử dụng Hình cầu để tính toán các cấu trúc như khoảng cách, hướng và diện tích. Tiện ích tới tính toán các công trình hình học hình cầu này có trong Maps Không gian tên google.maps.geometry.spherical của API. Không gian tên này cung cấp các phương thức tĩnh để tính giá trị vô hướng từ toạ độ cầu (vĩ độ và kinh độ).

Hàm khoảng cách và diện tích

Khoảng cách giữa hai điểm là độ dài đường đi ngắn nhất giữa chúng. Đường đi ngắn nhất này được gọi là đường trắc địa. Trên một hình cầu, tất cả các đường trắc địa của một vòng kết nối lớn. Để tính khoảng cách này, hãy gọi computeDistanceBetween(), truyền vào đó 2 LatLng .

Thay vào đó, bạn có thể sử dụng computeLength() để tính chiều dài của một đường dẫn nhất định nếu bạn có nhiều vị trí.

Kết quả về khoảng cách được biểu thị bằng mét.

Để tính diện tích (tính bằng mét vuông) của một khu vực đa giác, hãy gọi computeArea(), truyền mảng đối tượng LatLng xác định một vòng lặp khép kín.

Khi điều hướng trên hình cầu, tiêu đề là góc của một hướng từ một điểm tham chiếu cố định, thường là hướng bắc. Trong API Google Maps, tiêu đề được xác định theo độ so với hướng bắc thực, trong đó tiêu đề được đo theo chiều kim đồng hồ từ hướng chính bắc (0 độ). Bạn có thể tính toán tiêu đề này trong khoảng hai địa điểm có phương thức computeHeading(), truyền vào đó hai Đối tượng fromto LatLng.

Cung cấp một tiêu đề cụ thể, vị trí điểm khởi hành và khoảng cách đến di chuyển (tính bằng mét), bạn có thể tính toạ độ điểm đến bằng cách sử dụng computeOffset().

Với 2 đối tượng LatLng và giá trị nằm trong khoảng từ 0 đến 1, bạn có thể để tính toán một đích đến giữa chúng bằng cách sử dụng Phương pháp interpolate() thực hiện tuyến tính hình cầu nội suy giữa hai vị trí, trong đó giá trị cho biết khoảng cách phân số để đi dọc theo con đường từ điểm gốc đến đích đến.

Ví dụ sau đây sẽ tạo ra hai hình nhiều đường khi bạn nhấp vào hai điểm trên bản đồ — một trắc địa và một đường trắc địa "thẳng" đường thẳng nối hai vị trí — và tính toán tiêu đề cho việc di chuyển giữa hai điểm:

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;
Xem ví dụ

Dùng thử mẫu

Phương thức mã hoá

Đường dẫn trong API JavaScript của Maps thường được chỉ định là một Array/LatLng đối tượng. Tuy nhiên, việc truyền xung quanh một mảng như vậy thường rất cồng kềnh. Thay vào đó, bạn có thể sử dụng hình nhiều đường thuật toán mã hoá để nén một đường dẫn nhất định mà sau này bạn có thể thực hiện giải nén thông qua tính năng giải mã.

geometry thư viện chứa encoding không gian tên cho các tiện ích để mã hoá và giải mã hình nhiều đường.

Phương thức tĩnh encodePath() mã hoá đường dẫn đã cho. Bạn có thể truyền một mảng LatLng hoặc một MVCArray (được trả về bởi Polyline.getPath()).

Để giải mã đường dẫn đã mã hoá, hãy gọi decodePath() truyền phương thức chuỗi mã hoá.

Ví dụ sau thể hiện bản đồ Oxford, Mississippi. Nhấp vào bản đồ sẽ thêm một điểm vào một hình nhiều đường. Vì hình nhiều đường là được tạo, chế độ mã hoá của mã đó sẽ xuất hiện bên dưới.

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;
Xem ví dụ

Dùng thử mẫu

Hàm đa giác và hàm nhiều đường

Không gian tên poly của thư viện hình học chứa các hàm hiệu dụng xác định xem một điểm cho trước nằm bên trong hay ở gần một đa giác hoặc hình nhiều đường.

containsLocation()

containsLocation(point:LatLng, polygon:Polygon)

Để tìm xem một điểm cho trước có nằm trong một đa giác hay không, hãy truyền điểm đó và đa giác đến google.maps.geometry.poly.containsLocation(). Chiến lược phát hành đĩa đơn hàm trả về true nếu điểm nằm trong đa giác hoặc trên cạnh của nó.

Mã sau đây viết là "true" vào bảng điều khiển của trình duyệt nếu người dùng nhấp vào nằm trong tam giác xác định; nếu không, hệ thống sẽ ghi "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);

Một phiên bản khác của mã này vẽ một hình tam giác màu xanh dương trên bản đồ nếu lượt nhấp giảm trong Tam giác Bermuda và nếu không phải là vòng tròn màu đỏ:

Xem ví dụ

isLocationOnEdge()

isLocationOnEdge(point:LatLng, poly:Polygon|Polyline, tolerance?:number)

Để xác định xem một điểm rơi trên hay gần một hình nhiều đường, hoặc nằm trên hoặc gần cạnh của đa giác, truyền điểm, hình nhiều đường/đa giác và giá trị dung sai tính bằng độ đến google.maps.geometry.poly.isLocationOnEdge(). Hàm trả về true nếu khoảng cách giữa điểm và điểm gần nhất trên đường hoặc cạnh nằm trong dung sai được chỉ định. Dung sai mặc định sẽ là 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);