[GIS] Yandex Traffic layer position issue with using openlayers

openlayersopenlayers-2openstreetmapyandex

i have got issue about traffic map with using openlayers library.

Traffic layer shifting from sublayer.
so roads and streets are mismatch.
can you help me please.

in jsfiddle

The code from the jsfiddle is as follows:
http://jsfiddle.net/L4qubkhd/.

enter image description here

var projection1 = new OpenLayers.Projection('EPSG:4326');
var displayProjection1 = new OpenLayers.Projection('EPSG:900913');
var centerLat = 55.75;
var centerLon = 37.62;  

function yandex_getTileURL(bounds) {
    var r = this.map.getResolution();
    var maxExt = (this.maxExtent) ? this.maxExtent : YaBounds;
    var w = (this.tileSize) ? this.tileSize.w : 256;
    var h = (this.tileSize) ? this.tileSize.h : 256;
    var x = Math.round((bounds.left - maxExt.left)/(r * w));
    var y = Math.round((maxExt.top - bounds.top)/(r * h));
    var z = this.map.getZoom();
    var lim = Math.pow(2, z);
    if (y <0>= lim) {
        return OpenLayers.Util.getImagesLocation() + "404.png";
    } else {
        x = ((x % lim) + lim) % lim;

        var url = (this.url) ? this.url : "http://vec02.maps.yandex.net/";
        //console.log("http://vec0"+((x+y)%5)+".maps.yandex.net/tiles?l=map&v=2.16.0&x=" +x + "&y=" + y + "&z=" + z + "");
        return "http://vec02.maps.yandex.net/tiles?l=map&v=2.16.0&x=" +x + "&y=" + y + "&z=" + z + "";

       // return url + "tiles?l=map&v=2.2.3&x=" + x + "&y=" + y + "&z=" + z;
    }
};
function yandex_traffic_getTileURL(bounds) {
    var r = this.map.getResolution();
    var maxExt = (this.maxExtent) ? this.maxExtent : YaBounds;
    var w = (this.tileSize) ? this.tileSize.w : 256;
    var h = (this.tileSize) ? this.tileSize.h : 256;
    var x = Math.round((bounds.left - maxExt.left)/(r * w));
    var y = Math.round((maxExt.top - bounds.top)/(r * h));
    var z = this.map.getZoom();
    var lim = Math.pow(2, z);
    if (y <0>= lim) {
        return OpenLayers.Util.getImagesLocation() + "404.png";
    } else {
        x = ((x % lim) + lim) % lim;
        var url = (this.url) ? this.url : "http://jgo.maps.yandex.net/1.1/"; 
    return  url + "tiles?l=trf,trfe,trfl&lang=tr_TR&z=" + z + "&x=" + x + "&y=" + y + "&tm=1445001388";
    }
};

var options = {
        projection : new OpenLayers.Projection("EPSG:900913"),
        displayProjection : new OpenLayers.Projection("EPSG:4326"), 
        maxExtent : new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34), 
         maxResolution: 'auto',
        numZoomLevels : 19,
        isBaseLayer:true,
        units : "m",
        transitionEffect : null,
        zoomMethod : null,
        controls : [new OpenLayers.Control.PanZoomBar(),new OpenLayers.Control.Attribution(), new OpenLayers.Control.KeyboardDefaults(), new OpenLayers.Control.MousePosition(), new OpenLayers.Control.Navigation({
                zoomWheelEnabled : true,
                dragPanOptions : {
                    enableKinetic : true
                }
            }),new OpenLayers.Control.LayerSwitcher({ascending:true})]
    };

var map = new OpenLayers.Map('map',options);

var layerTraffic = new OpenLayers.Layer.TMS("TrafficLayer", "http://jgo.maps.yandex.net/1.1/", {
        tileOrigin: new OpenLayers.LonLat(map.maxExtent.left, map.maxExtent.bottom),
        visibility : true,
        type : "png",
        getURL : yandex_traffic_getTileURL,
        isBaseLayer : false,
        transitionEffect : null,
        zoomMethod : null
    });

 var YaBounds = new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34);



 var yandexMapLayer = new OpenLayers.Layer.Yandex("Yandex Map", { 
      sphericalMercator:true,
        type: "png",
        getURL: yandex_getTileURL,
        numZoomLevels: 18,
        attribution: '<a href="http://beta-maps.yandex.ru/">Яндекс.Карты</a>',
        transitionEffect: 'resize'
    });

var gmap = new OpenLayers.Layer.Google('Google Streets', // the default
    {
        numZoomLevels : 18

    });

map.addLayers([yandexMapLayer,gmap,layerTraffic]); 

 var lonlat = new OpenLayers.LonLat(centerLon,centerLat);
 lonlat.transform(map.displayProjection,map.projection);     
// map.setCenter(lonlat, 13); 
// 17501610 24592741    29.16935000 40.98790166 -0.19044156
 var yeditepeCad = new   OpenLayers.LonLat(17501610/600000.0,(24592741/600000.0)-0.19044156).transform( 
    new OpenLayers.Projection("EPSG:4326"),
    new OpenLayers.Projection("EPSG:900913"));
map.setCenter(lonlat, 9); 

Best Answer

Yandex uses different projection than Google Maps or OSM. You may find this post useful: https://habrahabr.ru/post/151103/ though it is in Russian and for Android Java (to add yandex maps layer to osmdroid project).

I hope you can use math from there, or try to google for the same math for OpenLayers.

Related Question