Яндекс.Карта на Вашем сайте с возможностью добавления меток пользователями — API Яндекс.Карт v2.x Продолжение

Продолжаю рассказ о том, как можно организовать добавление меток на карту пользователями, используя API Яндекс.Карт v2.x.

В этой части я рассмотрю возможность сохранения добавленных меток в базу данных MySQL, с последующим выводом на карту.

С начала создадим в базе данных таблицу ymapapiv2_markers для хранения параметров меток.

Сделать это можно с помощью SQL-запроса:

CREATE TABLE IF NOT EXISTS `ymapapiv2_markers` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `iconText` varchar(255) NOT NULL,
  `hintText` varchar(255) NOT NULL,
  `balloonText` varchar(255) NOT NULL,
  `stylePlacemark` varchar(255) NOT NULL,
  `lat` varchar(255) NOT NULL,
  `lon` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

После этого создадим файл addmetki.php для записи данных в нашу таблицу.

<?php
 
header('Content-Type: text/html; charset=utf-8');
 
include("bd.php");
 
$iconText = htmlspecialchars($_POST['icontext']);
$hintText = htmlspecialchars($_POST['hinttext']);
$balloonText = htmlspecialchars($_POST['balloontext']);
$stylePlacemark = $_POST['styleplacemark'];
$lat = $_POST['lat'];
$lon = $_POST['lon'];
 
$sql = "INSERT INTO ymapapiv2_markers (`id`, `iconText`, `hintText`, `balloonText`, `stylePlacemark`, `lat`, `lon`) VALUES (NULL, '$iconText', '$hintText', '$balloonText', '$stylePlacemark', '$lat', '$lon');";
 
$result = mysql_query($sql) or die("Ошибочный запрос: " . mysql_error());
 
?>

В нем сначала подключаем файл bd.php для соединения с базой данных

<?php
 
$sdb_name = "localhost";
$user_name = "root";
$user_password = "";
$db_name = "ymaps_bd";
 
// соединение с сервером базы данных
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');
 
?>

Затем принимаем переданные значения и записываем их в нашу таблицу ymapapiv2_markers.

Теперь мы изменим файл с картой для передачи данных файлу addmetki.php.

После строки

stylePlacemark = $('select[@name=image] option:selected').text();

добавим код:

$("#res").load("addmetki.php", {icontext: iconText, hinttext : hintText, balloontext : balloonText, styleplacemark : stylePlacemark, lat : coords[0].toPrecision(6), lon : coords[1].toPrecision(6)});

Все параметры асинхронно методом POST мы передаем скрипту addmetki.php

Посмотреть работу примера

Организуем вывод меток из таблицы на карту.

Файл vivodpointsmap.php будет посылать запрос к таблице ymapapiv2_markers и из результат выборки отправлять в формате JSON.

Код файла vivodpointsmap.php

<?php
header('Content-Type: text/html; charset=utf-8');
 
require ("bd.php");
 
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
 
$result = mysql_query("SELECT * FROM ymapapiv2_markers");
if(mysql_num_rows($result)>0)
{
while ($mar = mysql_fetch_array($result))
{
$json =  array(icontext=>$mar['iconText'], hinttext=>$mar['hintText'], balloontext=>$mar['balloonText'], styleplacemark=>$mar['stylePlacemark'], lat=>$mar['lat'], lon=>$mar['lon']);
$markers[] = $json;
}
 
}
$points = array(markers=>$markers);
 
echo json_encode($points);
 
}
 
 
?>

А в файл отображения карты мы добавляем код

$.getJSON("vivodpointsmap.php",
function(json){
for (i = 0; i < json.markers.length; i++) {
 
var myPlacemark = new ymaps.Placemark([json.markers[i].lat,json.markers[i].lon], {
	// Свойства
	iconContent: json.markers[i].icontext, 
	hintContent: json.markers[i].hinttext,
	balloonContentBody: json.markers[i].balloontext                   
	}, {
    // Опции
  	preset: json.markers[i].styleplacemark					
  });
 
  // Добавляем метку на карту
  myMap.geoObjects.add(myPlacemark);
}
 
});

И еще одно замечание.

Хотелось чтобы в балуне можно было использовать html-код, но в тоже время нужно обеспечить безопасность.

Для этого мы используем php-скрипт для фильтрации html-тегов html_filter_class.php

Подключаем его после строки

include("bd.php");

добавив код

require_once "html_filter_class.php";

и записываем параметры фильтрации:

$tags_set = array(
 
		'h1'		=> array('id', 'class'),
		'h2'		=> array('id', 'class'),
		'h3'		=> array('id', 'class'),
		'h4'		=> array('id', 'class'),
		'h5'		=> array('id', 'class'),
		'h6'		=> array('id', 'class'),
 
		'p'			=> array('id', 'class'),
		'span'		=> array('id', 'class'),
		'a'			=> array('id', 'class', 'href'),
		'img'		=> array('id', 'class', 'src', 'alt', FALSE),
		'br'		=> array(FALSE),
		'hr'		=> array(FALSE),
 
		'strong'		=> array('id', 'class'),	
		'div'		=> array('id', 'class', 'style'),		
 
 
		'ul'		=> array('id', 'class'),
		'ol'		=> array('id', 'class'),
		'li'		=> array('id', 'class'),
 
		'table'		=> array('id', 'class'),
		'tr'		=> array('id', 'class'),
		'td'		=> array('id', 'class'),
		'th'		=> array('id', 'class'),
		'thead'		=> array('id', 'class'),
		'tbody'		=> array('id', 'class'),
		'tfoot'		=> array('id', 'class')	
 
	);	
 
	$html_filter = new html_filter();
	$html_filter->set_tags($tags_set);

Перепишем строку присвоения $balloonText

в виде

$balloonText = $html_filter->filter($_POST['balloontext']);

Посмотреть пример в действии

Загрузить архив с файлами примера

  • Гость: Добрый день! Я скачал пример (http://webmap-blog.ru/files/arhivs/add-users-ymapsapi2-pr.zip), но он у меня не работает. Метки ставятся, но при обновлении все исчезает. (Пока все на локальном компьютере на Денвере) Еще такие вопросы 1. Как добавить свои метки вместо стандартных? 2. Как сделать чтобы не добавлялось автоматически, а отправлялось на модерацию, а также можно было править метки в дальнейшем?
  • Гость: Красиво, а с категориями будет дополнение как в старой версии? Я так понимаю этот "Значок метки" и есть категория, так можно как то сделать чтоб вывести на карту все оъекты только одной категории (например кафе). Ну и этим "Значок метки" можно дать нормальные названия, а не twirl#arrowUpIcon? И еще, как задать фильтр для ссылки. Например, если у ссылки есть атрибут rel='my', то ссылка добавляется, а если атрибут другой или его вообще нет, то ссылка не добавляется. Это как защита от спама. И по картинкам, нету ограничения расширения? Чтобы не добавляли большие картинки
  • Гость: Ребята помогите не сохраняются данные в Mysql wifi.dn.ua
  • Гость: Очень бы хотелось примера с категориями, как есть для старой версии http://webmap-blog.ru/examples/ymap-ymapsml/viv-grups-menu-2.html
  • Гость: Подскажите пожалуйста как увеличить количество знаков в координатах записываемых в базу данных - в данном примере 4 знака после точки (56.3269, 44.0075), а вот как сделать чтоб было 6 знаков (56.326944, 44.007544) ???
  • Гость: Здравствуйте. А есть возможность эти метки удалять? В смысле, удалять кнопкой из балуна, к примеру? Интуитивно догадываюсь, что можно прикрутить ссылку в каждый балун, ведущую на скрипт-обработчик, передавая при этом в ней все параметры. Как-то можно это осуществить без перехода на другую страницу и без показа параметров get пользователю?
  • Гость: Подскажите чайнику. а как сделать чтобы центр карты менялсяи показывал область метки в случае когда она всего одна?
  • Steve Johnson: У меня вопрос следующего характера, почему код так странно реагирует, когда я вставляю просто на страницу элемент <select> ... при этом всё работает, но только работает одна и таже метка вне зависимости, что я выбрал! как исправить?
  • Timur: Здравствуйте, подскажите пожалуйста как реализовать получение меток с другого сервера ? допустим логика лежит на одном сервере а хтмл файл на другом как быть
  • Сергей Угольников: На сервере из исходных данных формировать файл в формате JSON или YMapsML, а на другом сервере принимать его и отображать на карте.
  • Timur: не могли бы вы ткнуть носом в какую сторону смотреть исходя из этого примера и формата json
  • Сергей: А как удалить метку?
  • Сергей: С удалением разобрался.
  • Владлен Макароф: помогите с удалением метки, как сделали?
  • Сергей: При чтении из базы свойств меток читаю также идентификатор каждой метки и присваиваю его метке на карте. При клике по метке читаю её идентификатор. Далее удаляю в базе строку с нужным id, получаю ссылку на метку и удаляю саму метку: myMap.geoObjects.remove(thisPlacemark);
  • Владлен Макароф: сделал у себя также, но все равно после удаления приходится обновлять страницу для удаления метки с карты
  • Владлен Макароф: myMap.geoObjects.remove(myPlacemark); чет не помогает:(
  • Сергей: Выложите где-нибудь код, посмотрим.
  • Владлен Макароф: http://pastebin.com/j6xfLrEf
  • Владлен Макароф: сделал так http://pastebin.com/8phdT0Wg Все удаляет, но после удаления метки приходится обновлять страницу, чтоб метка пропала с карты.... Что добавить, чтоб не обновлять страницу?
  • Сергей: А есть пример для API 2.1, а не 2.0 ? А то этот пример в 2.1 не работает.
  • вясеслав: шиномонтаж
  • вясеслав: как поставить метку?