פיתוח מפת חנויות/משרדים ב-1C-Bitrix
לעתים קרובות אנו נתקלים במשימה: לקוח מבקש להוסיף מפה עם נקודות מכירה לאתר, אבל הכלים הסטנדרטיים של Bitrix לא מאפשרים ליישם חיפוש גיאוגרפי, סינון וקיבוץ (clustering). התוצאה: המשתמש מזין עיר אבל רואה רשימת כתובות ללא מפה — חוויית משתמש ירודה. כדי לפתור זאת, אנו מפתחים מפת חנויות מותאמת אישית המבוססת על אינפובלוקים ו-API של מפות. הניסיון שלנו: 10+ שנים בפיתוח Bitrix, 100+ פרויקטים שהושלמו.
משתמש רוצה למצוא במהירות את החנות הקרובה ולבנות מסלול. ללא מפה, זה בלתי אפשרי. אנו יוצרים רכיב (component) ששומר את קואורדינטות הנקודות, מציג אותן על מפה עם קיבוץ, מאפשר סינון לפי סוג ועיר, וגם מזהה את מיקום המשתמש.
כיצד פועלת מפת החנויות ב-Bitrix?
כל נקודת מכירה היא אלמנט אינפובלוק. מאפיינים מרכזיים — קואורדינטות (LAT/LNG), כתובת, טלפון, שעות עבודה. אנו מוסיפים גיאוקידינג (geocoding): בעת יצירת נקודה, הקואורדינטות מתמלאות אוטומטית דרך Yandex.Geocoder API. זה מבטל הזנה ידנית ושגיאות.
מדוע חשוב לאחסן קואורדינטות באינפובלוק?
אחסון LAT/LNG באינפובלוק מאפשר ביצוע שאילתות מרחביות בצד PHP — למשל, חיפוש נקודות ברדיוס מהמשתמש. ללא זה, היית צריך ליצור קואורדינטות תוך כדי תנועה, דבר שאיטי ולא אמין. אינפובלוקים v2.0 עם מאפיינים מספריים נותנים דיוק עד 6 ספרות עשרוניות — מספיק כדי לזהות בניין ספציפי.
אחסון נתוני נקודת מכירה
קבוצת מאפיינים מינימלית של אלמנט אינפובלוק:
| מאפיין | סוג | דוגמה |
|---|---|---|
| ADDRESS | מחרוזת | "מוסקבה, רחוב טברסקיה 1" |
| LAT | מספר (6 ספרות עשרוניות) | 55.756123 |
| LNG | מספר (6 ספרות עשרוניות) | 37.614567 |
| PHONE | מחרוזת או מרובה | "+7 (495) 123-45-67" |
| WORKING_HOURS | מחרוזת | "{"mon-fri":"9:00-20:00"}" |
| POINT_TYPE | רשימה | "חנות", "נקודת איסוף", "שירות" |
| CITY_ID | אלמנט אינפובלוק של ערים | מזהה העיר |
| METRO | מחרוזת | "טברסקיה" |
| PHOTO | קובץ | נתיב לתמונה |
אנו מקבלים קואורדינטות דרך גיאוקידינג בעת שמירת אלמנט. דוגמה למטפל אירועים OnBeforeIBlockElementAdd:
AddEventHandler('iblock', 'OnBeforeIBlockElementAdd', 'geocodeStoreAddress'); function geocodeStoreAddress(&$arFields) { if ($arFields['IBLOCK_ID'] !== IBLOCK_STORES_ID) return; $address = urlencode($arFields['PROPERTIES']['ADDRESS']['VALUE']); $http = new \Bitrix\Main\Web\HttpClient(); $response = $http->get("https://geocode-maps.yandex.ru/1.x/?apikey=KEY&format=json&geocode=$address"); $data = json_decode($response, true); $coords = $data['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['Point']['pos']; [$lng, $lat] = explode(' ', $coords); $arFields['PROPERTIES']['LAT']['VALUE'] = $lat; $arFields['PROPERTIES']['LNG']['VALUE'] = $lng; } Yandex.Geocoder API משמש בחינם עד 25,000 בקשות ביום.
בחירת API למפות
השוואה בין פתרונות פופולריים:
| API | כיסוי | מגבלה חינמית | תכונות |
|---|---|---|---|
| Yandex.Maps | רוסיה, חבר המדינות | 1,000 בקשות/יום | תנועה, מסלולים, גיאולוקיישן |
| 2GIS | רוסיה, חבר המדינות | עד 100,000 טעינות/יום | תוכניות קומות של מבנים |
| OpenStreetMap + Leaflet.js | עולמי | ללא הגבלה | צריך גיאוקודר משלו (Nominatim) |
לפרויקטים רוסיים אנו משתמשים ב-Yandex.Maps — כיסוי מפורט וקיבוץ מובנה. קיבוץ משפר ביצועים פי 5 עם 200+ נקודות.
ארכיטקטורת הרכיב
הרכיב מורכב מקצה אחורי PHP וקצה קדמי JS. הקצה האחורי מקבל את רשימת הנקודות מהאינפובלוק, ומסנן אופציונלית לפי עיר או רדיוס. הנתונים מועברים ל-JS דרך JSON בסקריפט או דרך נקודת קצה AJAX.
$res = CIBlockElement::GetList( [], ['IBLOCK_ID' => IBLOCK_STORES_ID, 'ACTIVE' => 'Y'], false, false, ['ID', 'NAME', 'PROPERTY_LAT', 'PROPERTY_LNG', 'PROPERTY_ADDRESS', 'PROPERTY_PHONE', 'PROPERTY_WORKING_HOURS', 'PROPERTY_POINT_TYPE'] ); $points = []; while ($el = $res->GetNext()) { $points[] = [ 'id' => $el['ID'], 'name' => $el['NAME'], 'lat' => (float)$el['PROPERTY_LAT_VALUE'], 'lng' => (float)$el['PROPERTY_LNG_VALUE'], 'address' => $el['PROPERTY_ADDRESS_VALUE'], 'phone' => $el['PROPERTY_PHONE_VALUE'], 'hours' => $el['PROPERTY_WORKING_HOURS_VALUE'], 'type' => $el['PROPERTY_POINT_TYPE_VALUE'], ]; } הקצה הקדמי מאתחל את המפה, מוסיף סמנים עם קיבוץ, מיישם חיפוש וסינון. קיבוץ הוא חובה עם 50+ נקודות — בלעדיו המפה מאטה.
// Яндекс.Карты API 3.0 const map = new ymaps3.YMap(document.getElementById('map'), { location: { center: [37.617, 55.755], zoom: 10 } }); const clusterer = new ymaps3.YMapClusterer({ ... }); ביצועים עם 500+ נקודות
עם מספר גדול של נקודות, העברת המערך כולו ב-JS אינה יעילה. פתרון:
- AJAX מפולח: טעינת נקודות בגבולות המפה הנראית, טעינת עוד בעת גלילה.
- חיפוש רדיוס בצד השרת: סינון ב-SQL באמצעות נוסחת haversine או PostGIS (אם משתמשים ב-PostgreSQL).
- קאש: רשימת הנקודות משתנה לעתים רחוקות, קאש לשעה ב-b_cache.
נוסחת Haversine ל-SQL (MySQL)
SELECT *, (6371 * acos(cos(radians(:lat)) * cos(radians(lat)) * cos(radians(lng) - radians(:lng)) + sin(radians(:lat)) * sin(radians(lat)))) AS distance FROM b_iblock_element_prop_... HAVING distance < :radius ORDER BY distance זה עובד לקטלוגים עד 5000 נקודות ללא PostGIS.
לוחות זמנים ועלות
| היקף | מה כלול | לוח זמנים |
|---|---|---|
| עד 50 נקודות | מפה + רשימה + סינון לפי עיר | 1–2 שבועות |
| 50–300 נקודות | + קיבוץ, גיאולוקיישן, חיפוש בקרבת מקום | 2–4 שבועות |
| 300+ נקודות | + חיפוש רדיוס בצד השרת, PostGIS | 4–6 שבועות |
העלות מחושבת באופן פרטני ותלויה במורכבות.
מה כלול בעבודה
- פיתוח הרכיב והתבנית
- אינטגרציה עם API למפות (Yandex.Maps, 2GIS או OpenStreetMap)
- גיאוקידינג של כתובות בעת הוספת נקודות
- הגדרת חיפוש גיאוגרפי וסינון
- קיבוץ סמנים
- פאנל צדדי עם רשימת נקודות (מסונכרן עם המפה)
- בדיקות ואופטימיזציית ביצועים
- מסירת תיעוד וגישה
- הדרכה למנהלים
- חודש תמיכה באחריות
הניסיון והערבויות שלנו
אנו מומחי 1C-Bitrix מוסמכים עם ניסיון של למעלה מ-10 שנים. השלמנו 100+ פרויקטים, כולל מפות חנויות לרשתות פדרליות. אנו מבטיחים עבודה לפי חוזה ועמידה בלוחות זמנים. צרו קשר לייעוץ בנוגע לפרויקט שלכם.







