Телеграм: @camouf_ru Почта: mihail@bazarow.ru

Определить местоположение пользователя и показать магазины поблизости.

Просмотров: 1142

Задача: в мобильном приложении, которое открывает сайт на 1С-Битрикс внутри себя, нужно определить местоположение пользователя и показать близжайшие к нему рестораны и кафе из базы данных сайта

Ресторны- это элементы инфоблока местоположение которых задано через свойство привязка к Яндекс Картам, в котором хранятся (через запятую) широта и долгота метки, в виде строки.

Определить местоположение пользователя и показать магазины поблизости.

Выводить будем с помощью API Яндекс Карт c их же помощью стилизуем внешний вид меток. Что бы получилось что-то такое.

Определить местоположение пользователя и показать магазины поблизости.

Само приложение работает на Apache Cordova (кстати, можете посмотреть мой новый видео-курс
Создание мобильного приложения на Apache Cordova), соответственно мы имеем полный доступ к GPS датчику и можем определить местоположение пользователя, вплоть до дома.

Определяем местоположение пользователя с датчиков телефона.

Тут все просто: устанавливаем плагин cordova-plugin-geolocation и не забываем установить плагин cordova-plugin-remote-injection, что бы можно было вызывать плагины Cordova с подключаемого сайта.

cordova plugin add cordova-plugin-geolocation
cordova plugin add cordova-plugin-remote-injection

Теперь мы можем получить данные с GPS/Глонасс датчиков телефона, тут много всякого- но нам нужны только широта и долгота (высота, скорость движения и.т.д. нам не нужны). Создаем две переменные (latitude и longitude) с нужными данными:

document.addEventListener("deviceready", onDeviceReady, false);
    function onDeviceReady() {
        var onSuccess = function (position) {
            var latitude = position.coords.latitude;
            var longitude = position.coords.longitude;
        };
        navigator.geolocation.getCurrentPosition(onSuccess, onError);
    }

Получаем список элементов со свойством "привязка к Яндекс Картам"

Теперь получим список всех ресторанов, самое главное получить свойство (в моем случае) с кодом ATT_MAP. Также получим название ресторана, что бы вывести его в метке.

Получать будем методом CIBlockElement::GetList по старинке, дабы не городить лишние запросы к свойствам элементов на D7, да и работает быстрее. Строку с широтой и долготой сразу раздробим с помощью explode (разбивает строку с помощью разделителя)

CModule::IncludeModule('iblock');
$restorants = CIBlockElement::GetList(
    false,
    array('IBLOCK_ID' => '4'),
    false,
    false,
    array('NAME', 'PROPERTY_ATT_MAP')
);
while($ar_fields = $dbRestorants->Fetch()){ 
$mapPosition = explode(',', $ar_fields['PROPERTY_ATT_MAP_VALUE']);
?>
	Ресторан <?=$ar_fields['NAME']?>
	Широта: <?=$mapPosition[0]?>
	Долгота: <?=$mapPosition[1]?>              
<?}?>

Выводим все данные с помощью API Яндекс карт

Теперь, это все нужно скомпоновать и вывести на карту. API у Яндекс карт достатсочно обширное и подробно описанное. Я буду использовать только указание типа меток и метки буду использовать из стандартного набора.

Все комментарии внутри кода:

<?
CModule::IncludeModule('iblock');
$restorants = CIBlockElement::GetList(
    false,
    array('IBLOCK_ID' => '4'),
    false,
    false,
    array('NAME', 'PROPERTY_ATT_MAP')
);
?>

<!-- Подключаем Яндекс Карты -->
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&apikey=ВАШ_КЛЮЧ_ОТ_API"></script>

<script>
document.addEventListener("deviceready", onDeviceReady, false);
 // Все делаем по готовности устройства
function onDeviceReady() {
	var onSuccess = function (position) {
    	var latitude = position.coords.latitude;
    	var longitude = position.coords.longitude;
            
            // Инициализируем карты
            ymaps.ready(init);

            function init() {
                var myMap = new ymaps.Map("map", {
                	// Центруем карту по геопозиции пользователя
                        center: [latitude, longitude],
                        // Приближение карты до улиц
                        zoom: 12,
                        // Показываем кнопки масштабирования карты
                        controls: ['zoomControl']
            }),

            myMap.geoObjects
            		// В центр карты (позиция пользователя) добавляем метку 
            		// с фразой 'Вы здесь'
                    .add(new ymaps.Placemark([latitude, longitude], {
                        iconCaption: 'Вы здесь'
                    }, {
                    	// Вид метки "запятая"
                        preset: 'islands#greenDotIconWithCaption',
                        // зеленого цвета
                        iconColor: '#0D9200'
                    }))
                    <?
                    // Вывод ресторанов (получаем выше CIBlockElement::GetList)
                    while($ar_fields = $restorants->Fetch()){ 
                    $mapPosition = explode(',', $ar_fields['PROPERTY_ATT_MAP_VALUE']);
                    ?>
                    // Добавляем метку с ресторанам по его координатам
                    .add(new ymaps.Placemark([<?=$mapPosition[0]?>, <?=$mapPosition[1]?>], {
                    	// При клике на метку выводится название ресторана
                    	// тут можно использовать и ссылку, на детальное описание (CODE или DETAIL_PAGE_URL)
                        balloonContent: 'Ресторан: <?=$ar_fields['NAME']?>'
                    }, {
                    	// Вид метки "круг" синего цвета
                        preset: 'islands#blueCircleDotIconWithCaption',
                        // Размер иконки
                        iconCaptionMaxWidth: '20'
                    }))
                <?}?>
            }
        };
        navigator.geolocation.getCurrentPosition(onSuccess, onError);
    }
</script>
<!-- выводим карту, пока грузится можно сделать прелоадер как фон -->
<div id="map"></div>

В общем-то и все. Карта заполнит собой div#map - пока подгружается карта, можно задать ему фон со спиннером, аля "идет загрузка".

Самих меток и их настроек (размеры, цвета, заготовки) достаточно много. Посмотреть параметры и примеры можно в документации Яндекс Карт. Если хотим сделать собственную метку, со своей картинкой, используем такой пример:

myPlacemark = new ymaps.Placemark(myMap.getCenter(), {
    hintContent: 'Заголовок метки',
    balloonContent: 'Текст при клике'
}, {
    // Тип картинка
    iconLayout: 'default#image',
    // Путь к собственной картинке
    iconImageHref: 'images/ico.gif',
    // Размер в пикселях
    iconImageSize: [30, 42],
    // Смещение в пикселях - что бы лучше выставить
    iconImageOffset: [-5, -38]
}),
Михаил Базаров 19.05.2022
Что бы показать балун с максимумом информации, можно воспользоваться вот таким примером
Внутри балуна можно назначить свои классы для элементов и сверстать как того требует дизайн сайта.



Код
 <?
while($ar_fields = $restorants->GetNext()){ // Вывод ресторанов (получаем выше CIBlockElement::GetList)
$mapPosition = explode(',', $ar_fields['PROPERTY_ATT_MAP_VALUE']);
$img_path = CFile::GetPath($ar_fields["PREVIEW_PICTURE"]);
$wFrom = $ar_fields['PROPERTY_ATT_ORDER_FROM_VALUE'];
$wTo = $ar_fields['PROPERTY_ATT_ORDER_TO_VALUE'];
?>
    .add(new ymaps.Placemark([<?=$mapPosition[0]?>, <?=$mapPosition[1]?>], {
          balloonContentHeader: '<strong><?=$ar_fields['NAME']?></strong>' +
               '<span><b>Время работы:</b><br> <?echo $wFrom ? 'c ' . $wFrom . ':00 ' : '';?> <?echo $wTo ? 'до ' . $wTo . ':00': '';?></span>',
          balloonContentBody: '<img class="baloon_img" src="<?=$img_path?>" width="120">',
          balloonContentFooter: '<a href="/mobileapp/restorants/?ELEMENT_ID=<?=$ar_fields['ID']?>">Посмотреть меню</a>' +
              '<a href="/mobileapp/restorants/?ELEMENT_ID=<?=$ar_fields['ID']?>">Бронирование столика</a>',
          hintContent: 'пустой блок'
}, {
preset: 'islands#blueCircleDotIconWithCaption',
iconCaptionMaxWidth: '20'
}))
<?}?>

Записная книжка разработчика

Примерно с 2013-го года пишу заметки по разработке сайтов на Битрикс.
Вы можете задавать уточняющие вопросы в комментариях- отвечаю или дополняю заметки по возможности.

Установка веб-сервера LAMP на ubuntu 20.04 LTS, оптимизированный под ... Просмотров: 11378 В последнее время, плотно пересел c macOS на ubuntu, и решил настроить себе полноценное ра... Многосайтовость битрикс на разных доменах и поддоменах Просмотров: 61196 Часто спрашивают "как настроить многосайтовость Битрикс на разных доменах", решил записать... Отключить поиск по описаниям товаров в Битрикс Просмотров: 10581 Иногда, нужно отключить поиск по описаниям анонсов и детальному описанию товаров, при разр... Вывести множественное свойство типа файл с названием и весом файла в ... Просмотров: 20138 В этой заметке расскажу как красиво вывести множественное свойство типа файл в инфоблоке 1... Если пользователь авторизован то... API Битрикс Просмотров: 22204 Достаточно часто, при создании сайта на битрикс нужно вывести в шаблон или компонент, неку... Memcached на сайте под управлением битрикс, при использовании Веб Окр... Просмотров: 6908 Если вам важна скорость отдачи сайта, а у вашего сервера медленный диск для использования ... Ускорение работы сайта на 1С-Битрикс Просмотров: 15838 Данная статья написана специально под видеоролик (приложен в конце статьи), опубликованный... Сгенерировать скидочные купоны, при заказе и отправить на почту Просмотров: 744 Задача: после того как пользователь сделал заказ, нужно сгенерировать одноразовые купоны д... Добавление своих полей в почтовые шаблоны Битрикс Просмотров: 43562 Иногда нужно внести свои поля в почтовые шаблоны битрикс. Например: добавить имя и номе... Добавить все свойства инфоблока в умный фильтр одним разом Просмотров: 9888 Если у вас достаточно много свойств, в инфоблоке с товарами, например: больше 1000-чи, пос... Вывести свойство привязка к Яндекс Картам в Битрикс Просмотров: 18143 Часто бывает нужно вывести свойство привязка к Яндекс карте в детальном описании элемента... Фотогалерея на базе компонента новостей, с fancybox. Просмотров: 1512 Это заметка обновление к очень старой, уже имеющейся на сайте. Сделаем что-то типа фотогал... Автоматически помечаем новинки лейблом в каталоге битрикс Просмотров: 5357 Если вы хотите помечать новинки каталога, вашего магазина на Битрикс, лейблом "Новинка". И... Получить множественное пользовательское поле раздела. Значения множес... Просмотров: 341 Задача: У разделов инфоблока есть множественное поле типа список. Зная ID раздела, нужно п... Вывести все разделы в которых находится элемент инфоблока Просмотров: 12970 Если нужно вывести все разделы, со всей доступной информацией о них, внутри элемента инфоб... Сниппеты типографики bootstrap, для Битрикс Просмотров: 7575 Если вы подключили bootstrap к своему сайту, или сверстали весь шаблон, подключив bootstra... Определить местоположение пользователя и показать магазины поблизости... Просмотров: 1142 Задача: в мобильном приложении, которое открывает сайт на 1С-Битрикс внутри себя, нужно оп... Вывести дату окончания скидки в карточке товара Просмотров: 3632 Если нужно вывести информацию о скидке в карточке товара, можно воспользоваться методом Заполнить свойство инфоблока ценой из торгового каталога Просмотров: 4568 Если вам по какой-то причине нужно скопировать цену товара в свойство этого же инфоблока. ... Добавить свойство в административную форму заказа Просмотров: 2770 Задача, кастомизировать административную форму заказа: добавить свойство заказа в шапку фо...