کتابخانه هندسه

  1. نمای کلی
  2. مفاهیم هندسه کروی
    1. عملکردهای مسافت و مساحت
    2. عملکردهای پیمایش
  3. کدبندی هندسی
  4. توابع چندضلعی و چندخطی
    1. containsLocation()
    2. isLocationOnEdge()
    3. بررسی حصارکشی جغرافیایی و شعاع منطقه امن

نمای کلی

مفاهیم موجود در این سند فقط به ویژگی‌های دردسترس در کتابخانه google.maps.geometry اشاره دارد. این کتابخانه به‌طور پیش‌فرض هنگام بار کردن Maps Javascript API بار نمی‌شود بلکه باید به‌طور صریح ازطریق استفاده از libraries پارامتر راه‌انداز مشخص شود. برای اطلاعات بیشتر، نمای کلی کتابخانه‌ها را ببینید.

کتابخانه هندسه Maps JavaScript API توابع سودمندی را برای محاسبه داده‌های هندسی روی سطح زمین ارائه می‌دهد. کتابخانه شامل سه فضای نام است:

  • spherical شامل ابزارهای هندسه کروی است که به شما امکان می‌دهد زاویه‌ها، فاصله‌ها، و مساحت‌ها را ازطریق عرض‌های جغرافیایی و طول‌های جغرافیایی محاسبه کنید.
  • encoding شامل ابزارهای کمکی برای کدبندی و کدگشایی مسیرهای چندخطی طبق الگوریتم چندخطی کدبندی‌شده است.
  • poly حاوی توابع سودمندی برای محاسبات مربوط به چندضلعی‌ها و چندخطی‌ها است.

کتابخانه google.maps.geometry حاوی هیچ کلاسی نیست؛ درعوض، کتابخانه حاوی روش‌های ایستا در فضاهای نام بالا است.

مفاهیم هندسه کروی

تصاویر موجود در Maps JavaScript API دوبعدی و «تخت» هستند. اما زمین سه‌بعدی است و اغلب به‌صورت کره پَخ یا بیشتر به‌صورت کره تخمین زده می‌شود. در Maps API از کره استفاده می‌کنیم و برای نمایش زمین روی سطح تخت دوبعدی (مثل صفحه‌نمایش رایانه)، Maps API از تصویر استفاده می‌کند.

در پیش‌بینی‌های دوبعدی، ظاهر گاهی اوقات می‌تواند فریبنده باشد. چون تصویر نقشه لزوماً به مقداری اعوجاج نیاز دارد، هندسه اقلیدسی ساده اغلب قابل‌اجرا نیست. برای مثال، کوتاه‌ترین فاصله بین دو نقطه روی یک کره خط مستقیم نیست، بلکه یک دایره بزرگ (نوعی ژئودزیک) است و مجموع زاویه‌هایی که یک مثلث را روی سطح کره تشکیل می‌دهند بیشتر از ۱۸۰ درجه است.

به‌دلیل این تفاوت‌ها، توابع هندسی روی کره (یا روی تصویر آن) مستلزم استفاده از هندسه کروی برای محاسبه ساختارهایی مانند فاصله، جهت، و مساحت است. ابزارهای کمکی برای محاسبه این ساختارهای هندسی کروی در فضای نام google.maps.geometry.spherical در Maps API قرار دارند. این فضای نام روش‌های ثابتی را برای محاسبه مقادیر اسکالر از مختصات کروی (عرض‌های جغرافیایی و طول‌های جغرافیایی) ارائه می‌دهد.

توابع فاصله و مساحت

فاصله بین دو نقطه، طول کوتاه‌ترین مسیر بین آن‌ها است. این کوتاه‌ترین مسیر، ژئودزیک نامیده می‌شود. در یک کره، همه ژئودزیک‌ها بخش‌هایی از یک دایره بزرگ هستند. برای محاسبه این فاصله، computeDistanceBetween() را فراخوانی کنید و دو شیء LatLng را به آن ارسال کنید.

درعوض می‌توانید از computeLength() برای محاسبه طول مسیر مشخصی استفاده کنید، اگر چند مکان دارید.

نتایج فاصله به متر بیان می‌شود.

برای محاسبه مساحت (به متر مربع) یک ناحیه چندضلعی، computeArea() را فراخوانی کنید و آرایه اشیای LatLng را که یک حلقه بسته را تعریف می‌کنند ارسال کنید.

هنگام پیمایش روی کره، جهت زاویه یک جهت از یک نقطه مرجع ثابت، معمولاً شمال واقعی است. در Google Maps API، جهت با درجه از شمال واقعی تعریف می‌شود، که در آن جهت‌ها در جهت عقربه‌های ساعت از شمال واقعی (۰ درجه) اندازه‌گیری می‌شوند. می‌توانید این جهت را بین دو مکان با روش computeHeading() محاسبه کنید و آن را به دو شیء from و to LatLng منتقل کنید.

با داشتن یک عنوان خاص، مکان مبدأ، و مسافت طی‌شده (به متر)، می‌توانید مختصات مقصد را بااستفاده از computeOffset() محاسبه کنید.

با داشتن دو شیء LatLng و مقداری بین ۰ و ۱، می‌توانید بااستفاده از روش interpolate() که درون‌یابی خطی کروی را بین دو مکان انجام می‌دهد، مقصد بین آن‌ها را نیز محاسبه کنید. در این روش، مقدار نشان‌دهنده فاصله کسری برای پیمودن درطول مسیر از مبدأ به مقصد است.

مثال زیر دو چندخطی را هنگام کلیک کردن روی دو نقطه در نقشه ایجاد می‌کند — یک خط ژئودزیک و یک خط «مستقیم» که دو مکان را به هم متصل می‌کند — و جهت حرکت بین دو نقطه را محاسبه می‌کند:

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 ترکیب کنید: