مكتبة الهندسة

  1. نظرة عامة
  2. مفاهيم الهندسة الكروية
    1. دوال المسافة والمساحة
    2. وظائف التنقّل
  3. الترميز الهندسي
  4. دوال المضلّعات والخطوط المتعددة
    1. containsLocation()
    2. isLocationOnEdge()

نظرة عامة

تشير المفاهيم الموجودة في هذا المستند إلى الميزات فقط المتاحة ضمن مكتبة google.maps.geometry. هذا النمط لا يتم تحميل المكتبة افتراضيًا عند تحميل واجهة برمجة تطبيقات JavaScript للخرائط ولكن يجب تحديده صراحةً من خلال استخدام سمة libraries معلمة التمهيد. لمزيد من المعلومات، يُرجى الاطّلاع على نظرة عامة على المكتبات:

توفر مكتبة هندسة واجهة برمجة تطبيقات JavaScript للخرائط الأداة دوال حساب البيانات الهندسية على سطح Google Earth تتضمن المكتبة ثلاث مساحات اسم:

  • spherical يحتوي على أدوات هندسية كروية تسمح لك بحساب الزوايا، المسافات والمناطق من خطوط العرض وخطوط الطول.
  • encoding يحتوي على أدوات لتشفير وفك تشفير المسارات المتعددة الخطوط وفقًا المشفرة خوارزمية الخطوط المتعددة:
  • poly يحتوي على دوال الخدمات الحاسوبية التي تتضمن المضلّعات الخطوط المتعددة.

لا تحتوي مكتبة google.maps.geometry على أي محتوى بدلاً من ذلك، تحتوي المكتبة على طرق ثابتة ومساحات الاسم.

مفاهيم الهندسة الكروي

تعد الصور المتوفرة في Maps JavaScript API ثنائية الأبعاد و"مسطّح". ومع ذلك، فإن الأرض ثلاثية الأبعاد، وغالبًا بالتقريب على أنه إما شكل كروي مفلوع أو أكثر على شكل كرة. نستخدم الكرة ضمن واجهة برمجة التطبيقات للخرائط، الأرض على سطح مستوٍ ثنائي الأبعاد — مثل شاشة جهاز الكمبيوتر — تستخدم واجهة برمجة تطبيقات الخرائط توقع.

ضمن الإسقاطات الثنائية الأبعاد، يمكن أن تكون المظاهر خادعة في بعض الأحيان. ونظرًا لأن إسقاط الخريطة يتطلب بالضرورة بعض التشويه، فإنه غالبًا ما لا تنطبق الهندسة الإقليدية. على سبيل المثال، أقصر مسافة بين نقطتين على الكرة ليس خطًا مستقيمًا، بل دائرة كبيرة (نوع من الجيوديسية)، والزوايا التي تشكل مثلثًا على السطح الكرة الأرضية يزيد مجموعها عن 180 درجة.

نتيجةً لهذه الاختلافات، تظهر الدوال الهندسية على الكرة (أو على التوقع) تتطلب استخدام هندسة كروية لحساب مثل هذه التركيبات، مثل المسافة والعنوان والمساحة. الأدوات المساعدة حساب التركيبات الهندسية الكروية ضمن الخرائط مساحة الاسم google.maps.geometry.spherical في واجهة برمجة التطبيقات. مساحة الاسم هذه توفر طرقًا ثابتة لحساب القيم العددية من الإحداثيات الكروية (خطوط العرض وخطوط الطول).

دوال المسافة والمساحة

المسافة بين نقطتين هي طول أقصر مسار بين معهم. يسمى هذا المسار الأقصر بالجيوديسية. على الكرة الأرضية، تكون جميع الجيوديسية أجزاء من دائرة كبيرة. ولحساب هذه المسافة، اطلب computeDistanceBetween()، تمريره مرّتين LatLng الأخرى.

يمكنك بدلاً من ذلك استخدام computeLength() لحساب الطول. لمسار معين إذا كانت لديك عدة مواقع.

يتم التعبير عن نتائج المسافة بالمتر.

لحساب مساحة المنطقة المضلّعة (بالمتر المربّع)، computeArea()، تمرير صفيف عناصر LatLng تحديد حلقة مغلقة.

عند التنقل على كرة، يكون العنوان هو زاوية الاتجاه من نقطة مرجعية ثابتة، عادة ما يكون صحيحًا في الشمال. ضمن واجهة برمجة تطبيقات خرائط Google، يتم تحديد العنوان بالدرجات من الشمال الحقيقي، حيث يتم قياس العناوين في اتجاه عقارب الساعة من الشمال الحقيقي (0 درجة). يمكنك حساب هذا العنوان بين موقعين حيث computeHeading()، تمريره اثنين عناصر from وto LatLng

وبالنظر إلى عنوان معين وموقع الانطلاق والمسافة إلى السفر (بالمتر)، يمكنك حساب إحداثيات الوجهة باستخدام computeOffset()

بالنظر إلى كائنين LatLng والقيمة التي تتراوح بين 0 و1، يمكنك أيضًا حساب الوجهة بينهما باستخدام طريقة 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 عنصرًا ومع ذلك، فإن المرور غالبًا ما تكون مثل هذه الصفيفة ضخمة. يمكنك بدلاً من ذلك استخدام واجهة برمجة تطبيقات خطوط متعدّدة خوارزمية الترميز لضغط مسار معيّن، والذي يمكنك لاحقًا وفك ضغطها من خلال فك التشفير.

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, polygon:Polygon)

لمعرفة ما إذا كانت نقطة معينة تقع داخل مضلّع، مرر النقطة المضلّع إلى 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);