Используем jQuery и JSON в месте с Google Maps API v3

На страницах своего блога, я уже рассказывал на примере, об использовании связки jQuery, JSON и API Google Maps v3, смотрите заметку: «Пример совместного использования Google Maps API, JSON и jQuery».

Но, тот пример слишком сложный для понимания, особенно новичкам.

В этой заметке я покажу, как можно использовать jQuery и JSON в месте с Google Maps API v3 на более простом примере.

Для начала мы подготовим файл map.json с данными, которые мы будем отображать на карту.

Он представляет из-себя обычный текстовый файл со структурой в формате JSON следующего содержания:

{
    "places": [
        {
            "title": "Кинотеатр КАРО ФИЛЬМ в ТЦ Шоколад",
            "description": "<div style="text-align:center; width: 250px;">ул. Белинского, 124<br><a rel="nofollow" href="http://www.map.cek.ru/index.php?option=com_content&view=article&id=33&Itemid=145" target="blank">Информация о кинотеатре КАРО ФИЛЬМ в ТЦ Шоколад с афишой фильмов</a></div>",
            "lat": 56.31927,
            "lng": 44.026297
        },
        {
            "title": "Кинотеатр Октябрь",
            "description": "<div style="text-align:center">ул. Большая Покровская, 51а<br><a rel="nofollow" href="http://www.map.cek.ru/index.php?option=com_content&view=article&id=27&Itemid=139" target="blank">Информация о кинотеатре Октябрь с афишой фильмов</a></div>",
            "lat": 56.31721300000001,
            "lng": 43.993976
        },
        {
            "title": "Кинотеатр Синема Парк",
            "description": "<div style="text-align:center">ул. Родионова, 187<br><a rel="nofollow" href="http://www.map.cek.ru/index.php?option=com_content&view=article&id=24&Itemid=143" target="blank"><img src="http://www.map.cek.ru/images/stories/afisha/cinema/sinemapark.jpg" width="100" height="62"></a></div>",
            "lat": 56.308056,
            "lng": 44.073827
        }
    ]
}

Здесь представлены данные о трех местах Нижнего Новгорода, кинотеатрах, в виде данных для меток и описанием в балуне, а также географическими координтатами.

Запись для каждой метки имеет следующую структуру:

— название (title);
— описание (description) — оно будет отображаться в балуне;
— значения координат (lat и lng)

Все три метки объединены в одну группу places.

Т. к. JSON формат представляет из себя набор пар ключ/значение каждый элемент которой заключен в кавычки, то нам необходимо проводить экранирование остальных кавычек с помощью символа (обратный слеш).

Теперь напишим код, который выводит данные из файла map.json на Google Maps в месте с меню.

Код файла:

<!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>Используем jQuery и JSON в месте с Google Maps API v3 - пример 1</title>
 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
 
<script type="text/javascript">
 
	var map;
 
	var arrMarkers = [];
 
	var arrInfoWindows = [];	
 
	function mapInit(){
 
		var centerCoord = new google.maps.LatLng(56.316667, 44); 
 
		var mapOptions = {
 
			zoom: 13,
 
			center: centerCoord,
 
			mapTypeId: google.maps.MapTypeId.ROADMAP
 
		};
 
		map = new google.maps.Map(document.getElementById("map"), mapOptions);
 
		//Загружаем данные в формате JSON из файла map.json
		$.getJSON("map.json", {}, function(data){
 
			$.each(data.places, function(i, item){
 
				$("#markers").append('<li><a href="#" rel="' + i + '">' + item.title + '</a></li>');
 
				var marker = new google.maps.Marker({
 
					position: new google.maps.LatLng(item.lat, item.lng),
 
					map: map,
 
					title: item.title
 
				});
 
				arrMarkers[i] = marker;
 
				var infowindow = new google.maps.InfoWindow({
 
					content: "<h3>"+ item.title +"</h3><p>"+ item.description +"</p>"
 
				});
 
				arrInfoWindows[i] = infowindow;
 
				google.maps.event.addListener(marker, 'click', function() {
 
					infowindow.open(map, marker);
 
				});
 
			});
 
		});
 
	}
 
	$(function(){
 
		//Определяем карту (добавляем маркеры, балуны и список со ссылками)
		mapInit();		
 
		// "live" отслеживает событие клика по ссылке
 
		$("#markers a").live("click", function(){
 
			var i = $(this).attr("rel");			
 
			arrInfoWindows[i].open(map, arrMarkers[i]);
 
		});
 
	});
 
</script>
 
<style type="text/css" media="screen">
 
	img { border: 0; }
 
	#map{
 
		width: 800px;
 
		height: 500px; 
 
	}
 
	#content {
 
		position: fixed;
 
		top: 10px;
 
		left: 800px;
 
		margin: 30px;
 
	}
 
</style>
 
</head>
 
<body>
 
<div id="container">
 
	<div id="header"></div>
 
	<div id="map"></div>
 
	<div id="content">	
 
	<ul id="markers"></ul>
 
	</div>
 
</div>
 
</body>
 
</html>

В самом начале перед подключением API Google Maps v3, мы подключаем JavaScript-библиотеку jQuery, с помощью ее мы будем загружать и обрабатывать данные из файла map.json.

Далее определяем глобальные переменные: map – карту, массив для хранения данных для маркеров — arrMarkers и массив с данными для балунов — arrInfoWindows.

После этого в функции mapInit определяем начальные параметры карты, а с помощью метода getJSON библиотеки jQuery, мы загружаем данные из файла map.json.

В цикле формируем массивы данных для меток и балунов.

Тут же формируем меню для перехода к отдельным меткам.

Функция без названия вызывается сразу после полной загрузки кода страницы, из нее происходит вызов функции mapInit, а также обрабатывается событие клика по ссылке из меню меток.

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

На карте расставляются метки, а с права формируется меню.

Если щелкнуть по какой-либо ссылке из меню, то на карте откроется балун с информацией об этой метке.

Из примера, мы видим, что одну метку не видно на карте после загрузки.

Для того, чтобы все метки были сразу видны, необходимо задать область видимости и предать ей координаты всех меток.

Для этого добавляем три строчки кода.

перед строкой $.getJSON("map.json", {}, function(data){

Добавляем строчку

var latlngbounds = new google.maps.LatLngBounds();

В цикле перед строкой arrMarkers[i] = marker;

Добавляем строчку

latlngbounds.extend(new google.maps.LatLng(item.lat, item.lng));

И в конце функции mapInit перед скобками });

добавляем строку для центрирования и масштабирования области с метками

map.setCenter( latlngbounds.getCenter(), map.fitBounds(latlngbounds));

Код измененого файла:

<!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>Используем jQuery и JSON в месте с Google Maps API v3 - пример 2</title>
 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
 
<script type="text/javascript">
 
	var map;
 
	var arrMarkers = [];
 
	var arrInfoWindows = [];
 
 
 
	function mapInit(){
 
		var centerCoord = new google.maps.LatLng(56.316667, 44); // Puerto Rico
 
		var mapOptions = {
 
			zoom: 13,
 
			center: centerCoord,
 
			mapTypeId: google.maps.MapTypeId.ROADMAP
 
		};
 
		map = new google.maps.Map(document.getElementById("map"), mapOptions);
 
		//Определяем область отображения меток на карте
 
		var latlngbounds = new google.maps.LatLngBounds();
 
		//Загружаем данные в формате JSON из файла map.json
 
		$.getJSON("map.json", {}, function(data){
 
			$.each(data.places, function(i, item){
 
				$("#markers").append('<li><a href="#" rel="' + i + '">' + item.title + '</a></li>');
 
				var marker = new google.maps.Marker({
 
					position: new google.maps.LatLng(item.lat, item.lng),
 
					map: map,
 
					title: item.title
 
				});
 
				//Добавляем координаты меток
				latlngbounds.extend(new google.maps.LatLng(item.lat, item.lng));
 
				arrMarkers[i] = marker;
 
				var infowindow = new google.maps.InfoWindow({
 
					content: "<h3>"+ item.title +"</h3><p>"+ item.description +"</p>"
 
				});
 
				arrInfoWindows[i] = infowindow;
 
				google.maps.event.addListener(marker, 'click', function() {
 
					infowindow.open(map, marker);
 
				});
 
			});
 
			//Центрируем и масштабируем карту так, чтобы были видны все метки
			map.setCenter( latlngbounds.getCenter(), map.fitBounds(latlngbounds));
 
		});
 
	}
 
	$(function(){
 
		//Определяем карту (добавляем маркеры, балуны и список со ссылками)
 
		mapInit();
 
 
 
		// "live" отслеживает событие клика по ссылке
 
		$("#markers a").live("click", function(){
 
			var i = $(this).attr("rel");
 
			arrInfoWindows[i].open(map, arrMarkers[i]);
 
		});
 
	});
 
</script>
 
<style type="text/css" media="screen">
 
	img { border: 0; }
 
	#map{
 
		width: 800px;
 
		height: 500px; 
 
	}
 
	#content {
 
		position: fixed;
 
		top: 10px;
 
		left: 800px;
 
		margin: 30px;
 
	}
 
</style>
 
</head>
 
<body>
 
<div id="container">
 
	<div id="header"></div>
 
	<div id="map"></div>
 
	<div id="content">	
 
	<ul id="markers"></ul>
 
	</div>
 
</div>
 
</body>
 
</html>

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

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

Если нажимать по ссылкам в меню, то открываются новые балуны, а старые не закрываются

Чтобы этого не происходило, нужно добавить еще немного кода перед строкой:

arrInfoWindows[i].open(map, arrMarkers[i]);

Строку:

for(x=0; x < arrInfoWindows.length; x++){ arrInfoWindows[x].close(); }

Код измененого примера:

<!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>Используем jQuery и JSON в месте с Google Maps API v3 - пример 3</title>
 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
 
<script type="text/javascript">
 
	var map;
 
	var arrMarkers = [];
 
	var arrInfoWindows = [];
 
 
 
	function mapInit(){
 
		var centerCoord = new google.maps.LatLng(56.316667, 44);
 
		var mapOptions = {
 
			zoom: 13,
 
			center: centerCoord,
 
			mapTypeId: google.maps.MapTypeId.ROADMAP
 
		};
 
		map = new google.maps.Map(document.getElementById("map"), mapOptions);
 
		//Определяем область отображения меток на карте
		var latlngbounds = new google.maps.LatLngBounds();
 
		//Загружаем данные в формате JSON из файла map.json
 
		$.getJSON("map.json", {}, function(data){
 
			$.each(data.places, function(i, item){
 
				$("#markers").append('<li><a href="#" rel="' + i + '">' + item.title + '</a></li>');
 
				var marker = new google.maps.Marker({
 
					position: new google.maps.LatLng(item.lat, item.lng),
 
					map: map,
 
					title: item.title
 
				});
 
				//Добавляем координаты меток
				latlngbounds.extend(new google.maps.LatLng(item.lat, item.lng));
 
				arrMarkers[i] = marker;
 
				var infowindow = new google.maps.InfoWindow({
 
					content: "<h3>"+ item.title +"</h3><p>"+ item.description +"</p>"
 
				});
 
				arrInfoWindows[i] = infowindow;
 
				google.maps.event.addListener(marker, 'click', function() {
 
					infowindow.open(map, marker);
 
				});
 
			});
 
			//Центрируем и масштабируем карту так, чтобы были видны все метки
			map.setCenter( latlngbounds.getCenter(), map.fitBounds(latlngbounds));
 
		});
 
	}
 
	$(function(){
 
		//Определяем карту (добавляем маркеры, балуны и список со ссылками)
 
		mapInit();
 
 
 
		// "live" отслеживает событие клика по ссылке
 
		$("#markers a").live("click", function(){
 
			var i = $(this).attr("rel");
 
			// Эта строка кода, закрывает все открытые балуны, для открытия выбранного
 
			for(x=0; x < arrInfoWindows.length; x++){ arrInfoWindows[x].close(); }
 
			arrInfoWindows[i].open(map, arrMarkers[i]);
 
		});
 
	});
 
</script>
 
<style type="text/css" media="screen">
 
	img { border: 0; }
 
	#map{
 
		width: 800px;
 
		height: 500px; 
 
	}
 
	#content {
 
		position: fixed;
 
		top: 10px;
 
		left: 800px;
 
		margin: 30px;
 
	}
 
</style>
 
</head>
 
<body>
 
<div id="container">
 
	<div id="header"></div>
 
	<div id="map"></div>
 
	<div id="content">	
 
	<ul id="markers"></ul>
 
	</div>
 
</div>
 
</body>
 
</html>

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

Скачать архив с файлами примеров.

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

Мне они очень помогают при выборе тем для написания новых материалов для блога.

К сожалению, у меня не хватает времени ответить на них каждому из написавших персонально, помочь выполнить ту или иную работу.

Я буду стараться максимально полно отвечать на них на страницах блога, а также в новом проекте, где по этапам, подробно на конкретном примере рассказывать о реализации интерактивных картографических проектов.

  • Гость: Сергей, добрый день. Напишите мне пожалуйста на почту. Писал Вам в FaceBook и по почте, Вы наверно не видели. Спасибо, жду.
  • Гость: Здравствуйте. Блог понравился, очень интересный. Но вот есть вопрос. Сейчас стоит задача написать динамическую карту, где будет отображаться ОЧЕНЬ много объектов. Как лучше сделать понимаю в двух словах не объяснить, но может есть где почитать?
  • Гость: Благодарю! Статья очень помогла.
  • Гость: Скачал архив, распаковал, запускаю любой пример, отображается только карта без меток и списка справа, почему???
  • axnel: Тоже так((
  • Гость: Конечно не будет работать.А где вы видели чтобы на халяву все работало) Годы изучения программирования на js дадут результат,иначе ни как. А Сергею минус в карму что не договаривает все... PS.Хотя инфа очень полезная)