Motivation:

Upgrading styles for more functionalities

Contact:

Johann Sorel

Tagline:

Style Upgrade

Description

Currently, GeoTools styles package is based on OGC SLD 1.0.0.

This proposal will upgrade GeoTools style package to follow newer specifications :

JavaDoc of the GeoAPI interfaces :

http://geoapi.sourceforge.net/snapshot/javadoc/index.html
package :
org.opengis.style

A Basic Implementation :

To tests on the go-renderer, I committed a basic implementation in the unsupported GO module.
package :
org.geotools.styling2

What is new :

Some changes may be more or less a problem like :

API

Style Creation

We will be adding additional methods as needed to the GeoTools StyleFactoryImpl. When we are happy with the result we will create a GeoAPI StyleFactory with the needed methods.

class StyleFactoryImpl extends AbstractStyleFactory implements StyleFactory2,
                                                           /** org.opengis.style.StyleFactory*/ {
    ...
    /**
     * Create an LineSymbolizer using stroke to draw the indicated geometry.
     * @param stoke Description of how to draw the line segments
     * @param geometryExpression Expression evaluating to a Geometry.
     *        (For SLD 1.1 documents this should be a PropertyName expression)
     * @since 2.6.0
     */
    LineSymbolizer lineSymbolizer( Stroke stroke, Expression geometryExpression );

    Rule rule();
    /**
     * ...
     * @param symbolizers List of symbolizers to use; these symbolizers will be copied into
     *                    an internal list so we can issue events.
     * ...
     */
    Rule rule( Description description, Filter filter, List<Symbolizer> symbolizers, LegendGraphic, double minScale, double maxScale, boolean isElse );

    ...

}

We will be using single words (no "create" prefix) similar to FilterFactory. We must be careful to provide each and every parameter during construction of the immutable objects. For mutable objects we will have two methods; one taking only the required parameters; and one taking each and every parameter.

Integration with existing Interfaces

We are making use of type narrowing to allow the GeoTools implementation to implement both org.geotools.styling and org.opengis.style interfaces. The acceptance test is to have existing code still compile; and to migrate the renderers to the new interfaces.

BEFORE:

public interface LineSymbolizer extends Symbolizer {
    Stroke getStroke();

    /** @deprecated Not thread safe - please use DuplicatingStyleVisitor */
    void setStroke(Stroke stroke);

    String getGeometryPropertyName();

    /** @deprecated Not thread safe - please use DuplicatingStyleVisitor */
    void setGeometryPropertyName(String geometryPropertyName);
}

AFTER:

public interface LineSymbolizer extends Symbolizer implements org.opengis.style.LineSymbolizer {

    @Override Type narrow org.opengis.style.Stoke to Stroke
    Stroke getStroke();

    /** @deprecated Not thread safe - please use DuplicatingStyleVisitor */
    void setStroke(Stroke stroke);

    String getGeometryPropertyName();

    /** @deprecated Not thread safe - please use DuplicatingStyleVisitor */
    void setGeometryPropertyName(String geometryPropertyName);
}

Direct Collection Use

We are setting up new methods for direct manipulation of collection based access. Modifications made to the collection will issue change events.
BEFORE:

public interface FeatureTypeStyle {
    ...
    Rule[] getRules();
    void setRules(Rule[] rules);
    void addRule(Rule rule);
}
public interface Rule {
    ...
}

AFTER:

public interface FeatureTypeStyle extends org.opengis.FeatureTypeStyle {
    ...
    /** Same as: rules().toObjectArray( new Rule[0] ) */
    @Deprecated
    Rule[] getRules();

    /** Same as:
     * rules().clear()
     * rules().addAll( Arrays.asList( rules ) );
    @Deprecated
    void setRules(Rule[] rules);

    /** same as rules().add( Rule ) */
    @Deprecated
    void addRule(Rule rule);

    /** Offer direct access to the rules list; contents are assumed to be org.geotools.styling.Rule */
    @override
    List<org.opengis.style.Rule> rules();
}
public interface Rule extends org.opengis.Rule {
    ...
}

NOTES:

Listeners for Mutable Classes

AFTER:

public interface FeatureTypeStyle extends org.opengis.FeatureTypeStyle {
   addStyleListener( StyleListener listener );
   removeStyleListener( StyleListener listener );
}
public interface Rule extends org.opengis.Rule {
   addStyleListener( StyleListener listener );
   removeStyleListener( StyleListener listener );
}
/** Utility class for Style implementors - issues events when asked */
public StyleList extends ArrayList {
   addStyleListener( StyleListener listener );
   removeStyleListener( StyleListener listener );
}

Note each data structure is having its own set of listeners.

Notes:

New Methods for FeatureTypeStyle

AFTER:

NEW METHODS
    /**
     * Returns a collection of Object identifying features object.
     *
     * <p>
     * ISO 19117 extends FeatureTypeStyle be providing this method.
     * This method enable the possibility to use a feature type style
     * on a given list of features only, which is not possible in OGC SE.
     * </p>
     *
     * @return Collection<String>
     */
    @UML(identifier="definedForInst", obligation=OPTIONAL, specification=ISO_19117)
    Id getFeatureInstanceID();

    /**
     * Returns a semanticType that identifies the more general "type" of geometry
     * that this style is meant to act upon.
     * In the current OGC SE specifications, this is an experimental element and
     * can take only one of the following values:
     * <p>
     * <ul>
     *   <li>{@code generic:point}</li>
     *   <li>{@code generic:line}</li>
     *   <li>{@code generic:polygon}</li>
     *   <li>{@code generic:text}</li>
     *   <li>{@code generic:raster}</li>
     *   <li>{@code generic:any}</li>
     * </ul>
     * <p>
     *
     */
    Set<SemanticType> getSemanticTypeIdentifiers();

New Methods for Symbolizer

AFTER:

NEW METHOD
    /**
     * Returns a string of containing the measure unit name.
     * This parameter is herited from GML.
     * Renderers shall use the unit to correctly render symbols.
     *
     * recommended uom definitions are :
     * <p>
     * <ul>
     *     <li>{@code metre}</li>
     *     <li>{@code foot}</li>
     *     <li>{@code pixel}</li>
     * </ul>
     * <p>
     *
     * @return String name for the measure unit to use,
     * can be null. If the unit is null than we shall use a the pixel unit
     */
    @XmlElement("uom")
    Unit getUnitOfMeasure();

API Change for ColorMap

BEFORE :

public interface ColorMap {
    public static final int TYPE_RAMP = 1;
    public static final int TYPE_INTERVALS = 2;
    public static final int TYPE_VALUES = 3;

    public void addColorMapEntry(ColorMapEntry entry);

    public ColorMapEntry[] getColorMapEntries();

    public ColorMapEntry getColorMapEntry(int i);

    public int getType();

    public void setType(int type);

    void accept(StyleVisitor visitor);

    public void setExtendedColors(boolean extended);

    public boolean getExtendedColors();
}

AFTER:

public interface ColorMap {
    /** This is a live view of the ColorMap in function form*/
    Function getFunction();
}

NOTES:

Those are only the most interesting/problematic changes, feel free to explore the interfaces to find other changes.

Status

This proposal was started by Johann Sorel but never completed; please see Cleanup Style Interface Deprecations for a plan to clean up after this incomplete work.

Voting on this proposal:

Community support:

Tasks

This section is used to make sure your proposal is complete (did you remember documentation?) and has enough paid or volunteer time lined up to be a success

 

no progress

(tick)

done

(error)

impeded

(warning)

lack mandate/funds/time

(question)

volunteer needed

July 15th deadline:

  1. API change before GeoTools 2.5 goes out; deprecate symbolizer setter methods (tick)
  2. Update wiki upgrade to to 2.5 pages; linking to instructions for DuplicatingStyleVisitor
  3. Start 2.5.x branch
  4. API changed based on BEFORE / AFTER
  5. Update default implementation
  6. Add factory methods
  7. Deploy for other team members

After July 15th deadline:

  1. Remove deprecated code from GeoTools project (yeah!)
  2. Create org.opengis.style.StyleFactory based on experience above
  3. Update or provided sample code in demo
  4. Update the user guide examples (there are only two pages; copy and paste from demo)