Active
Project:
Openlayers
Version:
7.x-3.x-dev
Component:
OL API
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Reporter:
Created:
10 Aug 2010 at 15:45 UTC
Updated:
3 Apr 2014 at 07:58 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
tmcw commentedEr, unclear.
openlayers_plus hacks in a legend behavior, and hacks in legend data, which is then hacked into layer objects because, after all, it's javascript. Unless this can be written in a way that can be accepted into OpenLayers proper, I don't think that this belongs in the OpenLayers module.
Comment #2
strk commentedI did take a look at OL+, but it didn't help WMS in any way.
Similar to the query behavior this one would aim at abstracting legend for all layers.
The attached patch provides implementation for the WMS part.
You're probably right the functionality might be in a separate module.
Just haven't found a good name yet for my own hacks (ol++ might be one :)
Comment #3
tmcw commentedUh, I don't really get why this patch is this way. The openlayers_plus legend implementation handles legends from any layer type, provided that that layer type provides the legend as an attribute on the layer object. Why not build this as WMS support for the openlayers_plus legend functionality, rather than ending up having two legend behaviors that do basically the same thing in slightly different ways with completely different code?
Comment #4
strk commentedYeah, you're right I should have worked on improving the ol+ behavior.
So, how would this be done ? Implementing a map_hook to fill up the 'legend' option for the layers I want to support ?
There's no UI provided by ol+ itself, right ?
Comment #5
strk commentedAfter some discussion on IRC I realized the ol+ behavior only takes care about putting legends in the page, but in no way attempts to create the legends, which is left to layer_type classes.
This approach requires to write more code to get the actual legend, so is pretty useless on itself.
My approach instead tries to enable legends automatically for WMS layers.
Not sure how the same could be done for other layer types, but surely such approach
needs to add layer-specific knowledge into the behavior. I'm not against that, also the
Query behavior (my other proposal) does that.
Comment #6
strk commentedOk, summary after a second talk on IRC. We agreed on the following:
As for implementation, the idea is that the OL layers created by DOL
layer factories would be optionally equipped with a method to be used
by the legend behavior to enable the layer's legend.
Such method would be passed a div object, so that the layer can also
decide to register map event callbacks to update the legend based on
scale.
The behavior itself will take care about making the layer legend visible or
not based on layer visibility.
Comment #7
strk commentedAbout passing a div object to the layer's legend manager I think that's not enough flexible.
Consider the case in which you may or may not want to add the layer name to the legend.
That'd be a behavior configuration, not a layer configuration.
So here's another architecture:
With the above model a layer_type willing to update the legend based on scale will register
its own events on 'enableLegend' call and possibly de-register it on 'disableLegend'.
The behavior will take care of putting the text to final destination so can decide to add
the layer name or not, and where to put the things as it will provide a legendHandler itself.
The behavior may call 'disableLegend' when hiding a layer's legend due to visibility state
and call 'enableLegend' again when it comes back visible.
How do you like it ?
Comment #8
strk commentedThe attached patch implements the idea in previous commit, basically adding enableLegend/disableLegend to WMS layer_type
and tweaking my previous legend behavior to use that information.
Should work fine with user-defined layer_types as long as they provide enableLegend/disableLegend too.
Only additional thing might be tweaking the interface to select which layers to handle legend for, which currently
only allows WMS layers.
Comment #9
tmcw commentedHuh? I think we might have been talking past each other at some point, or all points... This code still has nothing in common with the openlayers_plus code, and it still includes coupling with the WMS layer.
The justification for this approach is still evading me. Have I not shown that all of this is possible with the stock ol+ control and a few lines of straightforward code?
If you read the openlayers_plus control, that's incredibly straightforward to implement within it, and it's by no means a limitation of its design.
How? I don't understand how the code that I've demonstrated can be exactly as functional as what you've just posted, but less complexity on the concept level and a more straightforward implementation of the 'normal case' in which Drupal is writing the legends.
Sorry, I must be missing something here, or we must be talking past each other, but the approach that this is taking really doesn't seem optimal, given that it misses out on a lot of the code cleanliness of the ol+ approach, it introduces a whole lot more javascript, the javascript is much more complex while doing the same thing.
If there's a one-off solution that needs to be built for your project, go for it, I just don't understand the rationale of this approach.
Comment #10
strk commentedComment #11
strk commented.. hopefully with better format ..
I didn't feel like touching openlayers_plus code at this stage, particularly didn't feel
like refactoring it to prepare for DOL-core (renames...).
The patch I sent is just for concept proving for the bahvior part, and proposal for
the WMS layer_type impelementation of the legend concept (enableLegend/disableLegend)
I still belive OL+legend is the one which should end up in core, appropriately modified
to make use of the enableLegend/disableLegend methods of layers, when available.
Not really. The behavior only checks for existance of 'enableLegend' and 'disableLegend' methods
in the OL layer object. Nothing more.
The patch does additionally contain a patch for layer_type_wms, but that's not part of the behavior.
Comment #12
tmcw commentedThe code within the legend behavior currently only lets users enable legends on WMS layers, and there's no construct for any other layer to have a legend (or indicate that it can provide one)
The problem is that this code is a whole lot different from the openlayers_plus approach - the way that HTML is written here and how it's generated in openlayers_plus is entirely different, and the way that they keep track of layer visibility and bind events (this method actually re-binds events every time visibility is changed), is entirely different.
And, as far as the disableLegend behavior, I just don't get it. What's the advantage of this approach over a legend simply managing its own legend and checking whether it is visible before doing anything?
Comment #13
strk commentedRight, this is a limitation which should be removed. Prompting for all layers which _can_provide_a_legend_ would be much better.
In order to do this we'll need an additional per-layer configuration (much like the current 'isBaseLayer' kind of thing).
I can work on adding that, still core, still useful for 'legend supports in core'.
I might try to fork from OL+legend if that'd make you less anxious, but again, take the code just as a proof of concept,
not as a proposal to put in core.
More on the points:
The advantage of the 'handler' approach is that the legend behavior can decide whether or not to enable a layer legend
and what to do with the legend text whenever the layer decides to update it.
What's your idea of a layer "simply managing its own legend" ? The layer (JS) would need to:
- create the legend
- optionally update it based on map events
Comment #14
tmcw commentedOn a per-layer level? Possibly there's some use case in which a layer can provide a legend but you don't want to see it (but want to see other layers's legends), but this just doesn't follow the pattern of, for instance, the built-in OpenLayer attribution control.
Yes, in order to not update the legend when the layer is inactive, you'd need... something like
if(this.visibility){, and that's all...Comment #15
strk commentedAnother version adding an .updateLegend() method in case a behavior would want to trigger the call to the handler again for any reason.
Comment #16
strk commentedNew version of wms.js adds scale-dependent legend support.
I've tested it, and works (with mapserver).
The way it works is you add a SCALE parameter to the GetLegendGraphic URL.
It's an optional parameter, so not guaranteed to work with all servers.
Comment #17
strk commentedNew version of full patch.
Now you can specify, for each LAYER object wheter or not it supports legends (in layer_type PHP side).
Then, the PHP side of legend behavior will only prompt you to select the layers actually SUPPORTing a legend,
and allow you to select NO layers to enable it for all supported ones.
Comment #18
zzolo commentedSome insignificant comments:
* Coding standards
* Variable names are inconsistent. Underscore in PHP, lowerCamelCase in JS, and the former for variables that pass form PHP to JS. (please note that the last one is not the standard)
* Too many comments about TODO or debugging
Overall, this seems to make sense, but I haven't actually put much thought into it. I do think a Drupal block implementation is better than an OL control, because 1) its not an interactive control like draw features, and 2) it could take up a lot of map real estate, and 3) a Drupal block can be put over top a map if needed.
Comment #19
tmcw commentedConsidering killing this ala #860444: Add WMSGetFeatureInfo behavior, and supporting openlayers_plus instead...
Comment #20
strk commentedYeah, let's kill.
My vector legend is much worst than teh GeoExt one, btw :)
Comment #21
tmcw commentedClosing - works as designed. Won't comment on the less-than-beautiful GeoExt panel :)
Comment #22
AgentJay commentedI believe it might be worth re-visiting this issue. Mainly as the Openlayers plus only supports point legends based on the styles defined in Drupal Openlayers, where this was intended to display WMS layer legends based on styles defined on the server that is storing the map.
I have re-opened the ticket and changed it to version 7.x-3.x. I am currently trying to figure out how to get this feature working with the newest version of Drupal Openlayers based on the old patch, but I would greatly appreciate some help.