מטרה
במאמר הזה נסביר איך לפתח אפליקציה אינטראקטיבית לאיתור חנויות באמצעות Google Maps Platform, ובפרט באמצעות ממשק API של JavaScript במפות Google וערכת כלי הממשק של Places: Place Details Element. תלמדו איך ליצור מפה שבה מוצגים מיקומי החנויות, איך לעדכן באופן דינמי רשימה של חנויות גלויות ואיך להציג מידע מפורט על כל חנות.
דרישות מוקדמות
מומלץ להכיר את הנושאים הבאים:
- Maps JavaScript API – ממשק שמשמש להצגת מפה בדף שלכם ולייבוא של Places UI Kit.
- Advanced Markers - משמש להצגת סמנים במפה.
- Places UI Kit – משמש להצגת מידע על החנויות בממשק המשתמש.
מפעילים את Maps JavaScript API ואת Places UI Kit בפרויקט.
לפני שמתחילים, צריך לוודא שטוענים את Maps JavaScript API ומייבאים את הספריות הנדרשות לשימוש בסמנים מתקדמים ובערכת ממשק המשתמש של Places. בנוסף, אנחנו מניחים שיש לכם ידע מעשי בפיתוח אתרים, כולל HTML, CSS ו-JavaScript.
הגדרה ראשונית
השלב הראשון הוא להוסיף מפה לדף. המפה הזו תשמש להצגת סיכות שקשורות למיקומי החנויות שלכם.
יש שתי דרכים להוסיף מפה לדף:
- שימוש ברכיב אינטרנט מסוג HTML של gmp-map
- שימוש ב-JavaScript
בוחרים את השיטה שהכי מתאימה לתרחיש לדוגמה שלכם. שתי הדרכים להטמעת המפה יפעלו עם המדריך הזה.
הדגמה (דמו)
בהדגמה הזו מוצגת דוגמה של איתור חנויות בפעולה, שבה מוצגים מיקומי המשרדים של Google באזור מפרץ סן פרנסיסקו. רכיב פרטי המקום מוצג לכל מיקום, לצד כמה מאפיינים לדוגמה.
טעינה והצגה של מיקומים גיאוגרפיים של חנויות
בקטע הזה נטען את נתוני החנויות שלכם ונציג אותם במפה. המדריך הזה מניח שיש לכם מאגר מידע על החנויות הקיימות שממנו אפשר לשלוף נתונים. הנתונים של החנות יכולים להגיע ממקורות שונים, כמו מסד הנתונים שלכם.
בדוגמה הזו, אנחנו מניחים שיש קובץ JSON מקומי (stores.json
) עם מערך של אובייקטים של חנויות, שכל אחד מהם מייצג מיקום של חנות. כל אובייקט צריך לכלול לפחות את המאפיינים name
, location
(עם lat
ו-lng
) ו-place_id
.
יש כמה דרכים לאחזר את מזהי המקומות של מיקומי החנויות, אם הם לא זמינים לכם. מידע נוסף זמין במסמכי התיעוד בנושא מזהה מקום.
דוגמה לפרטי חנות בקובץ stores.json
:
יש שדות לשם, למיקום (קו רוחב/קו אורך) ולמזהה המקום. יש אובייקט
שמכיל את שעות הפתיחה של החנות (המשך). יש גם שני ערכים בוליאניים שבעזרתם אפשר לתאר תכונות ייחודיות של מיקום החנות.
{
"name": "Example Store Alpha",
"location": { "lat": 51.51, "lng": -0.12 },
"place_id": "YOUR_STORE_PLACE_ID",
"opening_hours": { "Monday": "09:00 - 17:00", "...": "..." },
"new_store_design": true,
"indoor_seating": false
}
בקוד JavaScript, מאחזרים את הנתונים של מיקומי החנויות ומציגים סיכה במפה לכל מיקום.
הנה דוגמה לאופן שבו עושים זאת. הפונקציה הזו מקבלת אובייקט שמכיל את הפרטים של החנויות, ויוצרת סמן על סמך המיקום של כל חנות.
function displayInitialMarkers(storeLocations) {
if (!AdvancedMarkerElement || !LatLng || !mapElement) return;
storeLocations.forEach(store => {
if (store.location) {
const marker = new AdvancedMarkerElement({
position: new LatLng(store.location.lat, store.location.lng),
title: store.name
});
mapElement.appendChild(marker);
}
});
}
אחרי שמעלים את החנויות ומוצגים במפה סיכות שמייצגות את המיקומים שלהן, יוצרים סרגל צד באמצעות HTML ו-CSS כדי להציג פרטים על כל אחת מהחנויות.
דוגמה לאופן שבו איתור החנויות יכול להיראות בשלב הזה:
האזנה לשינויים באזור התצוגה במפה
כדי לבצע אופטימיזציה של הביצועים ושל חוויית המשתמש, צריך לעדכן את האפליקציה כך שסמנים ופרטים יוצגו בסרגל הצד רק כשהמיקומים התואמים נמצאים באזור המפה הגלוי (חלון התצוגה). התהליך כולל האזנה לשינויים באזור התצוגה של המפה, ביטול כפילויות של האירועים האלה ואז שרטוט מחדש רק של הסמנים הנדרשים.
מצרפים event listener לאירוע idle של המפה. האירוע הזה מופעל אחרי השלמת פעולות של הזזה או שינוי גודל התצוגה, ומספק אזור תצוגה יציב לחישובים.
map.addListener('idle', debounce(updateMarkersInView, 300));
קטע הקוד שלמעלה מאזין לאירוע idle
ומפעיל פונקציה debounce
. שימוש בפונקציית ביטול הקפצה מבטיח שהלוגיקה של עדכון הסמן תפעל רק אחרי שהמשתמש יפסיק את האינטראקציה עם המפה למשך זמן קצר, וכך משפרת את הביצועים.
function debounce(func, delay) {
let timeoutId;
return function(...args) {
const context = this;
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(context, args);
}, delay);
};
}
הקוד שלמעלה הוא דוגמה לפונקציית ביטול הקפצה. היא מקבלת פונקציה וארגומנט של השהיה, שאפשר לראות שהועברו ב-listener של חוסר הפעילות. השהיה של 300 אלפיות השנייה מספיקה כדי להמתין עד שהמפה תפסיק לזוז, בלי להוסיף השהיה מורגשת לממשק המשתמש.
אחרי שפסק הזמן הזה יסתיים, המערכת תקרא לפונקציה שהועברה, במקרה הזה,
updateMarkersInView
.
הפונקציה updateMarkersInView
צריכה לבצע את הפעולות הבאות:
מחיקה של כל הסמנים הקיימים מהמפה
בודקים אם המיקום של החנות נמצא בתוך גבולות המפה הנוכחיים, למשל:
if (map.getBounds().contains(storeLatLng)) {
// logic
}
בתוך משפט התנאי if שלמעלה, כותבים קוד כדי להציג את הסמנים ואת פרטי החנות בסרגל הצד, אם מיקום החנות נמצא באזור התצוגה של המפה.
הצגת פרטים עשירים על מקומות באמצעות רכיב פרטי המקום
בשלב הזה, האפליקציה מציגה את כל מיקומי החנויות, והמשתמשים יכולים לסנן אותם לפי אזור התצוגה במפה. כדי לשפר את החוויה, אנחנו מוסיפים פרטים עשירים על כל חנות, כמו תמונות, ביקורות ופרטי נגישות, באמצעות רכיב פרטי המקום. בדוגמה הזו נעשה שימוש ספציפי ב-Place Details Compact Element.
לכל מיקום חנות במקור הנתונים צריך להיות מזהה מקום תואם. המזהה הזה מזהה באופן ייחודי את המיקום במפות Google, והוא חיוני לאחזור הפרטים שלו. בדרך כלל מקבלים את מזהי המקומות האלה מראש ושומרים אותם לצד כל רשומה של חנות.
שילוב רכיב קומפקטי של פרטי מקום באפליקציה
אם נקבע שחנות נמצאת באזור התצוגה הנוכחי של המפה והיא מוצגת בסרגל הצד, אפשר ליצור ולהוסיף באופן דינמי רכיב קומפקטי של פרטי מקום בשבילה.
מאחזרים את מזהה המקום מהנתונים שלכם עבור החנות הנוכחית שעוברת עיבוד. מזהה המקום משמש לקביעת המקום שבו הרכיב יוצג.
ב-JavaScript, יוצרים באופן דינמי מופע של PlaceDetailsCompactElement
. נוצר גם PlaceDetailsPlaceRequestElement
חדש, מועבר אליו מזהה המקום והוא מצורף ל-PlaceDetailsCompactElement
. לסיום, משתמשים ב-PlaceContentConfigElement
כדי להגדיר את התוכן שיוצג ברכיב.
הפונקציה הבאה מניחה שספריות Place UI Kit הנדרשות מיובאות וזמינות בהיקף שבו הפונקציה הזו נקראת, ושהפרמטר storeData
שמועבר לפונקציה מכיל place_id
.
הפונקציה הזו תחזיר את הרכיב, והקוד שקורא לפונקציה יהיה אחראי להוספה שלו ל-DOM.
function createPlaceDetailsCompactElement(storeData) {
// Create the main details component
const detailsCompact = new PlaceDetailsCompactElement();
detailsCompact.setAttribute('orientation', 'vertical'); // Or 'horizontal'
// Specify the Place ID
const placeRequest = new PlaceDetailsPlaceRequestElement();
placeRequest.place = storeData.place_id;
detailsCompact.appendChild(placeRequest);
// Configure which content elements to display
const contentConfig = new PlaceContentConfigElement();
// For this example, we'll render media, rating, accessibility, and attribution:
contentConfig.appendChild(new PlaceMediaElement({ lightboxPreferred: true }));
contentConfig.appendChild(new PlaceRatingElement());
contentConfig.appendChild(new PlaceAccessibleEntranceIconElement());
// Configure attribution
const placeAttribution = new PlaceAttributionElement();
placeAttribution.setAttribute('light-scheme-color', 'gray');
placeAttribution.setAttribute('dark-scheme-color', 'gray');
contentConfig.appendChild(placeAttribution);
detailsCompact.appendChild(contentConfig);
// Return the element
return detailsCompact;
}
בדוגמת הקוד שלמעלה, הרכיב מוגדר להצגת תמונות של המקום, דירוג הביקורות ופרטי הנגישות. אפשר להתאים אישית את התצוגה על ידי הוספה או הסרה של רכיבי תוכן זמינים אחרים. כל האפשרויות הזמינות מפורטות במסמכי התיעוד של PlaceContentConfigElement
.
רכיב ה-Place Details Compact תומך בסגנון באמצעות מאפיינים מותאמים אישית של CSS. כך תוכלו להתאים את המראה שלו (צבעים, גופנים וכו') לעיצוב של האפליקציה. מחילים את המאפיינים המותאמים אישית האלה בקובץ ה-CSS. אפשר לעיין במאמרי העזרה של PlaceDetailsCompactElement
כדי לראות את מאפייני ה-CSS הנתמכים.
דוגמה לאופן שבו האפליקציה יכולה להיראות בשלב הזה:
שיפור הכלי לאיתור חנויות
יצרת בסיס מוצק לאפליקציה לאיתור חנויות. עכשיו, נציג כמה דרכים להרחיב את הפונקציונליות שלו וליצור חוויה עשירה יותר וממוקדת יותר במשתמש.
הוספת השלמה אוטומטית
כדי לשפר את האופן שבו משתמשים מוצאים אזורים לחיפוש חנויות, אפשר לשלב קלט חיפוש עם השלמה אוטומטית של מקומות. כשמשתמשים מקלידים כתובת, שכונה או נקודת עניין ובוחרים הצעה, צריך לתכנת את המפה כך שהיא תתמרכז אוטומטית במיקום הזה ותפעיל עדכון של חנויות בקרבת מקום. כדי לעשות את זה, מוסיפים שדה קלט ומצרפים אליו את הפונקציונליות של השלמה אוטומטית של מקומות. כשבוחרים הצעה, אפשר למרכז את המפה בנקודה הזו. חשוב לזכור להגדיר את ההטיה או ההגבלה של התוצאות לאזור הפעילות שלכם.
זיהוי מיקום
כדי להציע רלוונטיות מיידית, במיוחד למשתמשים בנייד, כדאי להטמיע פונקציונליות לזיהוי המיקום הגאוגרפי הנוכחי שלהם. אחרי קבלת הרשאת הדפדפן לזיהוי המיקום, המפה תתמרכז אוטומטית במיקום של המשתמש ותציג את החנויות הקרובות ביותר. המשתמשים מעריכים מאוד את התכונה בסביבה כשהם מחפשים אפשרויות מיידיות. מוסיפים כפתור או הנחיה ראשונית כדי לבקש גישה למיקום.
הצגת המרחק והמסלול
אחרי שהמשתמש מזהה חנות שמעניינת אותו, אפשר לשפר משמעותית את חוויית השימוש שלו באמצעות שילוב של Routes API. לכל חנות שמופיעה ברשימה, מחשבים ומציגים את המרחק מהמיקום הנוכחי של המשתמש או מהמיקום שחיפש. בנוסף, צריך לספק לחצן או קישור שמשתמשים ב-Routes API כדי ליצור מסלול מהמיקום של המשתמש לחנות שנבחרה. אחר כך תוכלו להציג את המסלול הזה במפה או לקשר למפות Google כדי לקבל הוראות הגעה, וכך ליצור מעבר חלק בין מציאת חנות לבין ההגעה אליה.
הטמעה של התוספים האלה מאפשרת לכם להשתמש ביכולות נוספות של פלטפורמת Google Maps כדי ליצור כלי מקיף ונוח יותר לאיתור חנויות, שנותן מענה ישיר לצרכים נפוצים של משתמשים.
סיכום
במדריך הזה הראינו את השלבים העיקריים ליצירת כלי אינטראקטיבי לאיתור חנויות. למדתם איך להציג את מיקומי החנויות שלכם במפה באמצעות Maps JavaScript API, איך לעדכן באופן דינמי את החנויות שמוצגות על סמך שינויים באזור התצוגה, וחשוב מכך, איך להציג את נתוני החנויות שלכם בהתאם ל-Places UI Kit. אם משתמשים בפרטי החנויות הקיימים, כולל מזהי מקומות, עם רכיב פרטי המקום, אפשר להציג פרטים עשירים ותקניים לכל אחד מהמיקומים, וכך ליצור בסיס איתן לאיתור חנויות שקל להשתמש בו.
כדאי לנסות את Maps JavaScript API ואת Places UI Kit כדי להציע כלים עוצמתיים מבוססי-רכיבים לפיתוח מהיר של אפליקציות מתוחכמות מבוססות-מיקום. השילוב של התכונות האלה מאפשר לכם ליצור חוויות מעניינות ואינפורמטיביות למשתמשים.
תורמים
Henrik Valve | DevX Engineer