الهدف
تعرَّف على كيفية دمج عنصر "البحث عن الأماكن" مع "خرائط Google" لمساعدة المستخدمين في العثور على أماكن باستخدام البحث عن الأماكن القريبة أو البحث النصي، ما يعزّز قدرتهم على استكشاف نقاط الاهتمام. استخدِم "العنصر المضغوط لتفاصيل المكان" لتقديم المزيد من التفاصيل حول الأماكن التي تظهر في تطبيقك.
ما هو "عنصر البحث عن الأماكن"؟
عنصر "البحث عن الأماكن" هو جزء من حزمة أدوات واجهة المستخدم الخاصة بخدمة "أماكن" في Maps JavaScript API. وهي عنصر HTML يعرض نتائج البحث عن مكان مباشرةً بتنسيق قائمة ضمن تطبيقك. يبسّط هذا العنصر عملية عرض الأماكن التي تم العثور عليها باستخدام "البحث القريب" أو "البحث النصي"، ما يوفّر تجربة سلسة للمستخدمين في ما يتعلّق باستكشاف الأماكن. عندما يختار المستخدم مكانًا من القائمة، يمكنك عرض تفاصيله على الخريطة، وغالبًا ما يتم ذلك باستخدام "نافذة المعلومات" و"عنصر تفاصيل المكان".
عرض مرئي لاكتشاف الأماكن
تعرض الصورة التالية مثالاً على "عنصر البحث عن الأماكن" أثناء العمل. على اليمين، تظهر قائمة بالمطاعم (عنصر "البحث عن مكان"). عند اختيار مطعم، تظهر تفاصيله في نافذة معلومات على الخريطة، ويتم توسيط الخريطة على موقعه الجغرافي.
حالات استخدام ميزة "اقتراحات"
يمكن أن يؤدي دمج عنصر "البحث عن الأماكن" إلى تحسين تطبيقات مختلفة في مجالات متنوعة، مثل:
- السفر والسياحة: تتيح للسياح البحث عن أماكن جذب أو فنادق أو أنواع معيّنة من المأكولات في منطقة معيّنة.
- العقارات: يمكنك السماح للمشترين أو المستأجرين المحتملين بالعثور على المدارس أو محلات السوبرماركت أو خيارات النقل العام القريبة.
- الخدمات اللوجستية: مساعدة السائقين في العثور على محطات شحن المركبات الكهربائية أو محطات الوقود أو مراكز الصيانة المحدّدة
سير عمل الحلّ: تنفيذ ميزة "اقتراحات"
يرشدك هذا القسم إلى خطوات دمج عنصر "البحث عن الأماكن" لاستكشاف الأماكن على الخريطة، بما في ذلك مقتطفات الرموز البرمجية للتفاعل مع Places UI Kit. سنتناول عملية تهيئة الخريطة وتنفيذ وظيفتَي "البحث القريب" و"البحث النصي". أخيرًا، سنستخدم عنصر Place Details لعرض المزيد من التفاصيل حول مكان معيّن عند النقر على الدبوس الخاص به على الخريطة.
المتطلبات الأساسية
ننصحك بالاطّلاع على المستندات التالية:
- عنصر "البحث عن الأماكن" - يُستخدَم لعرض الأماكن باستخدام ميزة "البحث في الأماكن القريبة" أو "البحث النصي"
- عنصر تفاصيل المكان - يُستخدَم لعرض تفاصيل مكان فردي
- Maps JavaScript API: تُستخدَم لعرض خريطة على صفحتك واستيراد Places UI Kit
فعِّل Maps JavaScript API وPlaces UI Kit في مشروعك.
قبل البدء، تأكَّد من تحميل Maps JavaScript API واستيراد المكتبات المطلوبة. يفترض هذا المستند أيضًا توفّر معرفة عملية بتطوير الويب، بما في ذلك HTML وCSS وJavaScript.
إضافة خريطة إلى الصفحة
تتمثل الخطوة الأولى في إضافة خريطة إلى صفحتك. سيتم استخدام هذه الخريطة لعرض نتائج "عنصر البحث عن الأماكن" على شكل دبابيس قابلة للتحديد.
هناك طريقتان لإضافة خريطة إلى صفحة:
- استخدام
gmp-map
مكوّن ويب HTML - استخدام JavaScript
تم إنشاء مقتطفات الرموز البرمجية في هذه الصفحة باستخدام خريطة JavaScript.
يمكن توسيط الخريطة على موقع جغرافي تريد أن يبحث المستخدم حوله، مثل فندق، أو يمكن ضبطها لطلب الموقع الجغرافي الحالي للمستخدم من أجل توسيط الخريطة. لأغراض هذا المستند، سنستخدم موقعًا جغرافيًا ثابتًا لتثبيت البحث.
إذا كنت تعرض أماكن قريبة من موقع جغرافي ثابت، مثل فندق، ضَع علامة على الخريطة لتمثيل هذا المكان. على سبيل المثال:
تتوسّط الخريطة مدينة سان فرانسيسكو، ويظهر دبوس أزرق للإشارة إلى المكان الذي نبحث عنه في المنطقة المجاورة. تم تخصيص لون الدبوس باستخدام
PinElement
.
تم إخفاء عنصر التحكّم في نوع الخريطة من واجهة المستخدِم.
إعداد "عنصر البحث عن الأماكن"
يمكننا الآن إعداد HTML وCSS لعرض "عنصر البحث عن الأماكن". في هذا المثال، سنضع العنصر فوق الجانب الأيسر من الخريطة، ولكن يُنصح بتجربة تنسيقات مختلفة لتناسب تطبيقك.
يستخدم عنصر "بحث الأماكن" أسلوبًا تصريحيًا. بدلاً من ضبطها بالكامل في 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'];
في ما يلي مثال على الشكل الذي يمكن أن يبدو عليه التطبيق في هذه المرحلة:
السماح للمستخدم بالبحث
يتيح "عنصر البحث عن الأماكن" خيارَي بحث:
<gmp-place-nearby-search-request>
: لعرض نتائج البحث من بحث الأماكن القريبة، باستخدام أنواع الأماكن<gmp-place-text-search-request>
: لعرض نتائج البحث من Places Text Search، باستخدام إدخال نصي مجاني، مثل "سوشي في سان فرانسيسكو".
هذه هي العناصر المتداخلة داخل <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
اختياري من عدد النتائج المعروضة.
عرض دبابيس الأماكن وتفاصيلها
يمكن للتطبيق الآن إجراء بحث عن مكان وتعبئة العنصر. في الخطوة التالية، سنحسّن وظائفها من خلال:
- عرض دبابيس على الخريطة لكل مكان تم ملؤه في عنصر "بحث الأماكن"
- السماح للمستخدم بالنقر على دبوس أو على المكان ضمن عنصر "بحث الأماكن" لعرض المزيد من التفاصيل حول هذا المكان
ويظل مبدأ هذه الخطوة كما هو سواء كان التطبيق يستخدم البحث القريب أو البحث النصي.
أولاً، أضِف متغيّرًا عامًا إلى رمز JavaScript لتخزين عناصر نائب عن موضع الإعلان. سيسمح لك ذلك بإزالتها عند تغيير البحث والتعامل مع أحداث النقر.
let markers = {};
أنشئ دالة لإضافة علامات إلى الخريطة. سيتم استدعاء هذه الدالة عند تحميل نتائج بحث جديدة. سيؤدي ذلك إلى:
- أزِل أي علامات أماكن حالية من الخريطة.
- كرِّر النتائج من "عنصر البحث عن الأماكن" وأضِف علامة لكل نتيجة.
- اضبط حدود الخريطة لتظهر جميع العلامات الجديدة.
للاستماع إلى وقت توفّر نتائج البحث، أضِف أداة معالجة الأحداث 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);
}
}
بعد إكمال هذه الخطوة، سيبدو التطبيق على النحو التالي، مع إمكانية عرض علامات لكل مكان تم عرضه من خلال عنصر "بحث الأماكن":
بعد إضافة العلامات على الخريطة، الخطوة الأخيرة هي معالجة أحداث النقر على العلامات والعناصر لعرض نافذة معلومات تتضمّن تفاصيل المكان، وذلك باستخدام عنصر تفاصيل المكان. في هذا المثال، سنستخدم عنصر "تفاصيل المكان" المضغوط.
أضِف رمز 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();
}
});
بعد إكمال هذه الخطوة، سيتمكّن التطبيق من استخدام إما Nearby Search أو Text Search لملء عنصر قائمة الأماكن. ستعرض نتائج هذا الطلب دبابيس على الخريطة، وعند النقر على دبوس أو مكان في عنصر "قائمة الأماكن"، سيتم عرض "نافذة معلومات" تتضمّن تفاصيل المكان، والتي يوفّرها عنصر "تفاصيل المكان" المضغوط.
سيبدو التطبيق على النحو التالي:
الخاتمة
يوفّر عنصر "البحث عن الأماكن" مع عنصر "تفاصيل المكان" المضغوط طريقة مبسطة لإضافة ميزات غنية لاكتشاف الأماكن إلى تطبيقاتك على Google Maps Platform.
جرِّب Places UI Kit اليوم لمساعدة المستخدمين في العثور على الأماكن واستكشافها باستخدام عمليات البحث النصية وعمليات البحث عن الأماكن القريبة، وعرض تفاصيل غنية عن الأماكن، ما يعزّز تفاعلهم مع حالات استخدام استكشاف الأماكن.
المساهمون
هنريك فالف | مهندس DevX