I have a map with two layers, which can (and almost always do) overlap. These layers are WMS from GeoServer using SQL views (POSTGIS). They use the same query but with a different parameter.
My hover control uses WMSGetFeatureInfo to get information from both layers to display in a label. When I've done this in the past from different layers with different parameter names this is easy. Supply all parameters and all layers and it works.
However, I don't know how to handle the situation where I have two layers with the same parameter name (as they are from the same view), but different value. If I add both layers then I get the same label twice. If I add the parameter twice it uses the second one added.
In the hover control's beforegetfeatureinfo event listener I setup the layers using:
self.control.layers = self.getLayers();self.control.vendorParams.VIEWPARAMS = self.getParams();with those methods defined as:
//This will give me one of the two results//The value does not depend on the layer used as they both have the same view//It only seems to depend on the VIEWPARAMS//If I supply both layers I get the same result twiceself.getLayers = function() { var layers = []; if (map.areaTypeLayer) { layers.push(map.areaTypeLayer); } else if (map.overlayLayer) { layers.push(map.overlayLayer); } return layers;};//Only the second typecode has any effectself.getParams = function () { var params = 'typecode:' + map.areaTypeIdentifier; if (map.overlayTypeIdentifier) params += ';typecode:' + map.overlayTypeIdentifier; return params;};The only workaround I can think of requires a lot of duplication and I'd rather avoid it if possible. I could duplicate the layer in GeoServer and give one of them a different parameter name. Then my code can create each layer from a different GeoServer layer.
Is there a better way? Maybe a way the control can call WMSGetFeatureInfo twice and merge the information? Hover control code below in case required.
esd.map.controls.hoverOver = function (map) { var self = this; self.control = null; self.init = function () { self.control = new OpenLayers.Control.WMSGetFeatureInfo({ url: esd.pathUtility.geoServerUrl + "/ESD/wms", infoFormat: 'application/json', output: 'features', format: new OpenLayers.Format.JSON, hover: true, queryVisible: true, autoActivate: true, vendorParams: { propertyName: 'label', VIEWPARAMS: null }, eventListeners: { getfeatureinfo: function (event) { var details = jQuery.parseJSON(event.text); map.showAreaInfo(self.buildLabel(details)); }, beforegetfeatureinfo: function (event) { map.showAreaInfo(null); self.control.layers = self.getLayers(); self.control.vendorParams.VIEWPARAMS = self.getParams(); } } }); }; self.getLayers = function() { var layers = []; if (map.areaTypeLayer) { layers.push(map.areaTypeLayer); } else if (map.overlayLayer) { layers.push(map.overlayLayer); } return layers; }; self.getParams = function () { var params = 'typecode:' + map.areaTypeIdentifier; if (map.overlayTypeIdentifier) params += ';typecode:' + map.overlayTypeIdentifier; return params; }; self.buildLabel = function(details) { if (!details || !details.features || !details.features.length) return null; var labels = []; for (var i = 0; i < details.features.length; i++) { labels.push({ label: details.features.properties.label}); } return labels; } self.init(); return self.control;};
أكثر...
My hover control uses WMSGetFeatureInfo to get information from both layers to display in a label. When I've done this in the past from different layers with different parameter names this is easy. Supply all parameters and all layers and it works.
However, I don't know how to handle the situation where I have two layers with the same parameter name (as they are from the same view), but different value. If I add both layers then I get the same label twice. If I add the parameter twice it uses the second one added.
In the hover control's beforegetfeatureinfo event listener I setup the layers using:
self.control.layers = self.getLayers();self.control.vendorParams.VIEWPARAMS = self.getParams();with those methods defined as:
//This will give me one of the two results//The value does not depend on the layer used as they both have the same view//It only seems to depend on the VIEWPARAMS//If I supply both layers I get the same result twiceself.getLayers = function() { var layers = []; if (map.areaTypeLayer) { layers.push(map.areaTypeLayer); } else if (map.overlayLayer) { layers.push(map.overlayLayer); } return layers;};//Only the second typecode has any effectself.getParams = function () { var params = 'typecode:' + map.areaTypeIdentifier; if (map.overlayTypeIdentifier) params += ';typecode:' + map.overlayTypeIdentifier; return params;};The only workaround I can think of requires a lot of duplication and I'd rather avoid it if possible. I could duplicate the layer in GeoServer and give one of them a different parameter name. Then my code can create each layer from a different GeoServer layer.
Is there a better way? Maybe a way the control can call WMSGetFeatureInfo twice and merge the information? Hover control code below in case required.
esd.map.controls.hoverOver = function (map) { var self = this; self.control = null; self.init = function () { self.control = new OpenLayers.Control.WMSGetFeatureInfo({ url: esd.pathUtility.geoServerUrl + "/ESD/wms", infoFormat: 'application/json', output: 'features', format: new OpenLayers.Format.JSON, hover: true, queryVisible: true, autoActivate: true, vendorParams: { propertyName: 'label', VIEWPARAMS: null }, eventListeners: { getfeatureinfo: function (event) { var details = jQuery.parseJSON(event.text); map.showAreaInfo(self.buildLabel(details)); }, beforegetfeatureinfo: function (event) { map.showAreaInfo(null); self.control.layers = self.getLayers(); self.control.vendorParams.VIEWPARAMS = self.getParams(); } } }); }; self.getLayers = function() { var layers = []; if (map.areaTypeLayer) { layers.push(map.areaTypeLayer); } else if (map.overlayLayer) { layers.push(map.overlayLayer); } return layers; }; self.getParams = function () { var params = 'typecode:' + map.areaTypeIdentifier; if (map.overlayTypeIdentifier) params += ';typecode:' + map.overlayTypeIdentifier; return params; }; self.buildLabel = function(details) { if (!details || !details.features || !details.features.length) return null; var labels = []; for (var i = 0; i < details.features.length; i++) { labels.push({ label: details.features.properties.label}); } return labels; } self.init(); return self.control;};
أكثر...