[Geoserver-devel] Express SLD literal using ground units

I have many times been looking for a way of expressing literals in sld using
ground units. This could be very useful if one wants to render something,
let's say road lines, approximately 2 meters wide.
So how to accomplish?
I'm thinking that if the query parameters, or at least the current scale
denominator of the request were available as 'variables' or xml entities you
could build up an expression using regular function calls in sld, example:

<CssParameter name="stroke-width">
<ogc:Div>
<!-- My preferred road width expressed in ground units -->
<ogc:Literal>2.0</ogc:Literal>
<!-- The magic value that maps ground units to pixel units -->
<ogc:Literal>&takeMeToPixelUnits;</ogc:Literal>
</ogc:Div>
</CssParameter>

Of course the users display resolution would have to be assumed or else
maybe provided as a vendor parameter in the request.

If someone could point me in the right direction I would be glad to help
implementing.

Best regards

/Peter

--
View this message in context: http://www.nabble.com/Express-SLD-literal-using-ground-units-tp23170881p23170881.html
Sent from the GeoServer - Dev mailing list archive at Nabble.com.

peter_se ha scritto:

I have many times been looking for a way of expressing literals in sld using
ground units. This could be very useful if one wants to render something,
let's say road lines, approximately 2 meters wide.
So how to accomplish?
I'm thinking that if the query parameters, or at least the current scale
denominator of the request were available as 'variables' or xml entities you
could build up an expression using regular function calls in sld, example:

<CssParameter name="stroke-width">
<ogc:Div>
<!-- My preferred road width expressed in ground units -->
<ogc:Literal>2.0</ogc:Literal>
<!-- The magic value that maps ground units to pixel units -->
<ogc:Literal>&takeMeToPixelUnits;</ogc:Literal>
</ogc:Div>
</CssParameter>

Of course the users display resolution would have to be assumed or else
maybe provided as a vendor parameter in the request.

If someone could point me in the right direction I would be glad to help
implementing.

This topic has been discussed a bit in the GeoTools mailing list here:
http://n2.nabble.com/Context-enviroment-variables-in-SLD-td1960257.html

In short:
- write an "enviroment" function that can be populated with information
   before the rendering process starts (that information is stored into
   a thread local)
- the renderer itself stores some information as environment items as
   well, such as the scale denominator, before actually starting to
   draw anything
- a symbolizer can have widths coded as:

   <CSSParameter name="stroke-width">
     <ogc:Mul>
       <ogc:literal>2.0</ogc:literal>
       <ogc:Function name="enviroment">
         <ogc:Literal>scaleDenominator</ogc:Literal>
       </ogc:Function>
     <ogc:Mul>
   </CSSParameter>

- when rendering is done the caller makes sure to call a cleanup
   method so that the thread local holding the "environment"
   gets cleaned up.

The filter function should not be that hard to code, just look
at the existing ones in GeoTools main module. And add some static
methods to the function to allow for manipulating the environment
contents (setting, cleaning), those would act against a simple
Map stored in a ThreadLocal.

This would open the road to more complex SLD parametrizations
than just scale handling, and it's not significantly more
complex than other ways to just pass down the current scale
(it also plays fully within the boundaries of the SLD specification).

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.