К сожалению, прошлая публикация была потёрта в результате какой то ошибке на сервере базы данных, поэтому приходится создавать новую, улучшенную версию. В этой публикации я постараюсь рассмотреть способ взаимодействия с картами не как со статичным объектом, когда предварительно формируется текст 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()");
Аналогичным образом осуществляется и перемещение маркеров. Только вместо события карты вызывается событие маркера, которое привязывается к нему при создании.
Интересная разработка. Правда она идет в виде конфигурации, т.е. она оторвана от клиентской базы? Все данные надо заносить вручную?
Кстати, я бы сказал даже отличная разработка. Нужно просто разобраться с некоторыми кнопками. Фактически создание и корректировка объектов идет на карте.
(1) maxlenium, Это пример, шаблон. Я его выдернул из одного своего проекта, по сути база тут нужна, как хранилище точек с дополнительными характеристиками. В полной версии ещё были фильтры по областям, рисованным на карте, по дополнительным признакам, но это было уже достаточно тривиально, поэтому было обрезано. Обработка возможна и без привязки к БД, но в её рамках хотелось показать взаимодействие, как GUIDы объектов передаются туда-обратно на хтмл страницу и параллельно модификации карты меняются и объекты БД с ней связанные.
Давно сделано:http://forum.infostart.ru/forum24/topic42266/
(4) CagoBHuK, Прям дежавю какое то. «Давно сделано» просит денег. Эта разработка — бесплатная.
(4) CagoBHuK, Хотя, Вас, как автораhttp://forum.infostart.ru/forum24/topic42266/ вполне можно понять. Своё детище нужно защищать и продвигать. 🙂
Поставил +. Очень хорошая бесплатная разработка.
(7) akomar, Спасибо
1. Есть ли кэширование?
2. Есть ли возможность работать офф-лайн (версия Яндекс.Карты под Android может быть скачена для оффлайн просмотра, правда, при этом не работает поиск)?
3. Почему Google Maps, а не Яндекс.Карты?
(9) Sergey Kamnev,
1. Сейчас работает сугубо интерактивно, вопрос кэширования не поднимался.
2. Соответственно, вопрос не поднимался.
3. АПИ у гугла приятнее документирован. Основной упор ставился именно на взаимодействие с сеансом 1С, у яндекса описание объектов событий, передаваемых в обработчик события я не нашёл, может плохо искал. За сим был избран гугл.
logos, ясно, спасибо за ответ.
Программу взял на заметку. Спасибо за труд!
Отличная разработка.
Долго мучался с картами и проблемой отлавливания событий в 1С — сразу снялись все вопросы.
Спасибо автору 🙂
Ставлю + безусловно. Однако у меня не работает — карты вообще не отображаются.
может Гугл что-то поменял в кодах?
при попытке поставить флаг «Ввод новых объектов» в карте объектов развития выводится следующая ошибка:
{Обработка.КартаСостоянийТК.Форма.Форма.Форма(56)}: Метод объекта не обнаружен (Eval)
Результат = Элемент.Документ.parentWindow.Eval(Код);
Нашел ошибку в коде Java — Обработки.КартаСостоянияТК.Макеты.МакетГуглВерсия3Текст надо заменить в тексте map_canvas на map-canvas, после исправления все работает.
то же исправление требуется для ОбластиНаКарте.Макет
Действительно, поменял гугл. Раньше у них в апи было предопределено имя map_canvas, потом заменили подчеркивание на тире. Альтернативный вариант — можно вручную для map_canvas задавать его размеры, что создает лишние проблемы с ресайзом итп. Сам недавно случайно заметил этот нюанс, обновить публикацию забыл. Спасибо за комментарий.
Возможно не совсем в тему, но все же, столкнулся с проблемой.
Стоит цель не программно дописывать код скрипта по добавлению координат полигона, а через функцию скрипта передавать координаты. Как я понимаю это нужно делать в обработчике события ДокументСформирован, вот только почему то при попытке обратиться к объекту у которого есть метод по добавлению координат, возвращается ошибка мол нет такого объекта, если я выполняю перед этим инициализацию программно через 1с, то переменную видит.
И еще почему то событие ДокументСформирован срабатывает дважды.
Есть задача вывести на карте района точки по списку адресов в 1С. Что посоветуете использовать для решения?
(19) JIeHIH, Криво, но можно использовать глобальную переменную, которая хранит ссылку на полигон, вызывать методы, добавляющие точки в полигон через eval.
(20) kovaleks78, По списку адресов сложнее, нужно делать запросы к тому же гуглу или яндексу, чтоб получить координаты по адресу, а так не принципиально чем. У меня, например, выводится список точек на карте, правда не по адресам, а по координатам.
(21) Возможно я немного некорректно изложил проблему, в скрипте я завел глобальную переменную, которая является полигоном, код взял у гугла в примерах, там создается объект полигона у которого есть методы добавления координат, присвоение этого полигона переменной происходит в момент обновления страницы, так вот задача узнать когда это произойдет, когда отработает скрипт.
«Ваш браузер не поддерживается Google Maps JavaScript API. Выберите другой.Подробнее…Закрыть»
Что посоветуете делать?
(23) 1С использует стандартный com компонент webbrowser который предоставляет windows. По умолчанию для всех приложений эта компонента работает в режиме совместимости IE7. Для смены режима совместимости требуется добавить в реестр ключ с именем приложения и кодом уровня совместимости.
Подробнее здесь:https://weblog.west-wind.com/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version
Карта вообще не отображается в 1С, хоть и учел изменения из (16). Автор писал, что учтет в публикации, но не сделал этого. Выгрузил итоговый скрипт в текстовый файл html, добавил свой google key в заголовок. После этого карта запускается из html в браузере, но никаких меток не выводит. В 1С всё равно не отображается. Помогите, пож., я пока совсем зелёный в этом.
(25) Это писалось в 2012 году, когда в платформу был встроен движок IE 9 (кажется), тогда это работало. Потом многое было переписано в угоду большей безопасности, современным браузерам. Некоторые наработки по использованию ПолеHTMLДокумента я публиковал в другой статье, про работу с большими данными. Оттуда можно взять «скелет» фрейма и в него уже положить страницу с гуглокартами. Подозреваю, что ещё и апи у гуглокарт могло с тех пор поменяться.
статью .
Вот ссылка на
Постараюсь найти время и актуализировать эту статью под современные реалии.