Форум русской поддержки Joomla!® CMS
25.07.2017, 14:45:57 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
   
   Начало   Поиск Joomla 3.0 FAQ Joomla 2.5 FAQ Joomla 1.5 FAQ Правила форума Новости Joomla Реклама Войти Регистрация Помощь  
Страниц: [1]   Вниз
  Добавить закладку  |  Печать  
Автор

расширенный функционал геолокации [Решено]

 (Прочитано 89 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Liss
Давно я тут
****

Репутация: +9/-0
Offline Offline

Сообщений: 219


« : 14.06.2017, 16:54:53 »

В RSForm есть поле типа "Карты Гугл", предусмотрен функционал геолокации. Суть его такова: на карте маркер, вы таскаете маркет по карте и в текстовом поле появляется адрес (или координаты) местоположения этого маркера. А что если мы хотим определить местоположение абонента автоматически, чтоб маркер сам туда перенесся? Вот решение этой задачи:

файл /administrator/components/com_rsform/helpers/fields/textbox.php
где-то внизу файла есть функция function generateMap(), обеспечивающая базовый функционал, и эту функцию мы скорректируем. Вот так она будет выглядеть:
Код:
public function generateMap() {
$id = $this->getProperty('componentId');
$zoom = (int) $this->getProperty('MAPZOOM', 2);
$center = $this->getProperty('MAPCENTER', '39.5500507,-105.7820674');
$geo = $this->getProperty('GEOLOCATION', 'NO');
$address = $this->getProperty('MAPRESULT', 'ADDRESS');
$name = $this->getProperty('NAME');
$mapType = $this->getProperty('MAPTYPE', 'ROADMAP');

$script = '  
 var rsformmap'.$id.';
 var geocoder;
 var rsformmarker'.$id.';
 
 
 function rsfp_initialize_map'.$id.'() {
var message = document.getElementById("message");
   geocoder = new Google.maps.Geocoder();
   var rsformmapDiv'.$id.' = document.getElementById(\'rsform-map'.$id.'\');
   rsformmap'.$id.' = new Google.maps.Map(rsformmapDiv'.$id.', {
     center: new Google.maps.LatLng('.$center.'),
     zoom: '.$zoom.',
     mapTypeId: Google.maps.MapTypeId.'.$mapType.',
     streetViewControl: false
   });
 
   rsformmarker'.$id.' = new Google.maps.Marker({
     map: rsformmap'.$id.',
     position: new Google.maps.LatLng('.$center.'),
     draggable: true
   });

document.getElementById("geoButton").addEventListener("click", function() { //включаем GPS /Wifi / мобильную геолокацию по клику на кнопку
     if (navigator.geolocation) {
   navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationFailure, {enableHighAccuracy: true, timeout: 10000, maximumAge: 60000});
         }
         else {
       alert("Ваш браузер не поддерживает геолокацию");  
         }
       });

function geolocationSuccess(position) {
         //карта уже определена ранее, просто задаем новые корродинаты
 var location = new Google.maps.LatLng(position.coords.latitude,position.coords.longitude);
 rsformmap'.$id.'.setCenter(location); // центрируем карту по новым координатам
 rsformmarker'.$id.'.setPosition (location); // и перемещаем сюда маркер  
 
 // Передаем полученный через GPS адрес в текстовое поле
 var latlng = {lat: position.coords.latitude, lng: position.coords.longitude};
 geocoder.geocode({"location": latlng}, function(results, status) {
   if (status == Google.maps.GeocoderStatus.OK) {
     if (results[0]) {';
           if ($address == 'ADDRESS')
         $script .= 'document.getElementById("'.$name.'").value = results[0].formatted_address;';
           else
         $script .= 'document.getElementById("'.$name.'").value = rsformmarker'.$id.'.getPosition().toUrlValue();';
           $script .= '
         }
   }

     });
 message.innerHTML = "Местоположение определено";
}
function geolocationFailure(position) {
 message.innerHTML = "Ошибка определения местоположения";
            }
 
   Google.maps.event.addListener(rsformmarker'.$id.', "drag", function() {
                      message.innerHTML = "";
     geocoder.geocode({"latLng": rsformmarker'.$id.'.getPosition()}, function(results, status) {
       if (status == Google.maps.GeocoderStatus.OK) {
         if (results[0]) {';
           if ($address == 'ADDRESS')
         $script .= 'document.getElementById("'.$name.'").value = results[0].formatted_address;';
           else
         $script .= 'document.getElementById("'.$name.'").value = rsformmarker'.$id.'.getPosition().toUrlValue();';
           $script .= '
         }
       }

     });
   });
';

 $currentValue = $this->getValue();
 if (!empty($currentValue)) {
   if ($address == 'ADDRESS') {
 $script .= '
   geocoder.geocode({\'address\': document.getElementById(\''.$name.'\').value}, function(results, status) {
     if (status == Google.maps.GeocoderStatus.OK) {
       rsformmap'.$id.'.setCenter(results[0].geometry.location);
   rsformmarker'.$id.'.setPosition(results[0].geometry.location);
     }
   });
 ';
   }
   else {
 $script .= '
   if (document.getElementById(\''.$name.'\') && document.getElementById(\''.$name.'\').value && document.getElementById(\''.$name.'\').value.length > 0 && document.getElementById(\''.$name.'\').value.indexOf(\',\') > -1) {
     rsformCoordinates'.$id.' = document.getElementById(\''.$name.'\').value.split(\',\');
     formPosition'.$id.' = new Google.maps.LatLng(parseFloat(rsformCoordinates'.$id.'[0]),parseFloat(rsformCoordinates'.$id.'[1]));
     rsformmap'.$id.'.setCenter(formPosition'.$id.');
     rsformmarker'.$id.'.setPosition(formPosition'.$id.');
   }
 ';
   }
 }

 $script .= '
 }
 
 Google.maps.event.addDomListener(window, \'load\', rsfp_initialize_map'.$id.');
 ';

 if ($geo) {
$isAdress = $address == 'ADDRESS';
$script .= '
 window.addEventListener("load", function(){
   rsfp_addEvent(document.getElementById(\''.$name.'\'),\'keyup\', function() {
     rsfp_geolocation(this.value,'.$id.',\''.$name.'\',rsformmap'.$id.',rsformmarker'.$id.',geocoder, '.(int) $isAdress.');
   });
 });
';
 }

// Add the Google Maps API JS
if (!RSFormProFieldTextbox::$mapScript) {
$this->addCustomTag('<script src="https://maps.google.com/maps/api/js?key='.urlencode(RSFormProHelper::getConfig('google.api_key')).'" type="text/javascript"></script>');
// Do not load the script for every map field
RSFormProFieldTextbox::$mapScript = true;
}
// Add the custom script after the maps.js is loaded in the dom
$this->addCustomTag('<script type="text/javascript">'.$script.'</script>');
}

Местоположение определяется по клику на кнопке. В админке создаем кнопку (простую, не submit), даем ей имя geoButton. А также в любом месте нам нужен блочный HTML тэг (в смысле имеющий открывающий и закрывающий тэг <p></p> или <div></div> и т.д), которому приписываем id="message" – тут будут выводится служебные сообщения (местоположение определено, ошибка и т.д.).

Ну а работает это так: жмем на кнопку, если браузер поддерживает геолокацию (любой современный), пользователь разрешил браузеру определить местоположение (а на мобильнике к тому же разрешил геолокацию в системных настройках), то маркер перемещается в новую точку и карта центрируется по маркеру (если все прошло без ошибок), а в текстовом input появляется адрес маркера (или координаты - это настраивается в админке). Далее можно стандартно сместить маркер на карте поточнее. Проверено на стационарном компе (геолокация по IP) и на мобильнике (GPS + Wifi + локация по мобильным вышкам)
« Последнее редактирование: 15.06.2017, 07:43:20 от Taatshi » Записан
Septdir
Практически профи
*******

Репутация: +97/-3
Online Online

Пол: Мужской
Сообщений: 1979


Skype: septdir


« Ответ #1 : 14.06.2017, 19:31:15 »

Хорошо бы исполнить в виде плагина, а то RSForm частенько обновляется.
Записан
Liss
Давно я тут
****

Репутация: +9/-0
Offline Offline

Сообщений: 219


« Ответ #2 : 14.06.2017, 19:46:25 »

вот это
Код:
else {
  message.innerHTML = "Ошибка";
}
в двух местах лучше удалить ("ошибка" выдается ошибочно)

а вот тут
Код:
google.maps.event.addListener(rsformmarker'.$id.', "drag", function() {
  geocoder.geocode({"latLng": rsformmarker'.$id.'.getPosition()}, function(results, status) {
.....
лучше обнулять сообщеньку (когда начинаем вручную корректировать положение маркера, сообщение "местоположении определено" уже как-то не в тему)
Код:
google.maps.event.addListener(rsformmarker'.$id.', "drag", function() {
  message.innerHTML = "";
  geocoder.geocode({"latLng": rsformmarker'.$id.'.getPosition()}, function(results, status) {
...

(лучше сейчас поправлю первый пост)
Записан
Liss
Давно я тут
****

Репутация: +9/-0
Offline Offline

Сообщений: 219


« Ответ #3 : 14.06.2017, 20:01:30 »

Хорошо бы исполнить в виде плагина, а то RSForm частенько обновляется.
мне слабо...
Записан
Страниц: [1]   Вверх
  Добавить закладку  |  Печать  
 
Перейти в:  

Powered by SMF 1.1.21 | SMF © 2006, Simple Machines

Joomlaforum.ru is not affiliated with or endorsed by the Joomla! Project or Open Source Matters.
The Joomla! name and logo is used under a limited license granted by Open Source Matters
the trademark holder in the United States and other countries.

LiveInternet