Читатели моего блога задают вопрос, как автоматически с генерировать файл в формате 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.х, если менять только
НА
НЕ РАБОТАЕТ (