Using CSS to customize the rendering process

Usually, renderers can be customized by means of their own Java™ API. For example, to obtain blue lines, you can use IlvDefaultCurveRenderer and call the setForeground method of its IlvMapLineRenderingStyle. To customize a renderer easily and quickly, you can also use the IlvMapCSSRenderer class, which is an IlvDefaultFeatureRenderer (it can render any known IlvMapGeometry).
Note
This feature is difficult to use with map layers having their own style. It leads to a situation in which each object style can be defined in two ways.
For more information about CSS, see Using CSS Syntax in the Style Sheet, in Rogue Wave® JViews Diagrammer, Developing with the SDK .

Cascading style sheets

For its customization, the IlvMapCSSRenderer class uses cascading style sheets, or CSS files. The customization is done so that for the same Java code you can have different style sheets, that is, different rendering aspects.
Basically, a style sheet is a set of rules. For more details on the structure of the CSS, refer to Using CSS Syntax in the Style Sheet, in Rogue Wave® JViews Diagrammer, Developing with the SDK .
The complete source code of this example can be found in the following files:
Here is how to use the IlvMapCSSRenderer class. Imagine, for example, that you have a shapefile data file, roads.shp , and you need to render the roads in red. Here is the simplest way to do it by means of a CSS:
IlvMapCSSRenderer cssRenderer = 
 new IlvMapCSSRenderer(null, //use as default renderer
        "roads", 
        new String[] { "simple.css"});
 IlvMapLoader loader = new IlvMapLoader(manager);
 IlvMapFeatureIterator iterator = loader.makeFeatureIterator("roads.shp");
    loader.load(iterator, cssRenderer);
and the simple.css file would be:
#roadsLinesStyle {	
    class : 'ilog.views.maps.rendering.IlvMapLineRenderingStyle';
    foreground : red;
}

roads {
    class : 'ilog.views.maps.rendering.IlvDefaultCurveRenderer';
    lineRenderingStyle : @=roadsLinesStyle;
}
Later in this section, all the content of the corsica.css file contained in the CSS demo (<installdir>/jviews-maps810/samples/css/data ) is examined and explained.

Customizing the CSS renderers

The following extracts of CSS code show how the user can customize the CSS renderer.
  • Set the debug mask to 0, so that no debug information will be printed. The maximum debug information is obtained by setting the debug mask to 65535.
    #IlvMapCSSRenderer {
        styleSheetDebugMask : 0;
    }
    
  • Customize the rendering of the airports.shp shapefile which contains Point geometries. Use an IlvLabeledPointRenderer IlvLabeled .
    #airportsPointStyle {
        class : 'ilog.views.maps.rendering.IlvMapPointRenderingStyle';
        markerSize : 8;
        markerType : 'FilledDiamond|Square';
        markerColor : #99ffee04;
    }
    
    #airPortsTextStyle {
        class : 'ilog.views.maps.rendering.IlvMapTextRenderingStyle';
        backgroundPaint : yellow;
        framePaint : green;
        innerMargin : 2;
        maximumHeight :20;
        minimumHeight : 15;
        scale : 0.0000025;
        antialiasing : true;
    }
    
    airports {
        class : "ilog.views.maps.labelling.IlvLabeledPointRenderer";
        attributeNames : nam;
        pointRenderingStyle : @=airportsPointStyle;
        textRenderingStyle : @=airPortsTextStyle;
    }
    
  • Create an instance of IlvLabeledPointRenderer , customize it and use it to render the shapefile. It is equivalent to the following Java code:
    IlvMapPointRenderingStyle pStyle = new IlvMapPointRenderingStyle();
    pStyle.setMarkerSize(8);
    pStyle.setMarkerType(IlvMarker.IlvMarkerFilledDiamond |
                                             IlvMarker.IlvMarkerSquare);
    pStyle.setMarkerColor(new java.awt.Color(255, 238, 4, 153));
    // The #99ffee04 color notation has the same syntax as HTML, 
    // the first 2 digits after the # represent the alpha channel.
    IlvMapTextRenderingStyle tStyle = new IlvMapTextRenderingStyle();
    tStyle.setBackgroundPaint(Color.yellow);
    tStyle.setFramePaint(Color.green);
    tStyle.setInnerMargin(2);
    tStyle.setMaximumHeight(20);
    tStyle.setMinimumHeight(15);
    tStyle.setScale(0.0000025);
    tStyle.setAntialiasing(true);
    IlvLabeledPointRenderer labelRender = 
           new IlvLabeledPointRenderer();
    labelRenderer.setAttributeNames (new String[] {"nam"});
    labelRenderer.setPointRenderingStyle(pStyle);
    labelRenderer.setTextRenderingStyle(tStyle);
    
  • Create an IlvDefaultCurveRenderer to render the coastlines.shp shapefile that contains Line geometries:
    #coastlinesStyle {	
        class : 'ilog.views.maps.rendering.IlvMapLineRenderingStyle';
        foreground : black;
        lineWidthZoomed : true;
        lineWidth : 2;
        lineStyle : 4.2,4.3;
        lineJoin : JOIN_BEVEL;
        endCap : Cap_Round;
    }
    
    coastlines {
        class : 'ilog.views.maps.rendering.IlvDefaultCurveRenderer';
        lineRenderingStyle : @=coastlinesStyle;
    }
    
Note
  1. In the previous code extract the class keyword was used to tell the renderer to instantiate the corresponding class and to use it. Here an ilog.views.maps.rendering.IlvMapLineRenderingStyle class is instantiated to customize an instance of the ilog.views.maps.rendering.IlvDefaultCurveRenderer class.
  2. You can assign a float array to the lineStyle keyword, as well as some predefined values such as Dash , Dot , and so on. Moreover, values assigned to the LineStyle , lineJoin and endCap are not case sensitive.
  • Create an IlvLabeledPointRenderer to render the cities.shp shapefile that contains Point geometries:
    #citiesPointStyle {
        class : ilog.views.maps.rendering.IlvMapPointRenderingStyle ;
        markerSize : 3;
        markerType : FilledCircle;
        markerColor : blue
    }
    
    #col1 {
        class : 'java.awt.Color(red, green, blue)' ;
        red : 0;
        green : 0;
        blue : 200;
    }
    
    #col2 {
        class : 'java.awt.Color(red, green, blue, transparency)' ;
        red : 150;
        green : 200;
        blue : 255;
        transparency : 180;
    }
    
    #citiesLabel {
        class : ilog.views.maps.rendering.IlvMapTextRenderingStyle ;
        backgroundPaint : @=col2;
        labelFillColor : black;
        framePaint : @=col1;
        innerMargin : 2;
        maximumHeight :15;
        minimumHeight : 10;
        antialiased : true;
        scale : 0.0000025;
    }
    
    cities {
        class : ilog.views.maps.labelling.IlvLabeledPointRenderer;
        attributeNames : NAME,txt;
        rejectedValues : UNK;	
        pointRenderingStyle : @=citiesPointStyle;
        textRenderingStyle : @=citiesLabel;
    }
    
    Notice here the syntax of the #col1 node. This shows how you can instantiate any kind of objects using the CSS. You just have to provide the class keyword in the node scope and link it to the definition of the constructor which is given with all the necessary parameters: class : 'java.awt.Color(red, green, blue)' .
    You can see here that an AWT Color with its three channels is constructed: red, green, and blue. To construct the Color, you have to provide the values of each parameter given in the list. For example, here it is 0 for red, 0 for green, and 200 for blue.
  • Create an IlvRailroadRenderer to render the roads.shp shapefile that contains Line geometries. The IlvRailroadRenderer is a renderer provided with its source code in the CSS demo. It is designed to render line geometries as roads or railroads. Note that, using the CSS, you can even customize your own renderer:
    #col3 {
        class : 'java.awt.Color(red, green, blue, transparency)' ;
        red : 220;
        green : 10;
        blue : 10;
        transparency : 100;
    }
    
    #roadsAttributes {
        class : 'ilog.views.maps.graphic.IlvRailroadAttributes';
        drawingTies : false;
        background : @=col3;
        railColor : #66ff0000;
        railSpacing : 1;
        maximumRailSpacing : 1;
        scale : 0.000000025;
    }
    
    roads {
        class : 'ilog.views.maps.rendering.IlvRailroadRenderer';
        attributes : @=roadsAttributes;
    }
    
  • Create an IlvDefaultAreaRenderer to render the builtareas.shp shapefile that contains Polygon geometries:
    #pattern1 {
        class : 'ilog.views.util.java2d.IlvPattern(type, foreground, background)';
       type: THICK_DIAGONAL_GRID;
       foreground: gray;
       background: wheat;
    }
    
    #builtareasLineStyle {
        class : 'ilog.views.maps.rendering.IlvMapLineRenderingStyle';
        foreground : maroon;	
        lineWidthZoomed : true;
        lineWidth : 2;
        lineJoin : join_Miter;
        endCap : CAP_Round;
    }
    
    #builtareasAreaStyle {	
        class : 'ilog.views.maps.rendering.IlvMapAreaRenderingStyle';
        fillingObject : true;
        fillPattern : @=pattern1;
        drawingStroke : true;
        lineRenderingStyle : @=builtareasLineStyle;
    }
    
    builtareas {
        class : 'ilog.views.maps.rendering.IlvDefaultAreaRenderer';
        usingGeneralPath : true;
        areaRenderingStyle : @=builtareasAreaStyle;
    }
    
    You can see here how to create an instance of IlvPattern and use it for the rendering process. The Java code corresponding to this CSS part of code is:
    IlvPattern pattern1 = 
           new IlvPattern(IlvPattern.THICK_DIAGONAL_GRID, 
                          Color.gray,
                          new Color(245,222,179));
    IlvMapLineRenderingStyle builtareasLineStyle = new
       IlvMapLineRenderingStyle();
    builtareasLineStyle.setForeground(new Color(128, 0, 0));
    builtareasLineStyle.setLineWidthZoomed(true);
    builtareasLineStyle.setLineWidth(2);
    builtareasLineStyle.setLineJoin(BasicStroke.JOIN_MITER);
    builtareasLineStyle.setEndCap(BasicStroke.CAP_ROUND);
    IlvMapAreaRenderingStyle builtareasAreaStyle = new
       IlvMapAreaRenderingStyle();
    builtareasAreaStyle.setFillingObject(true);
    builtareasAreaStyle.setFillPattern(pattern1);
    builtareasAreaStyle.setDrawingStroke(true);
    builtareasAreaStyle.setLineRenderingStyle(builtareasLineStyle);
    
    IlvDefaultAreaRenderer builtareas = new IlvDefaultAreaRenderer();
    builtareas.setUsingGeneralPath(true);
    builtareas.setAreaRenderingStyle(builtareasAreaStyle);
    
  • Create an IlvRailroadRenderer to render the railroads .shp shapefile that contains Line geometries:
    #railRoadStyle {
        class : 'ilog.views.maps.graphic.IlvRailroadAttributes';
        railSpacing : 1;
        scale : 0.00000025;
        maximumRailSpacing : 1;
        tieWidth : 3;
        maximumTieWidth : 3;
        tieSpacing : 4;
        slantingLimit : 15;
        railColor : green;
        tieColor : #ff40ff40;
    }
    
    railroads {
        class : 'ilog.views.maps.rendering.IlvRailroadRenderer';
        attributes : @=railRoadStyle;
        dummy[0] : "@#col1";
        dummy[1] : "@#col2";
        dummy[2] : "@#col3";
    }
    
Another interesting aspect of this part of the CSS code is the manipulation of indexed properties, called dummy here. The IlvRailroadRenderer class defines a dummy attribute member, which is an array of String ( String[] ).
To customize this array by using the CSS, you need to:
  1. Define the get/set methods according to the JavaBeans specifications.
    Here is the part of the code of IlvRailroadRenderer that declares these methods:
    public Color getDummy(int i)
    {
      return _dummy[i];
    }
    
    public Color[] getDummy()
    {
      return _dummy;
    }
    
    public void setDummy(Color[] val)
    {
      _dummy = val;
    }
    
    public void setDummy(int i, Color val)
    {
      _dummy[i] = val;
    }
    
    The complete source code of this example can be found in the following file:
    Note
    In our example, the number of dummy colors is limited to 3.
  2. Define the descriptor in the BeanInfo class, IlvRailroadRendererbeanInfo :
    public class IlvRailroadRendererBeanInfo
      extends SimpleBeanInfo 
    {  
      private final static Class beanClass = IlvRailroadRenderer.class;
    
      public PropertyDescriptor[] getPropertyDescriptors() 
      {
        try {
          PropertyDescriptor[] properties = {
            new PropertyDescriptor("attributes", beanClass),
            new IndexedPropertyDescriptor("dummy", beanClass) 
                            // The dummy indexed property.
          };
          return properties;
        } catch (IntrospectionException e) {
          throw new Error(e.toString());
        }
      }
    }
    
    The complete source code of this example can be found in the following file:
  3. Define indexed properties in your CSS file by using the @# syntax.
Note
You can define a unique CSS file for all your CSS renderers. But each time you instantiate the CSS renderer, the long CSS file is parsed, and depending on the size of the CSS file, it can be time consuming. In this case, you can cut your CSS file into smaller CSS files to avoid the performance drop.
For more information about CSS, see Using CSS Syntax in the Style Sheet in Rogue Wave® JViews Diagrammer, Developing with the SDK .