Читатели моего блога задают вопрос, как автоматически с генерировать файл в формате YmapsML с данными о метках?
В этой заметке я на конкретном примере покажу, как это сделать.
Для начала, нам нужно подготовить исходные данные для примера и добавить их в таблицу базы данных MySQL.
Используем файл org_yandexmapnn.sql с данными об организациях Нижнего Новгорода.
Используя инструмент для администрирования базы данных MySQL – phpMyAdmin, создаем там таблицу org_yandexmapnn с данными.
Таблица org_yandexmapnn имеет следующую структуру:
ID — уникальный идентификатор строки записи;
NAME — наименование организации;
TYPE — тип организации (Туристическое агентство, кинотеатр, гостиница …);
CAT_ID – ID категории (тип организации);
ADRES — адрес организации;
TELEPHON — номер телефона;
FOTO — адрес фотографии для организации;
POISK — поле для осуществления поиска организации по различным параметрам (название, тип, райот, адрес);
XX — поле для хранения значения координаты по широте latitude;
YY — поле для хранения значения координаты по долгате longitude.
Теперь, когда данные подготовлены будем писать скрипт формирования YmapsML-файла.
Назовем его create_ymapsml.php
С начала напишем скрипт, который будет выводить метки на карту с одинаковым стилем, а затем изменим его так, чтобы для каждого типа меток был свой стиль.
Код файла create_ymapsml.php
<?php
header("Content-type: text/xml");
include("bd.php");
echo '<ymaps xmlns="http://maps.yandex.ru/ymaps/1.x" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maps.yandex.ru/schemas/ymaps/1.x/ymaps.xsd">
<Representation xmlns="http://maps.yandex.ru/representation/1.x">
<Style gml:id="org">
<iconStyle>
<href>http://api-maps.yandex.ru/i/0.4/micro/pmrds.png</href>
<size x="28" y="29"/>
<offset x="14" y="-14"/>
</iconStyle>
<balloonContentStyle>
<template>#balloonTemplate</template>
</balloonContentStyle>
</Style>
<Template gml:id="balloonTemplate">
<text><![CDATA[
<div style="font-size:12px;">
<div style="color:#ff0303;font-weight:bold">$[name]</div>
<div>Адрес: $[metaDataProperty.AnyMetaData.adres|не задан]</div>
<div>Телефон: $[metaDataProperty.AnyMetaData.telefon|не задан]</div>
<div>Тип: $[metaDataProperty.AnyMetaData.type|не задан]</div>
</div>]]></text>
</Template>
</Representation>
<GeoObjectCollection>
<gml:name>Объекты карте</gml:name>
<style>#org</style>
<gml:featureMembers>';
$query1= "SELECT * FROM org_yandexmapnn";
$result1 = mysql_query($query1);
while ($par1 = mysql_fetch_array($result1))
{
echo '<GeoObject>';
echo '<gml:name>', htmlspecialchars($par1['NAME']), '</gml:name>';
echo '<gml:metaDataProperty>';
echo '<AnyMetaData>';
echo '<adres>', $par1['ADRES'], '</adres>';
echo '<telefon>', $par1['TELEPHON'], '</telefon>';
echo '<type>', $par1['TYPE'], '</type>';
echo '</AnyMetaData>';
echo '</gml:metaDataProperty>';
echo '<gml:Point>';
echo '<gml:pos>', $par1['XX'], ' ', $par1['YY'], '</gml:pos>';
echo '</gml:Point>';
echo '</GeoObject>';
echo "n";
}
echo '</gml:featureMembers>
</GeoObjectCollection>
</ymaps>';
?> |
Рассмотрим его код подробнее.
В начале, мы сообщаем браузеру, что будет передан текст в формате xml.
Для чего передаем соответствующий заголовок header("Content-type: text/xml");
После этого, мы подключаем файл для соединения с базой данных bd.php.
Он имеет следующий код:
<?php
$sdb_name = "localhost"; //адрес сервера базы данных, обычно localhost
$user_name = "root"; //логин пользователя
$user_password = ""; //пароль пользователя
$db_name = "ymap_bd"; //имя базы данных MySQL
// соединение с сервером базы данных
if(!$link = mysql_connect($sdb_name, $user_name, $user_password))
{
echo "<br>Не могу соединиться с сервером базы данных<br>";
exit();
}
// выбираем базу данных
if(!mysql_select_db($db_name, $link))
{
echo "<br>Не могу выбрать базу данных<br>";
exit();
}
mysql_query('SET NAMES utf8');
?> |
После этого, мы начинаем формировать YmapsML-файл, выводим начало файла с помощью оператора echo.
Подробнее о формате файлов YmapsML можно прочитать в документации.
Для определения внешнего вида меток на карте и содержимого балуна используется элемент Representation.
В нем мы определяем стиль для значка метки org, адрес изображения — http://api-maps.yandex.ru/i/0.4/micro/pmrds.png, размеры значка в пикселях size x="28" y="29", и отступы значка от точки привязки — offset x="14" y="-14".
Для задания стиля для отображения содержимого балуна, используется специальный шаблон balloonTemplate.
Элемент GeoObjectCollection содержит набор описаний геообъектов, отображаемых на карте.
В нашем случае набор меток.
Для всего набора мы задаем общий стиль отображения #org.
Затем делаем обращение к базе данных в таблицу org_yandexmapnn, из которой извлекаем необходимые параметры для меток.
При выводе названия организации, мы используем функцию htmlspecialchars, она производит преобразование спецсимволов в их HTML эквиваленты, для нормального формирования XML-файла.
Вывод динамически сформированного YmapsML-файла на карту осуществляет файл viv-map.html
Код файла viv-map.html
<!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/1.1/index.xml?key=ACuF2EkBAAAAzahYCgIASLsFm9n8EPvNjaTc8nAWiETKgYcAAAAAAAAAAAC-q61vWtIK3Kzt2yQ9qFaGJGKzXw==" type="text/javascript"></script>
<script type="text/javascript">
// Создание обработчика для события window.onLoad
YMaps.jQuery(function () {
// Создание экземпляра карты и его привязка к созданному контейнеру
var map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]);
// Установка для карты ее центра и масштаба
map.setCenter(new YMaps.GeoPoint(44.0075,56.326944), 15);
//Добавляем элементы управления.
map.addControl(new YMaps.TypeControl());//Тип карты, кнопочки Схема, Гибрид, Спутник
map.addControl(new YMaps.ToolBar());//Тулбар, кнопки Рука, Лупа, Линейка
map.addControl(new YMaps.Zoom());//Увеличение
// Создание и добавление YMapsML-документа на карту
var ml = new YMaps.YMapsML('http://webmap-blog.ru/examples/ymap-ymapsml/create_ymapsml.php');
map.addOverlay(ml);
// Обработчик неудачной загрузки YMapsML
YMaps.Events.observe(ml, ml.Events.Fault, function (ml, error) {
alert('Ошибка: ' + error);
});
});
</script>
</head>
<body>
<div id="YMapsID" style="width:800px;height:600px"></div>
</body>
</html> |

Теперь изменим код файла create_ymapsml.php так, чтобы каждый тип организаций на карте отображался значком со своим стилем.
Гостиница
Железнодорожный вокзал
интернет-кафе
Кафе и рестораны
Кинотеатр
Музеи
Парки
Речной вокзал
Театры
Туристическое агентство
Фитнес центы, спортивные клубы
Зададим соответствующие стили для каждого типа, используя наследования стилей.
С начала мы определяем общий стиль commonStyle для всех объектов.
<Style gml:id="commonStyle"> <iconStyle> <size x="32" y="37"/> <offset x="-16" y="-18"/> </iconStyle> <balloonContentStyle> <template>#balloonTemplate</template> </balloonContentStyle> </Style> |
А затем отдельные стили для каждого типа организаций, наследующие параметры стиля commonStyle.
Для гостиниц:
<Style gml:id="styleHotels"> <parentStyle>#commonStyle</parentStyle> <iconStyle> <href> http://webmap-blog.ru/examples/ymap-ymapsml/images/hotel.png </href> </iconStyle> </Style> |
И так далее …
После мы также определяем набор описаний геообъектов, отображаемых на карте.
Но для каждого объекта задаем свой стиль.
Полный код файла create_ymapsml-2.php
<?php
header("Content-type: text/xml");
include("bd.php");
$styleorg = array("#styleHotels", "#styleTrain", "#styleInternetcafe", "#styleCafe", "#styleCinema", "#styleMuseum", "#styleParks", "#styleShips", "#styleTheater", "#styleTurism", "#styleFitness");
echo '<ymaps xmlns="http://maps.yandex.ru/ymaps/1.x" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maps.yandex.ru/schemas/ymaps/1.x/ymaps.xsd">
<Representation xmlns="http://maps.yandex.ru/representation/1.x">
<Style gml:id="commonStyle">
<iconStyle>
<size x="32" y="37"/>
<offset x="-16" y="-18"/>
</iconStyle>
<balloonContentStyle>
<template>#balloonTemplate</template>
</balloonContentStyle>
</Style>
<Style gml:id="styleHotels">
<parentStyle>#commonStyle</parentStyle>
<iconStyle>
<href>
http://webmap-blog.ru/examples/ymap-ymapsml/images/hotel.png
</href>
</iconStyle>
</Style>
<Style gml:id="styleTrain">
<parentStyle>#commonStyle</parentStyle>
<iconStyle>
<href>
http://webmap-blog.ru/examples/ymap-ymapsml/images/train.png
</href>
</iconStyle>
</Style>
<Style gml:id="styleInternetcafe">
<parentStyle>#commonStyle</parentStyle>
<iconStyle>
<href>
http://webmap-blog.ru/examples/ymap-ymapsml/images/internet.png
</href>
</iconStyle>
</Style>
<Style gml:id="styleCafe">
<parentStyle>#commonStyle</parentStyle>
<iconStyle>
<href>
http://webmap-blog.ru/examples/ymap-ymapsml/images/coffee.png
</href>
</iconStyle>
</Style>
<Style gml:id="styleCinema">
<parentStyle>#commonStyle</parentStyle>
<iconStyle>
<href>
http://webmap-blog.ru/examples/ymap-ymapsml/images/cinema.png
</href>
</iconStyle>
</Style>
<Style gml:id="styleMuseum">
<parentStyle>#commonStyle</parentStyle>
<iconStyle>
<href>
http://webmap-blog.ru/examples/ymap-ymapsml/images/museum.png
</href>
</iconStyle>
</Style>
<Style gml:id="styleParks">
<parentStyle>#commonStyle</parentStyle>
<iconStyle>
<href>
http://webmap-blog.ru/examples/ymap-ymapsml/images/parks.png
</href>
</iconStyle>
</Style>
<Style gml:id="styleShips">
<parentStyle>#commonStyle</parentStyle>
<iconStyle>
<href>
http://webmap-blog.ru/examples/ymap-ymapsml/images/ships.png
</href>
</iconStyle>
</Style>
<Style gml:id="styleTheater">
<parentStyle>#commonStyle</parentStyle>
<iconStyle>
<href>
http://webmap-blog.ru/examples/ymap-ymapsml/images/theater.png
</href>
</iconStyle>
</Style>
<Style gml:id="styleTurism">
<parentStyle>#commonStyle</parentStyle>
<iconStyle>
<href>
http://webmap-blog.ru/examples/ymap-ymapsml/images/turism.png
</href>
</iconStyle>
</Style>
<Style gml:id="styleFitness">
<parentStyle>#commonStyle</parentStyle>
<iconStyle>
<href>
http://webmap-blog.ru/examples/ymap-ymapsml/images/fitness.png
</href>
</iconStyle>
</Style>
<Template gml:id="balloonTemplate">
<text><![CDATA[
<div style="font-size:12px;">
<div style="color:#ff0303;font-weight:bold">$[name]</div>
<div>Адрес: $[metaDataProperty.AnyMetaData.adres|не задан]</div>
<div>Телефон: $[metaDataProperty.AnyMetaData.telefon|не задан]</div>
<div>Тип: $[metaDataProperty.AnyMetaData.type|не задан]</div>
</div>]]></text>
</Template>
</Representation>
<GeoObjectCollection>
<gml:name>Объекты карте</gml:name>
<gml:featureMembers>';
for($i=1; $i<12; $i++)
{
$query1= "SELECT * FROM org_yandexmapnn WHERE CAT_ID = '$i'";
$result1 = mysql_query($query1);
while ($par1 = mysql_fetch_array($result1))
{
echo '<GeoObject gml:id="', $par1['ID'], '">';
echo '<gml:name>', htmlspecialchars($par1['NAME']), '</gml:name>';
echo '<gml:metaDataProperty>';
echo '<AnyMetaData>';
echo '<adres>', $par1['ADRES'], '</adres>';
echo '<telefon>', $par1['TELEPHON'], '</telefon>';
echo '<type>', $par1['TYPE'], '</type>';
echo '</AnyMetaData>';
echo '</gml:metaDataProperty>';
echo '<gml:Point>';
echo '<gml:pos>', $par1['XX'], ' ', $par1['YY'], '</gml:pos>';
echo '</gml:Point>';
echo '<style>', $styleorg[$i-1], '</style>';
echo '</GeoObject>';
echo "n";
}
}
echo '</gml:featureMembers>
</GeoObjectCollection>
</ymaps>';
?> |
Значки для объектов получены на сайте
Код файла для вывода карты с метками аналогичен viv-map.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/1.1/index.xml?key=ACuF2EkBAAAAzahYCgIASLsFm9n8EPvNjaTc8nAWiETKgYcAAAAAAAAAAAC-q61vWtIK3Kzt2yQ9qFaGJGKzXw==" type="text/javascript"></script>
<script type="text/javascript">
// Создание обработчика для события window.onLoad
YMaps.jQuery(function () {
// Создание экземпляра карты и его привязка к созданному контейнеру
var map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]);
// Установка для карты ее центра и масштаба
map.setCenter(new YMaps.GeoPoint(44.0075,56.326944), 15);
//Добавляем элементы управления.
map.addControl(new YMaps.TypeControl());//Тип карты, кнопочки Схема, Гибрид, Спутник
map.addControl(new YMaps.ToolBar());//Тулбар, кнопки Рука, Лупа, Линейка
map.addControl(new YMaps.Zoom());//Увеличение
// Создание и добавление YMapsML-документа на карту
var ml = new YMaps.YMapsML('http://webmap-blog.ru/examples/ymap-ymapsml/create_ymapsml-2.php');
map.addOverlay(ml);
// Обработчик неудачной загрузки YMapsML
YMaps.Events.observe(ml, ml.Events.Fault, function (ml, error) {
alert('Ошибка: ' + error);
});
});
</script>
</head>
<body>
<div id="YMapsID" style="width:800px;height:600px"></div>
</body>
</html> |

Когда меток на карте очень много, можно не выводить их все одним файлом YmapsML, а разбить на несколько по категориям.
Пример реализации я покажу в следующей заметке.
Большое спасибо за статью, обязательно попробую реализовать, только один вопрос, как адаптировать к Народной карте, дописать к ключу &modules=pmap или еще что то?
Заранее спасибо.
Ссылка на документацию.
Как использовать Народную карту заметка на блоге
Здравствуйте. Пробовала сделать тоже самое у себя на локальном хосте. Создала документ create-ymapsml.php, как показано в примере, а в файл viv_map.html, где:
» // Создание и добавление YMapsML-документа на карту
var ml = new YMaps.YMapsML(‘http://webmap-blog.ru/examples/ymap-ymapsml/create_ymapsml-2.php’);
map.addOverlay(ml);
»
вместо http://webmap-blog.ru/examples/ymap-ymapsml/create_ymapsml-2.php поставила свой адрес http://localhost/1/create-ymapsml.php.
Постоянно выдает ошибку: Ошибка: server responded 404. Подскажите пожалуйста, что нужно поменять.
Ответ нашла тут: http://clubs.ya.ru/mapsapi/replies.xml?item_no=20711
но, к сожалению, после замены http://webmap-blog.ru/examples/ymap-ymapsml/create_ymapsml-2.php
поставила свой адрес http://localhost/1/create-ymapsml.php на http://gipros.kiev.ua/create_ymapsml.php
но опять ошибка: Ошибка: :19: parser error : Input is not proper UTF-8, indicate encoding !
Bytes: 0xC0 0xE4 0xF0 0xE5
$
Дело в том, что файл create_ymapsml.php должен быть виден из интернета. Еще необходимо содержимое файла create_ymapsml.php сохранить в нужной кодировке (UTF-8) в текстовом редакторе.
Здравствуйте. Создал файлы create_ymapsml.php, bd.php, viv-map.html. Изменил в файле viv-map.html
http://webmap-blog.ru/examples/ymap-ymapsml/create_ymapsml.php
на
http://detsad16d.ru/create_ymapsml.php
и поменял ключ на свой.
Разумеется изменил данные в базе не свои. После всего этого выдается ошибка «server responded 404»
сайт находится по адресу http://detsad16d.ru/viv-map.html
Здесь лежат все файлы http://detsad16d.ru
Скажите пожалуйста, что нужно сделать, чтобы все выводилось верно?
P.S. Когда пробую без замены http://webmap-blog.ru/examples/ymap-ymapsml/create_ymapsml.php
тогда все работает
А соединение со своей базой данных в файле bd.php Вы настроили?
Добрый день!
Сделала все по вашим указаниям, разместила на: http://test.arsisclub.ru/components/com_yandexmaps/twirl/ind.html
данные своей базы указала. выдает: Ошибка: Couldn’t resolve host name.
может быть Вы знаете,в чем дело?
И еще вопрос: как изменить этот пример, чтоб можно было использовать активные области как здесь http://webmap-blog.ru/yandex-maps/otobrazhenie-mnozhestva-markerov-na-yandeks-kartax#comments ?
Проверьте путь к файлу create_ymapsml.php, в вашем примере он http://test1.ru/components/com_yandexmaps/twirl/create_ymapsml.php
На второй вопрос, нужно сохранить полученный YMapsML-файл и с помощью скрипта https://github.com/twirl/hsTiler получить набор тайлов.
Где-то в клубе Яндекс.Карт обсуждался вопрос динамической генерации тайлов. Найду, пришлю Вам ссылку
Спасибо! путь к файлу поправила, но теперь выдает:
«Ошибка: server responded 500», буду крайне благодарна если еще раз поможете))
Ошибка возникала при загрузке файла create_ymapsml.php, вероятно скрипту не хватает времени на выполнение. Попробуйте для начала выгружать только часть данных.
Так у меня в базе всего штук 10 записей с метами, неужели он их не может выгрузить? как же тогда выгружать тысячи, как в проекте Банкоматор?
Можете мне Ваши данные прислать, я попробую их вывести. А то так не понятно, где ошибка
Тоже ошибка 500. Многие говорят, что это из-за настроек файла .htaccess. Помогите пожалуйста!
нашел одну ошибку. сейчас выдает:
Ошибка: :1: parser error : Start tag expected, ‘<' not found
^
Url: ******/create_ymapsml.php
Где-то в генерируемом коде лишний символ «<", надо посмотреть код формирования скрипта create_ymapsml.php. Проверьте формат получаемого YMapsML-файла.
YMapsML-файл в формате .xml
Вот код create_ymapsml.php
<?php
header("Content-type: text/xml");
include("bd.php");
echo '
http://api-maps.yandex.ru/i/0.4/micro/pmrds.png
#balloonTemplate
<![CDATA[
$[name]
Адрес: $[metaDataProperty.AnyMetaData.adres|не задан]
Телефон: $[metaDataProperty.AnyMetaData.telefon|не задан]
Тип: $[metaDataProperty.AnyMetaData.type|не задан]
]]>
Объекты карте
#org
‘;
$query1= «SELECT * FROM org_yandexmapnn»;
$result1 = mysql_query($query1);
while ($par1 = mysql_fetch_array($result1))
{
echo »;
echo », htmlspecialchars($par1[‘NAME’]), »;
echo »;
echo »;
echo », $par1[‘ADRES’], »;
echo », $par1[‘TELEPHON’], »;
echo », $par1[‘TYPE’], »;
echo »;
echo »;
echo »;
echo », $par1[‘XX’], ‘ ‘, $par1[‘YY’], »;
echo »;
echo »;
echo «n»;
}
echo ‘
‘;
?>
вот код, выше скопировался не верно
<?php
header("Content-type: text/xml");
include("bd.php");
echo '
http://api-maps.yandex.ru/i/0.4/micro/pmrds.png
#balloonTemplate
<![CDATA[
$[name]
Адрес: $[metaDataProperty.AnyMetaData.adres|не задан]
Телефон: $[metaDataProperty.AnyMetaData.telefon|не задан]
Тип: $[metaDataProperty.AnyMetaData.type|не задан]
]]>
Объекты карте
#org
‘;
$query1= «SELECT * FROM org_yandexmapnn»;
$result1 = mysql_query($query1);
while ($par1 = mysql_fetch_array($result1))
{
echo »;
echo », htmlspecialchars($par1[‘NAME’]), »;
echo »;
echo »;
echo », $par1[‘ADRES’], »;
echo », $par1[‘TELEPHON’], »;
echo », $par1[‘TYPE’], »;
echo »;
echo »;
echo »;
echo », $par1[‘XX’], ‘ ‘, $par1[‘YY’], »;
echo »;
echo »;
echo «n»;
}
echo ‘
‘;
?>
Не все вставляется почему-то, он абсолютно такой же как в уроку
Так сложно что-то сказать, лучше дайте ссылку на ваш пример. Формируемый YMapsML-файл должен быть доступен из интернета, для его разбора парсером Яндекса. У меня формируемый код можно посмотреть по ссылкессылке. Проверьте, что у Вас выводится.
когда прописсываю вашу ссылку все метки выводятся
// Создание и добавление YMapsML-документа на карту
var ml = new YMaps.YMapsML(‘http://webmap-blog.ru/examples/ymap-ymapsml/create_ymapsml.php’);
map.addOverlay(ml);
resttime.info/3.html
Сергей, Вы писали, чтоб я прислала свои данные, я скинула доступы вам на почту ugolsergey@gmail.com
Моя ошибка «server responded 500″ прошла, после переноса сайта на другой хостинг, видимо тот сервер не хотел обрабатывать запрос.
Фаил YmapsML у меня автоматически генерируется из БД, я могу открыть его и он идентичен с тем что открывается по ссылке «http://webmap-blog.ru/examples/ymap-ymapsml/create_ymapsml.php», но при замене его в коде на свой, появляется «server responded 404».
Правильно ли я понял, что на локальном хосте (денвер) невозможно проверить работу «create_ymapsml.php» так как к нему должен быть доступ извне и поэтому постоянно появляется ошибка «server responded 404» ?
Да, он должен быть доступен из интернета
Подскажите как адаптировать этот пример под API Яндекс.Карт 2.х, если менять только
НА
НЕ РАБОТАЕТ (