В этой заметке я хочу рассказать Вам, как можно организовать поиск по своим данным о метках с использованием PHP и MySQL.
Я в своем примере буду использовать данные по некоторым агентствам недвижимости Нижнего Новгорода.
В начале нам необходимо в базе данных MySQL создать таблицу mymetki_ymap, для хранения данных о наших метках.
Сделать это можно используя phpMyAdmin с помощью SQL-запроса:
CREATE TABLE IF NOT EXISTS `mymetki_ymap` ( `id` int(5) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `adress` varchar(255) NOT NULL, `phone` varchar(255) NOT NULL, `lat_map` varchar(255) NOT NULL, `lng_map` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
Поясню значение полей таблицы:
name — служит для хранения наименования организации;
address – здесь хранится адрес расположения организации;
phone — телефоны;
lat_map и lng_map — для хранения значений долготы и широты соответственно
Также используя phpMyAdmin заполним нашу таблицу mymetki_ymap исходными данными:
INSERT INTO `mymetki_ymap` (`id`, `name`, `adress`, `phone`, `lat_map`, `lng_map`) VALUES (1, 'Абзац ', 'Нижний Новгород, Совнаркомовская,25', '8-915-955-98-95', '43.956211', '56.324411'), (2, 'Абсолют-НН ', 'Нижний Новгород, пр.Кораблестроителей,26/1', '(831) 227-06-35', '43.810935', '56.363608'), (3, 'Аверс ', 'Нижний Новгород, Рождественская,24-13', '(831) 430-06-89', '43.988047', '56.327655'), (4, 'Какаду ', 'Нижний Новгород, ул. Гордеевская, 7, ул. Б. Печерская, 83', '(831) 220-31-17, 220-31-18, 277-26-81, 432-71-97', '43.943006', '56.326348'), (5, 'Алые паруса ', 'Нижний Новгород, пл.Театральная,5/Пискунова,6', '(831) 419-60-63, 419-57-05', '44.000426', '56.323987'), (6, 'Альфа недвижимость ', 'Нижний Новгород, Сергея Есенина,32', '(831) 414-55-17, 249-60-02', '43.934382', '56.334867'), (7, 'Альфа Риэлти ', 'Нижний Новгород, Чаадаева,5-320', '(831) 274-58-51,413-20-71', '43.854378', '56.329188'), (8, 'Берегиня+ ', 'Нижний Новгород, Адмирала Васюнина,2-212', '(831) 417-55-26,417-41-41', '44.039053', '56.296729'), (9, 'Благовест ', 'Нижний Новгород, Берёзовская,22', '(831) 274-22-70,413-23-59', '43.881471', '56.318651'), (10, 'Благострой ', 'Нижний Новгород, Кошелева,2', '(831) 279-50-49', '43.888873', '56.314966'), (11, 'Большой город ', 'Нижний Новгород, Максима Горького,184', '(831) 439-12-78, 411-96-40', '44.017907', '56.318895'), (12, 'Ваш жилой континет ', 'Нижний Новгород, Маршала Воронова,3', '(831) 413-94-11,275-49-74', '43.926647', '56.323573'), (13, 'Гарант плюс ', 'Нижний Новгород, Лескова,18', '(831) 256-36-65,259-10-46', '43.862768', '56.235931'), (14, 'Гарант риэлти ', 'Нижний Новгород, Варварская,32-414', '(831) 419-81-59,419-81-55', '44.012876', '56.321281'), (15, 'Геосфера ', 'Нижний Новгород, Полтавская,14-401', '(831) 438-35-35,416-70-94', '44.025273', '56.316634'), (16, 'Дом-52 ', 'Нижний Новгород, пр.Гагарина,110в', '(831) 278-94-66,278-94-64,413-54-25', '43.977968', '56.270621'), (17, 'Единство ', 'Нижний Новгород, Рождественская,28а', '(831) 430-50-80,439-77-01,439-77-02', '43.986834', '56.327750'), (18, 'Жилсервис-НН ', 'Нижний Новгород, пр.Октября,15', '(831) 295-55-83', '43.864825', '56.250272'), (19, 'Заречье ', 'Нижний Новгород, пер.Райниса,1-3', '(831) 413-62-00,257-99-79,258-50-63', '43.917547', '56.265852'), (20, 'ЗемСтрой ', 'Нижний Новгород, Максима Горького,151', '(831) 419-42-12,414-12-21', '44.018482', '56.318246'), (21, 'Золотое руно ', 'Нижний Новгород, Баранова,9а', '(831) 410-82-90', '43.845691', '56.335236'), (22, 'Золотой ключик ', 'Нижний Новгород, Родионова,191', '(831) 438-47-94,413-97-61', '44.079046', '56.303481'), (23, 'Император ', 'Нижний Новгород, Октябрьской Революции,56', '(831) 245-01-04,240-03-81', '43.937391', '56.309893'), (24, 'Камелот Риэлти ', 'Нижний Новгород, Красных Зорь,25-1', '(831) 272-18-88,413-51-18', '43.867394', '56.333395'), (25, 'Квадри НН ', 'Нижний Новгород, Октябрьская,27-4', '(831) 434-03-97', '44.084634', '56.293277'), (26, 'Квартирный вопрос ', 'Нижний Новгород, Культуры,5', '(831) 215-06-83', '43.857872', '56.349629'), (27, 'Кворум ', 'Нижний Новгород, Мечникова,39', '(831) 276-77-40,271-68-83', '43.839286', '56.336403'), (28, 'Континет ', 'Нижний Новгород, Переходникова,29', '(831) 253-75-55', '43.899527', '56.262632'), (29, 'Кредо ', 'Нижний Новгород, пр.Ленина,58', '(831) 258-49-29,244-93-86', '43.922057', '56.275404'), (30, 'Ларец ', 'Нижний Новгород, Бориса Корнилова,8', '(831) 413-09-22,417-82-92,417-73-13', '44.044344', '56.299676'), (31, 'Лига Лайн ', 'Нижний Новгород, Зайцева,31-718', '(831) 414-29-90', '43.801377', '56.373734'), (32, 'Титан ', 'Нижний Новгород, Долгополова,24', '(831) 414-28-75,246-52-52', '43.946850', '56.319110'), (33, 'Титул ', 'Нижний Новгород, пр.Героев,19', '(831) 270-08-33', '43.893508', '56.318106'), (34, 'Уют-компания ', 'Нижний Новгород, пр.Октября,8-9', '(831) 295-06-47', '43.865274', '56.246891'), (35, 'Александр Невский ', 'Нижний Новгород, пр.Ленина,56-37', '8-920-059-59-99', '43.922263', '56.276024'); |
Затем организуем поиск по таблице в базе данных.
YmapsML-файл формировать будем с помощью файла creat-ymapsml-avtosal.php
Код файла:
<?php header("Content-type: text/xml"); include("bd.php"); echo '<ymaps xmlns="http://maps.yandex.ru/ymaps/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"> <Representation xmlns="http://maps.yandex.ru/representation/1.x"> <Style gml:id="agentnedv"> <iconStyle> <href>http://api-maps.yandex.ru/i/0.4/icons/buildings.png</href> <size x="27" y="26"/> <offset x="-13" y="-13"/> </iconStyle> <balloonContentStyle> <template>#balloonTemplate</template> </balloonContentStyle> </Style> <Template gml:id="balloonTemplate"> <text><![CDATA[ <div style="font-size:12px;"> <div style="color:#ff0303;font-weight:bold">$[name]</div> <div>Адрес: $[metaDataProperty.AnyMetaData.adres|не задан]</div> <div>Телефон: $[metaDataProperty.AnyMetaData.telefon|не задан]</div> </div>]]></text> </Template> </Representation> <GeoObjectCollection> <gml:name>Объекты карте</gml:name> <style>#agentnedv</style> <gml:featureMembers>'; $query1= "SELECT * FROM mymetki_ymap"; $result1 = mysql_query($query1); while ($par1 = mysql_fetch_array($result1)) { echo '<GeoObject>'; echo '<gml:name>', $par1['name'], '</gml:name>'; echo '<gml:metaDataProperty>'; echo '<AnyMetaData>'; echo '<adres>', $par1['adress'], '</adres>'; echo '<telefon>', $par1['phone'], '</telefon>'; echo '</AnyMetaData>'; echo '</gml:metaDataProperty>'; echo '<gml:Point>'; echo '<gml:pos>', $par1['lat_map'], ' ', $par1['lng_map'], '</gml:pos>'; echo '</gml:Point>'; echo '</GeoObject>'; echo "n"; } echo '</gml:featureMembers> </GeoObjectCollection> </ymaps>'; ?> |
В начале мы объявляем тип файла для браузера text/xml.
Затем подключаем файл bd.php для соединения с базой данных:
<?php $sdb_name = "localhost"; $user_name = "user"; $user_password = "user123"; $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'); ?> |
После с помощью оператора echo формируем YMapsML-файл.
Задаем стиль agentnedv для отображения значка метки iconStyle и шаблон содержимого балуна balloonTemplate
Выбираем данные из таблицы mymetki_ymap и формируем объекты геоколлекции.
Подробнее о формате YmapsML можно прочитать в документации
Файл vivagentnedv-ymap.html будет выводить карту с метками из файла YmapsML.
Код:
<!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>Поиск по своим меткам на Яндекс.Карте с использованием PHP и 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=ANpUFEkBAAAAf7jmJwMAHGZHrcKNDsbEqEVjEUtCmufxQMwAAAAAAAAAAAAvVrubVT4btztbduoIgTLAeFILaQ==~AMSxmUwBAAAA5WSyQAMAwB5YJ3rvTgSgDcPJynaIsXvmUkYAAAAAAAAAAABv1IbpHjj4ZIFUHyMRhnQtZxjXZg==" 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), 12); map.addControl(new YMaps.Zoom()); map.addControl(new YMaps.TypeControl()); map.addControl(new YMaps.ToolBar()); // Создание и добавление YMapsML-документа на карту var ml = new YMaps.YMapsML("http://map.cek.ru/files/fs/creat-ymapsml-agentnedv.php"); map.addOverlay(ml); // Обработчик неудачной загрузки YMapsML YMaps.Events.observe(ml, ml.Events.Fault, function (ml, error) { alert('Ошибка: ' + error); }); }); </head> <body> <table> <tr> <td style="vertical-align:top; "> <div id="YMapsID" style="width:500px;height:400px"></div> </td> <td style="vertical-align:top; "> <strong>Поиск поставщиков агенств недвижимости по карте:</strong> <form action="#" method="POST" onSubmit="do_search(this.company.value); return false;"> <input type="text" id="company" name="company" size="30" value="" /><br> <em>например: Абзац</em> <p><input type="submit" value="Найти" /></p></form> <div id="search_res"></div> </td> </tr> </table></p> </body> </html> |
В разделе body расположена таблица в одной ячейке отображается карта , в другой форма поиска с контейнером для результатов.
Замечание: если Вы будете выполнять пример на локальном компьютере нужно чтобы creat-ymapsml-agentnedv.php был доступен из Интернета, т. к. содержимое файла YmapsML обрабатывается сервером Яндекса.
Для осуществления поиска мы добавим в код файла vivagentnedv-ymap.html функцию do_search.
Код функции:
function do_search(company){ map.removeAllOverlays(); YMaps.jQuery('#search_res').html(''); YMaps.jQuery.getJSON("http://map.cek.my/files/fs/searcheagentnedv.php", {company:company}, function(json){ if (json.status == 'OK') { var src_res="<p><strong>результаты поиска: </strong></p>"; src_res=src_res+'<p><strong>Найдено объектов: '+json.markers.length+'</strong></p>'; for (i = 0; i < json.markers.length; i++) { var placemark=new YMaps.Placemark(new YMaps.GeoPoint(json.markers[i].lat,json.markers[i].lon)); placemark.description='<div style="color:#ff0303;font-weight:bold">'+json.markers[i].cname+'</div>'; placemark.description=placemark.description+'<strong>Адрес:</strong> '+json.markers[i].address+'<br><strong>Телефон:</strong> '+json.markers[i].phone; map.addOverlay(placemark); src_res=src_res+'<p><a href="#" onClick="return go_to('+json.markers[i].lat+', '+json.markers[i].lon+",'"+json.markers[i].cname+"','"+json.markers[i].address+"','"+json.markers[i].phone+"','"+json.markers[i].id+"');"+'">'+json.markers[i].cname+'</a><br>'+json.markers[i].address+'</p>'; } } else { var src_res = '<p><strong>результаты поиска</strong></p><font color="red">По Вашему запросу объектов на карте не найдено</font>'; } YMaps.jQuery('#search_res').html(src_res); }); } |
В качестве параметра функции выступает company — название компании из формы поиска.
В функции do_search в начале мы удаляем все оверлеи с карты с помощью
map.removeAllOverlays() и очищаем контейнер с результатами поиска Ymaps.jQuery(‘#search_res’).html(‘ ‘);
После мы осуществляем AJAX запрос к файлу searcheagentnedv.php используя функцию getJSON с
помощью встроенной в API Яндекс.Карт JavaScript-библиотеки jQuery.
В файле searcheagentnedv.php мы осуществляем запрос к базе данных для поиска и формируем файл формата JSON с результатами поиска.
Подробнее о формате JSON можно прочитать здесь
В месте с данными о найденных метках передается параметр успешности поиска status, если он равен OK, то мы обрабатываем переданные значения — наносим найденные метки на карту и выводим список со ссылками в контейнер результатов поиска search_res.
Если поиск завершился неудачно, выводится сообщение: «По Вашему запросу объектов на карте не найдено».
По клику по названию метки в списке результатов поиска вызывается функция go_to — происходит центрирование карты по координатам данной метки и открывается балун с информацией.
Код функции:
function go_to(lat,lon,cname,address,phone,id){ map.setCenter(new YMaps.GeoPoint(lat,lon),17); map.removeAllOverlays(); var placemark=new YMaps.Placemark(new YMaps.GeoPoint(lat,lon)); placemark.name='<div style="color:#ff0303;font-weight:bold">'+cname+'</div>'; placemark.description='<div><strong>Адрес:</strong> '+address+'<br><strong>Телефон:</strong> '+phone+'</div>'; map.addOverlay(placemark); placemark.openBalloon(); return false; } |
Теперь приведу код файла searcheagentnedv.php, который осуществляет запрос к базе данных и формирует результаты поиска в формате JSON:
Код
<?php include("bd.php"); header('Content-Type: text/html; charset=utf-8'); if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') { $company = $_GET['company']; $name_remont = htmlspecialchars(trim($company)); $json = '{markers:['."n"; $query1= "SELECT * FROM mymetki_ymap where name LIKE '%$name_remont%' ORDER BY name"; $result1 = mysql_query($query1); if(mysql_num_rows($result1)>0) { while ($par1 = mysql_fetch_array($result1)){ $cname = htmlspecialchars($par1['name']); $json.= "n".'{'.'"id": "'.$par1['id'].'",'; $json.= '"cname": "'.$cname.'",'; $json.= '"address": "'.$par1['adress'].'",'; $json.= '"phone": "'.$par1['phone'].'",'; $json.= '"lat": "'.$par1['lat_map'].'",'; $json.= '"lon": "'.$par1['lng_map'].'"'; $json.= '},'; } $json = substr($json, 0,-1); echo $json; echo '], ', "n", '"status": "OK"', "n", '}'; } else { echo '{"status": "false"}'; } } ?> |
Вид JSON-файла с результатами поиска (запрос: альфа):
{markers:[
{"id": "6","cname": "Альфа недвижимость ","address": "Нижний Новгород, Сергея Есенина,32","phone": "(831) 414-55-17, 249-60-02","lat": "43.934382","lon": "56.334867"},
{"id": "7","cname": "Альфа Риэлти ","address": "Нижний Новгород, Чаадаева,5-320","phone": "(831) 274-58-51,413-20-71","lat": "43.854378","lon": "56.329188"}],
"status": "OK"
}
В коде файла searcheagentnedv.php все предельно ясно.
Проверяем как отправлено значение переменной company, если через AJAX, то $_SERVER[‘HTTP_X_REQUESTED_WITH’] == ‘XMLHttpRequest’.
Мы получаем переданные методом GET данные, удаляем из строки $company лишние пробелы и производим преобразование спецсимволов в их HTML эквиваленты, на всякий случий, если кто-то захочет в нашу форму написать какой-либо код.
Затем мы посылаем запрос к таблице mymetki_ymap и если результат найден с помощью оператора echo формируем содержимое JSON-файла.
Если результат не найден, отправляем строку {"status": "false"}.
У YMaps.SearchControl (http://api.yandex.ru/maps/jsapi/doc/ref/reference/searchcontrol.xml) можно указать опции геокодирования. Одна из них, позволяет переопределить используемый сервис геокодирования — geocodeProvider. Для этого нужно реализовать несложный интерфейс YMaps.IGeocodeProvider (http://api.yandex.ru/maps/jsapi/doc/ref/reference/igeocodeprovider.xml).
Таким образом, вы можете «научить» SearchControl искать по своей базе объектов, а если в базе ничего не было найдено, то пробовать произвести обычное геокодирование.
Думаю, что это будет неплохим продолжением вашей статьи.
Большое спасибо авторам за объемную работу по кластерам, очень полезные скрипты, а самое главное работают без отказно!!! РЕСПЕКТ!
Подскажите пож-та, после обработки поиска можно ли выводить данные с различными иконками? например иконка кафе и кинотеатра.
можете помочь с примером? эти данные надо добавлять в вывод
JSON-файла??