Очень удобно загружать свои данные на карту сформировав файл в формате YMapsML.
Мы можем формировать его динамически из записей в базе данных.
Для отображения информации в балуне используется шаблон.
Но иногда возникают проблемы, если мы имеем каждый раз различное число элементов для отображения в балуне метки.
Это может быть информация о маршрутах транспорта по остановкам со ссылками на отображения маршрута или число фотографий для объявлений о недвижимости и т. д.
Как же можно решить данную проблему?
В этой заметке я рассмотрю один из вариантов ее решения.
Суть его заключается в том, что мы будем разбирать данные из YmapsML-файла и добавлять к ним необходимый html-код для отображения в скрипте вывода карты.
Чтобы было все понятно рассмотрим небольшой пример.
У нас имеются данные о продаже квартир в Нижнем Новгороде с различным числом фотографий для каждого объявления, нужно вывести эти данные в виде меток на карту, используя YmapsML.
Я заранее сформировал YmapsML?файл с данными nedv-data.xml
В нем используется следующий шаблон для вывода данных в балуне:
<Template gml:id="balloonTemplate"> <text><![CDATA[ <div style="font-size:12px;"> <div style="color:#ff0303;font-weight:bold">$[name]</div> <div><strong>Тип объявления: </strong>$[metaDataProperty.AnyMetaData.type]</div> <div><strong>Адрес: </strong>$[metaDataProperty.AnyMetaData.address]</div> <div><strong>Район: </strong>$[metaDataProperty.AnyMetaData.rayon]</div> <div><strong>Продавец: </strong>$[metaDataProperty.AnyMetaData.prodavec]</div> <div><strong>Телефон: </strong>$[metaDataProperty.AnyMetaData.telephon]</div> <div><strong>Тип жилья: </strong>$[metaDataProperty.AnyMetaData.typeflat]</div> <div><strong>Кол-во комнат: </strong>$[metaDataProperty.AnyMetaData.roomnum]</div> <div><strong>Этаж: </strong>$[metaDataProperty.AnyMetaData.floor]</div> <div><strong>Всего этажей: </strong>$[metaDataProperty.AnyMetaData.floorfool]</div> <div><strong>Общая площадь кв.м: </strong>$[metaDataProperty.AnyMetaData.area]</div> <div><strong>Жилая площадь кв.м: </strong>$[metaDataProperty.AnyMetaData.livingspace]</div> <div><strong>Площадь кухни кв.м: </strong>$[metaDataProperty.AnyMetaData.kitchenarea]</div> <div><strong>Цена руб: </strong>$[metaDataProperty.AnyMetaData.price]</div> <div><strong>Подробнее: </strong>$[metaDataProperty.AnyMetaData.text]</div> <div><strong>Фото: </strong>$[metaDataProperty.AnyMetaData.foto|не задан]</div> </div>]]></text> </Template> |
Обычно для вывода YmapsML?файла используют следующий код:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>YMapsML - отображение на карте</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU" type="text/javascript"></script> <script type="text/javascript"> // Как только будет загружен API и готов DOM, выполняем инициализацию ymaps.ready(init); function init () { var myMap = new ymaps.Map("map", { center: [56.326944,44.0075], zoom: 12 }); // Загрузка YMapsML-файла ymaps.geoXml.load("http://webmap-blog.ru/xml/nedv-data.xml") .then(function (res) { // функция обрабатывает успешный результат получения YMapsML myMap.geoObjects.add(res.geoObjects); // Добавление геообъектов на карту }, function (error) { // Вызывается в случае неудачной загрузки YMapsML console.error('Ошибка: ' + error); }); } </script> </head> <body> <div id="map" style="width:800px;height:600px"></div> </body> </html> |
Единственная проблема это вывод фотографий, т. к. их число может быть различным.
В моем примере, сейчас в место фото выводиться их назвние.
Для вывода фотографий необходимо обработать данные из YmapsML?файла в скрипте вывода карты.
А теперь рассмотрим его код:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>YMapsML - отображение на карте</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU" type="text/javascript"></script> <script type="text/javascript"> // Как только будет загружен API и готов DOM, выполняем инициализацию ymaps.ready(init); function init () { var myMap = new ymaps.Map("map", { center: [56.326944,44.0075], zoom: 12 }); // Загрузка YMapsML-файла ymaps.geoXml.load("http://webmap-blog.ru/xml/nedv-data.xml") .then(function (res) { // функция обрабатывает успешный результат получения YMapsML myMap.geoObjects.add(res.geoObjects); // Добавление геообъектов на карту }, function (error) { // Вызывается в случае неудачной загрузки YMapsML console.error('Ошибка: ' + error); }); } </script> </head> <body> <div id="map" style="width:800px;height:600px"></div> </body> </html> |
В этом коде в начале, мы получаем YMapsML методом geoXml.load, который возвращает вам объект-обещание (т.к. это асинхронный http-вызов), вызваваем у этого объекта метод then и передаемему в параметрах 2 функции.
В первой мы получем упорядоченную коллекцию геообъектов, перебирая элементы которой, мы можем получить доступ к данным геообъекта.
Используем item.properties.get.
Перед тем, как формировать код содержимого для балуна, мы обрабатываем данные о фотографиях.
Разбиваем строку на части по символу «,» и из полученного массива формируем код ссылки и вывода изображения.
Далее добавляем метки на карту.
Загрузить архив с файлами примера
Для заметки использовались материалы из Клуба разработчиков API Яндекс.Карт
Спасибо, как всегда замечательная статья!
У меня коллекции разбиты на группы (чтобы каждой группе задать свой стиль) и видимо из-за этих групп возникает ошибка вот тут:
res.geoObjects.each(function (item) {
эту строчку надо как-то изменить?
Спасибо большое. Долго мучался с этим АПИ 2.0. Только вот не понятно одно. Мы в XML файле определяем шаблон, а по итогу вынуждены шаблон собирать заново в скрипте через конкатенацию balloonContentBody. Я так понимаю, что из XML можно выкинуть определение шаблона и просто динамически его создавать в скрипте?
как можно скрыть исходный файл ymaps.geoXml.load(«http://webmap-blog.ru/xml/nedv-data.xml»), чтобы его не было видно? где-то видел, что XML файл был зашифрован в виде ymaps.geoXml.load(«http://webmap-blog.ru/xml/e65151ac8262d01df.xml»)
Скрыть его не получится, т.к он должен быть доступен парсеру Яндекса для обработки.
я как то видел вместо файла указано e65151ac8262d01df + видел реализацию через php