wikipoints/public/js/map.js

584 lines
19 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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;
var rightCoords = [];
var allPointsLoaded = false;
categories.im = L.icon({
iconUrl: '/ico/man.png',
iconSize: [32, 37],
iconAnchor: [16, 37],
popupAnchor: [0, 1]
});
categories.lock = L.icon({
iconUrl: '/ico/lock.png',
iconSize: [32, 37],
iconAnchor: [16, 37],
popupAnchor: [0, 1]
});
categories.simplepoint = L.icon({
iconUrl: '/ico/simplepoint.png',
iconSize: [13, 13],
iconAnchor: [7, 7],
popupAnchor: [7, 7]
});
categories.marker = L.icon({
iconUrl: '/ico/marker.png',
iconSize: [32, 37],
iconAnchor: [16, 37],
popupAnchor: [0, 1]
});
// -----------------------------------------------------------------------------
if (pointLat == pointLng) {
init(userLat, userLng);
} else {
init(pointLat, pointLng);
}
points.im = L.marker([userLat, userLng], {icon: categories.im, title: 'Вы здесь'});
points.im.addTo(myMap);
points.im.bindPopup('<h3>Похоже, что вы здесь!</h3><img src="/ico/man.png" style="float: left; margin-right: 5px;" /> <b>Ваше местоположение</b> - это точка, которую можно добавить в маршрут. При первоначальной загрузке страницы определение координат происходит очень неточно, по вашему адресу в сети интеренет. При желании координаты можно уточнить, нажав соответствующую пиктограмму справа [ <div class="glyphicon glyphicon-screenshot _b"></div> ].<br/><br/> <button type="button" class="btn btn-default" onclick="addToRoute(\'im\')"><span class="glyphicon glyphicon-map-marker"></span> Добавить в маршрут</button>');
suggestInit('#addressField');
/**
* Инициализируем переменные и подгружаем данные.
* @returns true
*/
function init(lat, lng) {
myMap = L.map('map', {zoomControl: false}).setView([lat, lng], defaultZoom);
markers = new L.MarkerClusterGroup({showCoverageOnHover: false, maxClusterRadius: 30});
// markersPlus = new L.MarkerClusterGroup({showCoverageOnHover: false, maxClusterRadius: 25});
layers['quest'] = L.tileLayer('https://otile1-s.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com" target="_blank">Mapbox</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 18});
layers['osm'] = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 18});
layers['topo'] = L.tileLayer('https://topo.wikipoints.ru/?z={z}&x={x}&y={y}&ver=0216', {attribution: 'Map data &copy; <a href="http://openstreetmap.org" target="_blank">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a>, Imagery © <a href="http://www.marshruty.ru/" target="_blank">Маршруты.ру</a> | Points data &copy; <a href="http://wikipoints.ru" target="_blank">WIKIPOINTS.RU</a>', maxZoom: 15});
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)
{
$('div#addHelper').hide(150);
$('#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();
$("#extraParamsContainer").sortable();
myMap.on('moveend', function (e) {
if (!myMap._popup && $('#boxRoute').css('display') == 'none' && status != statusMovingInHistory)
{
document.title = 'Лучшие выходные — это выходные в путешествии! wikipoints.ru';
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());
loadPointsInBounds();
}
if (status == statusMovingInHistory)
{
resetStatus();
}
});
myMap.on('popupclose', function(e){
$('#control').show(100);
});
$('.filterSelector').bind('change', function () {
filter()
});
// Добавление произвольной точки в маршрут по правому клику
myMap.on('contextmenu', function (e) {
if (status == statusReady)
{
rightCoords = [e.latlng.lat, e.latlng.lng];
popupContent = '<button type="button" class="btn btn-default" onclick="addToRoute(rightCoords)"><span class="glyphicon glyphicon-map-marker"></span> Добавить в маршрут</button>';
popup = L.popup();
popup.setContent(popupContent);
popup.setLatLng(e.latlng);
popup.openOn(myMap);
}
});
$(document).keyup(function (e) {
if (e.keyCode === 27) { // escape key
closePopup();
}
});
// Пользователь на карте
myMap.on('locationfound', onLocationFound);
myMap.on('locationerror', onLocationError);
return true;
}
/**
* Создаёт точку для карты - Placemark.
* @param {Array} data
* @returns {Array}
*/
function constructPoint(data)
{
id = data['id'];
icon = categories[data['categoryId']];
if (data['status'] != 'published') {
icon = categories.lock;
data['name'] = 'На модерации: ' + data['name'];
}
points[id] = L.marker(
[data['lat'], data['lng']], {icon: icon, title: data['name'], id: id, categoryId: data['categoryId']}
).on('click', function (e) {
if (!(id in pointsSources)) {
showInfo(e.target.options.id, true);
} else {
history.pushState({pointId: id}, document.title, "/?point=" + e.target.options.id);
document.title = e.target.options.title;
}
});
return points[id];
}
/**
* Загружает точки с сервера.
* @returns {Boolean}
*/
function initPoints(useBounds)
{
bounds = myMap.getBounds();
if (useBounds == true && getURLParameter('route') == 'null') {
bounds = Array(bounds._northEast.lat,bounds._northEast.lng,bounds._southWest.lat,bounds._southWest.lng)
} else {
bounds = 0
}
$.ajax({
url: "/json/points/",
data: {
bounds: bounds
},
success: function (data) {
for(var i=0; i<data.length; i++) {
if (typeof points[data[i].id] == 'undefined') {
markers.addLayer(constructPoint(data[i]));
}
}
myMap.addLayer(markers);
allPointsLoaded = bounds == 0;
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'));
if (getURLParameter('marker') == 'true') {
L.popup()
.setLatLng([getURLParameter('lat'), getURLParameter('lng')])
.setContent('Координаты: N°' + getURLParameter('lat').substring(0,8) + ' E°' + getURLParameter('lng').substring(0,8))
.openOn(myMap);
}
} else if (getURLParameter('track') != 'null')
{
showTrack(getURLParameter('track'))
$('#trackShowHide' + getURLParameter('track')).prop('checked', true);
}
}
});
return true;
}
function loadPointsInBounds()
{
if (allPointsLoaded) {
return true;
}
bounds = myMap.getBounds();
bounds = Array(bounds._northEast.lat,bounds._northEast.lng,bounds._southWest.lat,bounds._southWest.lng)
$.ajax({
url: "/json/points/",
data: {
bounds: bounds
},
success: function (data) {
if (typeof (data) != 'undefined' && data.length > 0) {
for(var i=0; i < data.length; i++) {
if (typeof points[data[i].id] == 'undefined') {
markers.addLayer(constructPoint(data[i]));
}
}
}
}
});
return true;
}
/**
* Показывает баллун для точки. Если данных для точки нет, то подгружает их с сервера.
* @param {type} id
* @returns {Boolean}
*/
function showInfo(id, mapClick,doNotPushToHistory)
{
if (!(id in points)) {
return false;
}
mapClick = Boolean(mapClick !== undefined && mapClick === true); // true если это клик по маркеру на карте
doNotPushToHistory = Boolean(doNotPushToHistory !== undefined && doNotPushToHistory === true); // true если НЕ добавляем в history
marker = points[id];
if (!(id in pointsSources))
{
marker.bindPopup("<h3>" + marker.options['title'] + "</h3><img src='/img/loading.gif' style='height: 16px;' /> Загрузка...").openPopup();
$.ajax({
url: "/json/point/id/" + id,
success: function (data) {
pointsSources[id] = data;
drawInfoPopup(id, true)
}
});
} else {
drawInfoPopup(id, !mapClick, doNotPushToHistory);
}
}
function drawInfoPopup(id, showPopup, doNotPushToHistory) {
data = pointsSources[id];
if (typeof (data.images) == 'object')
{
photos = '<div class="photoContainer">';
if (data.images.length > 1) {
photos += '<div class="photosCount"><span class="glyphicon glyphicon-camera"></span> <b>+' + (data.photosCount - 1) + '</b></div>';
}
photos += '<img src="/photos/small/' + data.img + '" onclick="showImage(\'' + id + '\')" />';
photos += '</div>';
}
else
{
photos = '<img src="' + data.img + '" onclick="showImage(\'' + id + '\')" />';
}
onModerate = '';
if (data.status != 'published') {
onModerate = 'На модерации: ';
}
description = '<div class="infoCard">' + '<h3>' + onModerate + data.name + '</h3>' + photos;
description += data.descriptionHtml;
description += '</div><div class="clear"></div>';
description += '<div class="btn-wrapper text-center"><div class="btn-group control">';
description += '<a type="button" class="btn btn-default" href="/point/' + id + '" title="Перейти на страницу точки"><span class="glyphicon glyphicon-eye-open"></span> <span class="label">Подробнее</span></a>';
description += '<button type="button" class="btn btn-default" onclick="addToRoute(' + id + ')" title="Добавить точку в маршрут"><span class="glyphicon glyphicon-map-marker"></span> <span class="label">В маршрут</span></button>';
// description += '<button type="button" class="btn btn-default" onclick="addRemoveLike(' + id + ')"><span id="myLikesButton" class="glyphicon glyphicon-' + (data.iLike ? 'ok' : 'thumbs-up') + '"></span> <span class="label">Нравится</span></button>';
description += '<button type="button" class="btn btn-default" onclick="addRemoveFavorite(' + id + ')" title="Добавить в избранное"><span id="myFavoritesButton" class="glyphicon glyphicon-star' + (data.inFavorites ? '' : '-empty') + ' "></span> <span class="label">Хочу посетить</span></button>';
// description += '<button type="button" class="btn btn-default" onclick="showRandomPoint();"><span class="glyphicon glyphicon-random"></span> <span class="label">Другая точка</span></button>';
if (isAdmin == '1' || data.status == "moderation")
{
description += '<button type="button" class="btn btn-default" onclick="editPoint(' + id + ')"><span class="glyphicon glyphicon-pencil"></span> <span class="label">Редактировать</span></button>';
if (getURLParameter('edit') == 'true')
{
editPoint(id);
}
}
description += '</div></div>';
maxWidth = $(window).width() < 500 ? ($(window).width() - 48) : 500;
maxHeight = $(window).height() < 300 ? $(window).height() : 300;
marker.options.description = description;
marker.bindPopup(marker.options.description, {maxWidth: maxWidth, minWidth: maxWidth, maxHeight: maxHeight});
markers.zoomToShowLayer(marker, function () {
bounds = myMap.getBounds();
diff = (bounds._northEast.lat - bounds._southWest.lat) / 4;
myMap.setView([points[id]._latlng.lat + diff, points[id]._latlng.lng], myMap.getZoom());
if (showPopup) {
marker.openPopup();
}
if (!doNotPushToHistory) {
history.pushState({pointId: id}, document.title, "/?point=" + id);
}
document.title = marker.options.title + ' wikipoints.ru';
});
setTimeout(function(){
if (myMap._popup && $(window).width() < 665) {
$('#control').hide(200);
}
}, 200);
return true;
}
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 showPointagreement()
{
$.ajax({
url: "/json/pointagreement",
success: function (data) {
$('#articleModal').modal('hide').remove();
$('body').append($(data));
$('#articleModal').modal('show');
}
});
}
// =============== ADD POINT
function addNewImage(link)
{
if ($('.extraImage', '#addPointForm').length < 10)
{
$('.extraImage', '#newIm').clone().appendTo('#imgsContainer').show(200);
if (link != undefined)
{
$('.form-control.images', '#addPointForm').last().attr('readonly', 'readonly').val(link);
$('.input-group-addon.type.button', '#addPointForm').remove();
}
}
}
function addNewExtraParam(name, value)
{
if ($('.extraParam', '#addPointForm').length < 10)
{
$('.extraParam', '#newExtraParam').clone().appendTo('#extraParamsContainer').show(200);
if (name != undefined && value != undefined)
{
$('.form-control.names', '#addPointForm').last().val(name);
$('.form-control.values', '#addPointForm').last().val(value);
}
}
}
function removeInput(el)
{
container = $(el).parent().parent();
container.hide(300, function () {
container.remove()
});
}
function switchType(el)
{
container = $(el).parent().parent();
if (container.hasClass('asLink'))
{
$('.ordering', container).val('FILE');
$('.ico span', container).removeClass('glyphicon-link').addClass('glyphicon-paperclip');
$('.form-control.images', container).attr('type', 'file').attr('name', 'photos[]');
$('.form-control.photoLinks', container).show();
container.removeClass('asLink');
el.attr('title', 'Указать ссылку на изображение');
$('.input-group-addon.type.ico', container).attr('title', 'Загрузите файл с изображением');
$('.input-group-addon.type.preview', container).hide();
}
else
{
$('.ordering', container).val('LINK');
$('.ico span', container).removeClass('glyphicon-paperclip').addClass('glyphicon-link');
$('.form-control.images', container).attr('type', 'text').attr('name', 'imgs[]');
$('.form-control.photoLinks', container).hide();
container.addClass('asLink');
el.attr('title', 'Загрузить файл');
$('.input-group-addon.type.ico', container).attr('title', 'Укажите ссылку на изображение');
$('.input-group-addon.type.preview', container).show();
}
}
function showPreview(el) {
img = $('input.images', el.parent()).val();
if ($('input.ordering', el.parent()).val() == 'FILE' || img.length < 12) {
return true;
}
if (img.toLowerCase().indexOf('http') == -1) {
img = '/photos/small/' + img;
}
$('#imgPreview').attr('src', img);
$('#imgPreview').show();
}
function hidePerview() {
$('#imgPreview').hide();
}
// ======================= VK Button
$(document).ready(function () {
if ($.cookie('doNotShowVKgroup')) {
$('#vkBigLogo').remove();
} else {
setTimeout(function () {
$('#vkBigLogo').css({'display': 'block'}).animate({'margin-left': "-225px"}, 1500);
}, 10000);
}
})
function hideBigLogo() {
$.cookie('doNotShowVKgroup', true, {expires: 100, path: '/'});
$('#vkBigLogo').animate({'margin-left': "285px"}, 1500, function () {
$('#vkBigLogo').remove();
});
}
// ======================= Swipe controll
window.addEventListener('load', function(){
var touchsurface = document.getElementById('box'),
startX,
startY,
dist,
threshold = 50,
allowedTime = 200,
elapsedTime,
startTime;
touchsurface.addEventListener('touchstart', function(e){
var touchobj = e.changedTouches[0];
dist = 0;
startX = touchobj.pageX;
startY = touchobj.pageY;
startTime = new Date().getTime();
}, false);
touchsurface.addEventListener('touchend', function(e){
var touchobj = e.changedTouches[0];
dist = touchobj.pageX - startX;
elapsedTime = new Date().getTime() - startTime;
var swiperightBol = (elapsedTime <= allowedTime && dist >= threshold && Math.abs(touchobj.pageY - startY) < dist);
if(swiperightBol) {
closeBox();
}
}, false);
}, false);
function getShortLink()
{
elements = Array();
$('#wayPoints div').each(function(i, el)
{
if ($(el).attr('pointId').length <= 10) {
elements.push({id: $(el).attr('pointId')});
} else {
coords = JSON.parse($(el).attr('pointId'));
lat = coords[0];
lng = coords[1];
elements.push({latLng: {lat: lat, lng: lng}});
}
});
$.ajax({
url: "/index/shorturlroute/",
data: {
elements: elements
},
success: function (data) {
$('#shortLink').val(data).select();
}
});
}
function onLocationFound(e) {
$.cookie('userLat', e.latlng.lat);
$.cookie('userLng', e.latlng.lng);
myMap.removeLayer(points.im);
points.im.setLatLng(e.latlng).addTo(myMap);
myMap.setView(e.latlng, myMap.getZoom());
return true;
}
function onLocationError(e) {
alert('Ошибка при определении координат: ' + e.message);
}