[OpenLayers-Users] OpenLayers.Feature.Vector style

Slawomir Messner slawomir.messner at staff.uni-marburg.de
Fri Aug 27 05:42:37 EDT 2010


  Ok, I've one...two questions.
When I shouldn't use

style.styles["default"].defaultStyle["attribName"]


then how can I change ..let's say fontSize... for the whole layer? 
Create a new Style and replace the old one?
And how to change the fontSize dependent on the map resolution. Is it 
possible by rules or do I have to use ${} with context? That's my 
current code:

...
var  defaultStyle = OpenLayers.Util.applyDefaults({'pointRadius': 5,'fillColor':'#123456','fillOpacity': 0.6,'stroke':true,'strokeColor':'#654321','strokeOpacity': 1,'strokeWidth': 1,'strokeDashstyle':'solid',"label":"${getName}",'fontFamily':'TeuthoBD',"fontWeight":"bold","fontSize":"${getFontSize}","fontColor":"#000000","labelAlign":"lt"  }, OpenLayers.Feature.Vector.style["default"]);
var  selectStyle = OpenLayers.Util.applyDefaults({'pointRadius': 6,'fillColor':'#123456','fillOpacity': 0.8,'stroke':true,'strokeColor':'#654321','strokeOpacity': 1,'strokeWidth': 1,'strokeDashstyle':'solid',"label":"${getName}",'fontFamily':'TeuthoBD',"fontWeight":"bold","fontSize":"${getFontSize}","fontColor":"#000000","labelAlign":"lt"  }, OpenLayers.Feature.Vector.style["default"]);var  layerStyleMap =new  OpenLayers.StyleMap({'default': defaultStyle,'select': selectStyle });
layerStyleMap.styles["default"].context = { getName: userContext.labelFunction, getFontSize: userContext.labelSize };
layerStyleMap.styles["select"].context = { getName: userContext.labelFunction, getFontSize: userContext.labelSize };
userContext.paintLayer =new  OpenLayers.Layer.Vector("BayDat", { styleMap: layerStyleMap});
userContext.map.addLayer(userContext.paintLayer);

....

     labelSize:function  (feature) {
         return  Math.min(20, Math.max(5, 6000 / feature.layer.map.getResolution())) +"px";
     },

     labelFunction:function  (feature) {
         if  (feature.attributes.value != undefined) {
             return  feature.attributes.value;
         }else  {
             return  '';
         }
     },

Regards,
Slawomir

Am 27.08.2010 10:17, schrieb Slawomir Messner:
>    Thanks for the very fast and detailed answer.
> We cannot render features at the server and send them as an image,
> because we want them editable and the look and feel of a desktop tool. I
> works well but not every part fits together. (I hope it changes with
> your hints.)
> I think it would be also possible to edit them on the server, but it
> works good with the Controls in OL on the client side, especially in
> chrome it's fast enough and we hope that the other browsers will follow.
> I see, I have many things to read, design and (re-)code. But now I know
> which way to go.
> Thx again,
> Slawomir
>
> Am 27.08.2010 09:18, schrieb Andreas Hocevar:
>> On Aug 27, 2010, at 07:52 , Slawomir Messner wrote:
>>
>>> 1. Is this the recommended way to work with styles or is there a better
>>> way? Is there maybe already a tool?
>> You have several options, as styling has evolved in OpenLayers 2.0. For the recommended way of client-side styling in OpenLayers, please refer to http://trac.openlayers.org/wiki/Styles. This is all about rule based styling.
>>
>> If you want to use a tool, you can go through SLD (see http://openlayers.org/dev/examples/sld.html) and use an SLD editor. There you have several options - I only list some that I know to be useful:
>>
>>    * Web-based: OpenGeo Suite Styler (http://opengeo.org/products/suite/)
>>    * Desktop GIS: UDig (http://udig.refractions.net/)
>>    * If you are familiar with CSS, you can try GeoServer CSS (http://dwins.wordpress.com/2010/07/25/geoserver-css-conversion/)
>>
>>> Jep, we could put any value in
>>> attributes or feature.sytle but sometimes there are more then 2000
>>> features so we want to have as few styles as possible.
>> With that many features, you should not even consider rendering them at the client. Instead, use a WMS (e.g. GeoServer or MapServer). But what I said above about SLD is also valid here - SLD is the way to go with GeoServer. For MapServer, the primary way to define styles is through the mapfile, which some people prefer over SLD.
>>
>>> Are rule maybe
>>> better even if harder to parse?
>>>    The functions described below are working already, but not always
>>> together, the workflow below will be the new one and before I change
>>> "all" our controls and loading mechanism from every source... I would
>>> like to have some opinions.
>> This is because you should not mix rule based styling (i.e. layers with a styleMap) with symbolizer based styling (i.e. features with a style).
>>
>>> 2. The docs telling you at OL.Feature.Vector under
>>> OpenLayers.Feature.Vector.style "OpenLayers features can have a number
>>> of style attributes..." but it's the layer, right?
>> Both is true. In the old way of styling, symbolizers defined on a feature (as style property) take precedence over the ones defined on the layer (also as style property).
>>
>>> I see my style only
>>> if I set OpenLayers.Feature.Vector.style like {'pointRadius':6,
>>> fillColor:'#FF0000'} not OL.StyleMap({'default': {'pointRadius':6,
>>> fillColor:'#FF0000'}, 'select': {'pointRadius':6, fillColor:'#0000FF'}
>>> }) or {'default': {'pointRadius':6, fillColor:'#FF0000'}, 'select':
>>> {'pointRadius':6, fillColor:'#0000FF'} }.
>> The OpenLayers.Style object cannot be used with features, it is part of the rule based styling framework. Only symbolizers are supported. So what you describe here is expected.
>>
>>> 3. StyleMap, Style and Object are the classes you have to work with.
>> For rule based styling (the new way), you work with StyleMap and Style. For symbolizer based styling (the old way) you work with symbolizer objects.
>>
>>> Sometimes it's ok to write attributes it into style directly and in some
>>> cases it's better to use style.styles["default"].defaultStyle.
>> style.styles["default"].defaultStyle is not part of the API, so you should never be working with that in an application. What you are referring to here is just the base style on which rules will be applied to.
>>
>>> Are there
>>> some plans to change styling or limit the way to style to make it more
>>> clearly for OL 3.0?
>> As I said, vector styling went through a long evolution in OpenLayers 2.x, and there are plans to give it an overhaul in 3.0. What exactly it will look like is not clear yet, but the aim is to make it simpler. My prediction is that rule based styling will be closer to SLD/CSS, and styling features individually will also be possible (for the sake of KML support).
>>
>>> Something like: Every stlye attribute is a stylemap
>>> and when it doesn't have the style you want look in it's "container"
>>> (control)->feature->layer(or should it be feature->(control)>layer).
>> This is exactly what you do with the StyleMap: On the layer, you have a StyleMap which contains Style instances for all renderIntents (default, select, temporary etc.). If you want to style a feature individually, you create a rule with a FeatureId filter for the desired renderIntent. A control is configured with a renderIntent, which it will use when drawing features.
>>
>>> Step 1. Let's say we have some named places in a vector layer some
>>> chosen geometries form our data. When we load them we use the common way
>>> to style them with StyleMap in the layer also the labels, the text is
>>> stored in an attribute so we use ${attribName}.
>>> Step 2. Now we want to edit the style of one feature so we have to use
>>> the style attribute of OL.Feature.Vector, right? Because we want to
>>> change only some attributes the layer style and not to create a new
>>> style than we have to copy the layer (default) style into the features
>>> style attribute before editing:
>>> feature.style =
>>> OpenLayers.Util.extend({},layer.style.styles["default"].defaultStyle);
>> Nope. If you wanted to get the style that the feature is currently rendered with, you would do
>>
>> layer.styleMap.createSymbolizer(feature, "default");
>>
>> But we do not want to do that here. Let's say you want to change the fillColor of the feature, then you would create a symbolizer with it:
>>
>> var symbolizer = {fillColor: "#FF32CC"};
>>
>> Now you add a rule with a FeatureId filter to the Style for the "default" renderIntent:
>>
>> layer.styleMap.styles["default"].addRules([new OpenLayers.Rule({
>>       filter: new OpenLayers.Filter.FeatureId({fids: [feature.id]}),
>>       symbolizer: symbolizer
>> })]);
>>
>> If your features have a fid (e.g. because they came from a GML format), you should replace "feature.id" above with "feature.fid".
>>
>>> Step 2b. Because some attributes are calculated from attributes so the
>>> attributes of feature.style are replaced by the values if there is
>>> something like this ${attribName}. Nearly all style attributes should be
>>> editable labels, graphics, strokes, fill, radius...
>> If you create a FeatureId filter like above, you still can do that by using ${whatever} in the symbolizer.
>>
>>> But now we lost the ability to mark this feature as selected, it doesn't
>>> work by the select style of the layer.
>> If you do like described above, selecting by rendering the feature with a "select" intent will still work, because you did not set a style property on the feature.
>>
>>> Expect we define a selectStyle in
>>> the SelectFeature control, but this style would be same for every
>>> feature so i.e. we cannot keep the different labels.
>> No need to use a selectStyle in the above scenario.
>>
>>> Step 3. Editing of attributes or moving features. For editing style it's
>>> not so important to have a select style but when you use the layer with
>>> other controls, like an attribute editor. What would we do if a user
>>> changes in a feature with edited style the attribute for the label? We
>>> have to read it again and put it into feature.style like in 2b.
>> Not with the above scenario, unless you allowed the user to hard-code a new label by setting a label property in the symbolizer.
>>
>>> Step 4. Adding new features.
>>> A user expects that he can do Step 2,3 and 4 not in the row and multiple
>>> times.
>> Still no problem. Add new rules with featureId filters with only the symbolizers properties that the user has edited.
>>
>>> Step 5. Now the user should be able to save the resulting map with style
>>> and attributes. so for every edited feature we have to save the style
>>> attribute for the others the layer.style.styles["default"].defaultStyle
>>> or mark them as "layerStyled" and save the default Style to reuse it as
>>> layer style the next time a user loads his layer.
>> Nope. Just use Format.SLD to write an SLD. And the good thing is: this will also work if your features were never rendered on the client, but by your WMS.
>>
>>> I'm looking forward for your critics, tipps and other helping things.
>> I think there were many in my post.
>>
>> Regards,
>> Andreas.
>>
>>> I'm open for questions and so on.
>>> Thx and Regards,
>>> Slawomir
>>>
>>> -- 
>>> -----------------------------------------------
>>> Slawomir Messner
>>> Forschungszentrum "Deutscher Sprachatlas"
>>>
>>> _______________________________________________
>>> Users mailing list
>>> Users at openlayers.org
>>> http://openlayers.org/mailman/listinfo/users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/openlayers-users/attachments/20100827/a1128ace/attachment.html


More information about the Users mailing list