The WMS spec does not provide any direction on how a server should implement the GetFeatureInfo response.
In some systems the "pixel tolerance" is a function of the client (web browser or desktop client) - a clicked point can be buffered and the resulting polygon is sent as the query geometry. However, GetFeatureInfo only accepts a point input so that's a dead end.
However, if you scale down the image size in your GetFeatureInfo request, and also scale down the X and Y coordinate of your query, you can effectively increase the pixel tolerance. Consider the following queries based on the Cities layer for the region surrounding Minneapolis/St.Paul:
WMS GetImage, 400 x 400 pixels
If I issue a GetFeatureInfo request at 138, 145 on a 400x400 map gets me Elk River:
WMS GetFeatureInfo, 138,145, 400x400 - gets results
If I re-issue the request at 140, 140 I get no results:
WMS GetFeatureInfo, 140,140, 400x400 - no results
However, if I halve all values and issue the request at 70,70 on a 200x200 map, it works:
WMS GetFeatureInfo, 70,70, 200x200 - gets results
It's extra work to do this sort of viewport adjustment on-the-fly but should do what you want.
Use esri.request() to hit each layer's REST endpoint to get info about fields. Here's a simple example:
<html>
<head>
<script type="text/javascript">var djConfig = {parseOnLoad: true};</script>
<script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.4"></script>
<script type="text/javascript">
dojo.require("esri.map");
// var service_url = 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Hurricanes/NOAA_Tracks_1851_2007/MapServer/layers';
var service_url = 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Fire/Sheep/MapServer/layers';
function init() {
esri.request({
url: service_url,
content: { f: 'json' },
callbackParamName: 'callback',
load: processServiceInfo,
error: errorHandler
});
}
// Runs once
function processServiceInfo(info) {
console.log('svc info: ', info);
dojo.byId('info').innerHTML = '';
dojo.forEach(info.layers, function(lyr) {
// Add a new div for each Layer
var lyr_div = dojo.create('div', {
id: 'layer_' + lyr.id,
innerHTML: '<strong>Layer: ' + lyr.name + '</strong><br />'
}, dojo.byId('info'));
dojo.forEach(lyr.fields, function(field) {
lyr_div.innerHTML += 'Name: ' + field.name + '; Alias: ' + field.alias + '<br />';
});
});
}
function errorHandler(err) {
console.log('error: ', err);
}
dojo.ready(init);
</script>
</head>
<body>
<div id="info">field names and aliases will show up here.</div>
</body>
</html>
That code uses v2.0 of the API but the same thing will work at 2.3 or 2.4. I originally posted in the Esri JS API forum.
Edit: Updated to handle all layers in a service. The code also now uses version 2.4 of the API.
Best Answer
The WMS GetFeatureInfo request is very similar to the GetMap request. There is an example here showing code sample for GetFeatureInfo.
Also, keep in mind, that the GetFeatureInfo is not "standardized", so depending on server vendor, the response is differently formatted. Expect to do some extra parsing/styling.