В этой заметке я продолжаю тему начатую в записи «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 поля)?