5

I can not understand the essence of the problem ... There is a web page with openlayers 4, on it as a base layers I can choose Bing, OSM, Yandex and others:

        src = new ol.source.BingMaps({
        imagerySet: 'AerialWithLabels',//'AerialWithLabels',
        key: '---'
    });
    bases["bing"] = new ol.layer.Tile({
        name: 'bing',
        title: 'Bing Maps aerial',
        is_base_layer: true,
        visible: false,
        source: src
    });

    src = new ol.source.XYZ({
        url: 'https://{a-c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png',
        visible: true
    });
    bases["tf"] = new ol.layer.Tile({
        name: 'tf',
        visible: false,
        source: src,
        is_base_layer: true
    });

    src = new ol.source.OSM();
    bases["osm"] = new ol.layer.Tile({
        name: 'osm',
        visible: false,
        source: src,
        is_base_layer: true
    });

With Yandex is more complicated:

        var yaex = [-20037508.342789244, -20037508.342789244, 20037508.342789244, 20037508.342789244];
    proj4.defs('EPSG:3395', '+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
    ol.proj.get('EPSG:3395').setExtent(yaex);

    bases["yandex"] = new ol.layer.Tile({
        source: new ol.source.XYZ({
            url: 'http://vec0{1-4}.maps.yandex.net/tiles?l=map&x={x}&y={y}&z={z}',
            projection: 'EPSG:3395',
            tileGrid: ol.tilegrid.createXYZ({
                extent: yaex
            })
        }),
        visible: false,
        is_base_layer: true
    });

I create a map as usual:

        var map = new ol.Map({
        controls: ol.control.defaults({
            attribution: false
        }).extend([mousePositionControl]),
        target: 'map',
        layers: [],
        view: new ol.View({
            projection: 'EPSG:3857'
        })
    });

Everything works fine, I can switch the base layers, everything is correct. Now I want to change the projection of the view to 4326:

view: new ol.View({
            projection: 'EPSG:4326'
        })

All the base layers are displayed correctly, but Yandex is not displayed. Chrome says:

proj4-src.js:1836 Uncaught TypeError: Cannot read property 'x' of null
at transformer (proj4-src.js:1836)
at forward (proj4-src.js:1875)
at ol-debug.js:5515
at ol.reproj.Triangulation.transformInv_ (ol-debug.js:67660)
at new ol.reproj.Triangulation (ol-debug.js:67720)
at new ol.reproj.Tile (ol-debug.js:70840)
at ol.source.XYZ.ol.source.TileImage.getTile (ol-debug.js:72003)
at ol.renderer.canvas.TileLayer.prepareFrame (ol-debug.js:69282)
at ol.renderer.canvas.Map.renderFrame (ol-debug.js:23128)
at ol.Map.renderFrame_ (ol-debug.js:31812)

Look more:

   function transformer(from, to, coords) {
 var transformedArray;
 if (Array.isArray(coords)) {
   transformedArray = transform(from, to, coords);
   if (coords.length === 3) {
     return [transformedArray.x, transformedArray.y, transformedArray.z];
   }
   else {
     return [transformedArray.x, transformedArray.y];// <--- ERROR HERE
   }
 }
 else {
   return transform(from, to, coords);
 }

}

transformedArray is null. null it is equal because transform() is called for point [0, -90], and Yandex has the extent [-180,-85,180,85], i.e. point outside the Yandex extent. I thought because of this, but I looked at Bing and they also had the same extent [-180,-85,180,85] as in Yandex. If I give Yandex a projection of 3857, then everything starts to be displayed, but the problem is that Yandex is then have offset. In general, I do not understand why this happens.

5

I tried to use yandex layer with EPSG:4326 attached on view and it works as expected. So it seems reprojecting tiles on client from 3395 to 4326 works fine.

This is the code I have used:

var yaex = [-20037508.342789244, -20037508.342789244, 20037508.342789244, 20037508.342789244];
proj4.defs('EPSG:3395', '+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
ol.proj.get('EPSG:3395').setExtent(yaex);

var layer = new ol.layer.Tile({
        source: new ol.source.XYZ({
            url: 'http://vec0{1-4}.maps.yandex.net/tiles?l=map&x={x}&y={y}&z={z}',
            projection: 'EPSG:3395',
            tileGrid: ol.tilegrid.createXYZ({
                extent: yaex
            })
        }),
        visible: true,
        is_base_layer: true
    });

var map = new ol.Map({
  layers: [layer],
  target: 'map',
  view: new ol.View({
    projection: 'EPSG:4326',
     center: [0, 0],
    zoom: 4
  })
});

And here is a fiddle to see it working. Maybe you are using a wrong version of proj4js. Check the "External Resources" of my fiddle to view the proj4js library I am using.

  • Thank you very very much! It's worked for me! I used proj4 of 2.4.3 version. With 2.3.14 it worked fine. – Pavel Aristarhov Apr 12 '17 at 9:07
  • glad to help my friend! – pavlos Apr 12 '17 at 9:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.