Styling with CSS
The CSS styling module in GeoTools provides a concise, easy-to-use mechanism for creating map styles using a CSS-like syntax. This syntax is translated internally into SLD (Styled Layer Descriptor) styles that can be used by various rendering systems. This approach offers a more human-readable alternative to SLD XML, while maintaining compatibility with OGC standards.
Overview of CSS Styling
The CSS styling module allows developers to define map styles using a familiar CSS-like syntax. These styles are then translated into the more verbose SLD representation required by GeoTools and OGC-compliant rendering systems.
CSS Syntax
Selectors
CSS styles are composed of selectors and property declarations. Selectors determine which features will be styled, while properties define how they will be styled.
The CSS module supports several types of selectors:
- Type selectors: Target features by their type name (
states,topp:states) - ID selectors: Target specific features by ID (
#states.2) - Attribute selectors: Filter based on attribute values (
[population > 100000]) - Scale selectors: Apply styles at specific scale ranges (
[@scale < 10000],[@z > 5]) - Pseudo-class selectors: Style specific parts of symbols (
:mark,:stroke,:fill)
Selectors can be combined using:
- AND: Simply placing selectors next to each other (
states [population > 100000]) - OR: Separating selectors with commas (
states, counties)
Properties
Properties define the visual appearance of features. The CSS module supports properties similar to both CSS and SLD:
- Stroke properties:
stroke,stroke-width,stroke-opacity,stroke-dasharray - Fill properties:
fill,fill-opacity - Mark properties:
mark,mark-size,mark-rotation - Label properties:
label,font-family,font-size,font-weight,font-style - Graphic properties:
graphic,graphic-size,graphic-opacity - Raster properties:
raster-channels,raster-opacity,raster-contrast-enhancement
Example CSS Style
Here's a simple example of a CSS style that creates a point layer with red circle symbols:
* {
mark: symbol(circle);
mark-size: 6px;
}
:mark {
fill: red;
}This is equivalent to the following SLD:
<PointSymbolizer>
<Graphic>
<Mark>
<WellKnownName>circle</WellKnownName>
<Fill>
<CssParameter name="fill">#ff0000</CssParameter>
</Fill>
</Mark>
<Size>6</Size>
</Graphic>
</PointSymbolizer>CSS to SLD Translation
Translation Process
The CSS to SLD translation process involves several key steps:
- Parsing: The CSS text is parsed into a
Stylesheetobject usingCssParser - Rule organization: Rules are organized by z-index and feature type name
- Rule combination: Rules are combined to create a set of non-overlapping rules
- SLD generation: The combined rules are converted to SLD rules and symbolizers
Translation Modes
The CSS translator supports multiple translation modes that control how rules are combined and optimized:
- Exclusive: Generates fully exclusive rules by computing the exact domain coverage
- Simple: Sets the "exclusive" evaluation mode in the FeatureTypeStyle and relies on the renderer to find the first matching rule
- Flat: Merges rules more directly without complex domain coverage calculations
- Auto: Chooses between Exclusive and Simple modes based on rule complexity
The translation mode can be set using a directive at the beginning of the CSS file:
@mode "Simple";
* { stroke: black; }Rule Combination and Domain Coverage
The translator combines CSS rules to create non-overlapping SLD rules. This is done using the DomainCoverage class, which tracks which parts of the "domain" (the combination of scale ranges and filters) are covered by different rules.
Power Set Generation
To handle rule combinations correctly, the CSS translator uses a RulePowerSetBuilder to generate a filtered power set of the input rules. This ensures that all possible rule combinations are considered while avoiding combinations that would result in contradicting selectors.
Z-Index and Multi-Layer Support
The CSS module supports z-ordering of symbolizers through the z-index property. This allows for precise control over the drawing order of symbols, similar to CSS in web development.
Z-Index Usage
* {
fill: black;
stroke: white;
z-index: 0;
}
[population > 1000000] {
fill: red;
z-index: 1;
}The CSS translator can also generate multi-layer SLD by creating a separate NamedLayer for each group of same-named feature types. This is done using the translateMultilayer method.
Advanced Features
Pseudo-Classes
Pseudo-classes allow styling specific parts of symbols:
* {
mark: symbol(circle);
}
:mark {
fill: red;
stroke: black;
}Expressions and Functions
The CSS module supports expressions and functions in property values, including CQL expressions surrounded by square brackets:
* {
label: [name];
font-size: [population / 10000 + 8];
}
[category = 'park'] {
fill: symbol('circle');
}
:fill {
fill: #00FF00;
}Vendor Options
Vendor-specific options are supported with the -gt- prefix:
* {
label: [name];
-gt-label-follow-line: true;
-gt-label-max-displacement: 50;
}Using the CSS Translator
Basic Usage
To use the CSS translator in your code:
// Parse the CSS text into a Stylesheet
Stylesheet ss = CssParser.parse(cssText);
// Create a translator
CssTranslator translator = new CssTranslator();
// Translate to a Style object
Style style = translator.translate(ss);
// Or translate to a multi-layer SLD
StyledLayerDescriptor sld = translator.translateMultilayer(ss);Directives
Directives can be used to configure the translation process:
@mode "Simple";
@styleName "My Style";
@styleTitle "My Style Title";
@styleAbstract "This is a description of my style";
@maxOutputRules "5000";
@autoThreshold "100";
* {
fill: #888888;
}System Architecture
The CSS styling module architecture consists of several key components:
Translation Workflow
Here's a detailed view of the CSS to SLD translation workflow:
Integration with GeoTools
The CSS styling module integrates with the broader GeoTools styling framework. The translated styles can be used anywhere GeoTools styles are accepted, such as in renderers, WMS services, or map viewers.
Conclusion
The CSS styling module provides a more concise and readable alternative to raw SLD for creating map styles. It supports a wide range of styling capabilities, from basic fill and stroke properties to complex expressions and multi-layer styles. The translation process ensures compatibility with OGC standards while offering a more developer-friendly authoring experience.
While the CSS module is currently in the "unsupported" category of GeoTools, it is fully functional and used in production environments, particularly in GeoServer's CSS styling extension.
For developers looking to work with geospatial styling, the CSS module offers a powerful compromise between the expressiveness of programmatic styling and the standardization of SLD.