I have a HTML/Leaflet page utilising BetterWMS script (https://gist.github.com/rclark/6908938). The script returns GetFeatureInfo over WMS layers. Unfortunately it is not working with WMSs published by Qgis Server and MapServer, although ArcGIS Server and GeoServer services work fine. Below, you can find my full html file including BetterWMS script and relevant WMSs (all queryable).
Any tips about how to enhance the BetterWMS script so as to use with WMS layers published by servers in question?
<!DOCTYPE html>
<html>
<head>
<title>Layers Control Tutorial - Leaflet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin=""/>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<style>
html, body {
height: 100%;
margin: 0;
}
#map {
width: 1200px;
height: 800px;
}
</style>
</head>
<body>
<div id='map'></div>
<script>
// BetterWMS (https://gist.github.com/rclark/6908938)
L.TileLayer.BetterWMS = L.TileLayer.WMS.extend({
onAdd: function (map) {
// Triggered when the layer is added to a map.
// Register a click listener, then do all the upstream WMS things
L.TileLayer.WMS.prototype.onAdd.call(this, map);
map.on('click', this.getFeatureInfo, this);
},
onRemove: function (map) {
// Triggered when the layer is removed from a map.
// Unregister a click listener, then do all the upstream WMS things
L.TileLayer.WMS.prototype.onRemove.call(this, map);
map.off('click', this.getFeatureInfo, this);
},
getFeatureInfo: function (evt) {
// Make an AJAX request to the server and hope for the best
var url = this.getFeatureInfoUrl(evt.latlng),
showResults = L.Util.bind(this.showGetFeatureInfo, this);
$.ajax({
url: url,
success: function (data, status, xhr) {
var err = typeof data === 'string' ? null : data;
//Fix for blank popup window
var doc = (new DOMParser()).parseFromString(data, "text/html");
if (doc.body.innerHTML.trim().length > 0)
showResults(err, evt.latlng, data);
},
error: function (xhr, status, error) {
showResults(error);
}
});
},
getFeatureInfoUrl: function (latlng) {
// Construct a GetFeatureInfo request URL given a point
var point = this._map.latLngToContainerPoint(latlng, this._map.getZoom()),
size = this._map.getSize(),
params = {
request: 'GetFeatureInfo',
service: 'WMS',
srs: 'EPSG:4326',
styles: this.wmsParams.styles,
transparent: this.wmsParams.transparent,
version: this.wmsParams.version,
format: this.wmsParams.format,
bbox: this._map.getBounds().toBBoxString(),
height: size.y,
width: size.x,
layers: this.wmsParams.layers,
query_layers: this.wmsParams.layers,
info_format: 'text/html'
};
params[params.version === '1.3.0' ? 'i' : 'x'] = point.x;
params[params.version === '1.3.0' ? 'j' : 'y'] = point.y;
return this._url + L.Util.getParamString(params, this._url, true);
},
showGetFeatureInfo: function (err, latlng, content) {
if (err) { console.log(err); return; } // do nothing if there's an error
// Otherwise show the content in a popup, or something.
L.popup({ maxWidth: 800, minWidth: 0, autoPan: false })
.setLatLng(latlng)
.setContent(content)
.openOn(this._map);
}
});
L.tileLayer.betterWms = function (url, options) {
return new L.TileLayer.BetterWMS(url, options);
};
// BetterWMS
var mbAttr = 'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, ' +
'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw';
var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr}),
streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr});
var arcgis = L.tileLayer.betterWms('https://nowcoast.noaa.gov/arcgis/services/nowcoast/forecast_meteoceanhydro_pts_zones_geolinks/MapServer/WMSServer',{
maxZoom: 21, format: 'image/png', layers: '1', transparent: true});
var geoserver = L.tileLayer.betterWms('https://www.mrlc.gov/geoserver/mrlc_display/NLCD_2016_Land_Cover_L48/wms',{
maxZoom: 21, format: 'image/png', layers: 'NLCD_2016_Land_Cover_L48', transparent: true});
var qgis = L.tileLayer.betterWms('https://ows.geo.hu-berlin.de/cgi-bin/qgis_mapserv.fcgi',{
maxZoom: 21, format: 'image/png', layers: 'sen2', transparent: true});
var mapserver = L.tileLayer.betterWms('https://demo.mapserver.org/cgi-bin/wms',{
maxZoom: 21, format: 'image/png', layers: 'cities', transparent: true});
var map = L.map('map', {
center: [40, -98],
zoom: 5,
layers: [grayscale]
});
var baseLayers = {
"Grayscale": grayscale,
"Streets": streets,
};
var overlays = {
"Arcgis Server": arcgis,
"GeoServer": geoserver,
"Qgis Server": qgis,
"MapServer": mapserver,
};
L.control.layers(baseLayers, overlays, { collapsed: false }).addTo(map);
</script>
</body>
</html>