Задать вопрос

Yii2 Yandex Google Map, как реализовать и хранить в базе?

Ребят, такой вопрос. Есть ли у вас в наработках модули под карты Яндекса или Гугла?
Задача следующая, пользователь может ставить несколько меток на карте, помечая свой адреса.

Не очень представляю как получать эти координаты(от пользователя т.к. раньше этим не занимался) и каким образом их хранить в базе в плане типа эти X и Y ?

На фронтенде вроде попробовал повтыкать карты и подключить метки как описано в API. Все работает и пашет, но как задавать их и как хранить в базе не очень понимаю. Можете подсказать как делаете вы?

Что касается добавления адресов. В основном это 1 адрес = 1 строка в бд. Т.е. не пачкой меток, а по одному.
  • Вопрос задан
  • 4021 просмотр
Подписаться 1 Оценить Комментировать
Решения вопроса 3
arutyunov
@arutyunov
Mooza.ru — Делаем сайты
https://github.com/kalyabin/yii2-select-google-map...

Я заюзал это расширение для админки.
Правда, мне нужно было у одной сущности хранить только 1 адрес.

Гугл, по-моему, запрещает иметь несколько инстансов карты на 1 странице.
Но попробовать определенно стоит.

Если что, можно унаследоваться от этого расширения и дописать его до использования нескольких меток для 1 сущности.

PS. Если писать свое, то у вас будет текст-инпут + карта. У карты события на клик + перемещение метки. Как только метка появилась на карте — в форму добавляем скрытый инпут с координатами метки. Новая метка — новый инпут. Переместили метку — поменяли инпут.
Текст-инпут нужен, чтобы метку руками не ставить на карте, а указать адрес в текст-инпуте, а через API определить координаты адреса и поставить метку по этим координатам.
Ответ написан
@kucheriavij
Код на идеал не претендует, но это работает

<?php

namespace application\widgets;

use webnula2\widgets\booster\TbActiveForm;
use webnula2\widgets\booster\TbBaseInputWidget;

/**
 * Class GoogleMap
 *
 * @package application\widgets
 */
class GoogleMap extends TbBaseInputWidget
{
	/**
	 * @var $options
	 */
	public $options;

	/**
	 * @var $cs
	 */
	private $cs;

	/**
	 *
	 */
	public function init()
	{
		parent::init();

		$this->cs = \Yii::app()->getClientScript();
	}

	public function run()
	{
		$options = array();

		if (empty($this->model[$this->attribute])) {
			if (empty($this->options['mapCenter'])) {
				$options['mapCenter'] = array('-8.36293738590362', '115.14429179101558');
			}

			if (empty($this->options['point'])) {
				$options['point'] = $options['mapCenter'];
			}

			if (empty($this->options['mapZoom'])) {
				$options['mapZoom'] = 10;
			}

			if (empty($this->options['mapType'])) {
				$options['mapType'] = 'roadmap';
			}
		} else {
			$options = $this->model[$this->attribute];
		}

		$id = \CHtml::activeId($this->model, $this->attribute);

		$mapId = "GMapsID-" . $this->getId();

		$searchControlId = 'pac-input-' . $this->getId();

		$js = <<<JS

function getMarkerPosition(marker) {
	return [marker.getPosition().lat(), marker.getPosition().lng()];
}

function initMap () {
	var map;

	var options = {
		mapCenter: [{$options['mapCenter'][0]}, {$options['mapCenter'][1]}],
		point: [{$options['point'][0]}, {$options['point'][1]}],
		mapZoom: {$options['mapZoom']},
		mapType: "{$options['mapType']}"
	};

	var latLng = new google.maps.LatLng(options.point[0], options.point[1]);

	map = new google.maps.Map(document.getElementById('{$mapId}'), {
	    center: latLng,
	    zoom: options.mapZoom,
	    mapTypeId: options.mapType
	});

	var marker = new google.maps.Marker({
		position: latLng,
		map: map,
		draggable: true
	});

	var input = document.getElementById('{$searchControlId}');
	var searchBox = new google.maps.places.SearchBox(input);
	map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);

	map.addListener('bounds_changed', function(){
		searchBox.setBounds(map.getBounds());
	});

	var markers = [];

	markers.push(marker);

	searchBox.addListener('places_changed', function(){

		var places = searchBox.getPlaces();

		if (places.length == 0) {
			return;
		}

		markers.forEach(function(marker){
			marker.setMap(null);
		});

		markers = [];

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

		places.forEach(function(place){
			var icon = {
				url: place.icon,
				size: new google.maps.Size(71, 71),
				origin: new google.maps.Point(0, 0),
				anchor: new google.maps.Point(17, 34),
				scaledSize: new google.maps.Size(25, 25)
			};

			markers.push(new google.maps.Marker({
				map: map,
				//icon: icon,
				title: place.name,
				position: place.geometry.location,
				draggable: true
			}));

			if (place.geometry.viewport){
				bounds.union(place.geometry.viewport);
			} else {
				bounds.extend(place.geometry.location);
			}
		});

		map.fitBounds(bounds);

		googleMapSave();
	});

	/*google.maps.event.addListener(markers[0], 'drag', function(){
		googleMapSave();
	});

	map.addListener('zoom_changed', function(){
		googleMapSave();
	});

	map.addListener('maptypeid_changed', function(){
		googleMapSave();
	});*/

	map.addListener('mouseout', function(){
		googleMapSave();
	});

	function googleMapSave(){
		options = {
			mapCenter: getMarkerPosition(markers[0]),
			point: getMarkerPosition(markers[0]),
			mapZoom: map.getZoom(),
			mapType: map.getMapTypeId()
		};

		$('#{$id}').val(JSON.stringify(options));
	}

	googleMapSave();
}
JS;
		$css = <<<CSS
.controls {
  margin-top: 10px;
  border: 1px solid transparent;
  border-radius: 2px 0 0 2px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  height: 32px;
  outline: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#{$searchControlId} {
  background-color: #fff;
  font-family: Roboto;
  font-size: 15px;
  font-weight: 300;
  margin-left: 12px;
  padding: 0 11px 0 13px;
  text-overflow: ellipsis;
  width: 300px;
}

#{$searchControlId}:focus {
  border-color: #4d90fe;
}
CSS;


		$this->cs->registerScriptFile("https://maps.googleapis.com/maps/api/js?key=AIzaSyDTOzQmfoHuYz5coANmmLtSezC-yMxnv8A&libraries=places&callback=initMap", \CClientScript::POS_END);
		$this->cs->registerScript($this->getId(), $js, \CClientScript::POS_HEAD);
		$this->cs->registerCss($this->getId(), $css);

		echo \CHtml::openTag('div', array('class' => 'map-container'));
		echo \CHtml::openTag('input', array('id' => $searchControlId, 'class' => 'controls search-control', 'placeholder' => 'Search Box'));
		echo \CHtml::openTag('div', array('style' => 'width: 100%;height:400px', 'id' => $mapId));
		echo \CHtml::closeTag('div');
		echo \CHtml::closeTag('div');

		$this->model[$this->attribute] = \CJSON::encode($this->model[$this->attribute]);
		echo \CHtml::activeHiddenField($this->model, $this->attribute);
	}
}
Ответ написан
@SlimSavernake
Я сейчас тоже пытаюсь для объявлений карту прикрутить. Для добавления одной точки установил https://github.com/Kolyunya/yii2-map-input-widget
поле в базе одно, хранит через запятую

А для отображения координат https://github.com/2amigos/yii2-google-maps-library
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@VitGun
Создаешь поля longitude и latitude и хранишь там координаты меток.
Ответ написан
@devian3000
В базах есть поля для геометок. В myself postgres точно есть. Принимать Ajax-ом. Во время ставки метки. Или post ом из формы.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы