openlayers 3 get layer for selected feature

2019-07-28 15:25发布

问题:

I'm trying to get the "id" of the layer for a selected feature and have tried maybe 3 or 4 methods for achieving this but have yet to achieve it.

I add my features like this...

 angular.forEach(response.FieldList, function (Field, key) {
                if (Field.FieldID != "") {
                    var shape = response.FieldList[key].Shape;
                    shape = shape.replace('}', ',"id":' + '"' + Field.FieldID + '"' + '}');
                    var geoJsonObj = {
                        'type': 'Feature',
                        'geometry': JSON.parse(shape),
                        'name': Field.FieldID,
                        'id': Field.FieldID

                    }
                    var vectorSource = new ol.source.Vector({
                        features: (new ol.format.GeoJSON()).readFeatures(geoJsonObj)
                    });

                      Fields[Field.FieldID] = new ol.layer.Vector({
                        projection: 'EPSG:4269',
                        source: vectorSource,
                        id: Field.FieldID,
                        name: 'Fields',
                        style: function (feature, resolution) {
                            var text = resolution * 100000 < 10 ? response.FieldList[key].Acres : '';

                            if (text != "") {
                                styleCache[text] = [new ol.style.Style({
                                    stroke: new ol.style.Stroke({
                                        color: '#319FD3',
                                        width: 1
                                    }),
                                    text: new ol.style.Text({
                                        font: '12px Calibri,sans-serif',
                                        text: text,
                                        fill: new ol.style.Fill({
                                            color: '#000'
                                        }),
                                        stroke: new ol.style.Stroke({
                                            color: '#fff',
                                            width: 3
                                        })
                                    }),
                                    fill: new ol.style.Fill({
                                        color: rcisWebMapUtilities.convertHex(response.FieldList[key].Shade, '0.5')
                                    })
                                })];
                            }
                            else if (text == "") {
                                styleCache[text] = [new ol.style.Style({
                                    fill: new ol.style.Fill({
                                        color: rcisWebMapUtilities.convertHex(response.FieldList[key].Shade, '0.5')
                                    })
                                })
                                ]
                            } return styleCache[text];
                        }


                      });



                      webMapValues.vectorFieldLayer.push(Fields[Field.FieldID])
                      webMapValues.fieldValues.push({
                          color: response.FieldList[key].Shade,
                          plantingName: response.FieldList[key].CropNickName,
                          acres: response.FieldList[key].Acres,
                          cropId: response.FieldList[key].CropID,
                          cropNumber: response.FieldList[key].CropNumber,
                          fieldID: response.FieldList[key].FiledID,
                          fieldName: response.FieldList[key].FieldName,
                          legalDesc: response.FieldList[key].LegalDesc,
                          policyNum: response.FieldList[key].PolicyNumber
                      })
                      var found = $filter('filter')(webMapValues.legend, { plantingName: response.FieldList[key].CropNickName }, true);
                      if (found == 0) {
                          webMapValues.legend.push({
                              color: response.FieldList[key].Shade,
                              plantingName: response.FieldList[key].CropNickName                          
                          })
                      }
                }
            });

as you can see I'm trying to set the "id" in many places...even altering the GeoJSON to include 'id' but it seems to get discarded somehow and is not there when I want to use it?

I am using a map.on 'click" like this...

map.on('click', function (evt) {
        var pixel = map.getEventPixel(evt.originalEvent);
        displayFeatureInfo(evt.pixel, evt.coordinate);

        //var coordinate = evt.coordinate;


    })

and this code to perform the highlight...

 var highlight;
    var displayFeatureInfo = function (pixel,coordinate) {

        var feature = map.forEachFeatureAtPixel(pixel, function (feature) {
            var id = Opelayers magic to get layer id;
            return feature;
        });

        var info = document.getElementById('info');
        if (feature) {
            info.innerHTML = feature.getId() + ': ' + feature.get('name');


        } else {
            info.innerHTML = '&nbsp;';
        }

        if (feature !== highlight) {
            if (highlight) {
                featureOverlay.getSource().removeFeature(highlight);
            }
            if (feature) {
                featureOverlay.getSource().addFeature(feature);
                document.getElementById('popup-content').innerHTML = '<p>It is working</p>';
                popup.setPosition(coordinate);
            }

            highlight = feature;
        }

    };

feature.getId() and feature.get('name') return undefined?

after I get the feature I would like to get the "id" of the layer it is on. so probably in this code...

var feature = map.forEachFeatureAtPixel(pixel, function (feature) {
            var id = Opelayers magic to get layer id;
            return feature;
        });

Is this possible? any help is greatly appreciated!!

回答1:

Look at ol.Feature. There does not seem to be a built-in way to get the containing source (or layer) that the feature is in. So, you have two choices, at least the way I see it.

First choice is to keep your code as is (using map.forEachFeatureAtPixel...) but make sure that for each feature, before the place that you call mySource.addFeature(myFeature), you call set(key, value, opt_silent) where the key would be sourceId (or layerId) and the value would be your identifying value for the containing source (or layer). So the OpenLayers MaGiC to get Layer ID would be materialized as feature.get('layerId').

The second choice is, instead of using map.forEachFeatureAtPixel, to consider using something along the lines of:

// When there is a single click on the map.
map.on('singleclick', function(evt) {
    // Get all features at the event's coordinate for mySource1 and for mySource2 separately.
    var clickedFeatures1 = mySource1.getFeaturesAtCoordinate(evt.coordinate);
    var clickedFeatures2 = mySource2.getFeaturesAtCoordinate(evt.coordinate);
    ....
}

This way you know who the parent source is for each feature, because you ask the parent directly. clickedFeatures1 and clickedFeatures2 are arrays, either one of which could, of course, be empty.

As for the feature's ID and name, does the feature have such attributes when it is added? If not, before adding the feature, go along the lines of this:

myFeature.setId(42);
myFeature.set('name', 'foo');
mySource.addFeature(myFeature);


回答2:

In openlayers 4, I am able to get the layer of each selected feature like this: (Im not sure if this works in OL3)

var infoClicker = map.on('click', function(evt) {
    map.forEachFeatureAtPixel(evt.pixel,
        function(feature, layer) {
            var idLayer = layer.get('myLayerID');

See http://openlayers.org/en/latest/apidoc/ol.Map.html#forEachFeatureAtPixel