1

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 twice
self.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 effect
self.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[i].properties.label});
        }
        return labels;
    }

    self.init();
    return self.control;
};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.