Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a single WMS tile to cover entire Google Map?

I basically want this OpenLayer functionality in Google Maps:

new ol.layer.Image({
  source: new ol.source.ImageWMS({
    url: 'someUrl',
    params: {
      'LAYERS': 'someLayer',
      'SRS': 'EPSG:3857',
      'VERSION': '1.1.1'
    },
    ratio: 1,
  })
})

Below is my attempt to implement this with Google Maps API. This is some exiting code where I have changed the static 256 size to map height/width. The WMS is showing correctly in the map, but still multiple tiles are fetched. I want just one tile to be loaded. Here is fiddle where the working OpenLayer solution and non-working Google solution are shown together: https://jsfiddle.net/HoffZ/9zjd4052/

  var map = new google.maps.Map(document.getElementById("g-map"), {
    zoom: 4,
    center: new google.maps.LatLng(40.0, -100.0)
  });

  // "Normal" 256 tiles
  //var TILE_WIDTH = 256;
  //var TILE_HEIGHT = 256;

  // Set tile size to map size to get just one single tile. But 
  // still  multiple tiles is fetched from server
  var TILE_WIDTH = getMapWidth();
  var TILE_HEIGHT = getMapHeight();


  var wmsOptions = {
    getTileUrl: WMSGetTileUrl,
    tileSize: new google.maps.Size(TILE_WIDTH, TILE_HEIGHT)
  };

  var wmsMapType = new google.maps.ImageMapType(wmsOptions);
  map.overlayMapTypes.insertAt(0, wmsMapType);

  function WMSGetTileUrl(tile, zoom) {
    var projection = map.getProjection();
    var zpow = Math.pow(2, zoom);
    var ul = new google.maps.Point(tile.x * TILE_WIDTH / zpow, (tile.y + 1) * TILE_HEIGHT / zpow);
    var lr = new google.maps.Point((tile.x + 1) * TILE_WIDTH / zpow, (tile.y) * TILE_HEIGHT / zpow);
    var ulw = projection.fromPointToLatLng(ul);
    var lrw = projection.fromPointToLatLng(lr);
    var baseURL = "http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi?";
    var version = "1.1.1";
    var request = "GetMap";
    var format = "image/png"; //type of image returned 
    var layers = "nexrad-n0r-wmst";
    var srs = "EPSG:4326";
    var bbox = ulw.lng() + "," + ulw.lat() + "," + lrw.lng() + "," + lrw.lat();

    var width = TILE_WIDTH;
    var height = TILE_HEIGHT;

    var styles = "default";

    var url = baseURL + "version=" + version + "&request=" + request + 
    "&Layers=" + layers + "&Styles=" + styles + "&SRS=" + srs + "&BBOX=" + 
    bbox + "&width=" + width + "&height=" + height + "&format=" + format +
    "&TRANSPARENT=TRUE";
    return url;
  }

  function getMapHeight() {
    var h = map.getDiv().offsetHeight;
    console.log('Google Map height is ' + h);
    return h;
  }

  function getMapWidth() {
    var w = map.getDiv().offsetWidth;
    console.log('Google Map width is ' + w);
    return w;
  }

Any suggestions on how to just get one single WMS tile?

like image 282
HoffZ Avatar asked Nov 08 '22 05:11

HoffZ


1 Answers

You don't have to calculate the bbox manually. Google API provides that functionality on map object as below.

function WMSGetTileUrl(tile, zoom) {
    var bond = map.getBounds();
    var ulw = bond.getSouthWest();
    var lrw = bond.getNorthEast();

    //other stuffs

    var bbox = ulw.lng() + "," + ulw.lat() + "," + lrw.lng() + "," + lrw.lat();

    //your other stuffs
 }

Here is the working sample for your requirement.

like image 189
Naveen Kumar H S Avatar answered Nov 10 '22 00:11

Naveen Kumar H S