Geometri Kitaplığı

  1. Genel Bakış
  2. Küresel Geometri Kavramları
    1. Mesafe ve Alan İşlevleri
    2. Gezinme İşlevleri
  3. Geometri Kodlaması
  4. Poligon ve Çoklu Çizgi İşlevleri
    1. containsLocation()
    2. isLocationOnEdge()

Genel bakış

Bu belgedeki kavramlar yalnızca google.maps.geometry kitaplığında bulunan özelliklerle ilgilidir. Maps JavaScript API'yi yüklediğinizde bu kitaplık varsayılan olarak yüklenmez ancak libraries önyükleme parametresi kullanılarak açıkça belirtilmelidir. Daha fazla bilgi için Kitaplıklara Genel Bakış konusuna bakın.

Maps JavaScript API geometri kitaplığı, Dünya yüzeyindeki geometrik verilerin hesaplanması için yardımcı işlevler sunar. Kitaplık üç ad alanı içerir:

  • spherical enlem ve boylamlardan açıları, mesafeleri ve alanları hesaplamanıza olanak tanıyan küresel geometri yardımcı programları içerir.
  • encoding, çoklu çizgi yollarını Kodlanmış Çoklu Çizgi Algoritması'na göre kodlamak ve kodunu çözmek için yardımcı programlar içerir.
  • poly, poligonlar ve çoklu çizgileri içeren hesaplamalar için yardımcı işlevler içerir.

google.maps.geometry kitaplığı herhangi bir sınıf içermez. Bunun yerine kitaplık, yukarıdaki ad alanlarında statik yöntemler içerir.

Küresel Geometri Kavramları

Maps JavaScript API'deki resimler iki boyutlu ve "düz"dür. Öte yandan Dünya üç boyutludur ve çoğu zaman kabarık spheroid veya daha çok küre şeklinde elde edilir. Maps API'de bir küre kullanırız. Dünyayı, bilgisayar ekranınız gibi iki boyutlu bir düz yüzeyde göstermek için ise Maps API bir projeksiyon kullanır.

2D projeksiyonlar içindeki görünümler bazen yanıltıcı olabilir. Harita projeksiyonu mutlaka bir miktar bozulma gerektirdiğinden, basit Öklid geometrisi çoğu zaman geçerli değildir. Örneğin, bir küre üzerinde iki nokta arasındaki en kısa mesafe düz bir çizgi değil, büyük bir daire (bir tür jeodezik) ve bir kürenin yüzeyinde bir üçgeni oluşturan açıların toplamı 180 dereceden fazladır.

Bu farklılıklar nedeniyle, bir küre üzerindeki (ya da projeksiyonu üzerindeki) geometrik fonksiyonlar, bu tür yapıları (mesafe, yön ve alan gibi) hesaplamak için Küresel Geometri'nin kullanılmasını gerektirir. Bu küresel geometrik yapıları hesaplayan yardımcı programlar, Maps API'nin google.maps.geometry.spherical ad alanı içinde yer alır. Bu ad alanı, küresel koordinatları (enlemler ve boylamlar) kullanarak skaler değerleri hesaplamak için statik yöntemler sunar.

Mesafe ve Alan İşlevleri

İki nokta arasındaki mesafe, aradaki en kısa yolun uzunluğudur. Bu en kısa yola jeodezik denir. Bir küredeki tüm jedezikler, büyük bir dairenin parçalarıdır. Bu mesafeyi hesaplamak için computeDistanceBetween() yöntemini çağırarak iki LatLng nesnesini geçirin.

Birden fazla konumunuz varsa belirli bir yolun uzunluğunu hesaplamak için bunun yerine computeLength() kullanabilirsiniz.

Mesafe sonuçları metre cinsinden ifade edilir.

Bir poligon alanın alanını (metrekare) hesaplamak için kapalı döngü tanımlayan LatLng nesne dizisinden computeArea() çağrısı yapın.

Bir kürede gezinirken, yön, genellikle gerçek kuzey olan sabit bir referans noktasından bir yönün açısıdır. Google Maps API'de bir başlık gerçek kuzeyden başlayarak derece cinsinden tanımlanır. Başlıklar, saat yönünde gerçek kuzeyden (0 derece) itibaren ölçülür. Bu başlığı computeHeading() yöntemini kullanarak iki konum arasında hesaplayarak iki from ve to LatLng nesnesi aktarabilirsiniz.

Belirli bir yön, kalkış konumu ve seyahat edilecek mesafe (metre cinsinden) dikkate alındığında, hedef koordinatlarını computeOffset() kullanarak hesaplayabilirsiniz.

İki LatLng nesnesi ve 0 ile 1 arasındaki bir değer verildiğinde, interpolate() yöntemini kullanarak bunlar arasındaki varış noktasını da hesaplayabilirsiniz. Bu yöntem, iki konum arasında küresel doğrusal interpolasyon gerçekleştirir. Burada değer, başlangıç noktasından varış noktasına giden yol boyunca katedilecek kesirli mesafeyi gösterir.

Aşağıdaki örnekte, harita üzerinde iki noktayı (bir jeodezik ve bir "düz" çizgi) birleştirdiğinizde iki çoklu çizgi oluşturulur ve iki nokta arasındaki seyahat için başlığı hesaplar:

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;
Örneği görüntüleyin

Örneği Deneyin

Kodlama Yöntemleri

Maps JavaScript API'deki yollar genellikle LatLng nesnenin Array değeri olarak belirtilir. Bununla birlikte, böyle bir dizinin etrafından geçmek genellikle hacimli olur. Bunun yerine, belirli bir yolu sıkıştırmak için Google'ın çoklu çizgi kodlama algoritmasını kullanabilir ve daha sonra kod çözme yoluyla bu sıkıştırmayı açabilirsiniz.

geometry kitaplığı, yardımcı programlara çoklu çizgileri kodlamak ve kodunu çözmek için bir encoding ad alanı içerir.

Statik yöntem encodePath() verilen yolu kodlar. LatLng dizilerinden oluşan bir dizi veya MVCArray (Polyline.getPath() tarafından döndürülür) aktarabilirsiniz.

Kodlanmış bir yolun kodunu çözmek için kodlanmış dizeyi ileterek decodePath() yöntemini çağırın.

Aşağıdaki örnekte Oxford, Mississippi'nin bir haritası gösterilmektedir. Haritayı tıkladığınızda çoklu çizgiye bir nokta eklenir. Çoklu çizgi oluşturulurken onun kodlaması altında görünür.

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;
Örneği görüntüleyin

Örneği Deneyin

Poligon ve Çoklu Çizgi işlevleri

Geometri kitaplığının poly ad alanı, belirli bir noktanın bir poligon veya çoklu çizginin içinde ya da yakınında olup olmadığını belirleyen yardımcı işlevler içerir.

containsLocation()

containsLocation(point:LatLng, polygon:Polygon)

Belirli bir noktanın bir poligonun içinde olup olmadığını bulmak için o noktayı ve poligonu google.maps.geometry.poly.containsLocation() geçişi yapın. Nokta poligonun içinde veya kenarındaysa işlevler doğru değerini döndürür.

Aşağıdaki kod, kullanıcının tıklaması tanımlı üçgenin içine denk geliyorsa tarayıcı konsoluna "true" (doğru), aksi takdirde "false" (yanlış) yazar.

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

Bu kodun başka bir sürümünde, tıklama Bermuda Şeytan Üçgeni'ne denk gelirse haritada mavi bir üçgen, aksi takdirde kırmızı bir daire çizer:

Örneği görüntüleyin

isLocationOnEdge()

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

Bir noktanın bir çoklu çizginin üzerine, yakınında veya poligonun kenarına ya da kenarına denk gelip gelmediğini belirlemek için noktayı, çoklu çizgiyi/poligonu ve isteğe bağlı olarak bir tolerans değerini derece cinsinden google.maps.geometry.poly.isLocationOnEdge() değerine geçirin. Nokta ile çizgi veya kenar üzerindeki en yakın nokta arasındaki mesafe, belirtilen tolerans seviyesine denk gelirse işlev doğru değerini döndürür. Varsayılan tolerans değeri 10-9 derecedir.

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