Поиск ближайших объектов в БД по координатам

Поиск ближайших объектов в БД по координатам

Рассмотрим пример как найти в базе данных соседние объекты по координатам и вывести их на карте Яндекс.

В таблице `objects` хранятся записи с адресами и координатами объектов.

CREATE TABLE IF NOT EXISTS `objects` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `point` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
 
INSERT INTO `objects` (`id`, `name`, `point`) VALUES
(1, 'Тверская 9', '55.75985606898725,37.61054750000002'),
(2, 'Тверская, 20', '55.766642568974845,37.60237299999997'),
(3, 'Охотный Ряд, 1 ', '55.75805306898262,37.6160005'),
(4, 'Солянка, 16 ', '55.75061056899327,37.64180899999995');
SQL

Найдем все объекты, которые находятся рядом с записью `id` = 1 «Тверская 9» в радиусе одного километра.

В системе координат один градус равен 111 км, значит 1 км = 1 / 111 = 0,009009009009009°.

Напишем SQL запрос который найдет все объекты у которых координаты входят в требуюмыю область.

// Запись с `id` = 1
$sth = $dbh->prepare("SELECT * FROM `objects` WHERE `id` = 1");
$sth->execute();
$object = $sth->fetch(PDO::FETCH_ASSOC);
 
// Объекты рядом
$area = 1 / 111;
$cord = explode(',', $object['point']);
 
$sth = $dbh->prepare("
	SELECT 
		* 
	FROM 
		`objects` 
	WHERE 
		`id` <> {$object['id']}
		AND SUBSTRING_INDEX(`point`, ',', 1) BETWEEN {$cord[0]} - {$area} AND {$cord[0]} + {$area} 
		AND SUBSTRING_INDEX(`point`, ',', -1) BETWEEN {$cord[1]} - {$area} AND {$cord[1]} + {$area}
	ORDER BY 
		`name`
");
 
$sth->execute();
$list = $sth->fetchAll(PDO::FETCH_ASSOC);
PHP

Выведем найденные метки синим цветом:

<div id="map" style="width: 100%; height:500px"></div>
 
<script src="http://api-maps.yandex.ru/2.1/?lang=ru-RU" type="text/javascript"></script>
<script type="text/javascript">
ymaps.ready(init);
function init() {
	var myMap = new ymaps.Map("map", {
		center: [<?php echo $object['point']; ?>],
		zoom: 16
	}, {
		searchControlProvider: 'yandex#search'
	});
 
	var myCollection = new ymaps.GeoObjectCollection(); 
 
	// Добавим метку красного цвета.
	var myPlacemark = new ymaps.Placemark([
		<?php echo $object['point']; ?>
	], {
		balloonContent: '<?php echo $object['name']; ?>'
	}, {
		preset: 'islands#icon',
		iconColor: '#ff0000'
	});
	myCollection.add(myPlacemark);
 
	// Добавим найденные метки.
	<?php foreach ($list as $row): ?>
	var myPlacemark = new ymaps.Placemark([
		<?php echo $row['point']; ?>
	], {
		balloonContent: '<?php echo $row['name']; ?>'
	}, {
		preset: 'islands#icon',
		iconColor: '#0000ff'
	});
	myCollection.add(myPlacemark);
	<?php endforeach; ?>
 
	myMap.geoObjects.add(myCollection);
	
	// Сделаем у карты автомасштаб чтобы были видны все метки.
	myMap.setBounds(myCollection.getBounds(),{checkZoomRange:true, zoomMargin:9});
}
</script>
HTML

Результат:

17.09.2019
10235

Комментарии

, чтобы добавить комментарий.

Другие публикации

Получить фото из Instagram без API
Так как Instagram и Fasebook ограничили доступ к API, а фото с открытого аккаунта всё же нужно периодически получать и...
24707
+7
Счетчик просмотров страниц с графиком
Для примера возьмем статейный сайт, на нём нужно сделать счетчик просмотров статей, с выводом результатов за день,...
19412
+23
Примеры использования PDO MySQL
В статье приведены основные примеры работы с расширением PHP PDO. Такие как подключение к БД, получение, изменение и...
104250
+8
База городов, регионов и федеральных округов РФ в MySQL
База состоит из трех связанных таблиц, версия от 2016 года.
35905
+5
PHP-класс обертка для PDO
Класс значительно упрощает работу с PDO, сокращает код. Реализован на статических классах и не требует создание экземпляра класса.
23030
+11
Список станций Московского метрополитена в PHP-массиве и SQL
Всего 300 станций включая монорельс и МЦК.
11166
+5