[OpenLayers-Dev] Random Colors on Vector Features?

Tim Schaub tschaub at openplans.org
Wed Mar 12 15:40:12 EDT 2008


Picking up an old thread...

Tim Schaub wrote:
> Hey-
> 
> Christopher Schmidt wrote:
>> I have a set of vector features. Each time I create a new feature, I
>> want that feature to be styled such that it has a random color, chosen
>> from a list of colors supplied by me.
>> I see a couple of examples for 'unique style value' stuff, but that
>> requires some unique attribute on my feature; I want to serialize the
>> features later, so I don't want bogus attributes attached to them.
>>
>> Can I set a Style() object directly on the feature with my fillColor
>> specified? Do I have to do something else? 
> 
>     var colors = ["red", "orange", "yellow", "green", "blue", "purple"];
>     var features = new Array(20);
>     var x, y, fill;
>     for(var i=0; i<20; i++) {
>         x = Math.random() * 360 - 180;
>         y = Math.random() * 180 - 90;
>         fill = colors[Math.round((colors.length - 1) * Math.random())];
>         features[i] = new OpenLayers.Feature.Vector(
>             new OpenLayers.Geometry.Point(x, y), null,
>             {fillColor: fill, pointRadius: 5}
>         );
>     }
> 
> Setting a symbolizer directly on a feature still works.
> 

But even less necessary if the patch #1434 gets in.

Say you have 20 features with no "style":

     var x, y;
     var features = new Array(20);
     for(var i=0; i<features.length; i++) {
         x = Math.random() * 360 - 180;
         y = Math.random() * 180 - 90;
         features[i] = new OpenLayers.Feature.Vector(
             new OpenLayers.Geometry.Point(x, y)
         );
     }
     layer.addFeatures(features);
     var colors = ["red", "green", "blue"];
     layer.styleMap = new OpenLayers.StyleMap(new OpenLayers.Style(
         {
             pointRadius: 5,
             fillColor: ${getColor}
         }, {
             getColor: function(feature) {
                 return colors[parseInt(3 * Math.random())];
             }
         }
     ));

You can create a style map with a symbolizer template that runs whatever 
function you want for each feature.  More verbose than giving each 
feature a simple symbolizer, but way more useful (if you accept that 
randomly styled features are less useful than features styled based on 
something non-random).

If you want to have features symbolized based on anything about the 
feature (geometry area/length, fid, location, even intersection with 
other features) you should do this with a style map.  Then, when you add 
new features to your layer, when those features are drawn, the same 
(underlying) rules get evaluated and symbolizers get created for those 
features.  This makes the preFeatureInsert styling completely obsolete.

As an added benefit, when you update something about your features that 
is responsible for the feature styling, the symbolizer gets updated on 
the next draw.  Move a feature whose style is based on position, the 
style changes.  You don't get this with feature.style.

Tim

> In the future, I think it would be good to encourage the use of 
> FeatureId rules.  This could be facilitated by having layer.addFeature 
> (to be written) optionally take a symbolizer.  If you specify a 
> symbolizer when adding a feature to the layer, the layer would create a 
> FeatureId rule for the corresponding feature (and add that rule to its 
> styleMap).
> 
> It might also make sense to have destroyFeatures remove the FeatureId 
> rules for the given features from its styleMap.
> 
> I'm curious about your use case.  I don't have a good idea how common it 
> is to want to style a feature in a way that has nothing to do with its 
> attributes.
> 
> Tim
> 
>>
>> Regards,
> 
> 




More information about the Dev mailing list