В этом посте я хочу показать пример того, как может быть использован сервис 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 этот способ не подойдет без доработок.
Что конкретно мы сделаем:
- Создадим html-файл, содержащий javascript-функции для работы с картой
- Создадим внешнюю обработку для 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