/* * Let's GO! */ ymaps.ready(init); var myMap; var categories; var points = Array(); var search; var route = false; // -------------------------------- Libs --------------------------------------- function getURLParameter(name) { return decodeURI((RegExp(name + '=' + '(.+?)(&|$)').exec(location.search) || [, null])[1]); } // ----------------------------------------------------------------------------- /** * Инициализируем переменные и подгружаем данные. * @returns true */ function init() { myMap = new ymaps.Map("map", { center: [ymaps.geolocation.latitude, ymaps.geolocation.longitude], zoom: 12, behaviors: ['default', 'scrollZoom'] }); myMap.controls.add('mapTools'); myMap.controls.add('typeSelector'); myMap.controls.add('smallZoomControl'); myMap.controls.add('scaleLine'); initCategories() getPoints(); myMap.events.add('click', function(e) { if (!myMap.balloon.isOpen()) { if ($('#addPointButton').hasClass('btn-success')) { coords = e.get('coordPosition'); $('#addPointLat').val(coords[0].toPrecision(11)); $('#addPointLng').val(coords[1].toPrecision(11)); $('#addPointModal').modal('show'); } } else { myMap.balloon.close(); } }); myMap.events.add('boundschange', function(e) { if (!myMap.balloon.isOpen() && $('#routeWindow').css('display') == 'none') { history.pushState({}, document.title, "/?lat=" + e.get('newCenter')[0] + "&lng=" + e.get('newCenter')[1] + "&zoom=" + e.get('newZoom')); } }); points.im = new ymaps.Placemark( [ymaps.geolocation.latitude, ymaps.geolocation.longitude], { balloonContentHeader: 'Вы здесь', hintContent: 'Ваше местоположение', balloonContent: '' }, { iconImageHref: '/ico/man.png', iconImageSize: [32, 37], iconImageOffset: [-16, -33], } ); myMap.geoObjects.add(points.im); $("#wayPoints").sortable(); $("#wayPoints").disableSelection(); return true; } /** * Создаёт точку для карту - Placemark. * @param {Array} data * @returns {ymaps.Placemark} */ function constructPoint(data) { id = data['id']; points[id] = new ymaps.Placemark( [data['lat'], data['lng']], { hintContent: data['name'], id: id }, { iconImageHref: data['categoryIcon'], iconImageSize: [32, 37], iconImageOffset: [-16, -33], openEmptyBalloon: true, balloonCloseButton: true }); points[id].events.add('click', function(e) { showInfo(e.get('target').properties.get('id')); }); return points[id]; } /** * Загружает точки с сервера. * @returns {Boolean} */ function getPoints() { $.ajax({ url: "/json/points/", success: function(data) { for (var k in data) { myMap.geoObjects.add(constructPoint(data[k])); } if (getURLParameter('point') != 'null') { showInfo(getURLParameter('point')); } else if (getURLParameter('route') != 'null') { loadRouteJSON(getURLParameter('route')); buildRoute(); } else if ((getURLParameter('lat') != 'null') && (getURLParameter('lng') != 'null') && (getURLParameter('zoom') != 'null')) { myMap.setCenter([getURLParameter('lat'), getURLParameter('lng')], getURLParameter('zoom')); } } }); return true; } /** * Показывает баллун для точки. Если данных для точки нет, то подгружает их с сервера. * @param {type} id * @returns {Boolean} */ function showInfo(id) { if (!(id in points) || points[id].properties.get('balloonContent') == undefined) { points[id].properties.set('balloonContent', 'Загрузка...'); $.ajax({ url: "/json/point/id/" + id, success: function(data) { description = '
' + '' + '

' + data.name + '

' + '
' + '' + '
' + data.description + ' Подробнее...
' points[id].properties.set('balloonContent', description); point = getURLParameter('point'); if (point != null && id == point) { points[point].balloon.open(); } } }); } history.pushState({}, document.title, "/?point=" + id); return true; } /** * Загружает с сервера список категорий точек. * @returns {Boolean} */ function initCategories() { $.ajax({ url: "/json/categories/", success: function(data) { categories = data; } }); return true; } /** * Производит поиск по адресу или координатам, введённым в соответствующее поле. * @returns {undefined} */ function searchAdderess() { var myGeocoder = ymaps.geocode($('#addressField').val()); myGeocoder.then( function(res) { search = new ymaps.Placemark(res.geoObjects.get(0).geometry.getCoordinates()); myMap.geoObjects.add(search); myMap.setCenter(res.geoObjects.get(0).geometry.getCoordinates(), 10); }, function(err) { } ); } /** * Пытается более точно определить координаты пользователя на карте и, при необходимости, обновляет положение точки "im" * @returns {undefined} */ function showMeOnTheMap() { navigator.geolocation.getCurrentPosition(function(pos) { points.im.geometry.setCoordinates([pos.coords.latitude, pos.coords.longitude]); myMap.setCenter(points.im.geometry.getCoordinates()); }); myMap.setCenter(points.im.geometry.getCoordinates()); } /** * Активирет добавление точки - ждёт выбор координат, меняет курсор на прицел. * @returns {Boolean} */ function activateAddPoint() { $('#addPointButton').toggleClass('btn-success').toggleClass('btn-default'); if ($('#addPointButton').hasClass('btn-success')) myMap.cursors.push('crosshair'); else myMap.cursors.push('arrow'); return true; } /** * Отправляет данные по новой точке на сервер. * @returns {Boolean} */ function addPoint() { $('.form-group').removeClass('has-error'); $.ajax({ type: "POST", url: "/json/addpoint/", data: { name: $('#addPointName').val(), img: $('#addPointImg').val(), description: $('#addPointDescription').val(), categoryId: $('#addPointCategoryId').val(), source: $('#addPointSource').val(), lat: $('#addPointLat').val(), lng: $('#addPointLng').val() }, success: function(data) { balloon = myMap.balloon.open([$('#addPointLat').val(), $('#addPointLng').val()], {content: 'Точка успешно добавлена!'}, {closeButton: false}); setTimeout(function() { balloon.close(); }, 3000); obj = {}; obj.id = data; obj.name = $('#addPointName').val(); obj.lat = $('#addPointLat').val(); obj.lng = $('#addPointLng').val(); obj.categoryIcon = categories[$('#addPointCategoryId').val()].icon; setTimeout(function() { myMap.geoObjects.add(constructPoint(obj)); }, 3000); $('#addPointModal').modal('hide'); // Clear form $('#addPointForm input').val(''); $('#addPointForm textarea').val(''); $('.form-group').removeClass('has-error'); $('#addPointButton').removeClass('btn-success').addClass('btn-default'); myMap.cursors.push('arrow'); 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) $('#addPointImg').parent().addClass('has-error'); else if (k == 3) $('#addPointDescription').parent().addClass('has-error'); else message += response[k] + '; '; } } if (message != '') alert(message); return false; } }); } /** * Строит маршрут по выбранным точкам. * @returns {undefined} */ function buildRoute() { wayPoints = Array(); if (route) myMap.geoObjects.remove(route); $('#wayPoints div').each(function(i, el) { wayPoints.push(points[$(el).attr('pointId')].geometry.getCoordinates()); }); ymaps.route(wayPoints, { mapStateAutoApply: true }).then(function(newRoute) { route = newRoute; route.options.set({ // в балуне выводим только информацию о времени движения с учетом пробок balloonContenBodyLayout: ymaps.templateLayoutFactory.createClass('$[properties.humanJamsTime]'), strokeColor: '9000ffff', opacity: 0.9 }); myMap.geoObjects.add(route); distance = Math.round(route.getLength() / 1000); $('#routeDistance').text(distance + ' км.'); routeToURL(); }); } /** * Сохраняет маршрут на сервере. * @returns {undefined} */ function saveRoute() { wayPoints = Array(); name = prompt('Как назвать маршрут?', 'Мой маршрут'); $('#wayPoints div').each(function(i, el) { wayPoints.push($(el).attr('pointId')); }); if (name && name != '') $.ajax({ type: "POST", url: "/json/saveroute/", data: { name: name, points: wayPoints }, success: function(data) { console.log(data); }, error: function(data) { console.log(data); } }); } /** * Формирует список точек маршрута из JSON.ы * @param {JSON} data * @returns {Boolean} */ function loadRouteJSON(data) { $('#wayPoints').text(''); response = JSON.parse(data); for (var k in response) { addToRoute(response[k]); } return true; } /** * Подгружает маршрут с заданныи ID с сервера. * @param {Integer} id * @returns {undefined} */ function loadRoute(id) { $('#myRoutesWindow').hide(200); $.ajax({ url: "/json/route/id/" + id, success: function(data) { loadRouteJSON(data) buildRoute(); } }); } /** * Удаляет маршрут с заданным ID с сервера. * @param {Integer} id * @returns {undefined} */ function deleteRoute(id) { $.ajax({ url: "/json/deleteroute/id/" + id, success: function(data) { console.log('Route '+id+' was removed.'); } }); } /** * Добавляет точку с маршрут (в список выбранных точек) * @param {Integer} id * @returns {Boolean} */ function addToRoute(id) { $('#wayPoints').append('
× ' + points[id].properties.get('hintContent') + '
'); myMap.balloon.close(); $('#routeWindow').show(200); return true; } /** * Формирует URL в соответсвии с точками маршрута. * @returns {Boolean} */ function routeToURL() { wayPoints = Array(); $('#wayPoints div').each(function(i, el) { wayPoints.push($(el).attr('pointId')); }); history.pushState({}, document.title, "/?route=" + JSON.stringify(wayPoints)); return true; }