openlayerswmsmapserver

OpenLayers showing multiple raster from MapServer


I would like to visualize a raster in OpenLayers and retrieve it from MapServer with WMS. My mapfile works fine in map and browse mode but when I try to implement it in my OpenLayers then it is a static image where I can't zoom in. I tried using ol.layers.Image and got one raster in the top left corner on top of the basemap. When I use ol.layer.Tile, then I get multiple images next to each other. I also tried it with different projections (the original data is in 4326) without any difference, and also with different URL compilations, but no difference either. I really don't know where my mistake is and are happy for any help and suggestions.

Here is my mapfile called interact.map

MAP
    NAME "testMap"
    IMAGETYPE png24
    STATUS ON
    SIZE 1300 600
    EXTENT -180 -90 180 90
    STATUS ON
    SHAPEPATH "../data"
    IMAGECOLOR 189 201 225

    PROJECTION
      "init=epsg:4326"
    END

WEB
    TEMPLATE 'test1.html'
    IMAGEPATH "/ms4w/tmp/ms_tmp/"
    IMAGEURL "/ms_tmp/"
    METADATA
      "wms_title"          "WMS Demo Server for MapServer"
      "wms_onlineresource" "http://127.0.0.1/cgi-bin/mapserv.exe?map=wms.map&" 
      "wms_srs"            "EPSG:4326"
      "wms_enable_request" "*"  # necessary
    END
END # WEB

LAYER
    NAME "pop"
    METADATA
      "wms_title"         "World population"
      "wms_srs"           "EPSG:4326" 
      "gml_include_items" "all" 
      "gml_featureid"     "ID" 
      "wms_enable_request" "*"
    END
    TEMPLATE "layertmp.html" 
    TYPE raster
    STATUS DEFAULT
    DATA "Pop10.tiff"

    PROJECTION
      "init=epsg:4326"
    END

    CLASS
      NAME "0-100"
      EXPRESSION ([pixel] >= 0 and [pixel] < 100)
      STYLE
        COLOR 255 255 178
      END
    END

    CLASS
      NAME "100-500"
      EXPRESSION ([pixel] >= 100 and [pixel] < 500)
      STYLE
        COLOR 254 204 92
      END
    END

    CLASS
      NAME "500-1000"
      EXPRESSION ([pixel] >= 500 and [pixel] < 1000)
      STYLE
        COLOR 253 141 60
      END
    END

    CLASS
      NAME "1000-2000"
      EXPRESSION ([pixel] >= 1000 and [pixel] < 2000)
      STYLE
        COLOR 240 59 32
      END
    END

    CLASS
      NAME ">= 5000"
      EXPRESSION ([pixel] >= 5000)
      STYLE
        COLOR 189 0 38
      END
    END
  END # LAYER
END # MAP

and this is my OpenLayer file:

    <!DOCTYPE html>
<html>
  <head>
    <title>Single Image WMS</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>
    <style>
  .ol-custom-overviewmap,
  .ol-custom-overviewmap.ol-uncollapsible {
    bottom: auto;
    left: auto;
    right: 0;
    top: 0;
  }

  .ol-custom-overviewmap:not(.ol-collapsed)  {
    border: 1px solid black;
  }

  .ol-custom-overviewmap .ol-overviewmap-map {
    border: none;
    width: 300px;
  }

  .ol-custom-overviewmap .ol-overviewmap-box {
    border: 2px solid red;
  }

  .ol-custom-overviewmap:not(.ol-collapsed) button{
    bottom: auto;
    left: auto;
    right: 1px;
    top: 1px;
  }

  .ol-rotate {
    top: 170px;
    right: 0;
  }
</style>
  </head>
  <body>
    <div id="map" class="map"></div>
    <script>

    var projection = new ol.proj.Projection({
          code: 'EPSG:3857',
          units: 'm'
        });
        ol.proj.addProjection(projection);

    var overviewMapControl = new ol.control.OverviewMap({

           className: 'ol-overviewmap ol-custom-overviewmap',
           layers: [
             new ol.layer.Tile({
               source: new ol.source.OSM()
             })
           ],
           collapseLabel: '\u00BB',
           label: '\u00AB',
           collapsed: false
         });
      var layers = [
        new ol.layer.Tile({
          source: new ol.source.OSM()
        }),
        new ol.layer.Image({
      source: new ol.source.ImageWMS({
        url: 'http://127.0.0.1/cgi-bin/mapserv.exe?map=/ms4w/apps/pop/htdocs/interact.map&layers=pops&mode=map',
        serverType: 'mapserver'  
          })
        })
      ];
      var map = new ol.Map({
        controls: ol.control.defaults().extend([
                  overviewMapControl
                ]),
        layers: layers,
        target: 'map',
        view: new ol.View({
          projection: projection,
          center: [2269873, 5087648],
          zoom: 2
        })
      });
    </script>
  </body>
</html>

Solution

  • The main issue is that you are trying to use the Mapserver browse mode that OpenLayers 3 and later don't support. You should use the WMS instead.

    Some clues, we'll see after as I've identified more than one issue at least.

    Change in the Mapserver part, in both the WEB block and the LAYER block

    "wms_srs"             "EPSG:4326"
    

    with

    "wms_srs"             "EPSG:3857 EPSG:4326"
    

    Try at the moment to change your code to correctly manage WMS layer call from OpenLayers

    new ol.source.ImageWMS({
      url: 'http://127.0.0.1/cgi-bin/mapserv.exe?map=/ms4w/apps/pop/htdocs/interact.map&layers=pops&mode=map',
      serverType: 'mapserver'  
    })
    

    with

    new ol.source.ImageWMS({
      url: 'http://127.0.0.1/cgi-bin/mapserv.exe',
      params: {
        'LAYERS': 'pop',
        'MAP': '/ms4w/apps/pop/htdocs/interact.map'
      },
      serverType: 'mapserver'  
    })
    

    The code below can be removed as "EPSG:3857" is already the default projection

    var projection = new ol.proj.Projection({
      code: 'EPSG:3857',
      units: 'm'
    });
    ol.proj.addProjection(projection);
    

    The projection: projection, can consequently be deleted.

    Change the [2269873, 5087648] with ol.proj.fromLonLat([20.390616089102306, 41.50857324328069]) that do the same as your previous code but use decimal degrees to set the center (more simple to change from a human viewpoint IMHO)