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

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

Задача: в мобильном приложении, которое открывает сайт на 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]
}),

Стоимость разработки на 1С-Битрикс:

Индивидуальная разработка магазина

от 500 000 руб. от 6-ти недель

Разработка магазина на 1С-Битрикс с нуля. Дизайн, сборка и оптимизация производительности под конкретный проект и требования. Реализация любого функционала без ограничений готовых решений.

Запуск сайта на готовом решении

от 150 000 руб. от 7-ми дней

Вариант для тех, кто не хочет тратить много средств на индивидуальный проект, и не имеет серьезных требований к сайту. Магазин, быстро запускается на базе одного из 200-та готовых решений.

Мобильное приложение

от 500 000 руб. от 1-го месяца

Разработка кроссплатформенного мобильного приложения, которое не уступает нативным решениям как в производительности, так и пользовательском опыте. Публикуется в AppStore, GooglePlay и RuStore

Сайт компании

от 350 000 руб. от 1-го месяца

Корпоративный сайт с информационными разделами, каталогом товаров или услуг. Включает формы обратной связи карточек каталога, любое количество статичных и динамичных разделов.

Инфресурс

от 400 000 руб. от 5-ти недель

Информационный ресурс любой сложности. Сайт для СМИ, городской портал или многопользовательская доска объявлений. Внутренние форумы, блоги- по необходимости.

Лечение сайтов от вирусов

от 40 000 руб. от 2-х дней

Выполню полную проверку сайта и окружения. В случае обнаружения вирусов проведу полный комплекс лечения проекта и закрытия лазеек.