Map API / [Из песочницы] Google.Maps + 1c: Предприятие 8.2

в 12:17, , рубрики: Google, maps, карта, предприятие, метки: , , ,

В этом посте я хочу показать пример того, как может быть использован сервис Google.Maps в конфигурациях 1с: Предприятие 8.2. Как вы все знаете, 1с прижилась (мягко сказать) практически во всех коммерческих структурах — вот и нас не обошла. Сфера применения картографических систем в 1с достаточно широка, например — возможность накладывания отчетности на карту, расчет стоимости маршрутов, и, конечно, поиск объектов на карте по географическим координатам, что вполне может использоваться операторами колл-центров при консультации клиентов.

О чем это я?

В основе повествования лежит <a rel="nofollow" href="http://code.google.com/intl/ru/apis/maps/documentation/javascript/basics.html">Google Maps JavaScript API V3(все примеры работы с сервисом получены именно отсюда) и конечно платформа 1с: Предприятие 8.2. Компоненты 1с, используемые в примере, так же присутствуют в версии 8.1, так что с большой долей вероятности все нижеописанное будет работать и там.

Подробнее о Google.Maps

3-я версия платформы имеет две возможности использования:

  • Использование Javascript-библиотеки на клиентской стороне, так называемое «Client-Side Geocoding». Этот способ Google позиционирует как основной.
  • Серверное использование, «Server-Side Geocoding». Этот способ предпочтителен для систем, где не происходит интерактивной работы с пользователем.

На оба способа Google накладывает ограничения — 2500 запросов на определение координат в сутки для одного ip-адреса. Впрочем, все это вы можете прочитать в оригинале, ссылка выше.
Пример будет построен на первом способе.

И немного про 1с

Мы будем использовать режим обычных форм, работающий в толстом клиенте 1с. К новомодному управляемому режиму работы с формами, появившемуся в версии 8.2 этот способ не подойдет без доработок.

Что конкретно мы сделаем:

  1. Создадим html-файл, содержащий javascript-функции для работы с картой
  2. Создадим внешнюю обработку для 1с, отображающую карту и имеющую контролы, позволяющие отображать метки, найденные по координатам или адресу
Итак, к делу:

1. Создаем файл html

Для работы с сервисом нам необходим файл, который будет содержать необходимые нам javascript-функции и будет открываться из 1с. Я не буду приводить его пример, поскольку за меня это сделали здесь: Здравствуй, мир!, а перейду к описанию.
Добавляем функции, которые при открытии html-документа получают координаты пункта «Москва» и инициализируют карту с автоматическим позиционированием на нем:
var map = null;
function initialize()
{
getLocation('Москва', function (results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
GoogleLocation = results[0].geometry.location;
initializeMap(GoogleLocation);
addMarkerForLocation(GoogleLocation.lat(), GoogleLocation.lng());//пример отображения метки по координатам
addMarkerForAddress('Москва Тушино');//пример отображения метки по адресу
} else alert('Координаты не определены');
});
}

//GoogleLocation - координаты, которые будут приняты за центр карты
function initializeMap(GoogleLocation)
{
if (GoogleLocation != null)
{
var latlng = new google.maps.LatLng(GoogleLocation.lat(), GoogleLocation.lng());
var myOptions = {
zoom: 10,//масштаб
center: latlng,//центр
mapTypeId: google.maps.MapTypeId.ROADMAP//тип карты
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
} else alert('Координаты не определены');
}


Функция, возвращающая географические координаты по адресу:

//address - строка адреса, к примеру 'Москва, Тушино'
//checkResult - функция для обработки результата запроса
function getLocation(address, checkResult)
{
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ address: address }, checkResult);
}


Функции, добавляющие метку на карту:
//Используется для добавления метки по заранее имеющимся координатам Широта и Долгота
function addMarkerForLocation(lat, lng)
{
if ((lat != null)&&(lng!=null))
{
var marker = new google.maps.Marker(
{
position: new google.maps.LatLng(lat, lng),
map: map,
title: 'Название метки, произвольное',
icon: 'http://google-maps-icons.googlecode.com/files/factory.png'
});
var infoWindow = new google.maps.InfoWindow;
bindInfoWindow(marker, infoWindow, 'Здесь может быть текст html');
} else alert('Координаты не определены');
}

//Используется для добавления метки по адресу, приводящая к запросу на сервер для получения географических координат
function addMarkerForAddress(address)
{
if (map != null)
{
getLocation(address, function (results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
var marker = new google.maps.Marker(
{
position: new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng()),
map: map,
title: address,//описание метки, может быть любой текст
icon: 'http://google-maps-icons.googlecode.com/files/factory.png'//иконка метки
});
} else alert('Координаты не определены');
});
} else alert('Карта не инициализирована');
}


Ну и конечно функция, умеющая отобразить описание метки в информационном окошке:

//marker - объект, представляющий собой метку
//infowindow - объект google.maps.InfoWindow
//html - произвольный текст html, представляющий собой описание метки
function bindInfoWindow(marker, infoWindow, html)
{
if (map != null)
{
google.maps.event.addListener(marker, 'click', function ()
{
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
} else alert('Карта не инициализирована');
}

2. Создаем обработку в 1с

На форме обработки 1с добавляем контрол типа «ПолеHTMLДокумента»(назовем его «ПолеHTMLДок») — он будет отображать сформированный нами ранее файл html (назовем его google.html). На практике возможно использование так же ActiveX-объекта «Microsoft Web Browser», но, это по вкусу, особенно учитывая то, что использоваться будет в любом случае IE.
После того, как добавили поле HTML документа, нам необходимо сделать так, чтобы при открытии обработки автоматически открывалась карта. Для этого добавляем обработчик формы «ПриОткрытии», и добавляем в него: ЭлементыФормы.ПолеHTMLДок.Перейти(«c:googlegoogle.html»);
Этого достаточно, чтобы при запуске нашей внешней обработки в 1с автоматически открывался наш html-файл, в котором при загрузке страницы стартует функция Initialize(), заполняющая и центрирующая карту.
Если все ок, давайте добавим возможность добавления меток по событию в 1с:
Для этого добавим на форму текстовое поле ввода «Адрес», «Широта», «Долгота» и две кнопки — «Добавить метку по адресу» и «Добавить метку по координатам».
И конечно соответствующие кнопкам обработчики:
ЭлементыФормы.ПолеHTMLДок.Документ.parentWindow.eval("addMarkerForAddress('" + Адрес + "')");
ЭлементыФормы.ПолеHTMLДок.Документ.parentWindow.eval("addMarkerForLocation(" + Формат(Широта, "ЧГ=") + "," + Формат(Долгота, "ЧГ=") + ")");

Как вы уже поняли, оба обработчика при нажатии кнопок вызывают те функции Javascript, которые были заданы нами в html-файле и создают на карте отметки. Собственно, для первой версии этого уже более чем достаточно.

Несомненно, на практике этот способ можно улучшить — к примеру тем, что в 1с возможно вовсе обойтись без файла html, используя метод объекта ПолеHTMLДокумента.УстановитьТекст() — при этом код самой страницы возможно хранить в базе 1с в виде текста и не заморачиваться с поддержкой внешнего файла html.
Так же стоит подумать над тем, что Google ограничивает нас в количестве запросов на определение координат — 2500 запросов в сутки с одного ip. Логично было бы добавить хранение в базе наиболее используемых координат, что, кроме экономии запросов даст возможность дополнительного функционала в виде, к примеру, возможности отбирать и отображать нужные метки в пределах заданных географических координат относительно заданного центра.

На этом все. Надеюсь, мой первый пост на Хабре был для вас полезен!

Автор: gromozeka07b9

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js