WME Yandex Layer

Добавление слоя с Yandex картами

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         WME Yandex Layer
// @namespace    https://greasyfork.org/ru/scripts/10760-wme-yandex-layer
// @version      0.12
// @description  Добавление слоя с Yandex картами
// @author       ixxvivxxi
// @include      https://www.waze.com/editor*
// @include      https://www.waze.com/*/editor*
// @include      https://beta.waze.com/editor*
// @include      https://beta.waze.com/*/editor*
// @grant        none
// ==/UserScript==

(function()
{
  //var WM = {};
  OpenLayers.Layer.Yandex = OpenLayers.Class(
    OpenLayers.Layer.EventPane,
    OpenLayers.Layer.FixedZoomLevels, {
      MIN_ZOOM_LEVEL:0,
      MAX_ZOOM_LEVEL:20,
      attribution:'<a href="http://beta-maps.yandex.ru"  class="mapLogo" title="Yandex maps"><img src="https://api-maps.yandex.ru/i/0.2/YMaps-logo.png" alt="Yandex logo" /></a>',
      type:null,
      sphericalMercator:false,
      dragObject:null,
      initialize:function (name, options) {
        OpenLayers.Layer.EventPane.prototype.initialize.apply(this, arguments);
        OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,
                                                                    arguments);
        this.addContainerPxFunction();
        if (this.sphericalMercator) {
          OpenLayers.Util.extend(this, OpenLayers.Layer.SphericalMercator);
          this.initMercatorParameters();
        }
      },
      
      loadMapObject:function () {
        try {
          this.mapObject = new YMaps.Map(this.div);
          this.mapObject.disableDragging();
          this.dragPanMapObject = null;
        }
        catch (e) {
          OpenLayers.Console.error(e);
        }
        
      },
      
      setMap:function (map) {
        OpenLayers.Layer.EventPane.prototype.setMap.apply(this, arguments);
        
        if (this.type !== null) {
          this.map.events.register("moveend", this, this.setMapType);
        }
      },
      
      setMapType2: function (type) {
        this.mapObject.setType(type);
      },
      
      setMapType:function () {
        if (this.mapObject.getCenter() != null) {
          this.mapObject.setType(this.type);//setType is function of YMaps.Map
          this.map.events.unregister("moveend", this, this.setType);
        }
      },
      
      onMapResize() {
        if (this.visibility) {
          this.mapObject.redraw();
        } else {
          this.windowResized = true;
        }
      },
      
      
      
      getOLBoundsFromMapObjectBounds:function (moBounds) {
        var olBounds = null;
        if (moBounds != null) {
          var sw = moBounds.getSouthWest();
          var ne = moBounds.getNorthEast();
          if (this.sphericalMercator) {
            sw = this.forwardMercator(sw.lng(), sw.lat());
            ne = this.forwardMercator(ne.lng(), ne.lat());
          } else {
            sw = new OpenLayers.LonLat(sw.lng(), sw.lat());
            ne = new OpenLayers.LonLat(ne.lng(), ne.lat());
          }
          olBounds = new OpenLayers.Bounds(sw.lon,
                                           sw.lat,
                                           ne.lon,
                                           ne.lat);
        }
        return olBounds;
      },
      
      getMapObjectBoundsFromOLBounds:function (olBounds) {
        var moBounds = null;
        if (olBounds != null) {
          var sw = this.sphericalMercator ?
          this.inverseMercator(olBounds.bottom, olBounds.left) :
          new OpenLayers.LonLat(olBounds.bottom, olBounds.left);
          var ne = this.sphericalMercator ?
          this.inverseMercator(olBounds.top, olBounds.right) :
          new OpenLayers.LonLat(olBounds.top, olBounds.right);
          moBounds = new YMaps.GeoBounds(new YMaps.GeoPoint(sw.lon, sw.lat),
                                         new YMaps.GeoPoint(ne.lon, ne.lat));
        }
        return moBounds;
      },
      
      addContainerPxFunction:function () {
        if ((typeof YMaps.Map != "undefined") && !YMaps.Map.prototype.fromLatLngToContainerPixel) {
          
          YMaps.Map.prototype.fromLatLngToContainerPixel = function (geoPoint) {
            // first we translate into "DivPixel"
            var divPoint = this.fromLatLngToDivPixel(geoPoint);
            // locate the sliding "Div" div
            var div = this.getContainer().firstChild.firstChild;
            //adjust by the offset of "Div"
            divPoint.x += div.offsetLeft;
            divPoint.y += div.offsetTop;
            return divPoint;
          };
        }
      },
      
      getWarningHTML:function () {
        return OpenLayers.i18n("yandexWarning");
      },
      
      setMapObjectCenter:function (center, zoom) {
        this.mapObject.setCenter(center, zoom);
      },
      
      getMapObjectCenter:function () {
        return this.mapObject.getCenter();
      },
      getMapObjectZoom:function () {
        return this.mapObject.getZoom();

        
      },
      
      
      getMapObjectLonLatFromMapObjectPixel:function (moPixel) {
        //return this.mapObject.fromContainerPixelToLatLng(moPixel);
        return this.mapObject.converter.mapPixelsToCoordinates(moPixel);
      },
      
      getMapObjectPixelFromMapObjectLonLat:function (moLonLat) {
        return this.mapObject.converter.coordinatesToMapPixels(moLonLat);
      },
      
      getMapObjectZoomFromMapObjectBounds:function (moBounds) {
        this.mapObject.setBounds(moBounds);
        
        return this.mapObject.getZoom();
      },
      
      getLongitudeFromMapObjectLonLat:function (moLonLat) {
        return this.sphericalMercator ?
        this.forwardMercator(moLonLat.getLng(), moLonLat.getLat()).lon :
        moLonLat.getLng();
      },
      
      getLatitudeFromMapObjectLonLat:function (moLonLat) {
        var lat = this.sphericalMercator ?
        this.forwardMercator(moLonLat.getLng(), moLonLat.getLat()).lat :
        moLonLat.getLat();
        return lat;
      },
      
      getMapObjectLonLatFromLonLat:function (lon, lat) {
        var gLatLng;
        if (this.sphericalMercator) {
          var lonlat = this.inverseMercator(lon, lat);
          gLatLng = new YMaps.GeoPoint(lonlat.lon, lonlat.lat);
        } else {
          gLatLng = new YMaps.GeoPoint(lon, lat);
        }
        return gLatLng;
      },
      
      getXFromMapObjectPixel:function (moPixel) {
        return moPixel.x;
      },
      
      getYFromMapObjectPixel:function (moPixel) {
        return moPixel.y;
      },
      
      getMapObjectPixelFromXY:function (x, y) {
        return new YMaps.Point(x, y);
      },
      
      CLASS_NAME:"OpenLayers.Layer.Yandex"
    });
  

  
  function startYa() {
    var evntObj = {},
    activeLayer = {},
   WM = window.Waze.map;
   var googleMapId = WM.layers.map(item => item.id).filter(item => item.indexOf("Google") > 0).join();
  
      
    var yandexAerialLayer = new OpenLayers.Layer.Yandex("Yandex Satellite", {
      type: YMaps.MapType.SATELLITE,
      sphericalMercator:true,
      numZoomLevels: 21,
      name: 'Yandex Satellite',
      uniqueName: "yandex_satellite",
    });
    var yandexMapLayer = new OpenLayers.Layer.Yandex("Yandex Map", {
      type: YMaps.MapType.MAP,
      sphericalMercator:true,
      numZoomLevels: 21, 
      name: 'Yandex Map',
      uniqueName: "yandex_map",
    });
      
    WM.addLayer(yandexAerialLayer);

    yandexAerialLayer.setMapType2(YMaps.MapType.SATELLITE);
    WM.setLayerIndex(yandexAerialLayer,1); 
    
    WM.addLayer(yandexMapLayer);
    WM.setLayerIndex(yandexMapLayer,2);
    
    WM.events.register("zoomend", map, function() {
      if (activeLayer.name == "Yandex Satellite" || activeLayer.name == "Yandex Map") {
        activeLayer.redraw();
        update();
      } 
    });
    
    WM.events.register("moveend", map, function() {
      if (activeLayer.name == "Yandex Satellite" || activeLayer.name == "Yandex Map") {
        activeLayer.redraw();
        update();
      }
    });
    
    
    WM.events.register( "changelayer", evntObj, changeLayer);
    
    function changeLayer(e) {
      if (e.property == "visibility" && e.layer.visibility && e.layer.isBaseLayer) {
        activeLayer = e.layer;
        if (activeLayer.name == "Yandex Satellite" || activeLayer.name == "Yandex Map") {
            if (activeLayer.name == "Yandex Satellite") {
               WM.getLayer(yandexMapLayer.id).setVisibility(false);
               WM.getLayer(googleMapId).setVisibility(false);
            } else {;
               WM.getLayer(yandexAerialLayer.id).setVisibility(false);
               WM.getLayer(googleMapId).setVisibility(false);
            }
            activeLayer.map.$map.resize();
        } else if (activeLayer.id == googleMapId) {
          WM.getLayer(yandexAerialLayer.id).setVisibility(false);
          WM.getLayer(yandexMapLayer.id).setVisibility(false);
      }
      }
    }      
    
      
     var buttonContainer = $('#layer-switcher-group_display').parent().parent();
      
      $('<li><div class="controls-container toggler"><input class="layer-switcher-item_yandex_map toggle" id="layer-switcher-item_yandex_map" type="checkbox"><label for="layer-switcher-item_yandex_map"><span class="label-text">Yandex map</span></label></div></li>').insertAfter(buttonContainer.find('.children li:first'));
      $('<li><div class="controls-container toggler"><input class="yandex_satellite toggle" id="layer-switcher-item_yandex_satellite" type="checkbox"><label for="layer-switcher-item_yandex_satellite"><span class="label-text">Yandex Satellite</span></label></div></li>').insertAfter(buttonContainer.find('.children li:first'));
      
      buttonContainer.on('click', '#layer-switcher-item_yandex_map', function(event) {
          if ($(this)[0].checked) {
              buttonContainer.find('#layer-switcher-item_yandex_satellite')[0].checked = false;
              buttonContainer.find('#layer-switcher-item_satellite_imagery')[0].checked = false;
               WM.getLayer(yandexMapLayer.id).setVisibility(true);
//               WM.getLayer(yandexAerialLayer.id).setVisibility(false);
//               WM.getLayer(googleMapId).setVisibility(false);
          } else {
              WM.getLayer(yandexMapLayer.id).setVisibility(false);
          }
      });
      
      buttonContainer.on('click', '#layer-switcher-item_yandex_satellite', function(event) {
          if ($(this)[0].checked) {
              WM.getLayer(yandexAerialLayer.id).setVisibility(true);
              buttonContainer.find('#layer-switcher-item_yandex_map')[0].checked = false;
              buttonContainer.find('#layer-switcher-item_satellite_imagery')[0].checked = false;
          } else {
              WM.getLayer(yandexAerialLayer.id).setVisibility(false);
          }
      });
      
      buttonContainer.on('click', '#layer-switcher-item_satellite_imagery', function(event) {
          if ($(this)[0].checked) {
              buttonContainer.find('#layer-switcher-item_yandex_map')[0].checked = false;
              buttonContainer.find('#layer-switcher-item_yandex_satellite')[0].checked = false;
          }
      });
      

  var sx = $('#toolbar').find('#WAS_sx'),
  sy = $('#toolbar').find('#WAS_sy');
 
  sx.change(update);
  sy.change(update);
 
 
 function update() {
   if (activeLayer.name == "Yandex Satellite" || activeLayer.name == "Yandex Map") {
     
     var ipu = OpenLayers.INCHES_PER_UNIT;
     var metersPerPixel = WM.getResolution() * ipu['m'] / ipu[WM.getUnits()];
     var shiftX = parseInt(sx.val(), 10);
     var shiftY = parseInt(sy.val(), 10);
     
     activeLayer.div.style.left = Math.round(shiftX / metersPerPixel) + 'px';
     activeLayer.div.style.top =  Math.round(shiftY / metersPerPixel) + 'px';
   }
 }  
 
  }
  
  
  $(function(){
    
    $.getScript( "https://api-maps.yandex.ru/1.1/" )
    .done(function( script, textStatus ) {
      $.getScript( "https://api-maps.yandex.ru/1.1/index.xml" )
      .done(function( script, textStatus ) {
        $.getScript( "https://api-maps.yandex.ru/1.1/_YMaps.js?v=1.1.21-43" )  
        .done(function( script, textStatus ) {
          startYa();
        });
      });
    });
  });
  
})();