I am trying to add two layers to a Map using OpenLayers 3, one is the information from Bing Maps, and the other is data from the Ordnance Survey data.

I have both maps displaying correctly in separate files, however I am unable to combine the two correctly on one map. When adding the two layers to the same map, it seems the Ordnance Survey layer is positioned at the [0,0] lat long point, rather than over the UK. Is there a way to align the two correctly, so they match each other? The accuracy of the overlay doesn't have to be too exact, as my final plan is to switch between the two layers at different resolutions.

This is my first real experience with GIS, so please forgive any obvious mistakes.

The code I currently have is

    var extent = [0, 0, 800000, 1300000];
    proj4.defs("EPSG:27700", '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717' +
        ' +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs');
    var proj = 'EPSG:27700';

    var resolutions = [2500, 1000, 500, 200, 100, 50, 25, 10, 5, 2, 1];

    var map = new ol.Map({
      //controls: [ new OpenLayers.Control.Navigation(), new OpenLayers.Control.PanZoomBar(), new OpenLayers.Control.LayerSwitcher()],
      layers: [
        new ol.layer.Tile({
          source: new ol.source.TileWMS({
            url: 'http://openspace.ordnancesurvey.co.uk/osmapapi/ts',
            params: {
              'VERSION': '1.1.1',
              'LAYERS': '200', // initial value; see view resolution below
              'KEY': 'API_KEY',
              'URL': document.URL
            // needs tilegrid otherwise uses inappropriate global grid
            tileGrid: new ol.tilegrid.TileGrid({
              tileSizes: [200, 200, 200, 200, 200, 200, 200, 200, 200, 250, 250],
              resolutions: resolutions,
              origin: ol.proj.transform([400000, 650000], proj, 'EPSG:3857')
          extent: extent,
          projection: proj,
          maxResolution: 1000
        new ol.layer.Tile({
            source: new ol.source.BingMaps({
                imagerySet: 'Road',
                key: 'API_KEY'
            projection: 'EPSG:3857',
            minResolution: 1000
      target: 'map',
      view: new ol.View({
        projection: 'EPSG:3857',
        center: ol.proj.transform([400000, 650000], proj, 'EPSG:3857'),
        resolution: 200,
        resolutions: resolutions

    //layers param needs to be changed on change of resolution
    map.getView().on('change:resolution', function(evt) {
      map.getLayers().item(0).getSource().updateParams({LAYERS: evt.target.getResolution()});

It's no possible using only web services. The images coming from the Ordnance Ordnance Survey are using projections EPSG:27700 and the Bing Maps are using EPSG:3857.

Different projections means different scales, different x,y origins, different units, different images deformations. It's not possible to apply transformations to correct this on client side (for rasters but no restrictions for vector).

You can always reproject images or tiles using a software like Mapproxy but labels will be bad, you will suffer precision lose. Moreover, you are maybe not allowed to do so in particular for Ordnance Survey : it's like caching images and cheating with rates limit on the OS API (PS: ask them, I don't live in UK, so I don't know the exact API licence conditions).

| improve this answer | |

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.