اكتشاف الأماكن باستخدام PlaceSearchElement

الهدف

تعرَّف على كيفية دمج PlaceSearchElement مع "خرائط Google" لمساعدة المستخدمين في العثور على الأماكن باستخدام ميزة "البحث في الجوار" أو "البحث النصي"، ما يعزّز قدرتهم على استكشاف نقاط الاهتمام. استخدِم عنصر "تفاصيل المكان" المدمج لتقديم مزيد من التفاصيل حول الأماكن التي تظهر في تطبيقك.

ما هو العنصر PlaceSearchElement؟

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

عرض مرئي لاكتشاف الأماكن

تعرض الصورة التالية مثالاً على PlaceSearchElement أثناء العمل. على اليمين، تظهر قائمة بالمطاعم (PlaceSearchElement). وعند اختيار مطعم، تظهر تفاصيله في نافذة معلومات على الخريطة، وتتوسّط الخريطة موقعه الجغرافي.

الصورة

حالات استخدام Place Discovery

يمكن أن يؤدي دمج PlaceSearchElement إلى تحسين التطبيقات المختلفة في مجالات متعددة:

  • السفر والسياحة: تتيح للسياح البحث عن المعالم السياحية أو الفنادق أو أنواع معيّنة من المأكولات في منطقة معيّنة.
  • العقارات: يمكنك مساعدة المشترين أو المستأجرين المحتملين في العثور على المدارس أو المتاجر الكبرى أو خيارات وسائل النقل العام القريبة.
  • الخدمات اللوجستية والخدمات: مساعدة السائقين في العثور على محطات شحن المركبات الكهربائية أو محطات الوقود أو مراكز صيانة معيّنة

سير عمل الحلّ: تنفيذ ميزة "اكتشاف الأماكن"

يقدّم لك هذا القسم شرحًا مفصّلاً حول كيفية دمج PlaceSearchElement لاستكشاف الأماكن على الخريطة، ويتضمّن مقتطفات من الرموز البرمجية للتفاعل مع حزمة أدوات "خرائط Google" الجاهزة للأماكن. تعرَّف على كيفية إعداد الخريطة وتنفيذ كل من "البحث في الجوار" و"البحث النصي". أخيرًا، استخدِم عنصر "تفاصيل المكان" لعرض المزيد من التفاصيل عن مكان معيّن عندما ينقر المستخدم على دبوسه على الخريطة.

المتطلبات الأساسية

ننصحك بالاطّلاع على المستندات التالية:

  • PlaceSearchElement - تُستخدَم لعرض الأماكن باستخدام ميزة "البحث في الجوار" أو "البحث النصي"
  • عنصر تفاصيل المكان - يُستخدَم لعرض تفاصيل مكان فردي
  • ‫Maps JavaScript API: تُستخدَم لعرض خريطة على صفحتك، ولاستيراد حزمة أدوات "خرائط Google" الجاهزة للأماكن

فعِّل Maps JavaScript API وحزمة أدوات "خرائط Google" الجاهزة للأماكن في مشروعك.

تأكَّد من تحميل Maps JavaScript API واستيراد المكتبات المطلوبة قبل البدء. يفترض هذا المستند أيضًا معرفة عملية بتطوير الويب، بما في ذلك HTML وCSS وJavaScript.

إضافة خريطة إلى الصفحة

الخطوة الأولى هي إضافة خريطة إلى صفحتك. سيتم استخدام هذه الخريطة لعرض نتائج PlaceSearchElement كدبابيس قابلة للاختيار.

هناك طريقتان لإضافة خريطة إلى صفحة:

  1. استخدام gmp-map مكوّن ويب HTML
  2. باستخدام JavaScript

تم إنشاء مقتطفات الرموز في هذه الصفحة باستخدام خريطة JavaScript.

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

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

الصورة

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

إعداد PlaceSearchElement

بعد ذلك، عليك إعداد HTML وCSS لعرض PlaceSearchElement. يعرض هذا المثال العنصر فوق الجانب الأيمن من الخريطة، ولكن يمكنك تجربة تنسيقات مختلفة لتناسب تطبيقك.

يستخدم PlaceSearchElement نهجًا تعريفيًا. بدلاً من ضبطه بالكامل في JavaScript، يمكنك تحديد نوع البحث مباشرةً في HTML من خلال تضمين عنصر طلب، مثل <gmp-place-nearby-search-request>، داخل مكوّن <gmp-place-search> الرئيسي.

ضمن رمز HTML، ابدأ عنصر <gmp-place-search>. استخدِم السمة selectable لتفعيل الأحداث الناتجة عن النقر على النتائج. أضِف داخلها <gmp-place-nearby-search-request> لتحديد أنّ هذا العنصر سيتم استخدامه للبحث في الجوار.

<gmp-place-search selectable>
  <gmp-place-nearby-search-request>
  </gmp-place-nearby-search-request>
</gmp-place-search>

لإجراء بحث أوّلي وعرض النتائج، سنستخدم JavaScript للحصول على مرجع لعنصر الطلب المضمّن وضبط خصائصه. ابدأ بإنشاء دائرة لاستخدامها كـ locationRestriction، باستخدام موضع العلامة من الخطوة السابقة كنقطة مركزية. بعد ذلك، اضبط السمتَين locationRestriction وincludedPrimaryTypes في عنصر الطلب لتفعيل البحث.

مقتطف الرمز لهذا هو كما يلي:

// Get references to the Place Search and its nested request element
const placeSearchElement = document.querySelector("gmp-place-search");
const placeSearchRequestElement = document.querySelector("gmp-place-nearby-search-request");

// Define the location restriction for the search
const circleRestriction = new Circle({
    center: marker.position,
    radius: 500
});

// Set the properties on the request element to perform an initial search for restaurants.
placeSearchRequestElement.locationRestriction = circleRestriction;
placeSearchRequestElement.includedPrimaryTypes = ['restaurant'];

في ما يلي مثال على الشكل الذي قد يبدو عليه التطبيق في هذه المرحلة:

الصورة

تتيح PlaceSearchElement خيارَي بحث:

هذه عناصر مدمجة داخل <gmp-place-search>. بعد ذلك، يمكنك تفعيل عمليات البحث من خلال ضبط السمات في عنصر الطلب المضمّن باستخدام JavaScript.

يصف هذا القسم كيفية تنفيذ كلتا الطريقتين.

الصورة

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

ننصحك باختيار مجموعة فرعية من الأنواع ذات الصلة بحالة الاستخدام. على سبيل المثال، إذا كنت تطوّر تطبيقًا لعرض الأماكن القريبة من الفندق للسياح، يمكنك اختيار: bakery وcoffee_shop وmuseum وrestaurant وtourist_attraction.

يجب أن يحتوي ملف HTML على العنصر <gmp-place-search> مع عنصر <gmp-place-nearby-search-request> مدمج بداخله.

<gmp-place-search selectable>
  <gmp-place-nearby-search-request>
  </gmp-place-nearby-search-request>
</gmp-place-search>

بعد ذلك، أنشئ مستمع JavaScript للحدث change في أداة اختيار نوع المكان. سيستدعي هذا المستمع دالة تعمل على تحديث خصائص العنصر <gmp-place-nearby-search-request>، مما يؤدي تلقائيًا إلى تشغيل بحث جديد وتحديث القائمة.

// Get a reference to the nested request element
const placeSearchRequestElement = document.querySelector('gmp-place-nearby-search-request');

// Function to update the place search based on the selected type
function updatePlaceList() {
    const selectedType = placeTypeSelect.value;
    if (!selectedType) {
        // If no type is selected, don't perform a search.
        // You could optionally hide the list or clear previous results here.
        placeSearchElement.style.display = 'none';
        return;
    }
    placeSearchElement.style.display = 'block';

    // Set properties on the request element to trigger a new search
    placeSearchRequestElement.locationRestriction = searchCircle;
    placeSearchRequestElement.maxResultCount = 8;
    placeSearchRequestElement.includedPrimaryTypes = [selectedType];
}

يتم استخدام searchCircle نفسه من خطوة الإعداد في locationRestriction. يتم ضبط السمة includedPrimaryTypes على القيمة من اختيار المستخدم. يتم أيضًا ضبط مَعلمة maxResultCount اختيارية للحدّ من عدد النتائج.

الصورة

لتفعيل ميزة البحث النصي، يجب تغيير إعدادات HTML. بدلاً من طلب البحث في الجوار، يمكنك تضمين عنصر <gmp-place-text-search-request>.

<gmp-place-search selectable>
  <gmp-place-text-search-request>
  </gmp-place-text-search-request>
</gmp-place-search>

أضِف حقل إدخال نص وزر بحث إلى واجهة المستخدم. أنشئ مستمع JavaScript للحدث click الخاص بالزر. سيأخذ معالج الأحداث إدخال المستخدم ويحدّث خصائص عنصر <gmp-place-text-search-request> لإجراء البحث.

// Get a reference to the text search request element
const placeTextSearchRequestElement = document.querySelector('gmp-place-text-search-request');
const textSearchInput = document.getElementById('textSearchInput');
const textSearchButton = document.getElementById('textSearchButton');

textSearchButton.addEventListener('click', performTextSearch);

function performTextSearch() {
    const query = textSearchInput.value.trim();
    if (!query) {
        console.log("Search query is empty.");
        return;
    }
    // Set properties on the request element to trigger a new search
    placeTextSearchRequestElement.textQuery = query;
    placeTextSearchRequestElement.locationBias = map.getBounds();
    placeTextSearchRequestElement.maxResultCount = 8;
}

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

عرض دبابيس الأماكن وتفاصيلها

يمكن للتطبيق الآن إجراء عملية بحث عن الأماكن وتعبئة العنصر. في الخطوة التالية، سنحسّن وظائفها من خلال:

  • يتم عرض دبابيس على الخريطة لكل مكان تم ملؤه في PlaceSearchElement.
  • السماح للمستخدم بالنقر على دبوس أو مكان ضمن PlaceSearchElement، لعرض المزيد من التفاصيل حول هذا المكان المحدّد.

مبدأ هذه الخطوة هو نفسه سواء كان التطبيق يستخدم بحثًا في الجوار أو بحثًا نصيًا.

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

let markers = {};

أنشئ دالة لإضافة علامات إلى الخريطة. سيتم استدعاء هذه الدالة عند تحميل نتائج بحث جديدة. سيؤدي ذلك إلى:

  • أزِل أي علامات أماكن حالية من الخريطة.
  • يمكنك تكرار النتائج من PlaceSearchElement وإضافة علامة لكل منها.
  • اضبط حدود الخريطة لتظهر جميع العلامات الجديدة.

للاستماع إلى وقت توفّر نتائج البحث، أضِف متتبِّع الأحداث gmp-load إلى العنصر <gmp-place-search>. يتم تنشيط هذا الحدث بعد اكتمال عملية البحث وعرض النتائج.

سنضيف المستمع داخل دالة البحث (مثل updatePlaceList)، ونستخدم الخيار { once: true } للتأكّد من أنّه يتم تفعيله فقط لنتائج البحث الحالي.

// In your search function, after setting the request properties:
placeSearchElement.addEventListener('gmp-load', addMarkers, { once: true });

تبدو الدالة addMarkers على النحو التالي:

async function addMarkers() {
    const { LatLngBounds } = await google.maps.importLibrary("core");
    const bounds = new LatLngBounds();

    if (placeSearchElement.places.length > 0) {
        // Remove existing markers
        for (const m in markers) {
            markers[m].map = null;
        }
        markers = {};

        // Loop through each place from the search results
        // and add a marker for each one.
        for (const place of placeSearchElement.places) {
            const marker = new google.maps.marker.AdvancedMarkerElement({
                map: map,
                position: place.location,
            });

            markers[place.id] = marker;
            bounds.extend(place.location);
            marker.collisionBehavior = google.maps.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL;

            // Add a click listener for each marker.
            marker.addListener('gmp-click', (event) => {
                // The main logic for showing details will go here.
            });
        }
        // Position the map to display all markers.
        map.setCenter(bounds.getCenter());
        map.fitBounds(bounds);
    }
}

بعد إكمال هذه الخطوة، سيظهر التطبيق على النحو التالي، مع إمكانية عرض علامات لكل مكان يتم عرضه من خلال PlaceSearchElement:

الصورة

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

أضِف رمز HTML الخاص بالعنصر المضغوط "تفاصيل المكان" إلى الرمز البرمجي، على سبيل المثال:

<gmp-place-details-compact orientation="vertical" style="display: none;">
    <gmp-place-all-content></gmp-place-all-content>
    <gmp-place-attribution light-scheme-color="gray" dark-scheme-color="white"></gmp-place-attribution>
</gmp-place-details-compact>

تم ضبط "style" على "display: none"، ولن يظهر إلا عند الحاجة إليه. يتم تمرير gmp-place-all-content لعرض كل محتوى العنصر. لاختيار المحتوى الذي تريد عرضه، يُرجى الاطّلاع على مستندات عنصر تفاصيل المكان المختصرة.

أنشئ متغيرًا عموميًا في JavaScript للاحتفاظ بمرجع إلى العنصر المدمج لتفاصيل المكان، وأدخِل هذه البيانات في رمز الإعداد، على سبيل المثال:

let placeDetailsElement;
...
placeDetailsElement = document.querySelector('gmp-place-details-compact');

ضمن الدالة addMarkers، أضِف متتبِّع الأحداث gmp-click إلى كل علامة، واضبط العنصر المضغوط لتفاصيل المكان لعرض تفاصيل المكان من خلال تمرير رقم تعريف المكان للعلامة الحالية.

بعد ذلك، يتم فتح نافذة معلومات لعرض عنصر تفاصيل المكان المصغّر، المثبَّت على العلامة.

أخيرًا، يتم تحديد موضع الخريطة على إطار العرض للمكان المحدّد، ما يجعله مرئيًا.

async function addMarkers() {
          ...
            marker.addListener('gmp-click', (event) => {
                //Set up Place Details Compact Widget
                placeDetailsElement.style.display = "block";
                // Remove any existing place request element
                const existingPlaceRequest = placeDetailsElement.querySelector('gmp-place-details-place-request');
                if (existingPlaceRequest) {
                    existingPlaceRequest.remove();
                }
                // Create and configure the new place request element
                const placeRequestElement = new google.maps.places.PlaceDetailsPlaceRequestElement({ place: place.id });
                // Prepend the new place request element to the main widget
                placeDetailsElement.prepend(placeRequestElement);
                if (infoWindow.isOpen) {
                    infoWindow.close();
                }
                infoWindow.setOptions({
                    content: placeDetailsElement
                });
                infoWindow.open({
                    anchor: marker,
                    map: map
                });
                // Position the map to show the selected place
                placeDetailsElement.addEventListener('gmp-load', () => {
                    map.fitBounds(place.viewport, { top: 500, left: 400 });
                });
            });
          ...
        });
    }
}

للسماح للمستخدم بالنقر على مكان في عنصر قائمة الأماكن لعرض عنصر تفاصيل المكان المصغّر، أضِف ما يلي إلى رمز JavaScript بعد طلب configureFromSearchNearbyRequest.

placeSearchElement.addEventListener("gmp-select", ({ place }) => {
    if (markers[place.id]) {
        markers[place.id].click();
    }
});

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

سيظهر التطبيق على النحو التالي:

الصورة

الخاتمة

يوفّر PlaceSearchElement مع عنصر "تفاصيل المكان" المختصر طريقة مبسّطة لإضافة ميزات غنية لاستكشاف الأماكن إلى تطبيقاتك على "منصة خرائط Google".

جرِّب حزمة أدوات "خرائط Google" الجاهزة للأماكن اليوم لتمكين المستخدمين من العثور على الأماكن واستكشافها باستخدام عمليات البحث النصية وعمليات البحث عن الأماكن المجاورة، وعرض تفاصيل غنية عن الأماكن، ما يعزّز تفاعلهم مع حالات استخدام استكشاف الأماكن.

المساهمون

هنريك فالف | مهندس DevX