Расположение на карте (Google Map)

Обзор

Поле «Расположение на карте» создает интерактивную карту с возможностью размещения маркера. В этом поле есть кнопка поиска, кнопка поиска местоположения и события щелчка / перетаскивания для размещения маркера. Данные сохраняются и возвращаются как массив, содержащий маркеры lat, lng и address.

API Google карт ограничивает количество сайтов, которые ежедневно могут использовать эту бесплатную услугу. Чтобы снять это ограничение, зарегистрируйте ключ Google API, следуя инструкциям, описанным далее в этой статье.

История изменений

  • Фильтр «acf/fields/google_map/api» добавлен в версии 4.3.9 (ACF) и 5.3.10 (ACF PRO)

Скриншоты

Настройки

ИмяОписание
ЦентрироватьУстанавливает начальное расположение карты с помощью lat и lng параметров.
МасштабУстанавливает начальный масштаб для карты.
ВысотаПозволяет выбрать откуда будет доступна картинка: только в текущем посте или во всей медиабиблиотеке.

API Google карт

Скорее всего, потребуется зарегистрировать ключ Google API, чтобы карты корректно работали. Перейдите по этой ссылке, чтобы получить ключ API Google.

Чтобы зарегистрировать свой ключ Google API, используйте фильтр «acf/fields/google_map/api» в functions.php следующим образом:

function my_acf_google_map_api( $api ){
	
	$api['key'] = 'xxx'; // Ваш ключ Google API
	
	return $api;
	
}

add_filter('acf/fields/google_map/api', 'my_acf_google_map_api');

Если вы используете ACF PRO, то проще обновить настройку «google_api_key» в functions.php.

function my_acf_init() {
	acf_update_setting('google_api_key', 'xxx'); // Ваш ключ Google API
}

add_action('acf/init', 'my_acf_init');

Использование в шаблоне

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

Обратите внимание, что нужно подключить ваш ключ Google API через JS, как в примере ниже. API Google карт — отличная библиотека для рендеринга карты, однако это не единственный доступный API. В документации Google вы можете найти множество других API и учебных материалов.

Хелперы

Примеры ниже требуют обязательного подключения следующих CSS и JS файлов в шаблоны страниц. Обратите внимание, что как CSS, так и JS файлы могут быть изменены по вашему вкусу. Однако, на их примере будет понятно, как данные PHP могут быть интегрированы через HTML в JS API Google карт.

<style type="text/css">

.acf-map {
	width: 100%;
	height: 400px;
	border: #ccc solid 1px;
	margin: 20px 0;
}

/* фиксим возможный конфликт css */
.acf-map img {
   max-width: inherit !important;
}

</style>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script> // Ваш ключ Google API 
<script type="text/javascript">
(function($) {

/*
*  new_map
*
*  Эта функция рендерит Google карту внутри выбранного jQuery элемента
*
*  @type	function
*  @date	8/11/2013
*  @since	4.3.0
*
*  @param	$el (jQuery элемент)
*  @return	n/a
*/

function new_map( $el ) {
	
	// Переменные
	var $markers = $el.find('.marker');
	
	
	// Переменные
	var args = {
		zoom		: 16,
		center		: new google.maps.LatLng(0, 0),
		mapTypeId	: google.maps.MapTypeId.ROADMAP
	};
	
	
	// Создаем карту	        	
	var map = new google.maps.Map( $el[0], args);
	
	
	// Создаем заготовку массива маркеров
	map.markers = [];
	
	
	// Добавляем маркеры
	$markers.each(function(){
		
    	add_marker( $(this), map );
		
	});
	
	
	// Центрируем карту
	center_map( map );
	
	
	// Возвращаем данные
	return map;
	
}

/*
*  add_marker
*
*  Эта функция добавляет маркер на Google карту
*
*  @type	function
*  @date	8/11/2013
*  @since	4.3.0
*
*  @param	$marker (jQuery элемент)
*  @param	map (Google Map object)
*  @return	n/a
*/

function add_marker( $marker, map ) {

	// Переменные
	var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );

	// Создаем маркер
	var marker = new google.maps.Marker({
		position	: latlng,
		map			: map
	});

	// Добавляем маркер в массив
	map.markers.push( marker );

	// Если маркер содержит HTML, добавим его в infoWindow
	if( $marker.html() )
	{
		// оздаем info window
		var infowindow = new google.maps.InfoWindow({
			content		: $marker.html()
		});

		// Показываем info window при нажатии на маркер
		google.maps.event.addListener(marker, 'click', function() {

			infowindow.open( map, marker );

		});
	}

}

/*
*  center_map
*
*  Эта функция центрирует карту и показывает все маркеры, прикрепленные к карте
*
*  @type	function
*  @date	8/11/2013
*  @since	4.3.0
*
*  @param	map (Google Map object)
*  @return	n/a
*/

function center_map( map ) {

	// Переменные
	var bounds = new google.maps.LatLngBounds();

	// Перебираем все маркеры и создаем bounds
	$.each( map.markers, function( i, marker ){

		var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );

		bounds.extend( latlng );

	});

	// Только 1 маркер?
	if( map.markers.length == 1 )
	{
		// Центрируем карту
	    map.setCenter( bounds.getCenter() );
	    map.setZoom( 16 );
	}
	else
	{
		// fit to bounds
		map.fitBounds( bounds );
	}

}

/*
*  document ready
*
*  Эта функция рендерит каждую карту когда страница загружена
*
*  @type	function
*  @date	8/11/2013
*  @since	5.0.0
*
*  @param	n/a
*  @return	n/a
*/
// global var
var map = null;

$(document).ready(function(){

	$('.acf-map').each(function(){

		// Создаем карту
		map = new_map( $(this) );

	});

});

})(jQuery);
</script>

Рендеринг одного маркера на карте

В этом примере показано, как использовать одну Google карту для отображения карты и маркера на странице. Каждый маркер не содержит внутреннего HTML, поэтому infoWindow не будет создано (используется приведенный выше JS).

<?php 

$location = get_field('location');

if( !empty($location) ):
?>
<div class="acf-map">
	<div class="marker" data-lat="<?php echo $location['lat']; ?>" data-lng="<?php echo $location['lng']; ?>"></div>
</div>
<?php endif; ?>

Рендеринг нескольких маркеров на карте

В этом примере показано поле повторителя (с именем «locations») с 3 вложенными полями (sub fields): title (текст), description (текстовое поле) и location (Google карта).

Каждый маркер содержит внутри HTML-код, поэтому будет создан infoWindow (используется приведенный выше JS).

<?php if( have_rows('locations') ): ?>
	<div class="acf-map">
		<?php while ( have_rows('locations') ) : the_row(); 

			$location = get_sub_field('location');

			?>
			<div class="marker" data-lat="<?php echo $location['lat']; ?>" data-lng="<?php echo $location['lng']; ?>">
				<h4><?php the_sub_field('title'); ?></h4>
				<p class="address"><?php echo $location['address']; ?></p>
				<p><?php the_sub_field('description'); ?></p>
			</div>
	<?php endwhile; ?>
	</div>
<?php endif; ?>

Решение проблем с невидимыми картами

API Google карт не будет работать, если инициализируется в невидимом элементе. Когда элемент станет видимым, карта не будет отображаться. К примеру, при использовании всплывающего модального окна.

Чтобы решить эту проблему, просто вызовите событие «resize» (изменение размера) для карты после того, как элемент карты будет виден.

google.maps.event.trigger(map, 'resize');

Похожие

Фильтры: acf/fields/google_map/api