Library Geometri

  1. Ringkasan
  2. Konsep Geometri Sferikal
    1. Fungsi Jarak dan Luas
    2. Fungsi Navigasi
  3. Encoding Geometri
  4. Fungsi Poligon dan Polyline
    1. containsLocation()
    2. isLocationOnEdge()

Ringkasan

Konsep dalam dokumen ini mengacu pada fitur yang hanya tersedia dalam library google.maps.geometry. Library ini tidak dimuat secara default saat Anda memuat Maps JavaScript API, tetapi harus ditentukan secara eksplisit melalui penggunaan parameter bootstrap libraries. Untuk informasi selengkapnya, lihat Ringkasan Library.

Library geometri Maps JavaScript API menyediakan fungsi utilitas untuk komputasi data geometris pada permukaan bumi. Library ini berisi tiga namespace:

  • spherical berisi utilitas geometri sferikal yang memungkinkan Anda menghitung sudut, jarak, dan luas dari garis lintang dan bujur.
  • encoding berisi utilitas untuk mengenkode dan mendekode jalur polyline sesuai dengan Algoritme Polyline yang Dienkode.
  • poly berisi fungsi utilitas untuk komputasi yang melibatkan poligon dan polyline.

Library google.maps.geometry tidak berisi class apa pun; sebaliknya, library-nya berisi metode statis untuk namespace di atas.

Konsep Geometri Sferikal

Gambar dalam Maps JavaScript API berbentuk dua dimensi dan "datar". Namun, Bumi adalah objek tiga dimensi, dan sering kali dianggap sebagai benda bulat yang datar pada kutubnya atau sekadar bola dunia. Dalam Maps API, kami menggunakan bola dunia, dan untuk menampilkan Bumi pada permukaan datar dua dimensi — seperti layar komputer Anda — Maps API menggunakan proyeksi.

Dalam proyeksi 2D, penampilan kadang-kadang bisa menipu. Karena proyeksi peta memerlukan beberapa distorsi, geometri Euclides sederhana sering kali tidak berlaku. Misalnya, jarak terpendek antara dua titik pada bola dunia bukanlah garis lurus, melainkan lingkaran besar (suatu jenis geodesi), dan sudut-sudut yang membentuk segi tiga pada permukaan bola dunia menghasilkan lebih dari 180 derajat.

Karena perbedaan ini, fungsi geometris pada bola dunia (atau pada proyeksinya) mengharuskan penggunaan Geometri Sferikal untuk menghitung konstruksi seperti jarak, arah tujuan, dan luas. Utilitas untuk menghitung konstruksi geometri sferikal ini terdapat dalam namespace google.maps.geometry.spherical Maps API. Namespace ini menyediakan metode statis untuk menghitung nilai-nilai skalar dari koordinat sferikal (garis lintang dan garis bujur).

Fungsi Jarak dan Luas

Jarak antara dua titik adalah panjang dari jalur terpendek di antara keduanya. Jalur terpendek ini disebut geodesi. Pada bola dunia, semua geodesi adalah segmen dari sebuah lingkaran besar. Untuk menghitung jarak ini, panggil computeDistanceBetween(), dengan meneruskan dua objek LatLng.

Anda juga dapat menggunakan computeLength() untuk menghitung panjang jalur tertentu jika Anda memiliki beberapa lokasi.

Hasil jarak dinyatakan dalam meter.

Untuk menghitung luas (dalam meter persegi) bidang poligon, panggil computeArea() dengan meneruskan array objek LatLng yang menentukan loop tertutup.

Saat melakukan navigasi pada bola dunia, arah tujuan adalah sudut arah dari titik acuan tetap, biasanya adalah utara sejati. Dalam Google Maps API, arah tujuan didefinisikan dalam derajat dari utara sejati, dengan arah tujuan diukur searah jarum jam dari utara sejati (0 derajat). Anda dapat menghitung arah tujuan ini di antara dua lokasi menggunakan metode computeHeading(), dengan meneruskan dua objek from dan to LatLng.

Dengan mempertimbangkan arah tujuan tertentu, lokasi asal, dan jarak ke perjalanan (dalam meter), Anda dapat menghitung koordinat tujuan menggunakan computeOffset().

Dengan dua objek LatLng dan nilai antara 0 dan 1, Anda juga dapat menghitung tujuan di antara keduanya menggunakan metode interpolate(), yang melakukan interpolasi linear sferikal di antara dua lokasi, yang nilainya menunjukkan jarak pecahan yang akan ditempuh sepanjang jalur dari tempat asal ke tujuan.

Contoh berikut membuat dua polyline jika Anda mengklik dua titik pada peta — satu geodesi dan satu garis "lurus" yang menghubungkan kedua lokasi — serta menghitung arah tujuan untuk perjalanan di antara kedua titik tersebut:

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;
Lihat contoh

Mencoba Contoh

Metode Encoding

Jalur dalam Maps JavaScript API sering ditentukan sebagai Array dari objek LatLng. Namun, meneruskan array seperti itu sering kali memakan tempat. Sebagai gantinya, Anda dapat menggunakan algoritme encoding polyline Google untuk mengompresi jalur tertentu, yang nantinya dapat Anda dekompresi melalui decoding.

Library geometry berisi namespace encoding agar utilitas dapat mengenkode dan mendekode polyline.

Metode statis encodePath() mengenkode jalur tertentu. Anda dapat meneruskan array dari LatLng atau MVCArray (yang ditampilkan oleh Polyline.getPath()).

Untuk mendekode jalur yang dienkode, panggil decodePath() dengan meneruskan metode string yang dienkode.

Contoh berikut menampilkan peta Oxford, Mississippi. Mengklik pada peta akan menambahkan titik ke polyline. Jika polyline telah terbentuk, encoding-nya akan muncul di bawah.

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;
Lihat contoh

Mencoba Contoh

Fungsi Poligon dan Polyline

Namespace poly library geometri berisi fungsi utilitas yang menentukan apakah titik tertentu berada di dalam atau di dekat poligon atau polyline.

containsLocation()

containsLocation(point:LatLng, polygon:Polygon)

Untuk menemukan apakah titik tertentu berada dalam poligon, teruskan titik dan poligon ke google.maps.geometry.poly.containsLocation(). Fungsi ini akan mengembalikan nilai true (benar) jika titik tersebut berada dalam poligon atau di tepinya.

Kode berikut akan menuliskan 'true' (benar) pada konsol browser jika klik pengguna berada dalam segi tiga yang didefinisikan; jika tidak, kode itu akan menulis 'false' (salah).

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

Versi lain dari kode ini menggambar segitiga biru pada peta jika klik berada dalam Segitiga Bermuda, dan lingkaran merah jika bukan:

Lihat contoh

isLocationOnEdge()

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

Untuk menentukan apakah suatu titik berada pada atau di dekat polyline, atau berada pada atau di dekat tepi poligon, teruskan titik, polyline/poligon, dan nilai toleransi opsional dalam derajat ke google.maps.geometry.poly.isLocationOnEdge(). Fungsi ini akan mengembalikan nilai true (benar) jika jarak antara titik dan titik terdekat pada garis atau tepi berada dalam toleransi yang ditetapkan. Nilai toleransi default adalah 10-9 derajat.

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