My application's objective is to:
- click on a cluster and produce a popup
- with a list of all placemarks clustered there
- where every entry is a hyperlink
- that closes current popup
- and opens a new popup with data from placemark
I can execute everything EXCEPT FINDING the EVENT.FEATURE (placemark) in the layer. I can read the layer (vector) feature list, but the original clustered feature (placemark) is not among the features that compose the layer.
Is the clustered feature "hidden" while its cluster is displayed? if so, how can I access it?
I am using OpenLayers with JavaScript, loosely based on the sundials example, yet with a cluster strategy.
1 is a standard cluster strategy.
var pointStyleTaxi = new OpenLayers.Style({
externalGraphic: "img/taxi.png",
pointRadius: 20,
graphicYOffset: -30,
fillOpacity: 0.6,
'label': "${label}"
}, {
context: {
label: function(feature) {
// clustered features count or blank if feature is not a cluster
return feature.cluster ? feature.cluster.length : "";
},
radius: function(feature) {
return Math.min(feature.attributes.count*5, 20) + 5;
}
}
});
var styleMapClusterTaxi = new OpenLayers.StyleMap({
'default': pointStyleTaxi,
});
var clusterStrategyTaxi = new OpenLayers.Strategy.Cluster({ distance: 35, threshold: 2 });
var refresh = new OpenLayers.Strategy.Refresh({force: true, active: true});
var stops = new OpenLayers.Layer.Vector("Paradas", {
styleMap: styleMapClusterTaxi,
strategies: [new OpenLayers.Strategy.Fixed(), clusterStrategyTaxi, refresh],
projection: map.displayProjection,
protocol: new OpenLayers.Protocol.HTTP({
url: "<?php echo $fileNameKML; ?>",
format: new OpenLayers.Format.KML({
extractStyles: true,
extractAttributes: true,
maxDepth: 2
})
})
});
map.addLayers([wms, stops]);
I achieve 2 by identifying that the selected feature is a cluster inside onFeatureSelect(event)
if (feature.cluster) {
and proceeding to extract the name
of each clustered placemark.
for (var i = 0; i < feature.attributes.count; i++) {
var feat = feature.cluster[i];
var featId = feature.cluster[i].id;
var featName = feat.attributes.name;
3 is obtained by creating a JavaScript hyperlink for each clustered placemark
content += "<br/><a href=\"javascript:onFeatureSelectFeature(";
content += '\'';
content += featId;
content += '\'';
content += ");\">"+featName+"</a>";
}
after clicking on link, 4 is obtained by calling
function popupClear() {
//alert('number of popups '+map.popups.length);
while( map.popups.length ) {
map.removePopup(map.popups[0]);
}
}
Which produces <a href="javascript:onFeatureSelectFeature('OpenLayers_Feature_Vector_58');">Jecabitiba</a>
Which is a JavaScript call to onFeatureSelectFeature('OpenLayers_Feature_Vector_58');
function onFeatureSelectFeature(featId) {
var layerNow = map.getLayersByName('Paradas')[0];
var layerFeatCount = layerNow.features.length;
//alert ("featId: "+featId+"\r\nlayer name:"+layerNow.name+"\r\nlayerFeatCount:"+layerFeatCount);
for(var i=0; i<layerFeatCount; i++){
if(layerNow.features[i].id == featId){
I'm stuck on 5 because I can't find the clustered feature in the layer feature list.
Any suggestions?
Best Answer
found the answer: the clustered feature (placemark) is "inside" the cluster feature, not the layer.
SOLUTION 1 first way out (not most efficient): inside
onFeatureSelectFeature(featureId)
i loop thru cluster features as seen below:SOLUTION 2 i also solved the problem changing the link javascript and sending along the clusterId to
onFeatureSelectFeature(featureId, clusterId)
.where
feature
is a cluster (as seen in code above).my
onFeatureSelectFeature
function now receives 2 strings (featureId, clusterId) and i dont loop thru all features (which can be resource intensive), but use thelayer.getFeatureById()
method.this function (both versions) calls a variation of
onFeatureSelect(event)
which isat some point in the future, i will probably overload the
onFeatureSelect(event)
toonFeatureSelect(event,feature)
and do a basic consistency check to see which object is being passed.