/*
* Let's GO!
*/
var myMap;
var categories = Array();
var points = Array();
var pointsSources = Array();
var markers; // Используется для кластеризации
var search;
var route = false;
var addPointInProcess = false;
var layer;
var layers = Array();
var defaultZoom = 13;
categories.im = L.icon({
iconUrl: '/ico/man.png',
iconSize: [32, 37],
iconAnchor: [16, 37],
popupAnchor: [0, 1]
});
// -----------------------------------------------------------------------------
/**
* Инициализируем яндекс-карты и узнаём расположение пользователя.
*/
ymaps.ready(function () {
lat = ymaps.geolocation.latitude;
lng = ymaps.geolocation.longitude;
init(lat, lng);
points.im = L.marker([lat, lng], {icon: categories.im, title: 'Вы здесь'});
points.im.addTo(myMap);
points.im.bindPopup('Ваше местоположение
')
});
/**
* Инициализируем переменные и подгружаем данные.
* @returns true
*/
function init(lat, lng) {
myMap = L.map('map', {zoomControl: false}).setView([lat, lng], defaultZoom);
markers = new L.MarkerClusterGroup({showCoverageOnHover: false, maxClusterRadius: 45});
layers['quest'] = L.tileLayer('http://otile1.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', {attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox', maxZoom: 18});
layers['osm'] = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery ©', maxZoom: 18});
layers['google'] = new L.Google('HYBRID');
layers['yandexMap'] = new L.Yandex();
layers['yandex'] = new L.Yandex('hybrid');
setLayer($.cookie('mapLayer') ? $.cookie('mapLayer') : 'quest');
initCategories(); // getPoints внутри
myMap.on('click', function (e) {
if (!myMap._popup) {
if (status == statusHunting)
{
$('#addPointId').remove();
$('#addPointForm input:text').val('');
$('#addPointForm textarea').val('');
$("#addPointCategoryId option").attr('selected', null);
$('#addPointLat').val(e.latlng.lat);
$('#addPointLng').val(e.latlng.lng);
$('#myModalLabel').text('Добавление новой точки');
$('#addPointModal').modal('show');
} else if (status == statusReHunting)
{
resetStatus();
$('#addPointLat').val(e.latlng.lat);
$('#addPointLng').val(e.latlng.lng);
$('#myModalLabel').text('Редактирование точки');
$('#addPointModal').modal('show');
}
}
else {
closePopup();
}
});
$("#wayPoints").sortable();
$("#wayPoints").disableSelection();
$("#imgsContainer").sortable();
myMap.on('moveend', function (e) {
if (!myMap._popup && $('#boxRoute').css('display') == 'none' && status != statusMovingInHistory)
{
document.title = pointsCount + ' или даже больше поводов не сидеть дома';
history.pushState({lat: myMap.getCenter().lat, lng: myMap.getCenter().lng, zoom: myMap.getZoom()}, document.title, "/?lat=" + myMap.getCenter().lat + "&lng=" + myMap.getCenter().lng + "&zoom=" + myMap.getZoom());
}
if (status == statusMovingInHistory)
{
resetStatus();
}
});
$('.filterSelector').bind('change', function () {
filter()
});
return true;
}
/**
* Создаёт точку для карту - Placemark.
* @param {Array} data
* @returns {ymaps.Placemark}
*/
function constructPoint(data)
{
id = data['id'];
points[id] = L.marker(
[data['lat'], data['lng']], {icon: categories[data['categoryId']], title: data['name'], id: id, categoryId: data['categoryId']}
).on('click', function (e) {
showInfo(e.target.options.id);
});
return points[id];
}
/**
* Загружает точки с сервера.
* @returns {Boolean}
*/
function initPoints()
{
$.ajax({
url: "/json/points/",
success: function (data) {
for (var k in data) {
markers.addLayer(constructPoint(data[k]));
}
myMap.addLayer(markers);
if (getURLParameter('point') != 'null')
{
if (getURLParameter('point') == 'random')
{
showRandomPoint();
}
else
{
showInfo(getURLParameter('point'));
}
} else if (getURLParameter('route') != 'null')
{
loadRouteJSON(getURLParameter('route'));
buildRoute(true);
} else if ((getURLParameter('lat') != 'null') && (getURLParameter('lng') != 'null') && (getURLParameter('zoom') != 'null'))
{
myMap.setView([getURLParameter('lat'), getURLParameter('lng')], getURLParameter('zoom'));
}
}
});
return true;
}
/**
* Показывает баллун для точки. Если данных для точки нет, то подгружает их с сервера.
* @param {type} id
* @returns {Boolean}
*/
function showInfo(id)
{
marker = points[id];
if (!(id in points) || marker.options.description == undefined)
{
marker.bindPopup("Загрузка...").openPopup();
$.ajax({
url: "/json/point/id/" + id,
success: function (data) {
pointsSources[id] = data;
if (typeof (data.images) == 'object')
{
photos = '
';
if (data.images.length > 1)
photos += '
+' + (data.photosCount - 1) + '
';
photos += '

';
photos += '
';
}
else
{
photos = '
';
}
description = '' + '
' + data.name + '
' + photos;
description += data.descriptionHtml;
description += '';
description += '';
if (data.source.length > 11)
{
description += '
Подробнее';
}
// description += '
Подробнее';
description += '
';
// description += '
';
// description += '
';
description += '
';
if (isAdmin == '1')
{
description += '
';
}
description += '
';
marker.options.description = description;
marker.bindPopup(marker.options.description, {maxWidth: 500, maxHeight: 300});
markers.zoomToShowLayer(marker, function () {
marker.openPopup();
bounds = myMap.getBounds();
diff = (bounds._northEast.lat - bounds._southWest.lat) / 4;
myMap.setView([points[id]._latlng.lat + diff, points[id]._latlng.lng], myMap.getZoom());
history.pushState({pointId: id}, document.title, "/?point=" + id);
document.title = data.name;
});
}
});
} else {
bounds = myMap.getBounds();
diff = (bounds._northEast.lat - bounds._southWest.lat) / 4;
myMap.setView([points[id]._latlng.lat + diff, points[id]._latlng.lng], myMap.getZoom());
history.pushState({pointId: id}, document.title, "/?point=" + id);
document.title = points[id].options.title;
}
}
function showRandomPoint()
{
roundIndex = Math.floor(Math.random() * points.length);
runner = 0;
for (var key in points)
{
if (runner++ >= roundIndex)
return showInfo(key);
}
}
/**
* Загружает с сервера список категорий точек.
* @returns {Boolean}
*/
function initCategories()
{
$.ajax({
url: "/json/categories/",
success: function (data) {
for (var k in data) {
categories[data[k]['id']] = L.icon({
iconUrl: data[k]['icon'],
iconSize: [32, 37],
iconAnchor: [16, 37],
popupAnchor: [0, 1]
});
}
initPoints();
}
});
return true;
}
/**
* Производит поиск по адресу или координатам, введённым в соответствующее поле.
* @returns {undefined}
*/
function searchAdderess()
{
$.ajax({
url: "/json/geocoding",
data: {
search: $('#addressField').val()
},
success: function (data)
{
if (data.lat && data.lng)
{
myMap.setView([data.lat, data.lng], defaultZoom);
L.popup()
.setLatLng([data.lat, data.lng])
.setContent('Координаты: lat:' + data.lat + ' lng:' + data.lng)
.openOn(myMap);
} else
{
alert('Ничего не найдено.');
}
}
});
}
/**
* Пытается более точно определить координаты пользователя на карте и, при необходимости, обновляет положение точки "im"
* @returns {undefined}
*/
function showMeOnTheMap()
{
navigator.geolocation.getCurrentPosition(function (pos) {
coords = [pos.coords.latitude, pos.coords.longitude];
myMap.removeLayer(points.im);
points.im.setLatLng(coords).addTo(myMap);
myMap.setView(coords, defaultZoom);
});
}
/**
* Активирет добавление точки - ждёт выбор координат, меняет курсор на прицел.
* @returns {Boolean}
*/
function activateAddPoint()
{
$('#addPointButton').toggleClass('active');
if ($('#addPointButton').hasClass('active'))
{
$('.extraImage', '#imgsContainer').remove();
addNewImage();
$('#map').css('cursor', 'crosshair');
setStatus(statusHunting)
}
else
{
$('#map').css('cursor', 'arrow');
setStatus(statusReady)
}
return true;
}
/**
* Отправляет данные о точке на сервер.
* @returns {Boolean}
*/
function addPoint()
{
$('.form-group').removeClass('has-error');
if (status != statusSendingToServer)
{
setStatus(statusSendingToServer)
id = $('#addPointId').length ? $('#addPointId').val() : 0;
hasImages = false;
$("input[name='imgs[]']", '#addPointForm').each(function () {
if ($(this).val().length > 10)
hasImages = true;
});
$("input[name='photos[]']", '#addPointForm').each(function () {
if ($(this).val().length > 5)
hasImages = true;
})
$.ajax({
type: "POST",
url: "/json/addpoint/",
data: {
name: $('#addPointName').val(),
img: hasImages ? 1 : 0,
description: $('#addPointDescription').val(),
categoryId: $('#addPointCategoryId').val(),
source: $('#addPointSource').val(),
lat: $('#addPointLat').val(),
lng: $('#addPointLng').val(),
id: id
},
success: function (data) {
if ($("input[name='photos[]']").length > 0 || $("input[name='imgs[]']").length > 0)
{
$('').appendTo('#addPointForm').val(data);
$('#addPointForm').submit();
}
text = id ? 'Точка успешно отредактирована!' : 'Точка успешно добавлена!';
if (id)
{
markers.removeLayer(points[id]);
}
balloon = L.popup()
.setLatLng([$('#addPointLat').val(), $('#addPointLng').val()])
.setContent(text)
.openOn(myMap);
setTimeout(function () {
balloon._close();
delete balloon;
}, 2000);
obj = {};
obj.id = data;
obj.name = $('#addPointName').val();
obj.lat = $('#addPointLat').val();
obj.lng = $('#addPointLng').val();
obj.categoryIcon = categories[$('#addPointCategoryId').val()].icon;
obj.categoryId = $('#addPointCategoryId').val();
setTimeout(function () {
markers.addLayer(constructPoint(obj));
}, 2000);
$('#addPointModal').modal('hide');
// Clear form
$('#addPointForm input').val('');
$('#addPointForm textarea').val('');
$('.form-group').removeClass('has-error');
$('#addPointButton').removeClass('active');
$('#addPointId').remove();
$('#map').css('cursor', 'arrow');
setStatus(statusReady);
return true;
},
error: function (data) {
response = data.responseJSON;
message = '';
for (var k in response) {
if (typeof response[k] !== 'function') {
if (k == 1)
$('#addPointName').parent().addClass('has-error');
else
if (k == 2)
{
$('.extraImage', '#addPointForm').addClass('has-error');
}
else
if (k == 3)
$('#addPointDescription').parent().addClass('has-error');
else
message += response[k] + '; ';
}
}
if (message != '')
alert(message);
resetStatus();
return false;
}
});
}
else
{
alert('Точка добавляется, нужно немного подождать.');
}
}
/**
* Включает режим редактирования точки.
* @param int id
* @returns {undefined}
*/
function editPoint(id)
{
$('#addPointId').remove();
$('').appendTo('#addPointForm').val(id);
$('#addPointName').val(pointsSources[id].name);
$('#addPointDescription').val(pointsSources[id].description);
$("#addPointCategoryId option").attr('selected', null);
$("#addPointCategoryId option[value='" + pointsSources[id].categoryId + "']").attr('selected', 'selected');
$('#addPointSource').val(pointsSources[id].source);
$('#addPointLat').val(pointsSources[id].lat);
$('#addPointLng').val(pointsSources[id].lng);
$('.extraImage', '#imgsContainer').remove();
if (pointsSources[id].images != undefined && pointsSources[id].images.length > 0)
{
for (var i = 0; i < pointsSources[id].images.length; i++)
{
addNewImage(pointsSources[id].images[i]);
}
}
else
{
addNewImage(pointsSources[id].img);
}
closePopup();
$('#addPointModal').modal('show');
setStatus(statusEdit);
}
function editSetNewCoords()
{
$('#addPointModal').modal('hide');
$('#map').css('cursor', 'crosshair');
setStatus(statusReHunting)
}
function setLayer(name)
{
if (layer)
myMap.removeLayer(layers[layer])
layer = name;
myMap.addLayer(layers[layer]);
$('.layers').removeClass('selected');
$('.' + layer + 'Layer').addClass('selected');
$.cookie('mapLayer', layer);
}
function closePopup()
{
if (myMap._popup)
myMap._popup._close();
}
function filter()
{
var selected = new Array();
$('.filterSelector:checked').each(function (i, e) {
selected.push($(e).val());
});
for (var key in points)
{
if (selected.length == 0 || points[key].options.categoryId == undefined || selected.indexOf(points[key].options.categoryId) != -1)
{
markers.addLayer(points[key]);
}
else
{
markers.removeLayer(points[key]);
}
}
}