После публикации заметки «Яндекс.Карта на Вашем сайте с возможностью добавления меток пользователями. Новая версия.» меня начали спрашивать, как организовать вывод меток по категориям на карту.
В этой заметке я расскажу как это сделать.
Исходный код файлов мы возьмем из уже упоминавшейся заметки «Яндекс.Карта на Вашем сайте с возможностью добавления меток пользователями. Новая версия.»:
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. Добавить новую категорию в форму добавления метки, изменить сроку
Например, добавить категорию кинотеатры, тогда строка будет иметь вид:
2. Изменить код файла vivodpointsmap.php, добавив после строки
Строчку
3. Изменить функцию show_c(c) в файле vivodpoints-2.html, добавив после строки
строчку
4. Добавить новый пункт в меню карты.
После строки
Добавить
И как сделать чтобы по умолчанию все объекты из всех категорий показывались на карте?
А то человек открывает пустую карту и не каждый додумается что можно нажать на категорию чтоб появились объекты.
Все просто, надо в основной функции после добавления элементов управления на карту, добавить три строки вызова функции вывода меток категории на карту:
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
Автор, ты, конечно, молодец! Но не мог бы ты для слабоумных, как я, выложить исходники полноценной версии. Ну или хотя бы собрать все в одной статье, а то хрен разберешь где какая часть, запутано пипец просто…. 🙁