Created
July 31, 2018 15:05
-
-
Save Atmden/73d9b2b2e2b61faf7028ef60438786e2 to your computer and use it in GitHub Desktop.
Sleepingowl YandexMap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Класс контрола "центр карты". | |
* @class | |
* @name CrossControl | |
*/ | |
function CrossControl(options) { | |
this.events = new ymaps.event.Manager(); | |
this.options = new ymaps.option.Manager(); | |
} | |
ymaps.ready(function () { | |
/** | |
* Макет контрола. | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/templateLayoutFactory.xml | |
* @class | |
* @name CrossControl.Layout | |
*/ | |
CrossControl.Layout = ymaps.templateLayoutFactory.createClass( | |
'<div class="cross-control" style="right:$[options.position.right]px; top:$[options.position.top]px;"></div>' | |
); | |
}); | |
/** | |
* @lends CrossControl.prototype | |
*/ | |
CrossControl.prototype = { | |
/** | |
* @constructor | |
*/ | |
constructor: CrossControl, | |
/** | |
* Устанавливает родительский объект. | |
* @function | |
* @name CrossControl.setParent | |
* @param {IControlParent} parent Родительский объект. | |
* @returns {CrossControl} Возвращает ссылку на себя. | |
*/ | |
setParent: function (parent) { | |
this.parent = parent; | |
if(parent) { | |
var map = this._map = parent.getMap(); | |
this._setPosition(map.container.getSize()); | |
this._setupListeners(); | |
/** | |
* Передаем в макет контрола данные о его опциях. | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/ILayout.xml#constructor-summary | |
*/ | |
this.layout = new this.constructor.Layout({ options: this.options }); | |
/** | |
* Контрол будет добавляться в pane событий, чтобы исключить интерактивность. | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/ILayout.xml#setParentElement | |
*/ | |
this.layout.setParentElement(map.panes.get('events').getElement()); | |
} | |
else { | |
this.layout.setParentElement(null); | |
this._clearListeners(); | |
} | |
return this; | |
}, | |
/** | |
* Возвращает ссылку на родительский объект. | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/IControl.xml#getParent | |
* @function | |
* @name CrossControl.getParent | |
* @returns {IControlParent} Ссылка на родительский объект. | |
*/ | |
getParent: function () { | |
return this.parent; | |
}, | |
/** | |
* Устанавливает контролу опцию "position". | |
* @function | |
* @private | |
* @name CrossControl._setPosition | |
* @param {Array} size Размер контейнера карты. | |
*/ | |
_setPosition: function (size) { | |
// -8, так как картинка 16х16 | |
this.options.set('position', { | |
top: size[1] / 2 - 8, | |
right: size[0] / 2 - 8 | |
}); | |
}, | |
_onPositionChange: function (e) { | |
this._setPosition(e.get('newSize')); | |
}, | |
_setupListeners: function () { | |
this._map.container.events | |
.add('sizechange', this._onPositionChange, this); | |
}, | |
_clearListeners: function () { | |
if(this._map) { | |
this._map.container.events | |
.remove('sizechange', this._onPositionChange, this); | |
} | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Класс Инструмент определения координат. | |
* @class | |
* @name LocationTool | |
* @param {ymaps.Map} map Карта. | |
*/ | |
function LocationTool(map, placemark, color,title,hint,content) { | |
this._domView = new LocationTool.DOMView(); | |
this._mapView = new LocationTool.MapView(map, placemark, color,title,hint,content); | |
this._monitor = new ymaps.Monitor(this._mapView.state); | |
this._setupMonitor(); | |
this._initDOMView(); | |
} | |
/** | |
* @lends LocationTool.prototype | |
*/ | |
LocationTool.prototype = { | |
/** | |
* @constructor | |
*/ | |
constructor: LocationTool, | |
/** | |
* Инициализирует DOMView начальными значениями карты. | |
* @private | |
* @function | |
* @name LocationTool._initView | |
*/ | |
_initDOMView: function () { | |
this._domView.render(this._mapView.state.getAll()); | |
}, | |
/** | |
* Настраиваем монитор для наблюдения за интересующими нас полями. | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Monitor.xml | |
* @private | |
* @function | |
* @name LocationTool._setupMonitor | |
*/ | |
_setupMonitor: function () { | |
this._monitor | |
.add(['mapCenter', 'mapZoom', 'markerPosition'], this._onMapViewStateChange, this); | |
}, | |
/** | |
* Останавливаем наблюдение. | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Monitor.xml#removeAll | |
* @private | |
* @function | |
* @name LocationTool._clearMonitor | |
*/ | |
_clearMonitor: function () { | |
this._monitor | |
.removeAll(); | |
}, | |
/** | |
* Обработчик изменения полей. | |
* @private | |
* @function | |
* @name LocationTool._onMapViewStateChange | |
*/ | |
_onMapViewStateChange: function (data) { | |
this._domView.render(data); | |
} | |
}; | |
/** | |
* Класс отображения на карте Инструмента определения координат. | |
* @class | |
* @name MapView | |
* @param {ymaps.Map} map Карта. | |
*/ | |
LocationTool.MapView = function (map, placemark, color,title,hint,content) { | |
this._map = map; | |
// Интервал обновления данных (millisec) при кинетическом движении карты. | |
this._updateTimeout = 10; | |
this._marker = this._createDraggableMarker(placemark, color,title,hint,content); | |
map.geoObjects.add(this._marker); | |
this.state = new ymaps.data.Manager({ | |
mapCenter: map.getCenter(), | |
mapZoom: map.getZoom(), | |
markerPosition: placemark | |
}); | |
this._attachHandlers(); | |
}; | |
/** | |
* @lends MapView.prototype | |
*/ | |
LocationTool.MapView.prototype = { | |
/** | |
* @constructor | |
*/ | |
constructor: LocationTool.MapView, | |
/** | |
* Навешиваем обработчики. | |
* @function | |
* @private | |
* @name MapView._attachHandlers | |
*/ | |
_attachHandlers: function () { | |
this._map.events | |
.add('boundschange', this._onMapBoundsChange, this) | |
.add('actiontick', this._onMapAction, this) | |
/* Во время плавного движения карты, у браузеров поддерживающих CSS3 Transition, | |
* actiontick не кидается, поэтому используем этот прием через setInterval. | |
*/ | |
.add('actionbegin', this._onMapActionBegin, this) | |
.add('actionend', this._onMapActionEnd, this); | |
this._marker.events | |
.add('drag', this._onMarkerDrag, this); | |
}, | |
/** | |
* Снимаем обработчики. | |
* @function | |
* @private | |
* @name MapView._detachHandlers | |
*/ | |
_detachHandlers: function () { | |
this._marker.events | |
.remove('drag', this._onMarkerDrag, this); | |
this._map.events | |
.remove('boundschange', this._onMapBoundsChange, this) | |
.remove('actiontick', this._onMapAction, this) | |
.remove('actionbegin', this._onMapActionBegin, this) | |
.remove('actionend', this._onMapActionEnd, this); | |
}, | |
/** | |
* Обработчик перетаскивания метки. | |
* @function | |
* @private | |
* @name MapView._onMarkerDrag | |
* @param {ymaps.Event} e Объект-событие | |
*/ | |
_onMarkerDrag: function (e) { | |
this.state.set({ | |
markerPosition: e.get('target').geometry.getCoordinates() | |
}); | |
}, | |
/** | |
* Обработчик начала плавного движения карты. | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Map.xml#event-actionbegin | |
* @function | |
* @private | |
* @name MapView._onMapActionBegin | |
* @param {ymaps.Event} e Объект-событие | |
*/ | |
_onMapActionBegin: function (e) { | |
if(this._intervalId) { | |
return; | |
} | |
this._intervalId = window.setInterval( | |
ymaps.util.bind(this._onMapAction, this), | |
this._updateTimeout | |
); | |
}, | |
/** | |
* Обработчик окончания плавного движения карты. | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Map.xml#event-actionend | |
* @function | |
* @private | |
* @name MapView._onMapActionEnd | |
* @param {ymaps.Event} e Объект-событие | |
*/ | |
_onMapActionEnd: function (e) { | |
window.clearInterval(this._intervalId); | |
this._intervalId = null; | |
}, | |
/** | |
* Обработчик исполнения нового шага плавного движения. | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Map.xml#event-actiontick | |
* @function | |
* @private | |
* @name MapView._onMapAction | |
* @param {ymaps.Event} e Объект-событие | |
*/ | |
_onMapAction: function (e) { | |
/** | |
* Определяет состояние карты в момент ее плавного движения. | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/map.action.Manager.xml#getCurrentState | |
*/ | |
var state = this._map.action.getCurrentState(), | |
zoom = state.zoom, | |
/** | |
* Преобразует пиксельные координаты на указанном уровне масштабирования в координаты проекции (геокоординаты). | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/IProjection.xml#fromGlobalPixels | |
*/ | |
center = this._map.options.get('projection').fromGlobalPixels( | |
state.globalPixelCenter, zoom | |
); | |
this.state.set({ | |
mapCenter: center, | |
mapZoom: zoom | |
}); | |
}, | |
/** | |
* Обработчик события изменения области просмотра карты (в результате изменения центра или уровня масштабирования) | |
* @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Map.xml#event-boundschange | |
* @function | |
* @private | |
* @name MapView._onMapBoundsChange | |
* @param {ymaps.Event} e Объект-событие | |
*/ | |
_onMapBoundsChange: function (e) { | |
this.state.set({ | |
mapCenter: e.get('newCenter'), | |
mapZoom: e.get('newZoom') | |
}); | |
}, | |
/** | |
* Создание перетаскиваемого маркера. | |
* @function | |
* @private | |
* @name MapView._createDraggableMarker | |
*/ | |
_createDraggableMarker: function (placemark, color,title,hint,content) { | |
return new ymaps.Placemark(placemark, { | |
iconcontent: title, | |
balloonContent: content, | |
hintContent: 'Перетащите метку' | |
}, { | |
preset: color, | |
draggable: true, | |
}); | |
} | |
}; | |
/** | |
* Класс DOM-отображения Инструмента определения координат. | |
* @class | |
* @name DOMView | |
*/ | |
LocationTool.DOMView = function () { | |
this._element = $('form'); | |
} | |
/** | |
* @lends DOMView.prototype | |
*/ | |
LocationTool.DOMView.prototype = { | |
/** | |
* @constructor | |
*/ | |
constructor: LocationTool.DOMView, | |
/** | |
* Отображаем изменений данных в DOM-структуре. | |
* @function | |
* @name DOMView.render | |
* @param {Object} data Объект с полями "mapCenter", "mapZoom" и "markerPosition". | |
*/ | |
render: function (data) { | |
$.each(data, $.proxy(this._setData, this)); | |
}, | |
/** | |
* Очистка DOM-отображения. | |
* @function | |
* @private | |
* @name DOMView.clear | |
*/ | |
clear: function () { | |
this._element.remove(); | |
}, | |
/** | |
* Форматируем координату до 6-ти точек после запятой. | |
* @function | |
* @private | |
* @name DOMView._toFixedNumber | |
* @param {Number|String} coords Широта или Долгота. | |
* @returns {Number} Число фиксированной длины. | |
*/ | |
_toFixedNumber: function (coords) { | |
return Number(coords).toFixed(8); | |
}, | |
/** | |
* Обновление значений полей формы. | |
* @function | |
* @private | |
* @name DOMView._setData | |
* @param {String} id Идентификатор поля. | |
* @param {Number|String} value Новое значение поля. | |
*/ | |
_setData: function (id, value) { | |
this._element | |
.find('#' + id) | |
.val( | |
$.isArray(value)? | |
$.map(value, this._toFixedNumber).join(', ') : value | |
); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use App\Map; | |
use \App\Langs; | |
use SleepingOwl\Admin\Model\ModelConfiguration; | |
use Illuminate\Database\Eloquent\Model; | |
AdminSection::registerModel(Map::class, function (ModelConfiguration $model) { | |
$model->setTitle('Схема проезда'); | |
$model->disableDeleting(); | |
$model->onDisplay(function () { | |
$display = AdminDisplay::table()->paginate(10); | |
$display->setApply(function ($query) { | |
$query->orderBy('order', 'asc'); | |
}); | |
$display->setHtmlAttribute('class', 'table-info table-hover'); | |
$display->setColumns([ | |
AdminColumn::link('translation_ru.page_name') | |
->setLabel('Наименование страницы') | |
->setWidth('250px'), | |
AdminColumn::datetime('updated_at')->setLabel('Последние изменения'), | |
AdminColumnEditable::checkbox('online')->setLabel('Активная страница'), | |
AdminColumn::order() | |
->setLabel('Порядок показа в меню') | |
->setHtmlAttribute('class', 'text-center') | |
->setWidth('200px'), | |
]); | |
return $display; | |
}); | |
// Create And Edit | |
$model->onCreateAndEdit(function () { | |
$langs = Langs::all(); | |
$tabs = AdminDisplay::tabbed(); | |
$tabs->setTabs(function ($id) use ($langs) { | |
$tabs = []; | |
foreach ($langs as $lang) { | |
$relationship = 'translation_' . $lang->locale; | |
$tabs[] = AdminDisplay::tab(AdminForm::elements([ | |
AdminFormElement::text($relationship . '.iconcontent', 'Текст на метке')->required(), | |
AdminFormElement::text($relationship . '.hintContent', 'Текст при наведении на метку'), | |
AdminFormElement::text($relationship . '.balloonContent', 'Текст при нажатии на метку'), | |
]))->setLabel($lang->full_name); | |
} | |
return $tabs; | |
}); | |
$map = Map::find(1); | |
$array_map = [ | |
'markerPosition' => $map->markerPosition, | |
'mapZoom' => $map->mapZoom, | |
'mapCenter' => $map->mapCenter, | |
'color' => $map->preset, | |
'hint' => $map->hintContent, | |
'title' => $map->iconcontent, | |
'content' => $map->balloonContent | |
]; | |
$form = AdminForm::panel()->addBody([ | |
AdminFormElement::view('mapyandexextend',$array_map), | |
AdminFormElement::text('markerPosition', 'Координаты позиции метки'), | |
AdminFormElement::text('mapZoom', 'Масштаб карты'), | |
AdminFormElement::text('mapCenter', 'Координаты центра карты'), | |
AdminFormElement::checkbox('online', 'Показывать схему проезда на странице контактов'), | |
AdminFormElement::select('preset', 'Выберите цвет метки на карте') | |
->setOptions([ | |
'islands#blueStretchyIcon' => 'Синий', | |
'islands#lightblueStretchyIcon' => 'Светло-синий', | |
'islands#darkBlueStretchyIcon' => 'Темно-синий', | |
'islands#greenStretchyIcon' => 'Зеленый', | |
'islands#darkgreenStretchyIcon' => 'Темно-зеленый', | |
'islands#yellowStretchyIcon' => 'Желтый', | |
'islands#orangeStretchyIcon' => 'Оранжевый', | |
'islands#darkorangeStretchyIcon' => 'Темно-оранжевый', | |
'islands#pinkStretchyIcon' => 'Розовый', | |
'islands#redStretchyIcon' => 'Красный', | |
'islands#violetStretchyIcon' => 'Фиолетовый', | |
'islands#greyStretchyIcon' => 'Серый', | |
'islands#brownStretchyIcon' => 'Коричневый' | |
])->required(), | |
])->addheader($tabs); | |
$form->getButtons() | |
->hideSaveAndCloseButton(); | |
return $form; | |
}); | |
$model->updated(function ($config, Model $content) { | |
redirect('/admin'); | |
}); | |
// $model->updating(function ($config, Model $content) { | |
// dd($_POST); | |
// }); | |
$model->creating(function ($config, Model $content) { | |
onCreatingAndUpdatingMap($config, $content); | |
}); | |
function onCreatingAndUpdatingMap($config, Model $content) | |
{ | |
foreach ($content->getRelations() as $key => $relation) { | |
if (!strpos($key, 'translation')) { | |
$locale = substr($key, 12); | |
// $lang_id = Lang::where('locale', $locale)->first()->id; | |
$content->{$key}->locale = $locale; | |
// $content->{$key}->updated_at =time(); | |
} | |
} | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="panel" style="padding: 10px; margin: 5px;"> | |
{{--<script src="//yandex.st/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>--}} | |
<script src="https://api-maps.yandex.ru/2.0-stable/?load=package.standard&lang=ru-RU" type="text/javascript"></script> | |
<script src="/js/location-tool.js" type="text/javascript"></script> | |
<script src="/js/cross-control.js" type="text/javascript"></script> | |
<script src="/js/geolocation-button.js" type="text/javascript"></script> | |
<script type="text/javascript"> | |
ymaps.ready(function () { | |
var myMap = new ymaps.Map('YMapsID', { | |
center: [{{ $mapCenter }}], | |
zoom: {{ $mapZoom }}, | |
behaviors: ['default', 'scrollZoom'] | |
}); | |
myMap.controls | |
.add('mapTools') | |
.add(new CrossControl) | |
.add('zoomControl') | |
.add('typeSelector', {top: 5, right: 5}) | |
.add(new ymaps.control.SearchControl({noPlacemark: true}), {top: 5, left: 200}); | |
new LocationTool(myMap, [{{$markerPosition}}], "{{ $color }}", "{{ $title }}", "{{ $hint }}", "{{ $content }}"); | |
}); | |
</script> | |
<style type="text/css"> | |
#YMapsID { | |
width: 900px; | |
height: 400px; | |
} | |
.hero-unit p { | |
line-height: 20px; | |
} | |
.cross-control { | |
background: url(/img/center.gif) no-repeat; | |
position: absolute; | |
width: 16px; | |
height: 16px; | |
} | |
.centered{ | |
margin: 0 auto; | |
} | |
</style> | |
<div class="centered text-center"><strong>Перетащите метку на карте в нужное место.</strong></div> | |
<div class="centered text-center" id="YMapsID"></div> | |
</div> |
Author
Atmden
commented
Jul 31, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment