/* * 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 = description + data.descriptionHtml; //description = description + ' Подробнее...'; if (data.source.length > 11) { description = description + ' Подробнее...'; } description = description + '
'; description = description + '
'; description = description + ''; // description = description + ''; // description = description + ''; description = description + ''; if (isAdmin == '1') { description = description + ''; } 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]); } } }