Closed skyl closed 14 years ago
Hi skyl,
Thanks for the reports. I finally got some time to work on olwidget today. In the latest master, I've fixed the zooming problem with cluster.
I've also fixed the problem with individual feature styles; but with a caveat: because of the way openlayers implements clustering, it is not straightforward to simply use the styles in the attribute dict. When a cluster strategy is added, the original vector features are removed, and new clustered features are added which lack the attributes passed into the original features. It is thus necessary to do more complicated things to achieve this.
Here is a writeup: http://openflights.org/blog/2009/10/21/customized-openlayers-cluster-strategies/
Here is an example that uses a new option I've added ("overlayStyleContext") to enable custom styling of clusters, using OpenLayers' style symbolizers: http://olwidget.org/olwidget/doc/examples/info_cluster_per_point_style.html
I know this solution isn't ideal, but it seems OpenLayers doesn't currently support more elegant solutions. Please let me know if you encounter any other problems with this.
youcelf,
Aye, good work. Thank you very much.
The remaining problem is that I really want a separate Layer.Vector for different kinds of objects. I edited the list comps to make them more readable and generic.
I'm using a simple view like the following
def poi_detail(request, slug): waters = POI.objects.filter(point__distance_lte = (poi.point, D(km=10)), feature_class='H' ) data = { 'waters': [[poi.point, {'html': poi.popup_html(), 'style': style1}] for poi in waters], }
options = {}
options.update({'cluster':True})
options.update({
'overlay_style': {'fillColor': "${specialAttributeHandler}", },
'overlay_style_context': {
'specialAttributeHandler': "function(feature) {return '#0000ff';}"
}
})
olmap = InfoMap(data['waters'], options=options)
return render_to_response('geonames/show.html', locals(),
context_instance=RequestContext(request)
)
If I just set 'fillColor': '#0000ff' directly, I get the blue color. But, if I try to set it through the specialAttributeHandler, I can't get anything to happen. Do I need to hack what I pass to the js olwidget.InfoMap contructor directly or am I supposed to be able to do it from the python constructor with some variant of what I have above?
Looks like this will require custom javascript in the template. "function(feature) {return '#0000ff'; }"
is rendered as a string on the way out of Django's JSON serializer. Since functions are not part of the JSON spec, it would be necessary to do a custom coder that converts the python dict to JSON but preserves functions, or to try to do some tricks with "eval" that I'm not really interested in doing.
I'm not too thrilled by OpenLayers implementation here anyway. I'll try to see if I can figure out some other way to do this. In the mean time, you should be able to get this work by using a custom template like this:
<div id="{{ id }}"></div>
<script type='text/javascript'>
new olwidget.InfoMap("{{ id }}", {{ info_array|safe }},
OpenLayers.Util.applyDefaults({{ map_opts|safe }}, {
overlayStyle: { fillColor: "${specialAttributeHandler}" },
overlayStyleContext: {
specialAttributeHandler: function(feature) {
return "#0000ff";
}
}
})
);
</script>
I also just fixed a couple of overlayStyleContext bugs that effect non-clustered maps, but unfortunately don't touch this.
yep, I've accomplished this by changing the template. Thanks for the hint about Util.applyDefaults. It seems that I could make another template that could do this generically something like:
No worries though, as my real problem was that I wanted fully separate vectorlayers so this is not something that I would be likely to use. Pardon any syntax errors and missteps above but I'm typing this in my eee with a little 3-high textbox.
If I uncomment the cluster option, I get clusters, but the style on individual features is gone and it looks like the map is zoomed to whatever is default and .. centered on the last point possibly .. either that or the default options ..
detail_map_options = { 'zoom_to_data_extent': True,
'cluster': True,
}
a_style = {'fill_color': '#5555FF', 'strokeColor': '#0000FF'} h_style = {'point_radius': 5,'fill_color': '#e0ffb8', 'strokeColor': '#669900'}