Monday, November 2, 2009

Getting the attributes of an OpenLayer.Feature.Point that has been clustered in a OpenLayers.Layer.Vector layer

I encountered this problem and spent a day trying to understand how it worked. I have figured it out and am sharing my understanding with everyone.

Issue
------------
I had a GeoJSON parser that parsed the following geojson file:

{
"type": "FeatureCollection",
"features": [
{"type":"Feature", "id":"computer1", "properties":{"trial":"test"}, "geometry":{"type":"Point", "coordinates":[143, -35.91]}},
{"type":"Feature", "id":"computer2", "properties":{"trial":"test"}, "geometry":{"type":"Point", "coordinates":[144, -37.81667]}}
]
}

Once the GeoJSON parser parsed the file and created 2 OpenLayer.Feature.Points, these points were parsed to the OpenLayers.Layer.Vector object that implemented the clustering strategy.

Now, since the two points were within a close distance (specified by me), they were clustered and only one top level feature point was displayed on the map.

I wanted to get the 'id' and 'properties' (as in the GeoJSON file above) of each of the two points (when I zoomed into the map). However, I could not get it. It seemed to me, back then, that the GeoJSON parser had somehow overriden the properties I added into the "properties":{} field (in the above geojson file) with the 'count' property of the clustering Vector layer.

Hence, the question was, how do I get the attributes and ID of each point in the map (as in the geojson file).


Fix
----
feature.cluster solved the problem.

For other users who come across this problem, try to get the attributes of a point (specified in the geojson file in the 'properties' list) by using
feature.cluster[0].attributes.

Basically, this is what happens when the geojson fileabove is parsed by OpenLayers.Format.GeoJSON parser and added as OpenLayers.Vector.Feature objects into a OpenLayers Vector layer (that performs the clustering strategy):
1. GeoJSON file is read by the GeoJSON parser.
2. Parser creates OpenLayers.Vector.Feature objects for each string.
3. These OpenLayers.Vector.Feature objects are then added to the OpenLayers Vector layer
4. OpenLayers Vector layer performs clustering strategy
5. Each feature point that appears on the map is the top-level feature point (for a group of clusters). The attributes for this feature point is:

undefinedlayer value :[object Object]
lonlat value :null
data value :[object Object]
id value :OpenLayers.Feature.Vector_201
geometry value :POINT(15918687.18122222 -4288244.5663272375)
state value :null
attributes value :[object Object]
style value :null
cluster value :[object Object],[object Object],[object Object] //this indicates that this cluster point has three feature objects underneath it
renderIntent value :select
marker value :null

6. As it can be seen above, there is a 'cluster' property that holds 3 objects (being the three points). Hence, if you drill down to the 'cluster' property (i.e. feature.cluster[0]), it will give you the attributes of the first object in the cluster (being the point):

undefined0 value :[object Object]
layer value :null
lonlat value :null
data value :[object Object]
id value :OpenLayers.Feature.Vector_197
geometry value :POINT(8218510.393273033 -2699238.272071229)
state value :null
attributes value :[object Object]
style value :null
fid value :computer14
marker value :null

7. From the above, it can be seen that the 'id' property from the geojson file has been mapped to the 'fid' key of the feature point object. You can also see that the 'attributes' key holds an [object Object]. If you do feature.cluster[0].attributes.trial , it will display the 'trial' property and value that you specified in the geojson file (i.e. 'test').

Hence, adding as many property-value pairs in the GeoJSON file is easy as the GeoJSON parser just parsers the property-value pairs and enters the data into feature point object attributes that are beneath the top-level cluster point (it does not override the properties as I initially thought).