gifts2017

Пример интерактивной работы с картами Google.

Опубликовал Anton Loginchev (logos) в раздел Обмен - Интеграция с WEB

В этой публикации приведен пример, как можно взаимодействовать с Google Maps API, интерактивно создавать и редактировать объекты карты, обрабатывать события объектов карты.

К сожалению, прошлая публикация была потёрта в результате какой то ошибке на сервере базы данных, поэтому приходится создавать новую, улучшенную версию. В этой публикации я постараюсь рассмотреть способ взаимодействия с картами не как со статичным объектом, когда предварительно формируется текст html страницы, который показывается пользователю, а как с объектом, обладающим "рычагами" для управления.

В тестовом примере показаны: рисование полигонов в статике из данных БД, рисование маркеров в статике, создание маркеров интерактивно без перерисовки карты, перемещение маркеров.

Массив статических элементов передается при формировании страницы, как xml блок, ввиду чего, к сожалению, страница некорректно работает в firefox. Проблема легко лечится вынесением массива из html блока и формированием объектов динамически.

Для динамических изменений веб страницы необходимо вызывать её скриптовые функции. В 1С это выглядит довольно "неудобно":

Функция Скрипт(Элемент,Код)
    Результат = Элемент.Документ.parentWindow.Eval(Код);
    Возврат Результат;
КонецФункции

Для собственного удобства я обернул вызов javascript кода в функцию. Здесь "Элемент" - поле HTML текста, а "Код" - код на языке javascript. Для вызова доступны глобальные переменные блока и функции оттуда же. Поэтому, для создания маркера мы создаем функцию в макете html страницы, которая по списку параметров создает маркер:

function placemarker(iconId,lat,lng,title,GUID){
         var pos = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
         var marker = new google.maps.Marker({ position: pos, map: map, title: title, icon: icons[iconId] });
        }

В функцию передаются текстовые значения координат, названия точки и иконки (если она есть)

Кроме того, что маркер размещается на поле HTML документа, необходимо отразить его создание в базе данных. Для этого создаются подписки на события нажатия на карту.

google.maps.event.addListener(map, 'click', mapClick);

function mapClick(event) {
         sender = "map";
         eventname = "click";
         latlng = event.latLng;
        }

Обработчик устанавливает значения глобальных переменных, к сожалению более красивого способа я пока не нашёл. Эти глобальные переменные доступны в обработчике нажатия на поле HTML документа в 1С. С помощью переменной sender определяется объект, с которым произошло событие, с помощью eventname - само событие, а в переменной latlng находятся координаты, если они применимы.

В обработке нажатия на поле HTML текста осуществляется обработка всех подобных событий.

&НаКлиенте
Процедура ПолеHTMLТекстаПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
    ИсточникСобытия  = Скрипт(Элемент,"sender");
    Событие    = Скрипт(Элемент,"eventname");
    Если ИсточникСобытия = "map" И Событие = "dragend" Тогда
        Возврат;
    КонецЕсли;
    Широта = Скрипт(Элемент,"latlng.lat()");
    Долгота = Скрипт(Элемент,"latlng.lng()");
    Если ИсточникСобытия = "marker" Тогда
        GUID  = Скрипт(Элемент,"myGUID");
        ТК = ПолеHTMLТекстаПриНажатииНаСервере(GUID);
        Если Событие = "click" Тогда
            Если НЕ ТК = Неопределено ИЛИ ВводНовыхОбъектов Тогда
                ПараметрыФормы  = Новый Структура("Ключ",ТК);
                Форма = ПолучитьФорму("Справочник.ОбъектыРазвития.ФормаОбъекта",ПараметрыФормы);
                ДанныеФормы = Форма.Объект;
                ЗаполнитьНаСервере(ДанныеФормы,Широта,Долгота);
                КопироватьДанныеФормы(ДанныеФормы,Форма.Объект);
                Форма.ОткрытьМодально();
            КонецЕсли;
        ИначеЕсли Событие = "dragend" Тогда
            ПараметрыОбновления = Новый Структура("Широта,Долгота,GUID",Широта,Долгота,GUID);
            Структура = Новый ФиксированнаяСтруктура(ПараметрыОбновления);
            ОбновитьКоординатыТК(Структура);
        КонецЕсли;
    ИначеЕсли ИсточникСобытия = "map" И Событие = "click" И ВводНовыхОбъектов Тогда
        ВводНовогоТК = Истина;
        ПараметрыФормы  = Новый Структура("Ключ",ТК);
        Форма = ПолучитьФорму("Справочник.ОбъектыРазвития.ФормаОбъекта",ПараметрыФормы);
        ДанныеФормы = Форма.Объект;
        ЗаполнитьНаСервере(ДанныеФормы,Широта,Долгота);
        КопироватьДанныеФормы(ДанныеФормы,Форма.Объект);
        Форма.ОткрытьМодально();
    КонецЕсли;
КонецПроцедуры

Следующим образом получаются значения глобальных переменных, играющих роль параметров события. Дальнейшая обработка тривиальна, рассматривать её не будем.

ИсточникСобытия = Скрипт(Элемент,"sender");

Широта = Скрипт(Элемент,"latlng.lat()");

Долгота = Скрипт(Элемент,"latlng.lng()");

Аналогичным образом осуществляется и перемещение маркеров. Только вместо события карты вызывается событие маркера, которое привязывается к нему при создании.

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
карты инфостарт2.dt
.dt 86,24Kb
16.10.12
158
.dt 86,24Kb 158 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Максим Волков (maxlenium) 17.10.12 08:31
Интересная разработка. Правда она идет в виде конфигурации, т.е. она оторвана от клиентской базы? Все данные надо заносить вручную?
2. Максим Волков (maxlenium) 17.10.12 08:39
Кстати, я бы сказал даже отличная разработка. Нужно просто разобраться с некоторыми кнопками. Фактически создание и корректировка объектов идет на карте.
3. Anton Loginchev (logos) 17.10.12 08:49
(1) maxlenium, Это пример, шаблон. Я его выдернул из одного своего проекта, по сути база тут нужна, как хранилище точек с дополнительными характеристиками. В полной версии ещё были фильтры по областям, рисованным на карте, по дополнительным признакам, но это было уже достаточно тривиально, поэтому было обрезано. Обработка возможна и без привязки к БД, но в её рамках хотелось показать взаимодействие, как GUIDы объектов передаются туда-обратно на хтмл страницу и параллельно модификации карты меняются и объекты БД с ней связанные.
4. Данила Елистратов (CagoBHuK) 17.10.12 10:58
5. Anton Loginchev (logos) 17.10.12 11:08
(4) CagoBHuK, Прям дежавю какое то. "Давно сделано" просит денег. Эта разработка - бесплатная.
6. Anton Loginchev (logos) 17.10.12 11:10
(4) CagoBHuK, Хотя, Вас, как автора http://forum.infostart.ru/forum24/topic42266/ вполне можно понять. Своё детище нужно защищать и продвигать. :-)
7. Андрей Комар (akomar) 20.10.12 20:39
Поставил +. Очень хорошая бесплатная разработка.
8. Anton Loginchev (logos) 20.10.12 22:59
9. Сергей Камнев (Sergey Kamnev) 22.10.12 10:04
1. Есть ли кэширование?
2. Есть ли возможность работать офф-лайн (версия Яндекс.Карты под Android может быть скачена для оффлайн просмотра, правда, при этом не работает поиск)?
3. Почему Google Maps, а не Яндекс.Карты?
10. Anton Loginchev (logos) 22.10.12 10:22
(9) Sergey Kamnev,
1. Сейчас работает сугубо интерактивно, вопрос кэширования не поднимался.
2. Соответственно, вопрос не поднимался.
3. АПИ у гугла приятнее документирован. Основной упор ставился именно на взаимодействие с сеансом 1С, у яндекса описание объектов событий, передаваемых в обработчик события я не нашёл, может плохо искал. За сим был избран гугл.
11. Сергей Камнев (Sergey Kamnev) 22.10.12 13:24
logos, ясно, спасибо за ответ.

Программу взял на заметку. Спасибо за труд!
12. Серж Иванов (adminfo2002) 21.02.13 16:09
Отличная разработка.
Долго мучался с картами и проблемой отлавливания событий в 1С - сразу снялись все вопросы.
Спасибо автору :)
SunShinne; +1 Ответить
13. Сергей Алферов (SunShinne) 03.01.14 19:15
Ставлю + безусловно. Однако у меня не работает - карты вообще не отображаются.
14. Сергей Алферов (SunShinne) 03.01.14 19:37
может Гугл что-то поменял в кодах?
15. Сергей Алферов (SunShinne) 03.01.14 19:46
при попытке поставить флаг "Ввод новых объектов" в карте объектов развития выводится следующая ошибка:
{Обработка.КартаСостоянийТК.Форма.Форма.Форма(56)}: Метод объекта не обнаружен (Eval)
Результат = Элемент.Документ.parentWindow.Eval(Код);
16. Сергей Алферов (SunShinne) 09.01.14 20:49
Нашел ошибку в коде Java - Обработки.КартаСостоянияТК.Макеты.МакетГуглВерсия3Текст надо заменить в тексте map_canvas на map-canvas, после исправления все работает.
17. Сергей Алферов (SunShinne) 09.01.14 20:54
то же исправление требуется для ОбластиНаКарте.Макет
18. Anton Loginchev (logos) 13.01.14 10:05
Действительно, поменял гугл. Раньше у них в апи было предопределено имя map_canvas, потом заменили подчеркивание на тире. Альтернативный вариант - можно вручную для map_canvas задавать его размеры, что создает лишние проблемы с ресайзом итп. Сам недавно случайно заметил этот нюанс, обновить публикацию забыл. Спасибо за комментарий.
19. Павел Титов (JIeHIH) 17.01.14 19:27
Возможно не совсем в тему, но все же, столкнулся с проблемой.
Стоит цель не программно дописывать код скрипта по добавлению координат полигона, а через функцию скрипта передавать координаты. Как я понимаю это нужно делать в обработчике события ДокументСформирован, вот только почему то при попытке обратиться к объекту у которого есть метод по добавлению координат, возвращается ошибка мол нет такого объекта, если я выполняю перед этим инициализацию программно через 1с, то переменную видит.
И еще почему то событие ДокументСформирован срабатывает дважды.
20. Александр Ковалев (kovaleks78) 17.01.14 22:14
Есть задача вывести на карте района точки по списку адресов в 1С. Что посоветуете использовать для решения?
21. Anton Loginchev (logos) 18.01.14 16:15
(19) JIeHIH, Криво, но можно использовать глобальную переменную, которая хранит ссылку на полигон, вызывать методы, добавляющие точки в полигон через eval.
(20) kovaleks78, По списку адресов сложнее, нужно делать запросы к тому же гуглу или яндексу, чтоб получить координаты по адресу, а так не принципиально чем. У меня, например, выводится список точек на карте, правда не по адресам, а по координатам.
22. Павел Титов (JIeHIH) 20.01.14 10:39
(21) logos, Возможно я немного некорректно изложил проблему, в скрипте я завел глобальную переменную, которая является полигоном, код взял у гугла в примерах, там создается объект полигона у которого есть методы добавления координат, присвоение этого полигона переменной происходит в момент обновления страницы, так вот задача узнать когда это произойдет, когда отработает скрипт.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа