После публикации заметки «Яндекс.Карта на Вашем сайте с возможностью добавления меток пользователями. Новая версия.» меня начали спрашивать, как организовать вывод меток по категориям на карту.
В этой заметке я расскажу как это сделать.
Исходный код файлов мы возьмем из уже упоминавшейся заметки «Яндекс.Карта на Вашем сайте с возможностью добавления меток пользователями. Новая версия.»:
config.php — содержит код для соединения с базой данных;
vivodpoints.html — основной файл нашего решения, выводит карту с метками и в нем же реализована возможность добавления меток пользователями;
addpoint.php — в нем производится запись параметров о добавленной метки в базу данных;
vivodpointsmap.php — в этом файле производиться запрос к базе данных для выборки всех меток и формируется ответ в формате JSON.
В начале мы создаем в базе данных новую таблицу mappointscat.
Сделать это можно используя PhpMyAdmin выполнив следующий SQL-код:
CREATE TABLE `mappointscat` ( `id` int(11) NOT NULL auto_increment, `name` varchar(255) NOT NULL, `descriptions` varchar(255) NOT NULL, `type` varchar(255) NOT NULL, `cx` varchar(10) NOT NULL, `cy` varchar(10) NOT NULL, `user` varchar(255) NOT NULL, `view` int(2) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
Здесь структура таблицы аналогична таблице mappoint, за исключением поля type, где мы будем хранить название категории.
Тепрерь, мы должны изменить файлы vivodpoints.html и addpoint.php.
В форму добавления параметров метки в файле vivodpoints.html добавить новое поле для выбора категории.
Для этого изменяем строку
var $element = YMaps.jQuery('<div>Название: <input type="text" id="name"/><br />Описание: <textarea id="descriptpoint" cols="20" rows="5"></textarea><br /><input type="button" value="Добавить" id="submit"/></div>'); |
На
var $element = YMaps.jQuery('<div>Название: <input type="text" id="name"/><br />Описание: <textarea id="descriptpoint" cols="20" rows="5"></textarea><br />Категория: <select id="type"><option value= "bar " SELECTED>Бар</option><option value="restaurant">Ресторан</option><option value="cafe">Кафе</option></select><br /><input type="button" value="Добавить" id="submit"/></div>'); |
И после строки
descriptpoint: $element.find(‘#descriptpoint’)[0].value,
добавляем
type: $element.find(‘#type option:selected’)[0].value,
А в файле addpoint.php принять переданный параметр, а затем записать все данные в таблицу базы данных.
Здесь добавляем строку $type = $_GET[‘type’]; перед $pcoord = $_GET[‘pcoord’];
И изменяе строку SQL-запроса к базе данных
$sql = "INSERT INTO mappoint VALUES(0, '$namepoint', '$descriptpoint', '$coordx', '$coordy', 'None', 1)"; |
На
$sql = "INSERT INTO mappointscat VALUES(0, '$namepoint', '$descriptpoint', '$type', '$coordx', '$coordy', 'None', 1)"; |
Новый код файла addpoint.php
<?php
header('Content-Type: text/html; charset=utf-8');
include ("config.php");
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
$namepoint = $_GET['namepoint'];
if (isset($_GET['namepoint']))
{
$namepoint = $_GET['namepoint'];
if ($namepoint == '')
{
unset($namepoint);
}
}
if (isset($_GET['descriptpoint']))
{
$descriptpoint = $_GET['descriptpoint'];
if ($descriptpoint == '')
{
unset($descriptpoint);
}
}
$type = $_GET['type'];
$pcoord = $_GET['pcoord'];
if (isset($namepoint) && isset($descriptpoint))
{
$namepoint = htmlspecialchars(trim($namepoint));
$descriptpoint = htmlspecialchars(trim($descriptpoint));
$exp_str1 = explode(",", $pcoord);
$coordx = $exp_str1[0];
$coordy = $exp_str1[1];
$sql = "INSERT INTO mappointscat VALUES(0, '$namepoint', '$descriptpoint', '$type', '$coordx', '$coordy', 'None', 1)";
$result = mysql_query($sql) or die("Ошибочный запрос: " . mysql_error());
if($result == true)
{
echo '{ success: true }';
}
else
{
echo '{ success: false, message: "Не удалось сохранить точку" }';
}
}
else
{
echo '{ success: false, message: "Вы ввели не всю информацию, поэтому метка не может быть добавлена" }';
}
}
?> |
Введем для примера несколько точек.

Теперь будем реализовывать вывод точек по категориям.
В начале рядом с картой добавим три ссылки для выбора категорий.
Поместим область с картой в таблицу.
В результате в разделе body будет следующий код:
<table>
<tr>
<td>
<div id="YMapsID" style="width:800px;height:600px"></div>
<div id="scriptmes"></div>
</td>
<td valign="top">
<ul id="menu">
<li><a href="#" id="bar" onclick="show_c('bar'); return false;">Бар</a></li>
<li><a href="#" id="restaurant" onclick="show_c('restaurant'); return false;">Ресторан</a></li>
<li><a href="#" id="cafe" onclick="show_c('cafe'); return false;">Кафе</a></li>
</ul>
</td>
</tr>
<table> |
Добавим еще стили.
<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> |
После этого мы добавляем функцию show_c для вывода меток для определенной категории.
function show_c(c){
YMaps.jQuery('#obj a').removeClass("active");
map.removeAllOverlays();
//Запрос данных и вывод маркеров на карту
YMaps.jQuery.getJSON("vivodpointsmap_echo2.php", {cat:c},
function(json){
for (i = 0; i < json.markers.length; i++) {
var placemark=new YMaps.Placemark(new YMaps.GeoPoint(json.markers[i].lat,json.markers[i].lng));
if(c == "bar"){placemark.setStyle("default#barIcon")};
if(c== "restaurant"){placemark.setStyle("default#restaurauntIcon")};
if(c== "cafe"){placemark.setStyle("default#cafeIcon")};
placemark.description= '<div style="color:#ff0303;font-weight:bold">'+json.markers[i].name+'</div>';
placemark.description = placemark.description+'<strong>Описание:</strong> '+json.markers[i].descriptions+'<br />Категория: '+json.markers[i].type;
map.addOverlay(placemark);
}
});
YMaps.jQuery('a#'+c).addClass("active");
return false;
} |
И удаляем код обращения к файлу vivodpointsmap.php между строчками
map.enableScrollZoom(); и var myLayout = function (geoPoint) {
Рассмотрим функцию show_c подробнее.
В нее мы передаем параметр с названием категории c.
После этого, ссылку по которой произошел клик мы делаем не активной.
Удаляем все оверлеи с карты.
Делаем запрос к файлу vivodpointsmap.php передавая ему в качестве параметра наименование категории.
Затем полученный ответ в формате JSON мы обрабатываем и выводим метки для данной категории на карту.
А ссылку делаем активной.
И нам нужно немного изменить файл vivodpointsmap.php
Добавить строку $type = $_GET[‘cat’]; для получения переданного параметра наименования категории.
Из таблицы базы данных мы выбираем значения только для данной категории.
И формируем ответ в формате JSON.
Новый код файла vivodpointsmap.php
<?php
header('Content-Type: text/html; charset=utf-8');
include ("config.php");
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
//Сохранение русских букв(кирилицы) при использовании json_encode()
function json_encode_cyr($str) {
$arr_replace_utf = array('u0410', 'u0430','u0411','u0431','u0412','u0432',
'u0413','u0433','u0414','u0434','u0415','u0435','u0401','u0451','u0416',
'u0436','u0417','u0437','u0418','u0438','u0419','u0439','u041a','u043a',
'u041b','u043b','u041c','u043c','u041d','u043d','u041e','u043e','u041f',
'u043f','u0420','u0440','u0421','u0441','u0422','u0442','u0423','u0443',
'u0424','u0444','u0425','u0445','u0426','u0446','u0427','u0447','u0428',
'u0448','u0429','u0449','u042a','u044a','u042d','u044b','u042c','u044c',
'u042d','u044d','u042e','u044e','u042f','u044f');
$arr_replace_cyr = array('А', 'а', 'Б', 'б', 'В', 'в', 'Г', 'г', 'Д', 'д', 'Е', 'е',
'Ё', 'ё', 'Ж','ж','З','з','И','и','Й','й','К','к','Л','л','М','м','Н','н','О','о',
'П','п','Р','р','С','с','Т','т','У','у','Ф','ф','Х','х','Ц','ц','Ч','ч','Ш','ш',
'Щ','щ','Ъ','ъ','Ы','ы','Ь','ь','Э','э','Ю','ю','Я','я');
$str1 = json_encode($str);
$str2 = str_replace($arr_replace_utf,$arr_replace_cyr,$str1);
return $str2;
}
$type = $_GET['cat'];
$result = mysql_query("SELECT * FROM mappointscat WHERE type='$type'");
if(mysql_num_rows($result)>0)
{
while ($mar = mysql_fetch_array($result))
{
if($mar['type'] == 'bar') {$cattype = "Бар";}
if($mar['type'] == 'restaurant') {$cattype = "Ресторан";}
if($mar['type'] == 'cafe') {$cattype = "Кафе";}
$json = array(name=>$mar['name'], descriptions=>$mar['descriptions'], type=>$cattype, lat=>$mar['cx'], lng=>$mar['cy']);
$markers[] = $json;
}
}
$points = array(markers=>$markers);
echo json_encode_cyr($points );
}
?> |
Если Вы формируете ответ через функцию echo
<?php
header('Content-Type: text/html; charset=utf-8');
include ("config.php");
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
$json = '{"markers" :['."n";
$type = $_GET['cat'];
$result = mysql_query("SELECT * FROM mappointscat WHERE type='$type'");
if(mysql_num_rows($result)>0)
{
while ($mar = mysql_fetch_array($result))
{
if($mar['type'] == 'bar') {$cattype = "Бар";}
if($mar['type'] == 'restaurant') {$cattype = "Ресторан";}
if($mar['type'] == 'cafe') {$cattype = "Кафе";}
$json = $json.'{"name" : "'.$mar['name'].'", "descriptions" : "'.$mar['descriptions'].'", "type":"'.$cattype.'", "lat" : "'.$mar['cx'].'", "lng" : "'.$mar['cy'].'"},';
}
}
$json = substr($json , 0,-1);
echo $json , ']}';
}
?> |
Посмотрим работу примера в действии.
Щелкая по карте, вы получаете форму для ввода параметров метки, с возможностью указания категории.
Уже сохраненные значения меток по категориям, можно вывести, нажав на соответствующую ссылку с права от карты.
Код измененного файла vivodpoints.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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Яндекс.Карта на Вашем сайте с возможностью добавления меток пользователями. Новая версия</title>
<script src="http://api-maps.yandex.ru/1.1/index.xml?key=ACuF2EkBAAAAzahYCgIASLsFm9n8EPvNjaTc8nAWiETKgYcAAAAAAAAAAAC-q61vWtIK3Kzt2yQ9qFaGJGKzXw==" type="text/javascript"></script>
<script type="text/javascript">
var map;
window.onload = function () {
map = new YMaps.Map(document.getElementById("YMapsID"));
map.setCenter(new YMaps.GeoPoint(43.99150,56.31534), 12);
map.addControl(new YMaps.TypeControl());
map.addControl(new YMaps.ToolBar());
map.addControl(new YMaps.Zoom());
map.addControl(new YMaps.ScaleLine());
map.enableScrollZoom();
var myLayout = function (geoPoint) {
var $element = YMaps.jQuery('<div>Название: <input type="text" id="name"/><br />Описание: <textarea id="descriptpoint" cols="20" rows="5"></textarea><br />Категория: <select id="type"><option value="bar" SELECTED>Бар</option><option value="restaurant">Ресторан</option><option value="cafe">Кафе</option></select><br /><input type="button" value="Добавить" id="submit"/></div>');
this.onAddToParent = function (parent) {
$element.find('#submit').bind('click', function () {
YMaps.jQuery.ajax({
url: 'addpoint2.php',
data: {
namepoint: $element.find('#name')[0].value,
descriptpoint: $element.find('#descriptpoint')[0].value,
type: $element.find('#type option:selected')[0].value,
pcoord: geoPoint.toString()
},
dataType: 'json',
// Это функция обработки ответа сервера
success: function (res) {
if (res.success) {
// если точка сохранилась, закрываем балун
map.closeBalloon();
// и ставим точку на карту
map.addOverlay(new YMaps.Placemark(geoPoint));
} else {
YMaps.jQuery("#scriptmes").html('<p style="color:red">' + e.message + '</p>');
}
}
});
});
$element.appendTo(parent);
};
this.onRemoveFromParent = function () {
$element.remove();
};
this.update = function () {};
}
YMaps.Events.observe(map, map.Events.Click, function (map, e) {
map.openBalloon(e.getCoordPoint(), new myLayout(e.getCoordPoint()));
});
}
function show_c(c){
YMaps.jQuery('#obj a').removeClass("active");
map.removeAllOverlays();
//Запрос данных и вывод маркеров на карту
YMaps.jQuery.getJSON("vivodpointsmap_echo2.php", {cat:c},
function(json){
for (i = 0; i < json.markers.length; i++) {
var placemark=new YMaps.Placemark(new YMaps.GeoPoint(json.markers[i].lat,json.markers[i].lng));
if(c == "bar"){placemark.setStyle("default#barIcon")};
if(c== "restaurant"){placemark.setStyle("default#restaurauntIcon")};
if(c== "cafe"){placemark.setStyle("default#cafeIcon")};
placemark.description= '<div style="color:#ff0303;font-weight:bold">'+json.markers[i].name+'</div>';
placemark.description = placemark.description+'<strong>Описание:</strong> '+json.markers[i].descriptions+'<br />Категория: '+json.markers[i].type;
map.addOverlay(placemark);
}
});
YMaps.jQuery('a#'+c).addClass("active");
return false;
}
</script>
</head>
<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>
<body>
<table>
<tr>
<td>
<div id="YMapsID" style="width:800px;height:600px"></div>
<div id="scriptmes"></div>
</td>
<td valign="top">
<ul id="menu">
<li><a href="#" id="bar" onclick="show_c('bar'); return false;">Бар</a></li>
<li><a href="#" id="restaurant" onclick="show_c('restaurant'); return false;">Ресторан</a></li>
<li><a href="#" id="cafe" onclick="show_c('cafe'); return false;">Кафе</a></li>
</ul>
</td>
</tr>
<table>
</body>
</html> |
Все супер, СПАСИБО! Вот на сайте http://vostokblog.com/informacija/map.html добавил еще категорий.
Автор пожалуйста добавьте возможность удалять метки непосредственно на карте!
Очень круто а вы не могли бы написать про добавление в балун медиа контента например видео или фотографий я думаю такая возможность многим бы пригодилась
или как вариант про добавление произвольного HTML код пользователем
Надо подумать над этим
Спасибо за статью, пожалуй, это единственное в интернете решение моей проблемы. Вы не могли бы кинуть на мою почту архив с файлами, использующимися для создания карты-обращения к базе-добавления меток? История создания вашего шедевра разбросана по трем заметкам, копировать код по кускам и вносить изменения довольно сложно.
Эти config.php; vivodpoints.html; addpoint.php; vivodpointsmap.php ? Из заметки «Яндекс.Карта на Вашем сайте с возможностью добавления меток пользователями. Новая версия»
Сделал 2 проекта по Вашему описанию, спасибо!
http://avtosfera.info/dorogi-buryatii/
http://grigpetr.ru/karta/
Добрый день, сделал всё как написано, но когда жму на карту выскакивает балун, я его заполняю жму добавить и ничего не происходит (балун не закрывается).
P.S. Локальный сервер XAMPP
Запустите пример в браузере Firefox и посмотрите консоль ошибок. Еще можно установить расширение Firebug.
>Добрый день, сделал всё как написано, но когда жму на карту выскакивает балун, я его заполняю жму добавить и ничего не происходит (балун не закрывается).
Добрый день!
Тоже самое получается и у меня( Автор помогите, если можно.
Присоединяюсь к вопросу. Балун не закрывается, точка не добавляется.
Но автору огромная благодарность за статью и подробное разжевывание!!!
Надо в файле карты vivodpoints.html прописать полный путь к файлам addpoint2.php и vivodpointsmap_echo2.php.
Если они лежат в том же каталоге maps, тогда для файла addpoint2.php полный путь будет http://www.vyborg-portal.com/maps/addpoint2.php, а для vivodpointsmap_echo2.php — http://www.vyborg-portal.com/maps/vivodpointsmap_echo2.php
Разобрался.
В vivodpointsmap.html указаны строки:
url: ‘addpoint2.php’
YMaps.jQuery.getJSON(«vivodpointsmap_echo2.php», {cat:c},
А в статье указаны имена: vivodpointsmap и addpoint.php
Соответственно, меняем в коде названия файлов:
url: ‘addpoint.php’
YMaps.jQuery.getJSON(«vivodpointsmap.php», {cat:c},
И все работает.
Спасибо автору!!!
У меня проблема. когда ввожу в балун многострочную информацию то потом не отображается метки всей категории.
Я уже исправил ошибку, надо до вывода данных в формате JSON добавить строку
$descriptions = str_replace(«n», «», $mar[‘descriptions’]);,
т.е. заменить все переводы строк на тег «».
И дальше в коде в место $mar[‘descriptions’] использовать $descriptions.
Наверное, не $descriptions = str_replace(«n», «», $mar[‘descriptions’]);, а
$descriptions = str_replace(«n», «», $mar[‘descriptions’]);
Хм, у вас в комментариях вырезаются HTML теги. Хотел в пустые кавычки вписать br, но его вырезало. Видимо у вас тоже:-)
Уже пол-дня сижу, перепробовал всё, что тут написано, но хоть тресни — балун не закрывается, метка не ставится… Автор, есть какие-то соображения?
Аналогично, проверить путь к файлу addpoint.php
А как сделать чтобы генерировалась ссылка для вставки карты на форум?
А как добавить новые категории? В нескольких местах по добовлял но в балу все равно нету новой категории.
Для добавления новой категории необходимо:
1. Добавить новую категорию в форму добавления метки, изменить сроку
var $element = YMaps.jQuery('<div>Название: <input type="text" id="name"/><br />Описание: <textarea id="descriptpoint" cols="20" rows="5"></textarea><br />Категория: <select id="type"><option value="bar" SELECTED>Бар</option><option value="restaurant">Ресторан</option><option value="cafe">Кафе</option></select><br /><input type="button" value="Добавить" id="submit"/></div>');Например, добавить категорию кинотеатры, тогда строка будет иметь вид:
var $element = YMaps.jQuery('<div>Название: <input type="text" id="name"/><br />Описание: <textarea id="descriptpoint" cols="20" rows="5"></textarea><br />Категория: <select id="type"><option value="bar" SELECTED>Бар</option><option value="restaurant">Ресторан</option><option value="cafe">Кафе</option><option value="cinima">Кинотеатр</option></select><br /><input type="button" value="Добавить" id="submit"/></div>');2. Изменить код файла vivodpointsmap.php, добавив после строки
if($mar['type'] == 'cafe') {$cattype = "Кафе";}Строчку
if($mar['type'] == 'cinima') {$cattype = "Кинотеатр";}3. Изменить функцию show_c(c) в файле vivodpoints-2.html, добавив после строки
if(c== "cafe"){placemark.setStyle("default#cafeIcon")};строчку
if(c== "cinima"){placemark.setStyle("default#cinemaIcon")}; - мы определяем стиль для обозначения меток новой категории Кинотеатр.4. Добавить новый пункт в меню карты.
После строки
<li><a href="#" id="cafe" onclick="show_c('cafe'); return false;" rel="nofollow">Кафе</a></li>Добавить
<li><a href="#" id="cinima" onclick="show_c('cinima'); return false;" rel="nofollow">Кинотеатр</a></li>И как сделать чтобы по умолчанию все объекты из всех категорий показывались на карте?
А то человек открывает пустую карту и не каждый додумается что можно нажать на категорию чтоб появились объекты.
Все просто, надо в основной функции после добавления элементов управления на карту, добавить три строки вызова функции вывода меток категории на карту:
show_c(‘bar’);
show_c(‘restaurant’);
show_c(‘cafe’);
Пример
Ага, я не добавил как надо было в первом пункте, а в остальных добавлял)
Еще раз спасибо, все отлично работает!
Начал добавлять объекты на карту и понял что у яндекса очень ограничен выбор иконок. У гугла например намного больше ассортимент вот тут http://mapicons.nicolasmollet.com/category/markers/.
Как не будь возможно поставить свои картинки иконок на карту?
Создание пользовательского значка метки
Здравствуйте.
Спасибо большое за прекрасные руководства. Очень сильно помогли в вопросе возможности добавления меток пользователями сайта.
Вот только с выведением меток по категориям у меня проблемы.
Создаю в файле vivodpointsmap_echo2.php запрос к базе данных через echo, а не json_encode.
На vivodpointsmap_echo2.php выводится вроде строка с данными, а на vivodpoints.html почему-то ничего не цепляется. Карта ошибок никаких не выдает,но и меток не выводит.
В чем может быть причина?
А как заключить категории в селектор
Делаю так:
Бар
и нет реакции (((
Как быть ?
Куда именно это добавлять ?
show_c(‘bar’);
show_c(‘restaurant’);
show_c(‘cafe’);
Классно, автору огромное спасибо за блог! очень интересно!
Только почему-то в данном примере добавляются и включаются на демо странице только кафе, два других пункта вроде бы добавляются, но при переключении пропадают (
Добрый день,уважаемый админ, большое спасибо за урок. очень помог, можно вас спросить как сделать
1) при входе на сайт сразу отображались все объекты, с разными иконками,
готов заплатить если это потребуется моя почта php84@bk.ru
Автор, ты, конечно, молодец! Но не мог бы ты для слабоумных, как я, выложить исходники полноценной версии. Ну или хотя бы собрать все в одной статье, а то хрен разберешь где какая часть, запутано пипец просто…. 🙁