OpenLayers OpenLayers

Ticket #1531 (new feature)

Opened 7 months ago

Last modified 7 months ago

add support for geometry type aware styling rules

Reported by: ahocevar Assigned to: ahocevar
Priority: minor Milestone: Future
Component: Style Version: 2.6
Keywords: Cc:
State: Needs Discussion

Description

Currently, some users seem to use OpenLayers.Rule.symbolizer to create a style that can be used independently for point, line and polygon features. This is not the way SLD intends PointSymbolizer, LineSymbolizer and PolygonSymbolizer to be used: applying a PointSymbolizer to a polygon or line in SLD means "if a line, polygon, or raster geometry is used with this symbolizer, then the semantic is to use the centroid of the geometry, or any similar representative point" (OGC, Styled Layer Descriptor Impelmentation Specification 1.0, 2002, p40).

So the appropriate way to give users the convenience they currently pack into a rule will be a method in OpenLayers.StyleMap to create styles with appropriate rules. Style.applySymbolizer will have to be changed to make the geometry type check only for symbolizers that are not geometry-hashed.

Attachments

1531-r7060-A0.patch (18.4 kB) - added by ahocevar on 05/04/08 15:17:02.
1531-r7137-B0.patch (20.7 kB) - added by ahocevar on 05/11/08 09:49:49.

Change History

05/04/08 15:17:02 changed by ahocevar

  • attachment 1531-r7060-A0.patch added.

05/04/08 15:39:35 changed by ahocevar

  • state changed from Needs Discussion to Review.

1531-r7060-A0.patch does significantly more than what I proposed in the original ticket description:

  • Implemented a new geometryType property for OpenLayers.Rule. This property can be set to determine for which geometry types (i.e. lines, points, polygons) the rule should apply.
  • Added support for FeatureTypeStyle and SemanticTypeIdentifier in OpenLayers.Format.SLD. For SLD.write, every geometry type that is found in the rules' geometryType properties will be assigned to a separate FeatureTypeStyle with the geometry type as SemanticTypeIdentifier. SLD.read will read SemanticTypeIdentifier, analyzes it and sets the appropriate geometry type. This works for SemanticTypeIdentifiers that address the geometry type (i.e. generic:point, generic:line and generic:polygon, according to the SLD spec).
  • Added a convenience method makeGeometryTypeAware() to OpenLayers.StyleMap. This will allow users who pack symbolizers that should only apply to point, line or polygon features into a single rule to convert those symbolizers to appropriate rules with geometryType

The whole idea of this patch is to meet both requirements of specifying symbolizers according to SLD's PointSymbolizer, LineSymbolizer and PolygonSymbolizer (a PointSymbolizer applied to a polygon means e.g. to draw a point symbol in the centroid point of a polygon), and to define different styles for different geometry types according to SLD's SemanticTypeIdentifier (i.e. apply a rule only if the feature's geometry type matches the rule's geometryType).

Note that rendering e.g. polygons with a point symbol is not supported yet in OpenLayers, but once that will happen, this patch gives us the API for it.

The patch includes tests for the new features. All tests pass in FF2 and IE6. Any review will be appreciated.

05/04/08 16:28:55 changed by ahocevar

  • type changed from task to feature.
  • summary changed from add a convenience method to create one stylemap that can hold different symbolizers for points, lines and polygons to add support for geometry type aware styling rules.

05/11/08 09:49:49 changed by ahocevar

  • attachment 1531-r7137-B0.patch added.

05/11/08 09:52:40 changed by ahocevar

1531-r7137-B0.patch is a new version which allows for multiple geometryTypes for a rule. The /*String*/ geometryType property is replaced with a /*Array(String)*/ geometryTypes property.

05/21/08 07:10:32 changed by ahocevar

  • state changed from Review to Needs More Work.

Andrea Aime of GeoServer just pointed me to a better way to do this. We start with SLD magic like this (which can be used in GT2-based applications like uDig or GeoServer):

<PropertyIsEqualTo>
 <Function name="geometryType">
   <PropertyName>the_geom</PropertyName>
 </Function>
 <Literal>Point</Literal>
</PropertyIsEqualTo>

So instead of using the GeometryTypes property of the rule, we would define functions in the filter, e.g.

Filter.functions = {
    geometryType: function(feature) {
        return feature.geometry.CLASS_NAME;
    }
}

This will allow us to do other cool things with filters too. It is almost in line with the rule context, except that the rule context (see #1548) should be replaced by filter functions.

I will start working on that as soon as I have time.

05/21/08 11:25:30 changed by ahocevar

  • state changed from Needs More Work to Needs Discussion.
  • milestone changed from 2.7 Release to Future.

Ok, after tschaub's suggestion of allowing functions as symbolizers, a little more thoughts about that. Currently, a symbolizer can have values or property names for its values, e.g.

var symbolizer = {
    strokeColor: "blue",
    fillColor: "${fill}"
}

In the future, we could add a third way to define symbolizer values:

var symbolizer = {
    strokeColor: function(feature) {
        switch(feature.state){
            "Insert": return "green";
            "Update": return "yellow";
            "Delete": return "red";
            default: return "gray";
        }
}

This is similar to what tschaub proposed (allow a function as symbolizer), just the other way around. With that, we have almost everything we need to implement ogc:Function. What we still need is a function factory that creates the correct functions with closures for the parameters when deserializing SLD or ogc:Filter. Those functions can then be attached to a feature.

The only concern with that is performance: calling functions is slow, and we might have to call a lot of functions if every symbolizer property is created by a function.

Anyway, that's just a few thoughts, discussion of a larger picture of all that might be in order.