Geometri Kitaplığı

  1. Genel Bakış
  2. Küresel Geometri Kavramları
    1. Mesafe ve Alan İşlevleri
    2. Navigasyon İşlevleri
  3. Coğrafi Kodlama
  4. Poligon ve Polyline İşlevleri
    1. containsLocation()
    2. isLocationOnEdge()

Genel bakış

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

Maps JavaScript API geometri kitaplığı, Dünya'nın yüzeyinde geometrik verilerin hesaplanması için yardımcı program işlevleri sağlar. Kitaplıkta üç ad alanı bulunur:

  • spherical enlem ve boylamlardaki açıları, mesafeleri ve alanları hesaplayabilmenizi sağlayan küresel geometri yardımcıları içerir.
  • encoding, Kodlanmış Çoklu Çizgi Algoritması'na göre çoklu çizgi yollarını kodlama ve kod çözme için yardımcı programlar içerir.
  • poly, çokgenleri ve çoklu çizgileri içeren hesaplamalar için yardımcı program işlevleri içerir.

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

Küresel Geometri Kavramları

Maps JavaScript API'deki resimler iki boyutludur ve "düz"dür. Bununla birlikte, Dünya üç boyutludur ve genellikle yaklaşık küresel küre ya da daha çok küre şeklinde ele alınır. Maps API'de bir küre kullanırız. Dünyayı bilgisayar ekranınız gibi iki boyutlu bir düz yüzey üzerinde göstermek için Maps API'de bir projeksiyon kullanılır.

2D tahminlerde bazen gösterimler aldatılabilir. Harita projeksiyonu için bir miktar distorsiyon olması gerektiğinden, basit Öklid geometrisi genellikle geçerli değildir. Örneğin, bir küre üzerindeki iki nokta arasındaki en kısa mesafe düz bir çizgi değildir, mükemmel bir dairedir (bir tür jeodezik) ve bir kürenin üçgenini oluşturan açılar toplamda 180 dereceden fazladır.

Bu farklar nedeniyle, bir küredeki (ya da projeksiyondaki) geometrik işlevler mesafe, başlık ve alan gibi yapıları hesaplamak için Küresel Geometri kullanılmasını gerektirir. Bu küresel geometrik yapıları hesaplayacak yardımcı programlar, Maps API'nin google.maps.geometry.spherical ad alanında yer alır. Bu ad alanı, küresel koordinatlardan (enlemler ve boylamlar) skaler değerleri hesaplamak için statik yöntemler sağlar.

Mesafe ve Alan İşlevleri

İki nokta arasındaki mesafe, bunlar arasındaki en kısa yolun uzunluğudur. Bu en kısa yol jeodezik olarak adlandırılır. Yerküre genelinde, tüm jeodezikler büyük bir dairenin segmentleridir. Bu mesafeyi hesaplamak için computeDistanceBetween() yöntemini çağırıp iki LatLng nesnesi iletin.

Birden fazla konumunuz varsa belirli bir yolun uzunluğunu hesaplamak için computeLength() özelliğini kullanabilirsiniz.

Mesafe sonuçları metre olarak ifade edilir.

Bir çokgen alanın alanını (metrekare) hesaplamak için computeArea() yöntemini çağırarak kapalı bir döngü tanımlayan LatLng nesnesi dizisini geçirin.

Yerküredeyken yön, genellikle kuzeydeki sabit bir referans noktasından yönün açısıdır. Google Haritalar API'sinde başlıklar, gerçek kuzeyden derece cinsinden tanımlanır ve başlıklar gerçek kuzeyden (0 derece) saat yönünde ölçülür. İki konum arasındaki bu başlığı computeHeading() yöntemiyle hesaplayarak ikifrom ve to LatLng nesneyi iletebilirsiniz.

Belirli bir başlık, kalkış noktası ve seyahat mesafesi (metre cinsinden) göz önünde bulundurularak hedef koordinatlarını computeOffset() kullanarak hesaplayabilirsiniz.

İki LatLng nesnesi ve 0 ile 1 arasındaki değer göz önüne alındığında, interpolate() yöntemini kullanarak bunların arasındaki bir hedefi de hesaplayabilirsiniz. Bu yöntem, iki konum arasında küresel doğrusal enterpolasyon gerçekleştirir. Değer, kaynaktan hedefe kadar olan yoldaki kesirli mesafeyi gösterir.

Aşağıdaki örnek, haritada iki nokta tıkladığınızda (biri jeodezik, diğeri de iki konumu birbirine bağlayan "düz" bir çizgi) iki çizgi çizgisi oluşturmakta ve iki nokta arasındaki seyahat başlığını 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öster

Örneği Deneyin

Kodlama Yöntemleri

Maps JavaScript API içindeki yollar genellikle Array/LatLng nesne olarak belirtilir. Ancak bu tür bir diziyi geçmek çoğu zaman hantaldır. Bunun yerine, belirli bir yolu sıkıştırmak için Google'ın çoklu kodlama algoritmasını kullanabilirsiniz. Daha sonra bunu kod çözme işlemi ile sıkıştırabilirsiniz.

geometry kitaplığı, yardımcı programların çoklu çizgileri kodlayıp çözmesi için bir encoding ad alanı içerir.

Statik yöntem encodePath() belirtilen yolu kodlar. LatLng veya MVCArray (Polyline.getPath() ile döndürülen) dizisini iletebilirsiniz.

Kodlanmış bir yolun kodunu çözmek için decodePath() yöntemini çağırarak kodlanmış dize yöntemini iletin.

Aşağıdaki örnekte Oxford, Mississippi'nin bir haritası gösterilmektedir. Haritayı tıkladığınızda bir çoklu çizgiye nokta eklenir. Çoklu çizgi oluşturulurken kodlamanın 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öster

Örneği Deneyin

Poligon ve Polyline işlevleri

Geometri kitaplığının poly ad alanı, belirli bir noktanın bir poligonun veya çoklu çizginin içinde mi yoksa yakın mı olduğunu belirleyen yardımcı program işlevleri içerir.

şunu içerir: YerKonumu()

containsLocation(point:LatLng, polygon:Polygon)

Belirli bir noktanın bir poligon içinde olup olmadığını bulmak için noktayı ve poligonu google.maps.geometry.poly.containsLocation() konumuna iletin. Nokta, çokgen 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 altına düşerse 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ü, tıklama Bermuda Üçgeni'ne giriyorsa harita üzerinde mavi bir üçgen, aksi halde kırmızı bir daire çizer:

Örneği göster

isLocationOnEdge()

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

Bir noktanın bir çoklu çizgiye veya poligonun kenarına mı yoksa kenara mı yakın olduğunu belirlemek için noktayı, çoklu çizgiyi/çokgeni ve isteğe bağlı olarak derece cinsinden tolerans değerini google.maps.geometry.poly.isLocationOnEdge() değerine aktarın. Nokta ile çizgi veya uçtaki en yakın nokta arasındaki mesafe, belirtilen tolerans dahilindeyse 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);