diff --git a/ground/controllers/IndexController.php b/ground/controllers/IndexController.php
index 0010718..4786285 100644
--- a/ground/controllers/IndexController.php
+++ b/ground/controllers/IndexController.php
@@ -11,7 +11,14 @@ class IndexController extends Controller
self::addScript('/js/jquery-2.1.0.min.js');
self::addScript('/js/jquery-ui-1.10.4.custom.min.js');
self::addScript('http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js');
- self::addScript('/js/main.js?ver='.App::getConfig('version'));
+
+ self::addScript('http://maps.google.com/maps/api/js?v=3&sensor=false');
+ self::addScript('/js/tile/Google.js');
+
+ self::addScript('http://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU');
+ self::addScript('/js/tile/Yandex.js');
+
+ self::addScript('/js/main.js?ver='.App::getConfig('version'));
self::addScript('/js/bootstrap.min.js');
self::addStyle('/css/style.css?ver='.App::getConfig('version'));
self::addStyle('http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css');
diff --git a/ground/views/indexTemplate.php b/ground/views/indexTemplate.php
index 8f7cbfd..a329822 100644
--- a/ground/views/indexTemplate.php
+++ b/ground/views/indexTemplate.php
@@ -30,7 +30,11 @@
Фильтры и поиск
diff --git a/public/css/style.css b/public/css/style.css
index ccb3dd8..e020960 100644
--- a/public/css/style.css
+++ b/public/css/style.css
@@ -47,5 +47,8 @@ div#box div {display: none;}
div#box div div{display: block;}
div#box h3 {margin-top: 10px;}
+.layers {cursor: pointer;}
+.layers.selected {font-weight: bold;}
+
/*Leaflet FIX*/
.leaflet-popup-content-wrapper .leaflet-popup-scrolled {border-bottom: none;border-top: none;}
\ No newline at end of file
diff --git a/public/js/main.js b/public/js/main.js
index 7804860..4524d06 100644
--- a/public/js/main.js
+++ b/public/js/main.js
@@ -43,6 +43,8 @@ var pointsSources = Array();
var search;
var route = false;
var addPointInProcess = false;
+var layer;
+var layers = Array();
// -------------------------------- Libs ---------------------------------------
@@ -57,52 +59,14 @@ function getURLParameter(name) {
* @returns true
*/
function init() {
- myMap = L.map('map',{zoomControl: false}).setView([51.505, -0.09], 13);
- 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
- }).addTo(myMap);
-
-//
-// questLayer = function () {
-// return new ymaps.Layer(
-// 'http://otile1.mqcdn.com/tiles/1.0.0/osm/%z/%x/%y.png', {projection: ymaps.projection.sphericalMercator});
-// };
-// ymaps.layer.storage.add('quest#layer', questLayer);
-// ymaps.mapType.storage.add('quest#type', new ymaps.MapType('MapQuest', ['quest#layer']));
-//
-// osmLayer = function () {
-// return new ymaps.Layer(
-// 'http://c.tile.openstreetmap.org/%z/%x/%y.png', {projection: ymaps.projection.sphericalMercator});
-// };
-// ymaps.layer.storage.add('osm#layer', osmLayer);
-// ymaps.mapType.storage.add('osm#type', new ymaps.MapType('OpenStreetMap', ['osm#layer']));
-//
-// googleLayer = function () {
-// return new ymaps.Layer('http://mt0.google.com/vt/lyrs=s@176000000&hl=ru&%c', {projection: ymaps.projection.sphericalMercator,tileTransparent: true});
-// }
-// ymaps.layer.storage.add('google#layer', googleLayer);
-// ymaps.mapType.storage.add('google#type', new ymaps.MapType('Google Maps', ['google#layer']));
-//
-// myMap = new ymaps.Map("map", {
-// center: [ymaps.geolocation.latitude, ymaps.geolocation.longitude],
-// zoom: 12,
-// type:'quest#type',
-// behaviors: ['default', 'scrollZoom']
-// });
-//
-// myMap.controls.add('mapTools');
-// myMap.controls.add('smallZoomControl');
-// myMap.controls.add('scaleLine');
-//
-// typeSelector = new ymaps.control.TypeSelector();
-// typeSelector.addMapType('quest#type', 0);
-// typeSelector.addMapType('google#type', 1);
-// typeSelector.addMapType('yandex#publicMap', 2);
-// typeSelector.addMapType('osm#type', 3);
-// myMap.controls.add(typeSelector);
-// myMap.copyrights.add('Участники
OpenStreetMap');
-// myMap.copyrights.add('Tiles courtesy of
MapQuest');
+ myMap = L.map('map',{zoomControl: false}).setView([57, 30], 4);
+
+ 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('quest');
initCategories(); // getPoints внутри
@@ -641,3 +605,14 @@ function closeBox()
return true;
}
+
+function setLayer(name)
+{
+ if (layer)
+ myMap.removeLayer(layers[layer])
+
+ layer = name;
+ myMap.addLayer(layers[layer]);
+ $('.layers').removeClass('selected');
+ $('.'+layer+'Layer').addClass('selected');
+}
diff --git a/public/js/tile/Google.js b/public/js/tile/Google.js
new file mode 100644
index 0000000..353a14d
--- /dev/null
+++ b/public/js/tile/Google.js
@@ -0,0 +1,199 @@
+/*
+ * Google layer using Google Maps API
+ */
+
+/* global google: true */
+
+L.Google = L.Class.extend({
+ includes: L.Mixin.Events,
+
+ options: {
+ minZoom: 0,
+ maxZoom: 18,
+ tileSize: 256,
+ subdomains: 'abc',
+ errorTileUrl: '',
+ attribution: '',
+ opacity: 1,
+ continuousWorld: false,
+ noWrap: false,
+ mapOptions: {
+ backgroundColor: '#dddddd'
+ }
+ },
+
+ // Possible types: SATELLITE, ROADMAP, HYBRID, TERRAIN
+ initialize: function(type, options) {
+ L.Util.setOptions(this, options);
+
+ this._ready = google.maps.Map !== undefined;
+ if (!this._ready) L.Google.asyncWait.push(this);
+
+ this._type = type || 'SATELLITE';
+ },
+
+ onAdd: function(map, insertAtTheBottom) {
+ this._map = map;
+ this._insertAtTheBottom = insertAtTheBottom;
+
+ // create a container div for tiles
+ this._initContainer();
+ this._initMapObject();
+
+ // set up events
+ map.on('viewreset', this._resetCallback, this);
+
+ this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this);
+ map.on('move', this._update, this);
+
+ map.on('zoomanim', this._handleZoomAnim, this);
+
+ //20px instead of 1em to avoid a slight overlap with google's attribution
+ map._controlCorners.bottomright.style.marginBottom = '20px';
+
+ this._reset();
+ this._update();
+ },
+
+ onRemove: function(map) {
+ map._container.removeChild(this._container);
+
+ map.off('viewreset', this._resetCallback, this);
+
+ map.off('move', this._update, this);
+
+ map.off('zoomanim', this._handleZoomAnim, this);
+
+ map._controlCorners.bottomright.style.marginBottom = '0em';
+ },
+
+ getAttribution: function() {
+ return this.options.attribution;
+ },
+
+ setOpacity: function(opacity) {
+ this.options.opacity = opacity;
+ if (opacity < 1) {
+ L.DomUtil.setOpacity(this._container, opacity);
+ }
+ },
+
+ setElementSize: function(e, size) {
+ e.style.width = size.x + 'px';
+ e.style.height = size.y + 'px';
+ },
+
+ _initContainer: function() {
+ var tilePane = this._map._container,
+ first = tilePane.firstChild;
+
+ if (!this._container) {
+ this._container = L.DomUtil.create('div', 'leaflet-google-layer leaflet-top leaflet-left');
+ this._container.id = '_GMapContainer_' + L.Util.stamp(this);
+ this._container.style.zIndex = 'auto';
+ }
+
+ tilePane.insertBefore(this._container, first);
+
+ this.setOpacity(this.options.opacity);
+ this.setElementSize(this._container, this._map.getSize());
+ },
+
+ _initMapObject: function() {
+ if (!this._ready) return;
+ this._google_center = new google.maps.LatLng(0, 0);
+ var map = new google.maps.Map(this._container, {
+ center: this._google_center,
+ zoom: 0,
+ tilt: 0,
+ mapTypeId: google.maps.MapTypeId[this._type],
+ disableDefaultUI: true,
+ keyboardShortcuts: false,
+ draggable: false,
+ disableDoubleClickZoom: true,
+ scrollwheel: false,
+ streetViewControl: false,
+ styles: this.options.mapOptions.styles,
+ backgroundColor: this.options.mapOptions.backgroundColor
+ });
+
+ var _this = this;
+ this._reposition = google.maps.event.addListenerOnce(map, 'center_changed',
+ function() { _this.onReposition(); });
+ this._google = map;
+
+ google.maps.event.addListenerOnce(map, 'idle',
+ function() { _this._checkZoomLevels(); });
+ //Reporting that map-object was initialized.
+ this.fire('MapObjectInitialized', { mapObject: map });
+ },
+
+ _checkZoomLevels: function() {
+ //setting the zoom level on the Google map may result in a different zoom level than the one requested
+ //(it won't go beyond the level for which they have data).
+ // verify and make sure the zoom levels on both Leaflet and Google maps are consistent
+ if (this._google.getZoom() !== this._map.getZoom()) {
+ //zoom levels are out of sync. Set the leaflet zoom level to match the google one
+ this._map.setZoom( this._google.getZoom() );
+ }
+ },
+
+ _resetCallback: function(e) {
+ this._reset(e.hard);
+ },
+
+ _reset: function(clearOldContainer) {
+ this._initContainer();
+ },
+
+ _update: function(e) {
+ if (!this._google) return;
+ this._resize();
+
+ var center = this._map.getCenter();
+ var _center = new google.maps.LatLng(center.lat, center.lng);
+
+ this._google.setCenter(_center);
+ this._google.setZoom(this._map.getZoom());
+
+ this._checkZoomLevels();
+ },
+
+ _resize: function() {
+ var size = this._map.getSize();
+ if (this._container.style.width === size.x &&
+ this._container.style.height === size.y)
+ return;
+ this.setElementSize(this._container, size);
+ this.onReposition();
+ },
+
+
+ _handleZoomAnim: function (e) {
+ var center = e.center;
+ var _center = new google.maps.LatLng(center.lat, center.lng);
+
+ this._google.setCenter(_center);
+ this._google.setZoom(Math.round(e.zoom));
+ },
+
+
+ onReposition: function() {
+ if (!this._google) return;
+ google.maps.event.trigger(this._google, 'resize');
+ }
+});
+
+L.Google.asyncWait = [];
+L.Google.asyncInitialize = function() {
+ var i;
+ for (i = 0; i < L.Google.asyncWait.length; i++) {
+ var o = L.Google.asyncWait[i];
+ o._ready = true;
+ if (o._container) {
+ o._initMapObject();
+ o._update();
+ }
+ }
+ L.Google.asyncWait = [];
+};
diff --git a/public/js/tile/Yandex.js b/public/js/tile/Yandex.js
new file mode 100644
index 0000000..afa0aa1
--- /dev/null
+++ b/public/js/tile/Yandex.js
@@ -0,0 +1,190 @@
+/*
+ * L.TileLayer is used for standard xyz-numbered tile layers.
+ */
+
+/* global ymaps: true */
+/* global console: true */
+
+L.Yandex = L.Class.extend({
+ includes: L.Mixin.Events,
+
+ options: {
+ minZoom: 0,
+ maxZoom: 18,
+ attribution: '',
+ opacity: 1,
+ traffic: false
+ },
+
+ possibleShortMapTypes: {
+ schemaMap: 'map',
+ satelliteMap: 'satellite',
+ hybridMap: 'hybrid',
+ publicMap: 'publicMap',
+ publicMapInHybridView: 'publicMapHybrid'
+ },
+
+ _getPossibleMapType: function (mapType) {
+ var result = 'yandex#map';
+ if (typeof mapType !== 'string') {
+ return result;
+ }
+ for (var key in this.possibleShortMapTypes) {
+ if (mapType === this.possibleShortMapTypes[key]) {
+ result = 'yandex#' + mapType;
+ break;
+ }
+ if (mapType === ('yandex#' + this.possibleShortMapTypes[key])) {
+ result = mapType;
+ }
+ }
+ return result;
+ },
+
+ // Possible types: yandex#map, yandex#satellite, yandex#hybrid, yandex#publicMap, yandex#publicMapHybrid
+ // Or their short names: map, satellite, hybrid, publicMap, publicMapHybrid
+ initialize: function(type, options) {
+ L.Util.setOptions(this, options);
+ //Assigning an initial map type for the Yandex layer
+ this._type = this._getPossibleMapType(type);
+ },
+
+ onAdd: function(map, insertAtTheBottom) {
+ this._map = map;
+ this._insertAtTheBottom = insertAtTheBottom;
+
+ // create a container div for tiles
+ this._initContainer();
+ this._initMapObject();
+
+ // set up events
+ map.on('viewreset', this._resetCallback, this);
+
+ this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this);
+ map.on('move', this._update, this);
+
+ map._controlCorners.bottomright.style.marginBottom = '3em';
+
+ this._reset();
+ this._update(true);
+ },
+
+ onRemove: function(map) {
+ this._map._container.removeChild(this._container);
+
+ this._map.off('viewreset', this._resetCallback, this);
+
+ this._map.off('move', this._update, this);
+
+ map._controlCorners.bottomright.style.marginBottom = '0em';
+ },
+
+ getAttribution: function() {
+ return this.options.attribution;
+ },
+
+ setOpacity: function(opacity) {
+ this.options.opacity = opacity;
+ if (opacity < 1) {
+ L.DomUtil.setOpacity(this._container, opacity);
+ }
+ },
+
+ setElementSize: function(e, size) {
+ e.style.width = size.x + 'px';
+ e.style.height = size.y + 'px';
+ },
+
+ _initContainer: function() {
+ var tilePane = this._map._container,
+ first = tilePane.firstChild;
+
+ if (!this._container) {
+ this._container = L.DomUtil.create('div', 'leaflet-yandex-layer leaflet-top leaflet-left');
+ this._container.id = '_YMapContainer_' + L.Util.stamp(this);
+ this._container.style.zIndex = 'auto';
+ }
+
+ if (this.options.overlay) {
+ first = this._map._container.getElementsByClassName('leaflet-map-pane')[0];
+ first = first.nextSibling;
+ // XXX: Bug with layer order
+ if (L.Browser.opera)
+ this._container.className += ' leaflet-objects-pane';
+ }
+ tilePane.insertBefore(this._container, first);
+
+ this.setOpacity(this.options.opacity);
+ this.setElementSize(this._container, this._map.getSize());
+ },
+
+ _initMapObject: function() {
+ if (this._yandex) return;
+
+ // Check that ymaps.Map is ready
+ if (ymaps.Map === undefined) {
+ if (console) {
+ console.debug('L.Yandex: Waiting on ymaps.load("package.map")');
+ }
+ return ymaps.load(['package.map'], this._initMapObject, this);
+ }
+
+ // If traffic layer is requested check if control.TrafficControl is ready
+ if (this.options.traffic)
+ if (ymaps.control === undefined ||
+ ymaps.control.TrafficControl === undefined) {
+ if (console) {
+ console.debug('L.Yandex: loading traffic and controls');
+ }
+ return ymaps.load(['package.traffic', 'package.controls'],
+ this._initMapObject, this);
+ }
+ //Creating ymaps map-object without any default controls on it
+ var map = new ymaps.Map(this._container, { center: [0, 0], zoom: 0, behaviors: [], controls: [] });
+
+ if (this.options.traffic)
+ map.controls.add(new ymaps.control.TrafficControl({shown: true}));
+
+ if (this._type === 'yandex#null') {
+ this._type = new ymaps.MapType('null', []);
+ map.container.getElement().style.background = 'transparent';
+ }
+ map.setType(this._type);
+
+ this._yandex = map;
+ this._update(true);
+
+ //Reporting that map-object was initialized
+ this.fire('MapObjectInitialized', { mapObject: map });
+ },
+
+ _resetCallback: function(e) {
+ this._reset(e.hard);
+ },
+
+ _reset: function(clearOldContainer) {
+ this._initContainer();
+ },
+
+ _update: function(force) {
+ if (!this._yandex) return;
+ this._resize(force);
+
+ var center = this._map.getCenter();
+ var _center = [center.lat, center.lng];
+ var zoom = this._map.getZoom();
+
+ if (force || this._yandex.getZoom() !== zoom)
+ this._yandex.setZoom(zoom);
+ this._yandex.panTo(_center, {duration: 0, delay: 0});
+ },
+
+ _resize: function(force) {
+ var size = this._map.getSize(), style = this._container.style;
+ if (style.width === size.x + 'px' && style.height === size.y + 'px')
+ if (force !== true) return;
+ this.setElementSize(this._container, size);
+ var b = this._map.getBounds(), sw = b.getSouthWest(), ne = b.getNorthEast();
+ this._yandex.container.fitToViewport();
+ }
+});