В этой заметке я продолжаю тему начатую в записи «API Яндекс.Карт – рисуем полилинию».
Здесь мы сохраним нарисованную ломаную линию в базе данных MySQL, а затем выведем ее на карту.
Для сохранения полилинии нам необходимо создать таблицу userslineymap в базе данных.
Сделать это можно с помощью следующего SQL-кода:
CREATE TABLE `userslineymap` (
`id_line` int(20) NOT NULL auto_increment,
`colour` varchar(10) NOT NULL,
`width` int(10) NOT NULL,
`users` varchar(255) NOT NULL,
`coordinats` text NOT NULL,
PRIMARY KEY (`id_line`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
id_line – здесь хранится порядковый номер записи в таблице, происходит его автоматическое увеличение на единицу при добавлении новой записи;
colour – служит для хранения цвета полилинии, например, красный – ff0000;
width – этот параметр отвечает за толщину полилинии;
users – параметр для хранения имени пользователя , добавившего полилинию – в нашем примере не используется, но если вы захотите учитывать пользователей – это поле вам понадобиться;
coordinats – хранятся координаты вершин полилинии в виде текстовой строки, пары значений разделяются между собой точкой с запятой.
Еще одно замечание, в базе данных MySQL реализована поддержка пространственных расширений, чтобы позволяет хранить и анализировать географические свойства, но для нашего примера мы будем использовать обычное текстовое поле для хранения координат.
Теперь мы напишем два php-скрипта для соединения с базой данных config.php и для записи данных в таблицу userslineymap — upload.php
Код файла config.php:
<?php $sdb_name = "localhost"; $user_name = "root"; $user_password = ""; $db_name = "gmapsbd"; // соединение с сервером базы данных 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'); ?> |
Код файла upload.php:
<?php include("config.php"); $points = trim($_POST['coords']); $result = mysql_query ("INSERT INTO userslineymap VALUES (0, '#FF0000', 2, ' ', '$points')"); ?> |
Тут тоже все очень просто.
Мы принимаем строку со значениями координат вершин полилинии вида 43.984359,56.319304;43.995346,56.313389;44.010109,56.324168;44.036544,56.311099;44.049934,56.318827.040664,56.3111942, переданную методом POST.
Убираем лишние переводы строк и пробелы, а затем, с помощью оператора INSERT записываем ее в нашу таблицу, а также толщину линии и ее цвет.
Для того чтобы, передать значения координат в скрипт upload.php необходимо в код, который мы получили в предидущей заметке «API Яндекс.Карт – рисуем полилинию» — https://webmap-blog.ru/examples/ymap_pr_45.html после строки
YMaps.jQuery("#coords").attr("value", polyline.getPoints().join(‘n’));
Еще одну строку кода:
YMaps.jQuery.post("upload.php", {coords : polyline.getPoints().join(‘;’)});
Здесь используя встроеную JavaScript-библиотеку jQuery асинхронно методом POST, передаем значения координат вершин ломаной линии в наш php-скрипт upload.php, разделяя пары значений широты и долготы точкой с запятой.
Приведу полный код примера:
<!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>API Яндекс.Карт - рисуем полилинию и сохраняем в БД MySQL</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"> var polyline // Создание обработчика для события window.onLoad YMaps.jQuery(function () { // Создание экземпляра карты и его привязка к созданному контейнеру var map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]); // Установка для карты ее центра и масштаба map.setCenter(new YMaps.GeoPoint(43.998779,56.316537), 13); map.addControl(new YMaps.Zoom()); map.addControl(new YMaps.TypeControl()); map.addControl(new YMaps.ToolBar()); // Создание ломанной var polyline = new YMaps.Polyline(); // Установка параметров режима редактирования polyline.setEditingOptions({ drawing: true, menuManager: function (index, menuItems) { menuItems.push({ id: "StopEditing", title: '<span style="white-space:nowrap;">Завершить редактирование<span>', onClick: function (polyline, pointIndex) { polyline.stopEditing(); YMaps.jQuery("#coords").attr("value", polyline.getPoints().join('n')); YMaps.jQuery.post("upload.php", {coords : polyline.getPoints().join(';')}); } }); return menuItems; } }); // Добавление ломаной на карту map.addOverlay(polyline); // Включение режима редактирования polyline.startEditing(); }) </script> </head> <body> <table> <tr> <td> <div id="YMapsID" style="width:800px;height:600px"></div> </td> <td valign="top"> <textarea rows="15" cols="35" id="coords" name="coord"></textarea> </td> </tr> </table> <p><a href="/?p=" title="API Яндекс.Карт – рисуем полилинию и сохраняем ее в базе данных MySQL" target="_blank">Вернуться к тексту заметки</a></p> </body> </html> |
Теперь нам нужно вывести, сохраненные в базе данных полилинии, на карту.
Удобнее всего для этого использовать файл в формате YMapsML и подгружать его на карту.
За создание YMapsML-файла будет отвечать скрипт – viv-xml.php
Для простоты я не буду в коде учитывать толщину линии и цвет, т.е. для отображения всех полилиний я буду использовать один стиль.
Приведу код файла viv-xml.php:
<?php header("Content-type: text/xml"); include("config.php"); echo '<?xml version="1.0" encoding="utf-8"?> <ymaps:ymaps xmlns:ymaps="http://maps.yandex.ru/ymaps/1.x" xmlns:repr="http://maps.yandex.ru/representation/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"> <repr:Representation> <repr:Style gml:id="customStyle"> <repr:lineStyle> <repr:strokeColor>FF9911</repr:strokeColor> <repr:strokeWidth>4</repr:strokeWidth> </repr:lineStyle> </repr:Style> <repr:Style gml:id="customStyle1"> <repr:parentStyle>#customStyle</repr:parentStyle> <repr:lineStyle> <repr:strokeColor>FF00FF</repr:strokeColor> </repr:lineStyle> </repr:Style> </repr:Representation> <ymaps:GeoObjectCollection> <gml:name>Полилинии из базы данных</gml:name> <gml:featureMembers>'; $result = mysql_query("SELECT id_line, coordinats FROM userslineymap"); if(mysql_num_rows($result)>0) { while ($mar = mysql_fetch_array($result)) { echo '<ymaps:GeoObject>'; echo '<gml:name>Маршрут-', $mar['id_line'], '</gml:name>'; echo ' <gml:description>Маршрут в виде ломаной</gml:description>'; echo ' <gml:LineString> '; $str_exp1 = explode(";", $mar['coordinats']); for($i=0; $i<count($str_exp1); $i++) { $str_exp2 = explode(",", $str_exp1[$i]); echo '<gml:pos>', $str_exp2[0], ' ', $str_exp2[1], '</gml:pos>'; } echo '</gml:LineString><ymaps:style>#customStyle1</ymaps:style></ymaps:GeoObject> '; } } echo '</gml:featureMembers> </ymaps:GeoObjectCollection> </ymaps:ymaps>'; ?> |
Здесь с использованием оператора echo, формируется код YMapsML-файла.
Для вывода, сформированного файла на карту, используется файл viv-ymapsml.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>Выводим полилинии из базы данных MySQL</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 language="JavaScript" type="text/javascript"> // Создание обработчика для события window.onLoad YMaps.jQuery(function () { // Создание экземпляра карты и его привязка к созданному контейнеру var map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]); // Установка для карты ее центра и масштаба map.setCenter(new YMaps.GeoPoint(43.998779,56.316537), 13); map.addControl(new YMaps.Zoom()); map.addControl(new YMaps.TypeControl()); map.addControl(new YMaps.ToolBar()); // Создание и добавление YMapsML-документа на карту var ml = new YMaps.YMapsML("http://webmap-blog.ru/examples/drawline/viv-xml.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.html
Для его изменения я использовал пример «Создание меню для отображения коллекций объектов »
В файле ymapsml.html нужно удалить строку map.addOverlay(ml); — добавление оверлея на карту.
Добавить следующие фрагменты кода:
— Обработчик успешной загрузки YMapsML-файла
YMaps.Events.observe(ml, ml.Events.Load, function (ml) {
// Создание списка групп
ml.get(0).forEach(function (item) {
addMenuItem(item, map, YMaps.jQuery("#menu"));
});
});
С разу после создания YMapsML-документа
var ml = new YMaps.YMapsML("https://webmap-blog.ru/xml/pline-pr1.xml");
Переменную map сделать глобальной, объявив ее до функции с оздание обработчика для события window.onLoad.
И добавить функцию addMenuItem для добавления пунктов меню
function addMenuItem (group, map, menuContainer) {
// Показать/скрыть группу на карте
YMaps.jQuery("<a class="title" href="#">" + group.name + "</a>")
.bind("click", function () {
var link = YMaps.jQuery(this);
// Если пункт меню "неактивный", то добавляем группу на карту,
// иначе — удаляем с карты
if (link.hasClass("active")) {
map.removeOverlay(group);
} else {
map.addOverlay(group);
}
// Меняем "активность" пункта меню
link.toggleClass("active");
return false;
})
// Добавление нового пункта меню в список
.appendTo(
YMaps.jQuery("<li></li>").appendTo(menuContainer)
)
};
Еще мы добавляем строку для объекта меню в секцию body и задаем стиль для пунктов меню.
В результате у нас должен получиться следующий код:
<!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>Выводим полилинии из базы данных MySQL и создаем меню</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 language="JavaScript" type="text/javascript"> var map; // Создание обработчика для события window.onLoad YMaps.jQuery(function () { // Создание экземпляра карты и его привязка к созданному контейнеру map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]); // Установка для карты ее центра и масштаба map.setCenter(new YMaps.GeoPoint(43.998779,56.316537), 13); map.addControl(new YMaps.Zoom()); map.addControl(new YMaps.TypeControl()); map.addControl(new YMaps.ToolBar()); // Создание и добавление YMapsML-документа на карту var ml = new YMaps.YMapsML("http://webmap-blog.ru/examples/drawline/viv-xml.php"); // Обработчик успешной загрузки YMaps.Events.observe(ml, ml.Events.Load, function (ml) { // Создание списка групп ml.get(0).forEach(function (item) { addMenuItem(item, map, YMaps.jQuery("#menu")); }); }); // Обработчик неудачной загрузки YMaps.Events.observe(ml, ml.Events.Fault, function (ml, error) { alert("При загрузке данных произошла ошибка: " + error); }); }) // Добавление одного пункта в список function addMenuItem (group, map, menuContainer) { // Показать/скрыть группу на карте YMaps.jQuery("<a class="title" href="#">" + group.name + "</a>") .bind("click", function () { var link = YMaps.jQuery(this); // Если пункт меню "неактивный", то добавляем группу на карту, // иначе - удаляем с карты if (link.hasClass("active")) { map.removeOverlay(group); } else { map.addOverlay(group); } // Меняем "активность" пункта меню link.toggleClass("active"); return false; }) // Добавление нового пункта меню в список .appendTo( YMaps.jQuery("<li></li>").appendTo(menuContainer) ) }; </script> <style type="text/css"> /* Оформление меню (начало)*/ #menu { list-style: none; margin: 0; padding: 0; } #menu a { text-decoration: none; border-bottom: dashed 1px; } a.active { color: #000; } /* Оформление меню (конец)*/ </style> </head> <body> <table> <tr> <td><div id="YMapsID" style="width:800px;height:600px"></div></td> <td valign="top"><ul id="menu"></ul></td> </tr> <table> <p><a href="/?p=" title="API Яндекс.Карт – рисуем полилинию и сохраняем ее в базе данных MySQL" target="_blank">Вернуться к тексту заметки</a></p> </body> </html> |
Выбирая тот или иной пункт меню, отображаются разные полилинии.
На этом я еще не заканчиваю рассмотрение темы работы с полилиниями и в дальнейших заметках рассмотрю вопросы кодирования вершин, хранение координат вершин ломаной в виде геометрического объекта в базе данных MySQL.
выдает ошибку,
то server responsed 404, то ymaps tags is not found
в чем проблема?
var ml = new YMaps.YMapsML(«http://webmap-blog.ru/examples/drawline/viv-xml.php»);
Выдает ошибку ymap tag is not found — как ее исправить?
Ошибки могли возникать из-за большого количества линий, одновременно выводимых на карту (около 700).
Не каждый браузер может обработать такое количество объектов. Я удалил лишние полилинии из базы и теперь все должно работать нормально
оно берет координаты из вашей БД, а не из той которая находиться у меня
как сделать чтобы координаты брались именно с моей БД?
Нужно отредактировать файл config.php для соединения с базой данных
$sdb_name = «localhost»; адрес сервера, как правило localhost
$user_name = «root»; — имя пользователя базы данных
$user_password = «»; — пароль
$db_name = «gmapsbd»; имя базы данных
да это понятно, я в поле $db_name = «gmapsbd» — указал имя своей базы данных.
просто
файл viv-xml.php из строки var ml = new YMaps.YMapsML(«http://webmap-blog.ru/examples/drawline/viv-xml.php»); обращается к вашей БД, на яндексе мне сказали что YMapsML не может использоваться локально, а я делаю сайт на Apache
Как мне сделать чтобы обращение было к моей БД?
Тут два выхода. Первый, базу данных и скрипты расположить на каком-нибудь сервере в интернет, можно бесплатном. Второй, сформировать XML-файл на локальном сервере и загрузить его на сервер в интернет и прописать путь к нему в файле viv-xml.php
а если нужно обновлять линии,
т.е добаВЛЯЮТЬСЯ ЛИНИ ТАМ ЧЕРЕЗ ДЕНЬ, как тогда поступить?
всегда загружать обновленный XML-файл в инет, тоже не выход
все супер! сделал, только вопрос, как сделать стрелочки направление движения маршрута как в примере: http://api.yandex.ru/maps/articles/examples/overlaypolylinewitharrows.html
В документации по API все написано ссылка
Почему вы использовали в этом примере метод POST?
Как будет выглядеть код при использовании метода GET?
Хочу задать вопрос, как возможно реализовать еще формочку ввода чтоб в файл YMaps.jQuery.post(«upload.php», {coords : polyline.getPoints().join(‘;’)});
вместе с координатами уходил бы еще и некий кортеж (2-3 поля)?