الأشكال والخطوط

اختيار النظام الأساسي: Android‏ iOS‏ JavaScript‏

يمكنك إضافة أشكال مختلفة إلى خريطتك. الشكل هو عنصر على الخريطة مرتبط بإحداثيات خط العرض/خط الطول. تتوفّر الأشكال التالية: الخطوط والمضلّعات والدوائر والمستطيلات. يمكنك أيضًا ضبط الأشكال بحيث يتمكّن المستخدمون من تعديلها أو سحبها، أو دمج الأشكال مع مكتبة الهندسة (google.maps.GeometryLibrary) للتحقّق من الحدود الجغرافية وحدود المناطق الآمنة.

خطوط متعدّدة

لرسم خط على خريطتك، استخدِم خطًا متعدّدًا. تحدّد الفئة Polyline تراكبًا خطيًا لأجزاء الخطوط المتصلة على الخريطة. يتكوّن عنصر Polyline من مصفوفة من المواقع الجغرافية LatLng، وينشئ سلسلة من مقاطع الخطوط التي تربط هذه المواقع الجغرافية في تسلسل منظّم.

إضافة شكل متعدّد الخطوط

تأخذ دالة الإنشاء Polyline مجموعة من PolylineOptions التي تحدّد إحداثيات LatLng للخط ومجموعة من الأنماط لضبط السلوك المرئي للخطوط المتعدّدة.

يتم رسم كائنات Polyline كسلسلة من المقاطع المستقيمة على الخريطة. يمكنك تحديد ألوان وأوزان ودرجات تعتيم مخصّصة لخط الرسم ضمن PolylineOptions عند إنشاء الخط، أو يمكنك تغيير هذه السمات بعد الإنشاء. يتيح الشكل المتعدّد الخطوط أنماط الخطوط التالية:

  • تحدّد السمة strokeColor لون HTML بنظام العد الستة عشري بالتنسيق "#FFFFFF". لا تتيح الفئة Polyline استخدام الألوان المُسمّاة.
  • تحدّد السمة strokeOpacity قيمة رقمية بين 0.0 و1.0 لتحديد درجة تعتيم لون الخط. القيمة التلقائية هي 1.0.
  • تحدّد السمة strokeWeight عرض الخط بالبكسل.

تحدّد السمة editable للشكل المتعدّد الخطوط ما إذا كان بإمكان المستخدمين تعديل الشكل. يُرجى الاطّلاع على الأشكال التي يمكن للمستخدم تعديلها أدناه. وبالمثل، يمكنك ضبط السمة draggable للسماح للمستخدمين بسحب الخط.

ينشئ هذا المثال خطًا متعدّدًا أحمر اللون بعرض بكسلَين يعرض مسار أول رحلة جوية عبر المحيط الهادئ بين أوكلاند، كاليفورنيا، وبريسبان، أستراليا.

TypeScript

// This example creates a 2-pixel-wide red polyline showing the path of
// the first trans-Pacific flight between Oakland, CA, and Brisbane,
// Australia which was made by Charles Kingsford Smith.
const mapElement = document.querySelector('gmp-map')!;
let innerMap: google.maps.Map;

async function init() {
    const { Polyline } = await google.maps.importLibrary('maps');
    innerMap = mapElement.innerMap;

    const flightPlanCoordinates = [
        { lat: 37.772, lng: -122.214 },
        { lat: 21.291, lng: -157.821 },
        { lat: -18.142, lng: 178.431 },
        { lat: -27.467, lng: 153.027 },
    ];
    const flightPath = new Polyline({
        path: flightPlanCoordinates,
        geodesic: true,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2,
    });

    flightPath.setMap(innerMap);
}

void init();

JavaScript

// This example creates a 2-pixel-wide red polyline showing the path of
// the first trans-Pacific flight between Oakland, CA, and Brisbane,
// Australia which was made by Charles Kingsford Smith.
const mapElement = document.querySelector('gmp-map');
let innerMap;

async function init() {
    const { Polyline } = await google.maps.importLibrary('maps');
    innerMap = mapElement.innerMap;

    const flightPlanCoordinates = [
        { lat: 37.772, lng: -122.214 },
        { lat: 21.291, lng: -157.821 },
        { lat: -18.142, lng: 178.431 },
        { lat: -27.467, lng: 153.027 },
    ];
    const flightPath = new Polyline({
        path: flightPlanCoordinates,
        geodesic: true,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2,
    });

    flightPath.setMap(innerMap);
}

void init();
الاطّلاع على مثال

إزالة خطوط متعدّدة

لإزالة شكل متعدّد الخطوط من الخريطة، استخدِم طريقة setMap() مع تمرير null كوسيطة. في المثال التالي، flightPath هو عنصر خطوط متعدّدة:

flightPath.setMap(null);

يُرجى العِلم أنّ الطريقة أعلاه لا تؤدي إلى حذف الخطوط المتعدّدة. ويؤدي ذلك إلى إزالة الخطوط المتعدّدة من الخريطة. إذا أردت بدلاً من ذلك حذف الخطوط المتعدّدة، عليك إزالتها من الخريطة، ثم ضبط الخطوط المتعدّدة نفسها على null.

فحص خطوط متعدّدة

يحدّد الشكل المتعدّد الخطوط سلسلة من الإحداثيات كمصفوفة من عناصر LatLng. تحدّد هذه الإحداثيات مسار الخط. لاسترداد الإحداثيات، يمكنك استدعاء getPath()، الذي سيعرض مصفوفة من النوع MVCArray. يمكنك التعامل مع المصفوفة وفحصها باستخدام العمليات التالية:

  • تعرض الدالة getAt() القيمة LatLng عند قيمة فهرس معيّنة تستند إلى الصفر.
  • تُدرج الدالة insertAt() قيمة LatLng تم تمريرها عند قيمة فهرس معيّنة تبدأ من الصفر. يُرجى العِلم أنّ أي إحداثيات حالية في قيمة الفهرس هذه يتم نقلها إلى الأمام.
  • تزيل الدالة removeAt() قيمة LatLng عند قيمة فهرس معيّنة تستند إلى الصفر.

يوضّح المثال التالي إنشاء خطوط متعدّدة استنادًا إلى النقرات (انقر على الخريطة لإضافة رأس).

TypeScript

/**
 * This example creates an interactive map which constructs a polyline based on
 * user clicks. Note that the polyline only appears once its path property
 * contains two LatLng coordinates.
 */

let poly: google.maps.Polyline;
const mapElement = document.querySelector('gmp-map')!;
let innerMap: google.maps.Map;

async function init() {
    // Import the needed libraries.
    const [{ Polyline }, { AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('marker'),
    ]);

    innerMap = mapElement.innerMap;

    poly = new Polyline({
        strokeColor: '#000000',
        strokeOpacity: 1.0,
        strokeWeight: 3,
    });
    poly.setMap(innerMap);

    // Handles click events on a map, and adds a new point to the Polyline.
    innerMap.addListener('click', (event: google.maps.MapMouseEvent) => {
        const latLng = event.latLng;
        if (!latLng) return;

        const path = poly.getPath();

        // Because path is an MVCArray, we can simply append a new coordinate
        // and it will automatically appear.
        path.push(latLng);

        // Add a new marker at the new plotted point on the polyline.
        new AdvancedMarkerElement({
            position: latLng,
            title: '#' + path.getLength(),
            map: innerMap,
        });
    });
}

void init();

JavaScript

/**
 * This example creates an interactive map which constructs a polyline based on
 * user clicks. Note that the polyline only appears once its path property
 * contains two LatLng coordinates.
 */

let poly;
const mapElement = document.querySelector('gmp-map');
let innerMap;

async function init() {
    // Import the needed libraries.
    const [{ Polyline }, { AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('marker'),
    ]);

    innerMap = mapElement.innerMap;

    poly = new Polyline({
        strokeColor: '#000000',
        strokeOpacity: 1.0,
        strokeWeight: 3,
    });
    poly.setMap(innerMap);

    // Handles click events on a map, and adds a new point to the Polyline.
    innerMap.addListener('click', (event) => {
        const latLng = event.latLng;
        if (!latLng) return;

        const path = poly.getPath();

        // Because path is an MVCArray, we can simply append a new coordinate
        // and it will automatically appear.
        path.push(latLng);

        // Add a new marker at the new plotted point on the polyline.
        new AdvancedMarkerElement({
            position: latLng,
            title: '#' + path.getLength(),
            map: innerMap,
        });
    });
}

void init();
الاطّلاع على مثال

تخصيص شكل متعدّد الخطوط

يمكنك إضافة صور مستندة إلى المتجهات إلى خطوط متعدّدة على شكل رموز. باستخدام مجموعة من الرموز وفئة PolylineOptions، يمكنك التحكّم بشكل كبير في مظهر الخطوط المتعدّدة على خريطتك. يُرجى الاطّلاع على الرموز للحصول على معلومات حول الأسهم والخطوط المتقطّعة والرموز المخصّصة والرموز المتحركة.

المضلّعات

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

يمكن أن تصف كائنات Polygon أشكالاً معقّدة، بما في ذلك:

  • مناطق متعددة غير متجاورة يحدّدها مضلّع واحد
  • المناطق التي تحتوي على ثقوب
  • تقاطعات منطقة واحدة أو أكثر

لتحديد شكل معقّد، يمكنك استخدام مضلّع بمسارات متعدّدة.

ملاحظة: توفّر طبقة البيانات طريقة بسيطة لرسم المضلّعات. ويتعامل مع التفاف المضلّعات نيابةً عنك، ما يسهّل رسم المضلّعات التي تحتوي على ثقوب. راجِع المستندات المتعلّقة بطبقة البيانات.

إضافة مضلّع

بما أنّ المنطقة المضلّعة قد تتضمّن عدة مسارات منفصلة، تحدّد السمة paths في الكائن Polygon مصفوفة من المصفوفات، كل منها من النوع MVCArray. وتحدّد كل مصفوفة تسلسلاً منفصلاً لإحداثيات LatLng مرتبة.

بالنسبة إلى المضلّعات البسيطة التي تتكوّن من مسار واحد فقط، يمكنك إنشاء Polygon باستخدام مصفوفة واحدة من إحداثيات LatLng. ستحوّل واجهة برمجة التطبيقات Maps JavaScript API المصفوفة البسيطة إلى مصفوفة من المصفوفات عند إنشائها عند تخزينها داخل السمة paths. توفّر واجهة برمجة التطبيقات طريقة getPath() بسيطة للمضلّعات التي تتألف من مسار واحد.

تحدّد السمة editable للمضلّع ما إذا كان بإمكان المستخدمين تعديل الشكل. يُرجى الاطّلاع على الأشكال القابلة للتعديل من قِبل المستخدم أدناه. وبالمثل، يمكنك ضبط السمة draggable للسماح للمستخدمين بسحب الشكل.

TypeScript

// This example creates a simple polygon representing the Bermuda Triangle.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 5,
      center: { lat: 24.886, lng: -70.268 },
      mapTypeId: "terrain",
    }
  );

  // Define the LatLng coordinates for the polygon's path.
  const triangleCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
    { lat: 25.774, lng: -80.19 },
  ];

  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example creates a simple polygon representing the Bermuda Triangle.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
    mapTypeId: "terrain",
  });
  // Define the LatLng coordinates for the polygon's path.
  const triangleCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
    { lat: 25.774, lng: -80.19 },
  ];
  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

window.initMap = initMap;
الاطّلاع على مثال

الإكمال التلقائي للمضلّعات

يتكوّن Polygon في المثال أعلاه من أربع مجموعات من إحداثيات LatLng، ولكن لاحظ أنّ المجموعتَين الأولى والأخيرة تحدّدان الموقع الجغرافي نفسه، ما يكمل الحلقة. ومع ذلك، من الناحية العملية، بما أنّ المضلّعات تحدّد مناطق مغلقة، ليس عليك تحديد آخر مجموعة من الإحداثيات. ستُكمل واجهة برمجة التطبيقات Maps JavaScript API المضلّع تلقائيًا عن طريق رسم خط يربط الموقع الجغرافي الأخير بالموقع الجغرافي الأول لأي مسار معيّن.

المثال التالي مطابق للمثال السابق، باستثناء أنّه تم حذف السمة LatLng الأخيرة: عرض المثال.

إزالة مضلّع

لإزالة مضلّع من الخريطة، استخدِم طريقة setMap() مع تمرير null كوسيطة. في المثال التالي، bermudaTriangle هو كائن مضلّع:

bermudaTriangle.setMap(null);

يُرجى العِلم أنّ الطريقة المذكورة أعلاه لا تؤدي إلى حذف المضلّع. ويؤدي ذلك إلى إزالة المضلّع من الخريطة. إذا أردت بدلاً من ذلك حذف المضلّع، عليك إزالته من الخريطة، ثم ضبط المضلّع نفسه على null.

فحص مضلّع

يحدّد المضلّع سلسلة الإحداثيات الخاصة به كمصفوفة من المصفوفات، حيث تكون كل مصفوفة من النوع MVCArray. وكل مصفوفة "ورقة" هي مصفوفة من إحداثيات LatLng تحدّد مسارًا واحدًا. لاسترداد هذه الإحداثيات، استخدِم طريقة getPaths() في عنصر Polygon. بما أنّ المصفوفة هي MVCArray، عليك معالجتها وفحصها باستخدام العمليات التالية:

  • تعرض الدالة getAt() القيمة LatLng عند قيمة فهرس معيّنة تستند إلى الصفر.
  • تُدرج الدالة insertAt() قيمة LatLng تم تمريرها عند قيمة فهرس معيّنة تبدأ من الصفر. يُرجى العِلم أنّ أي إحداثيات حالية في قيمة الفهرس هذه يتم نقلها إلى الأمام.
  • تزيل الدالة removeAt() قيمة LatLng عند قيمة فهرس معيّنة تستند إلى الصفر.

TypeScript

// This example creates a simple polygon representing the Bermuda Triangle.
// When the user clicks on the polygon an info window opens, showing
// information about the polygon's coordinates.

let map: google.maps.Map;

let infoWindow: google.maps.InfoWindow;

function initMap(): void {
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
    mapTypeId: "terrain",
  });

  // Define the LatLng coordinates for the polygon.
  const triangleCoords: google.maps.LatLngLiteral[] = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];

  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);

  // Add a listener for the click event.
  bermudaTriangle.addListener("click", showArrays);

  infoWindow = new google.maps.InfoWindow();
}

function showArrays(event: any) {
  // Since this polygon has only one path, we can call getPath() to return the
  // MVCArray of LatLngs.
  // @ts-ignore
  const polygon = this as google.maps.Polygon;
  const vertices = polygon.getPath();

  let contentString =
    "<b>Bermuda Triangle polygon</b><br>" +
    "Clicked location: <br>" +
    event.latLng.lat() +
    "," +
    event.latLng.lng() +
    "<br>";

  // Iterate over the vertices.
  for (let i = 0; i < vertices.getLength(); i++) {
    const xy = vertices.getAt(i);

    contentString +=
      "<br>" + "Coordinate " + i + ":<br>" + xy.lat() + "," + xy.lng();
  }

  // Replace the info window's content and position.
  infoWindow.setContent(contentString);
  infoWindow.setPosition(event.latLng);

  infoWindow.open(map);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example creates a simple polygon representing the Bermuda Triangle.
// When the user clicks on the polygon an info window opens, showing
// information about the polygon's coordinates.
let map;
let infoWindow;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
    mapTypeId: "terrain",
  });

  // Define the LatLng coordinates for the polygon.
  const triangleCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];
  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
  // Add a listener for the click event.
  bermudaTriangle.addListener("click", showArrays);
  infoWindow = new google.maps.InfoWindow();
}

function showArrays(event) {
  // Since this polygon has only one path, we can call getPath() to return the
  // MVCArray of LatLngs.
  // @ts-ignore
  const polygon = this;
  const vertices = polygon.getPath();
  let contentString =
    "<b>Bermuda Triangle polygon</b><br>" +
    "Clicked location: <br>" +
    event.latLng.lat() +
    "," +
    event.latLng.lng() +
    "<br>";

  // Iterate over the vertices.
  for (let i = 0; i < vertices.getLength(); i++) {
    const xy = vertices.getAt(i);

    contentString +=
      "<br>" + "Coordinate " + i + ":<br>" + xy.lat() + "," + xy.lng();
  }

  // Replace the info window's content and position.
  infoWindow.setContent(contentString);
  infoWindow.setPosition(event.latLng);
  infoWindow.open(map);
}

window.initMap = initMap;
الاطّلاع على مثال

إنشاء ثقب في مضلّع

لإنشاء منطقة فارغة داخل مضلّع، عليك إنشاء مسارَين، أحدهما داخل الآخر. لإنشاء الثقب، يجب أن تكون الإحداثيات التي تحدّد المسار الداخلي بترتيب معاكس لتلك التي تحدّد المسار الخارجي. على سبيل المثال، إذا كانت إحداثيات المسار الخارجي في اتجاه عقارب الساعة، يجب أن يكون المسار الداخلي عكس اتجاه عقارب الساعة.

ملاحظة: تعالج طبقة البيانات ترتيب المسارات الداخلية والخارجية نيابةً عنك، ما يسهّل رسم المضلّعات التي تحتوي على ثقوب. راجِع المستندات المتعلّقة بطبقة البيانات.

يرسم المثال التالي مضلّعًا بمسارَين، مع التفاف المسار الداخلي في الاتجاه المعاكس للمسار الخارجي.

TypeScript

// This example creates a triangular polygon with a hole in it.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 5,
      center: { lat: 24.886, lng: -70.268 },
    }
  );

  // Define the LatLng coordinates for the polygon's  outer path.
  const outerCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];

  // Define the LatLng coordinates for the polygon's inner path.
  // Note that the points forming the inner path are wound in the
  // opposite direction to those in the outer path, to form the hole.
  const innerCoords = [
    { lat: 28.745, lng: -70.579 },
    { lat: 29.57, lng: -67.514 },
    { lat: 27.339, lng: -66.668 },
  ];

  // Construct the polygon, including both paths.
  const bermudaTriangle = new google.maps.Polygon({
    paths: [outerCoords, innerCoords],
    strokeColor: "#FFC107",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FFC107",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example creates a triangular polygon with a hole in it.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
  });
  // Define the LatLng coordinates for the polygon's  outer path.
  const outerCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];
  // Define the LatLng coordinates for the polygon's inner path.
  // Note that the points forming the inner path are wound in the
  // opposite direction to those in the outer path, to form the hole.
  const innerCoords = [
    { lat: 28.745, lng: -70.579 },
    { lat: 29.57, lng: -67.514 },
    { lat: 27.339, lng: -66.668 },
  ];
  // Construct the polygon, including both paths.
  const bermudaTriangle = new google.maps.Polygon({
    paths: [outerCoords, innerCoords],
    strokeColor: "#FFC107",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FFC107",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

window.initMap = initMap;
الاطّلاع على مثال

مستطيلات

بالإضافة إلى فئة Polygon العامة، تتضمّن واجهة برمجة التطبيقات JavaScript في &quot;خرائط Google&quot; فئة معيّنة لكائنات Rectangle، وذلك لتبسيط إنشائها.

إضافة مستطيل

يشبه Rectangle Polygon من حيث إمكانية تحديد ألوان مخصّصة وأوزان ودرجات تعتيم لحافة المستطيل (الحد) وألوان مخصّصة ودرجات تعتيم للمنطقة داخل المستطيل (التعبئة). يجب الإشارة إلى الألوان بنمط HTML رقمي بنظام العد الستة عشري.

على عكس Polygon، لا يمكنك تحديد paths لـ Rectangle. بدلاً من ذلك، يحتوي المستطيل على سمة bounds التي تحدّد شكله من خلال تحديد google.maps.LatLngBounds للمستطيل.

تحدّد السمة editable للمستطيل ما إذا كان بإمكان المستخدمين تعديل الشكل. يمكنك الاطّلاع على الأشكال التي يمكن للمستخدم تعديلها أدناه. وبالمثل، يمكنك ضبط السمة draggable للسماح للمستخدمين بسحب المستطيل.

TypeScript

// This example adds a red rectangle to a map.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 11,
      center: { lat: 33.678, lng: -116.243 },
      mapTypeId: "terrain",
    }
  );

  const rectangle = new google.maps.Rectangle({
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
    map,
    bounds: {
      north: 33.685,
      south: 33.671,
      east: -116.234,
      west: -116.251,
    },
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example adds a red rectangle to a map.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 11,
    center: { lat: 33.678, lng: -116.243 },
    mapTypeId: "terrain",
  });
  const rectangle = new google.maps.Rectangle({
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
    map,
    bounds: {
      north: 33.685,
      south: 33.671,
      east: -116.234,
      west: -116.251,
    },
  });
}

window.initMap = initMap;
الاطّلاع على مثال

تنشئ التعليمة البرمجية التالية مستطيلاً في كل مرة يغيّر فيها المستخدم مستوى التكبير أو التصغير على الخريطة. يتم تحديد حجم المستطيل من خلال إطار العرض.

TypeScript

// This example creates a rectangle based on the viewport
// on any 'zoom-changed' event.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 11,
      center: { lat: 40.74852, lng: -73.981687 },
      mapTypeId: "terrain",
    }
  );

  const rectangle = new google.maps.Rectangle();

  map.addListener("zoom_changed", () => {
    // Get the current bounds, which reflect the bounds before the zoom.
    rectangle.setOptions({
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map,
      bounds: map.getBounds() as google.maps.LatLngBounds,
    });
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example creates a rectangle based on the viewport
// on any 'zoom-changed' event.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 11,
    center: { lat: 40.74852, lng: -73.981687 },
    mapTypeId: "terrain",
  });
  const rectangle = new google.maps.Rectangle();

  map.addListener("zoom_changed", () => {
    // Get the current bounds, which reflect the bounds before the zoom.
    rectangle.setOptions({
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map,
      bounds: map.getBounds(),
    });
  });
}

window.initMap = initMap;
الاطّلاع على مثال

إزالة مستطيل

لإزالة مستطيل من الخريطة، استخدِم طريقة setMap() مع تمرير null كوسيطة.

rectangle.setMap(null);

يُرجى العِلم أنّ الطريقة المذكورة أعلاه لا تؤدي إلى حذف المستطيل. ويؤدي ذلك إلى إزالة المستطيل من الخريطة. إذا أردت بدلاً من ذلك حذف المستطيل، عليك إزالته من الخريطة، ثم ضبط المستطيل نفسه على null.

دوائر

بالإضافة إلى فئة Polygon العامة، تتضمّن واجهة برمجة التطبيقات JavaScript لـ &quot;خرائط Google&quot; فئة معيّنة لكائنات Circle، وذلك لتبسيط إنشائها.

إضافة دائرة

يشبه Circle Polygon من حيث إمكانية تحديد ألوان مخصّصة وأوزان ودرجات تعتيم لحافة الدائرة (الحد) وألوان مخصّصة ودرجات تعتيم للمنطقة داخل الدائرة (التعبئة). يجب الإشارة إلى الألوان بنمط HTML رقمي بنظام العد الستة عشري.

على عكس Polygon، لا يمكنك تحديد paths لـ Circle. بدلاً من ذلك، تحتوي الدائرة على سمتَين إضافيتَين تحدّدان شكلها:

  • يحدّد center google.maps.LatLng مركز الدائرة.
  • تحدّد السمة radius نصف قطر الدائرة بالأمتار.

تحدّد السمة editable للدائرة ما إذا كان بإمكان المستخدمين تعديل الشكل. يُرجى الاطّلاع على الأشكال القابلة للتعديل من قِبل المستخدم أدناه. وبالمثل، يمكنك ضبط السمة draggable للسماح للمستخدمين بسحب الدائرة.

يستخدم المثال التالي الدوائر لعرض أوقات المشي التقريبية بين المواقع الجغرافية في كيوتو، اليابان. اختَر المسافة المطلوبة من القائمة، وانقر على الخريطة لإعادة توسيط الدائرة، ثم اسحب الدائرة لتغيير موضعها.

TypeScript

const mapElement = document.querySelector('gmp-map')!;
let innerMap: google.maps.Map;

async function init() {
    // Request needed libraries.
    const [{ Circle }, { AdvancedMarkerElement }, { event }] =
        await Promise.all([
            google.maps.importLibrary('maps'),
            google.maps.importLibrary('marker'),
            google.maps.importLibrary('core'),
        ]);

    // Set the initial map center point.
    const initialCenter = { lat: 34.98956821576194, lng: 135.74239981260283 }; // Hotel Emion, Kyoto, Japan

    // Get the inner map.
    innerMap = mapElement.innerMap;

    // Get the buttons.
    const buttons = document.querySelectorAll('input[name="radius"]');

    // Create the circle.
    const walkingCircle = new Circle({
        strokeColor: '#ffdd00ff',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#ffdd00ff',
        fillOpacity: 0.35,
        map: innerMap,
        center: initialCenter,
        radius: 400,
        draggable: true,
        editable: false,
    });

    // Define a "Crosshair" vector icon
    const parser = new DOMParser();
    const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-6 -6 12 12"><path d="M -6,0 L 6,0 M 0,-6 L 0,6" stroke="black" stroke-width="1"/></svg>`;

    const pinSvg = parser.parseFromString(
        svgString,
        'image/svg+xml'
    ).documentElement;

    const centerMarker = new AdvancedMarkerElement({
        position: initialCenter,
        title: 'A marker using a custom SVG image.',
        anchorLeft: '-50%',
        anchorTop: '-50%',
    });
    centerMarker.append(pinSvg);
    mapElement.append(centerMarker);

    // Wait for the map to finish drawing its tiles.
    event.addListenerOnce(innerMap, 'tilesloaded', () => {
        // Get the controls div
        const controls = document.getElementById('control-panel');

        // Display controls once map is loaded.
        if (controls) {
            controls.style.display = 'block';
        }
    });

    // Add event listener to update the radius based on user selection.
    buttons.forEach((button) => {
        button.addEventListener('change', (changeEvent) => {
            const target = changeEvent.target as HTMLInputElement;
            walkingCircle.setRadius(Number(target.value));
        });
    });

    // Handle user click, reset the map center and position the circle.
    innerMap.addListener(
        'click',
        (
            mapsMouseEvent:
                google.maps.MapMouseEvent | google.maps.IconMouseEvent
        ) => {
            const newCenter = mapsMouseEvent.latLng;
            if (!newCenter) return;
            walkingCircle.setCenter(newCenter);
            centerMarker.position = newCenter;
            innerMap.panTo(newCenter);
        }
    );

    // Handle user dragging the circle, update the center marker position.
    walkingCircle.addListener('center_changed', () => {
        centerMarker.position = walkingCircle.getCenter();
    });
}

void init();

JavaScript

const mapElement = document.querySelector('gmp-map');
let innerMap;

async function init() {
    // Request needed libraries.
    const [{ Circle }, { AdvancedMarkerElement }, { event }] =
        await Promise.all([
            google.maps.importLibrary('maps'),
            google.maps.importLibrary('marker'),
            google.maps.importLibrary('core'),
        ]);

    // Set the initial map center point.
    const initialCenter = { lat: 34.98956821576194, lng: 135.74239981260283 }; // Hotel Emion, Kyoto, Japan

    // Get the inner map.
    innerMap = mapElement.innerMap;

    // Get the buttons.
    const buttons = document.querySelectorAll('input[name="radius"]');

    // Create the circle.
    const walkingCircle = new Circle({
        strokeColor: '#ffdd00ff',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#ffdd00ff',
        fillOpacity: 0.35,
        map: innerMap,
        center: initialCenter,
        radius: 400,
        draggable: true,
        editable: false,
    });

    // Define a "Crosshair" vector icon
    const parser = new DOMParser();
    const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-6 -6 12 12"><path d="M -6,0 L 6,0 M 0,-6 L 0,6" stroke="black" stroke-width="1"/></svg>`;

    const pinSvg = parser.parseFromString(
        svgString,
        'image/svg+xml'
    ).documentElement;

    const centerMarker = new AdvancedMarkerElement({
        position: initialCenter,
        title: 'A marker using a custom SVG image.',
        anchorLeft: '-50%',
        anchorTop: '-50%',
    });
    centerMarker.append(pinSvg);
    mapElement.append(centerMarker);

    // Wait for the map to finish drawing its tiles.
    event.addListenerOnce(innerMap, 'tilesloaded', () => {
        // Get the controls div
        const controls = document.getElementById('control-panel');

        // Display controls once map is loaded.
        if (controls) {
            controls.style.display = 'block';
        }
    });

    // Add event listener to update the radius based on user selection.
    buttons.forEach((button) => {
        button.addEventListener('change', (changeEvent) => {
            const target = changeEvent.target;
            walkingCircle.setRadius(Number(target.value));
        });
    });

    // Handle user click, reset the map center and position the circle.
    innerMap.addListener('click', (mapsMouseEvent) => {
        const newCenter = mapsMouseEvent.latLng;
        if (!newCenter) return;
        walkingCircle.setCenter(newCenter);
        centerMarker.position = newCenter;
        innerMap.panTo(newCenter);
    });

    // Handle user dragging the circle, update the center marker position.
    walkingCircle.addListener('center_changed', () => {
        centerMarker.position = walkingCircle.getCenter();
    });
}

void init();

CSS

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#control-panel {
    display: none; /* Set to 'display: block' after the map loads. */
    background-color: #fff;
    border: 2px solid #fff;
    border-radius: 3px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    font-family: 'Roboto', sans-serif;
    font-size: medium;
    margin: 10px;
    padding: 10px;
}

HTML

<html>
    <head>
        <title>Circles</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
                key: "GOOGLE_MAPS_API_KEY"
            });
        </script>
    </head>
    <body>
        <gmp-map
            center="34.98956821576194, 135.74239981260283"
            zoom="15"
            map-id="DEMO_MAP_ID">
            <div id="control-panel" slot="control-inline-start-block-start">
                <input
                    id="short-walk"
                    type="radio"
                    name="radius"
                    value="400"
                    checked />
                <label for="short-walk">Short Walk (~5 minutes)</label><br />
                <input
                    id="medium-walk"
                    type="radio"
                    name="radius"
                    value="800" />
                <label for="medium-walk">Medium Walk (~15 minutes)</label><br />
                <input id="long-walk" type="radio" name="radius" value="1600" />
                <label for="long-walk">Long Walk (~30 minutes) </label>
            </div>
        </gmp-map>
    </body>
</html>
الاطّلاع على مثال

إزالة دائرة

لإزالة دائرة من الخريطة، استخدِم طريقة setMap() مع تمرير null كوسيطة.

circle.setMap(null);

يُرجى العِلم أنّ الطريقة المذكورة أعلاه لا تؤدي إلى حذف الدائرة. ويؤدي ذلك إلى إزالة الدائرة من الخريطة. إذا أردت بدلاً من ذلك حذف الدائرة، عليك إزالتها من الخريطة، ثم ضبط الدائرة نفسها على null.

أشكال قابلة للتعديل والسحب من قِبل المستخدم

عند جعل الشكل قابلاً للتعديل، تتم إضافة مقابض إليه يمكن للمستخدمين استخدامها لتغيير موضع الشكل وشكله وحجمه مباشرةً على الخريطة. يمكنك أيضًا جعل الشكل قابلاً للسحب، ليتمكّن المستخدمون من نقله إلى مكان مختلف على الخريطة.

لا يتم الاحتفاظ بالتغييرات التي يجريها المستخدم على العنصر بين الجلسات. إذا كنت تريد حفظ تعديلات المستخدم، عليك تسجيل المعلومات وتخزينها بنفسك.

جعل الشكل قابلاً للتعديل

يمكن ضبط أي شكل (خطوط متعدّدة ومضلّعات ودوائر ومستطيلات) ليكون قابلاً للتعديل من قِبل المستخدم، وذلك من خلال ضبط editable على true في خيارات الشكل.

var bounds = {
  north: 44.599,
  south: 44.490,
  east: -78.443,
  west: -78.649
};

// Define a rectangle and set its editable property to true.
var rectangle = new google.maps.Rectangle({
  bounds: bounds,
  editable: true
});

الاطّلاع على مثال

جعل الشكل قابلاً للسحب

سيتم تلقائيًا تثبيت الشكل المرسوم على الخريطة في موضعه. للسماح للمستخدمين بسحب شكل إلى موقع جغرافي مختلف على الخريطة، اضبط draggable على true في خيارات الشكل.

var redCoords = [
  {lat: 25.774, lng: -80.190},
  {lat: 18.466, lng: -66.118},
  {lat: 32.321, lng: -64.757}
];

// Construct a draggable red triangle with geodesic set to true.
new google.maps.Polygon({
  map: map,
  paths: redCoords,
  strokeColor: '#FF0000',
  strokeOpacity: 0.8,
  strokeWeight: 2,
  fillColor: '#FF0000',
  fillOpacity: 0.35,
  draggable: true,
  geodesic: true
});

عند تفعيل السحب على شكل مضلّع أو شكل متعدّد الخطوط، عليك أيضًا مراعاة جعل الشكل المضلّع أو شكل متعدّد الخطوط جيوديسيًا، من خلال ضبط السمة geodesic على true.

سيحتفظ المضلّع الجيوديسي بشكله الجغرافي الحقيقي عند نقله، ما يؤدي إلى ظهور المضلّع بشكل مشوّه عند نقله شمالاً أو جنوبًا في إسقاط مركاتور. ستحتفظ المضلّعات غير الجيوديسية دائمًا بمظهرها الأولي على الشاشة.

في الخطوط المتعدّدة الجيوديسية، يتم رسم أجزاء الخطوط المتعدّدة كأقصر مسار بين نقطتين على سطح الأرض، بافتراض أنّ الأرض كروية، على عكس الخطوط المستقيمة في إسقاط مركاتور.

لمزيد من المعلومات حول أنظمة الإحداثيات، يُرجى الرجوع إلى دليل إحداثيات الخريطة والمربّعات.

تعرض الخريطة التالية مثلّثَين بالحجم والأبعاد نفسها تقريبًا. تم ضبط السمة geodesic للمثلث الأحمر على true. لاحظ كيف يتغيّر شكله أثناء تحرّكه شمالاً.

الاطّلاع على مثال

الاستماع إلى أحداث التعديل

عند تعديل شكل، يتم تنشيط حدث عند اكتمال التعديل. وفي ما يلي هذه الأحداث.

الشكل الفعاليات
دائرة radius_changed
center_changed
مضلّع insert_at
remove_at
set_at

يجب ضبط المستمع على مسار المضلّع. إذا كان المضلّع يحتوي على مسارات متعددة، يجب ضبط مستمع على كل مسار.

خط متعدد insert_at
remove_at
set_at

يجب ضبط المستمع على مسار الخطوط المتعدّدة.

مستطيل bounds_changed

بعض مقتطفات الرموز المفيدة:

google.maps.event.addListener(circle, 'radius_changed', function() {
  console.log(circle.getRadius());
});

google.maps.event.addListener(outerPath, 'set_at', function() {
  console.log('Vertex moved on outer path.');
});

google.maps.event.addListener(innerPath, 'insert_at', function() {
  console.log('Vertex removed from inner path.');
});

google.maps.event.addListener(rectangle, 'bounds_changed', function() {
  console.log('Bounds changed.');
});

يمكنك الاطّلاع على مثال على معالجة حدث تعديل على مستطيل: عرض المثال.

الاستماع إلى أحداث السحب

عند سحب شكل، يتم تنشيط الأحداث عند بدء إجراء السحب وانتهائه، وكذلك أثناء السحب. يتم تنشيط الأحداث التالية للخطوط المتعدّدة والمضلّعات والدوائر والمستطيلات.

الحدث الوصف
dragstart يتم تنشيطه عندما يبدأ المستخدم في سحب الشكل.
drag يتم تفعيله بشكل متكرّر أثناء سحب المستخدم للشكل.
dragend يتم تنشيطه عندما يتوقف المستخدم عن سحب الشكل.

لمزيد من المعلومات حول معالجة الأحداث، يُرجى الاطّلاع على المستندات حول الأحداث.

الحدود الجغرافية وحدود المناطق الآمنة

لا توفّر "منصة خرائط Google" واجهة برمجة تطبيقات مستقلة للحدود الجغرافية. لعرض نطاق حدود جغرافية أو منطقة آمنة على خريطة ويب والتحقّق مما إذا كانت إحداثيات الموقع المباشر تقع داخل تلك الحدود، يمكنك دمج الأشكال مع مكتبة الهندسة (google.maps.GeometryLibrary) التي يتم تحميلها من خلال google.maps.importLibrary("geometry"):

يوضّح المثال التالي كيفية رسم منطقة آمنة دائرية وحدود جغرافية مضلّعة، ثم التحقّق مما إذا كانت الإحداثيات المباشرة تقع داخل كل حدود:

const {Circle, Polygon} = await google.maps.importLibrary("maps");
const {poly} = await google.maps.importLibrary("geometry");

const livePosition = {lat: 37.424, lng: -122.085};

// 1. Circular geofence (500-meter radius)
const circularGeofence = new Circle({
  map,
  center: {lat: 37.422, lng: -122.084},
  radius: 500,
});
const isInsideCircle = poly.containsLocation(livePosition, circularGeofence);

// 2. Polygonal geofence
const polygonGeofence = new Polygon({
  map,
  paths: [
    {lat: 37.420, lng: -122.088},
    {lat: 37.420, lng: -122.080},
    {lat: 37.426, lng: -122.080},
    {lat: 37.426, lng: -122.088},
  ],
});
const isInsidePolygon = poly.containsLocation(livePosition, polygonGeofence);