This is an automated email from the ASF dual-hosted git repository.
jsorel pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
new 5ba3ea5 Portrayal : add feature type style filtering test cases for
SEPortrayer
5ba3ea5 is described below
commit 5ba3ea5402ce34162869a62ea2d29c3a4cc76479
Author: jsorel <[email protected]>
AuthorDate: Fri Jan 15 17:02:07 2021 +0100
Portrayal : add feature type style filtering test cases for SEPortrayer
---
.../org/apache/sis/internal/map/Presentation.java | 35 +++
.../org/apache/sis/internal/map/SEPortrayer.java | 259 ++++++++++++++++++++-
.../apache/sis/internal/map/SEPresentation.java | 28 ++-
.../apache/sis/internal/map/SymbologyVisitor.java | 242 +++++++++++--------
.../apache/sis/test/suite/PortrayalTestSuite.java} | 46 ++--
5 files changed, 470 insertions(+), 140 deletions(-)
diff --git
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/Presentation.java
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/Presentation.java
index 9dd5ecb..092a920 100644
---
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/Presentation.java
+++
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/Presentation.java
@@ -16,6 +16,7 @@
*/
package org.apache.sis.internal.map;
+import java.util.Objects;
import org.apache.sis.coverage.grid.GridCoverage;
import org.apache.sis.portrayal.MapLayer;
import org.apache.sis.storage.DataStore;
@@ -107,4 +108,38 @@ public abstract class Presentation {
public void setCandidate(Feature feature) {
this.candidate = feature;
}
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 89 * hash + Objects.hashCode(this.layer);
+ hash = 89 * hash + Objects.hashCode(this.resource);
+ hash = 89 * hash + Objects.hashCode(this.candidate);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Presentation other = (Presentation) obj;
+ if (!Objects.equals(this.layer, other.layer)) {
+ return false;
+ }
+ if (!Objects.equals(this.resource, other.resource)) {
+ return false;
+ }
+ if (!Objects.equals(this.candidate, other.candidate)) {
+ return false;
+ }
+ return true;
+ }
+
}
diff --git
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPortrayer.java
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPortrayer.java
index 23c751a..1b17612 100644
---
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPortrayer.java
+++
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPortrayer.java
@@ -21,20 +21,28 @@ import java.awt.geom.NoninvertibleTransformException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.sis.coverage.grid.GridGeometry;
import org.apache.sis.feature.Features;
+import org.apache.sis.filter.DefaultFilterFactory;
+import org.apache.sis.geometry.Envelopes;
+import org.apache.sis.geometry.GeneralEnvelope;
import org.apache.sis.internal.feature.AttributeConvention;
import org.apache.sis.internal.storage.query.SimpleQuery;
+import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.portrayal.MapItem;
import org.apache.sis.portrayal.MapLayer;
import org.apache.sis.portrayal.MapLayers;
+import org.apache.sis.referencing.CRS;
import org.apache.sis.referencing.operation.matrix.AffineTransforms2D;
import org.apache.sis.storage.Aggregate;
import org.apache.sis.storage.DataStoreException;
@@ -57,13 +65,16 @@ import org.opengis.feature.IdentifiedType;
import org.opengis.feature.PropertyNotFoundException;
import org.opengis.feature.PropertyType;
import org.opengis.filter.Filter;
-import org.opengis.filter.Id;
+import org.opengis.filter.FilterFactory;
+import org.opengis.filter.FilterFactory2;
+import org.opengis.filter.expression.Expression;
import org.opengis.filter.expression.PropertyName;
import org.opengis.geometry.Envelope;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
import org.opengis.style.FeatureTypeStyle;
import org.opengis.style.Rule;
import org.opengis.style.SemanticType;
@@ -77,6 +88,15 @@ import org.opengis.util.GenericName;
* NOTE: this class is a first draft subject to modifications.
* </p>
*
+ * <p>
+ * Style properties ignored :
+ * </p>
+ * <ul>
+ * <li>Style : isDefault : behavior from ISO 19117 which can be replaced by
OGC SE Rule.isElseRule</li>
+ * <li>Style : defaultSpecification : behavior from ISO 19117 which can be
replaced by OGC SE Rule.isElseRule</li>
+ * <li>FeatureTypeStyle : instance ids : behavior from ISO 19117 which can
be replaced by OGC SE Rule.filter</li>
+ * </ul>
+ *
* @author Johann Sorel (Geomatys)
* @version 2.0
* @since 2.0
@@ -101,6 +121,8 @@ public final class SEPortrayer {
*/
public static final Predicate<IdentifiedType> IS_NOT_CONVENTION = p ->
!AttributeConvention.contains(p.getName());
+ private final FilterFactory2 filterFactory;
+
/**
* Hint to avoid decimating feature properties because they may be used
* later for other purposes.
@@ -114,7 +136,13 @@ public final class SEPortrayer {
}
};
- public SEPortrayer() {}
+ public SEPortrayer() {
+ FilterFactory filterFactory =
DefaultFactories.forClass(FilterFactory.class);
+ if (!(filterFactory instanceof FilterFactory2)) {
+ filterFactory = new DefaultFilterFactory();
+ }
+ this.filterFactory = (FilterFactory2) filterFactory;
+ }
/**
* Replace default margin solver.
@@ -154,6 +182,18 @@ public final class SEPortrayer {
FeatureType type;
if (resource instanceof FeatureSet) {
+
+ //apply user query if defined
+ final Query basequery = layer.getQuery();
+ if (basequery != null) {
+ try {
+ resource = ((FeatureSet) resource).subset(basequery);
+ } catch (DataStoreException ex) {
+ stream = Stream.concat(stream, Stream.of(new
ExceptionPresentation(ex)));
+ return stream;
+ }
+ }
+
try {
type = ((FeatureSet) resource).getType();
} catch (DataStoreException ex) {
@@ -277,10 +317,10 @@ public final class SEPortrayer {
symbolsMargin *= AffineTransforms2D.getScale(dispToObj);
}
- //optimize
- final Query query = prepareQuery(canvas, fs, layer, names,
rules, symbolsMargin);
-
try {
+ //optimize query
+ final Query query = prepareQuery(canvas, fs, names, rules,
symbolsMargin);
+
final Stream<Presentation> s = fs.subset(query)
.features(false)
.flatMap(new Function<Feature,
Stream<Presentation>>() {
@@ -311,7 +351,7 @@ public final class SEPortrayer {
}
});
stream = Stream.concat(stream, s);
- } catch (DataStoreException ex) {
+ } catch (DataStoreException | TransformException ex) {
stream = Stream.concat(stream, Stream.of(new
ExceptionPresentation(ex)));
}
}
@@ -338,9 +378,142 @@ public final class SEPortrayer {
* Creates an optimal query to send to the Featureset, knowing which
properties are knowned and
* the appropriate bounding box to filter.
*/
- private SimpleQuery prepareQuery(GridGeometry canvas, FeatureSet fs,
MapLayer layer, Set<String> names, List<Rule> rules, double symbolsMargin) {
- //TODO
- throw new UnsupportedOperationException("todo");
+ private SimpleQuery prepareQuery(GridGeometry canvas, FeatureSet fs,
Set<String> requiredProperties, List<Rule> rules, double symbolsMargin) throws
DataStoreException, TransformException {
+
+ final SimpleQuery query = new SimpleQuery();
+ final FeatureType schema = fs.getType();
+
+ //search all geometry expression used in the symbols
+ boolean allDefined = true;
+ final Set<Expression> geomProperties = new HashSet<>();
+ if (rules != null) {
+ for (Rule r : rules) {
+ for (Symbolizer s : r.symbolizers()) {
+ final Expression expGeom = s.getGeometry();
+ if (expGeom != null) {
+ geomProperties.add(expGeom );
+ } else {
+ allDefined = false;
+ }
+ }
+ }
+ } else {
+ allDefined = false;
+ }
+ if (!allDefined) {
+ //add the default geometry property
+ try {
+ PropertyType geomDesc = getDefaultGeometry(schema);
+
geomProperties.add(filterFactory.property(geomDesc.getName().toString()));
+ } catch (PropertyNotFoundException | IllegalStateException ex) {
+ //do nothing
+ };
+ }
+
+ if (geomProperties.isEmpty()) {
+ //no geometry selected for rendering
+ query.setFilter(Filter.EXCLUDE);
+ return query;
+ }
+
+ final Envelope bbox = optimizeBBox(canvas, symbolsMargin);
+
+ Filter filter;
+ //make a bbox filter
+ if (geomProperties.size() == 1) {
+ final Expression geomExp = geomProperties.iterator().next();
+ filter = filterFactory.bbox(geomExp, bbox);
+ } else {
+ //make an OR filter with all geometries
+ final List<Filter> geomFilters = new ArrayList<>();
+ for (Expression geomExp : geomProperties) {
+ geomFilters.add(filterFactory.bbox(geomExp,bbox));
+ }
+ filter = filterFactory.or(geomFilters);
+ }
+
+ //combine the filter with rule
filters----------------------------------
+ ruleOpti:
+ if (rules != null) {
+ final List<Filter> rulefilters = new ArrayList<>();
+ for (Rule rule : rules) {
+ if (rule.isElseFilter()) {
+ //we can't append styling filters, an else rule match all
features
+ break ruleOpti;
+ } else {
+ final Filter rf = rule.getFilter();
+ if (rf == null || rf == Filter.INCLUDE) {
+ //we can't append styling filters, this rule matchs
all features.
+ break ruleOpti;
+ }
+ rulefilters.add(rf);
+ }
+ }
+
+ final Filter combined;
+ if (rulefilters.size() == 1) {
+// //TODO need a stylefactory in SIS
+// //special case, only one rule and we passed the filter to
the query
+// //we can remove it from the rule
+// final Rule original = rules.get(0);
+// Rule rule = styleFactory.rule(null, null, null,
+// original.getMinScaleDenominator(),
+// original.getMaxScaleDenominator(),
+// new ArrayList(original.symbolizers()),
+// Filter.INCLUDE);
+// rules.set(0, rule);
+ combined = rulefilters.get(0);
+ } else {
+ combined = filterFactory.or(rulefilters);
+ }
+
+ if (filter != Filter.INCLUDE) {
+ filter = filterFactory.and(filter,combined);
+ } else {
+ filter = combined;
+ }
+ }
+ query.setFilter(filter);
+
+ //reduce requiered attributes
+ if (requiredProperties == null) {
+ //all properties are required
+ } else {
+ final Set<String> copy = new HashSet<>();
+ //add used properties
+ for (String str : requiredProperties) {
+ copy.add(stripXpath(str));
+ }
+
+ //add properties used as geometry
+ for (Expression exp : geomProperties) {
+ final PropertyNameCollector collector = new
PropertyNameCollector();
+ collector.visit(exp);
+ collector.getPropertyNames().stream()
+ .map(PropertyName::getPropertyName)
+ .map(SEPortrayer::stripXpath)
+ .forEach(copy::add);
+ }
+
+ try {
+ //always include the identifier if it exist
+ schema.getProperty(AttributeConvention.IDENTIFIER);
+ copy.add(AttributeConvention.IDENTIFIER);
+ } catch (PropertyNotFoundException ex) {
+ //no id, ignore it
+ }
+
+ final List<SimpleQuery.Column> columns = new ArrayList<>();
+ for (String propName : copy) {
+ columns.add(new
SimpleQuery.Column(filterFactory.property(propName), propName));
+ }
+ query.setColumns(columns.toArray(new
SimpleQuery.Column[columns.size()]));
+ }
+
+ //TODO optimize filter
+ //TODO add linear resolution
+
+ return query;
}
/**
@@ -376,8 +549,20 @@ public final class SEPortrayer {
*/
private static List<Rule> getValidRules(final FeatureTypeStyle fts, final
double scale, final FeatureType type) {
- final Id ids = fts.getFeatureInstanceIDs();
final Set<GenericName> names = fts.featureTypeNames();
+ if (!names.isEmpty()) {
+ //TODO : should we check parent types ?
+ boolean found = false;
+ for (GenericName name : names) {
+ if (name.equals(type.getName())) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return Collections.emptyList();
+ }
+ }
//check semantic, only if we have a feature type
if (type != null) {
@@ -497,7 +682,6 @@ public final class SEPortrayer {
throw e2;
}
}
-
return geometry;
}
@@ -527,4 +711,57 @@ public final class SEPortrayer {
}
}
+ /**
+ * Remove any xpath elements, keep only the root property name.
+ *
+ * @param propertyName
+ * @return
+ */
+ private static String stripXpath(String attName) {
+ int index = attName.indexOf('/');
+ if (index == 0) {
+ attName = attName.substring(1); //remove first slash
+ final Pattern pattern =
Pattern.compile("(\\{[^\\{\\}]*\\})|(\\[[^\\[\\]]*\\])|/{1}");
+ final Matcher matcher = pattern.matcher(attName);
+
+ final StringBuilder sb = new StringBuilder();
+ int position = 0;
+ while (matcher.find()) {
+ final String match = matcher.group();
+ sb.append(attName.substring(position, matcher.start()));
+ position = matcher.end();
+
+ if (match.charAt(0) == '/') {
+ //we don't query precisely sub elements
+ position = attName.length();
+ break;
+ } else if (match.charAt(0) == '{') {
+ sb.append(match);
+ } else if (match.charAt(0) == '[') {
+ //strip indexes or xpath searches
+ }
+ }
+ sb.append(attName.substring(position));
+ attName = sb.toString();
+ }
+ return attName;
+ }
+
+ /**
+ * Extract envelope and expand it's horizontal component by given margin.
+ */
+ private static Envelope optimizeBBox(GridGeometry canvas, double
symbolsMargin) throws TransformException {
+ Envelope env = canvas.getEnvelope();
+ //keep only horizontal component
+ env = Envelopes.transform(env,
CRS.getHorizontalComponent(env.getCoordinateReferenceSystem()));
+
+ //expand the search area by given margin
+ if (symbolsMargin > 0) {
+ final GeneralEnvelope e = new GeneralEnvelope(env);
+ e.setRange(0, e.getMinimum(0) - symbolsMargin, e.getMaximum(0) +
symbolsMargin);
+ e.setRange(1, e.getMinimum(1) - symbolsMargin, e.getMaximum(1) +
symbolsMargin);
+ env = e;
+ }
+ return env;
+ }
}
diff --git
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPresentation.java
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPresentation.java
index 08c3612..b00cbd6 100644
---
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPresentation.java
+++
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPresentation.java
@@ -16,6 +16,7 @@
*/
package org.apache.sis.internal.map;
+import java.util.Objects;
import org.apache.sis.portrayal.MapLayer;
import org.apache.sis.storage.Resource;
import org.opengis.feature.Feature;
@@ -33,7 +34,7 @@ import org.opengis.style.Symbolizer;
* @since 2.0
* @module
*/
-public class SEPresentation extends Presentation {
+public final class SEPresentation extends Presentation {
private Symbolizer symbolizer;
@@ -56,4 +57,29 @@ public class SEPresentation extends Presentation {
this.symbolizer = symbolizer;
}
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 71 * hash + Objects.hashCode(this.symbolizer);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final SEPresentation other = (SEPresentation) obj;
+ if (!Objects.equals(this.symbolizer, other.symbolizer)) {
+ return false;
+ }
+ return super.equals(obj);
+ }
+
}
diff --git
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SymbologyVisitor.java
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SymbologyVisitor.java
index 0d25141..587f91e 100644
---
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SymbologyVisitor.java
+++
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SymbologyVisitor.java
@@ -16,6 +16,8 @@
*/
package org.apache.sis.internal.map;
+import java.util.Collection;
+import java.util.List;
import org.opengis.filter.BinaryComparisonOperator;
import org.opengis.filter.BinaryLogicOperator;
import org.opengis.filter.ExcludeFilter;
@@ -88,19 +90,19 @@ public abstract class SymbologyVisitor {
public void visit(Style candidate) {
for (FeatureTypeStyle fts : candidate.featureTypeStyles()) {
- visit(fts);
+ if (fts != null) visit(fts);
}
}
public void visit(FeatureTypeStyle candidate) {
for (Rule rule : candidate.rules()) {
- visit(rule);
+ if (rule != null) visit(rule);
}
}
public void visit(Rule candidate) {
for (Symbolizer symbolizer : candidate.symbolizers()) {
- visit(symbolizer);
+ if (symbolizer != null) visit(symbolizer);
}
}
@@ -123,59 +125,79 @@ public abstract class SymbologyVisitor {
}
public void visit(PointSymbolizer candidate) {
- visit(candidate.getGeometry());
- visit(candidate.getGraphic());
+ visitNoNull(candidate.getGeometry());
+ final Graphic graphic = candidate.getGraphic();
+ if (graphic != null) visit(graphic);
}
public void visit(LineSymbolizer candidate) {
- visit(candidate.getGeometry());
- visit(candidate.getPerpendicularOffset());
- visit(candidate.getStroke());
+ visitNoNull(candidate.getGeometry());
+ visitNoNull(candidate.getPerpendicularOffset());
+ final Stroke stroke = candidate.getStroke();
+ if (stroke != null) visit(stroke);
}
public void visit(PolygonSymbolizer candidate) {
- visit(candidate.getDisplacement());
- visit(candidate.getFill());
- visit(candidate.getGeometry());
- visit(candidate.getPerpendicularOffset());
- visit(candidate.getStroke());
+ visitNoNull(candidate.getGeometry());
+ visitNoNull(candidate.getPerpendicularOffset());
+
+ final Displacement displacement = candidate.getDisplacement();
+ final Fill fill = candidate.getFill();
+ final Stroke stroke = candidate.getStroke();
+ if (displacement != null) visit(displacement);
+ if (fill != null) visit(fill);
+ if (stroke != null) visit(stroke);
}
public void visit(TextSymbolizer candidate) {
- visit(candidate.getFill());
- visit(candidate.getFont());
- visit(candidate.getGeometry());
- visit(candidate.getHalo());
- visit(candidate.getLabel());
- visit(candidate.getLabelPlacement());
+ visitNoNull(candidate.getGeometry());
+ visitNoNull(candidate.getLabel());
+ final Fill fill = candidate.getFill();
+ final Font font = candidate.getFont();
+ final Halo halo = candidate.getHalo();
+ final LabelPlacement labelPlacement = candidate.getLabelPlacement();
+ if (fill != null) visit(fill);
+ if (font != null) visit(font);
+ if (halo != null) visit(halo);
+ if (labelPlacement != null) visit(labelPlacement);
}
public void visit(RasterSymbolizer candidate) {
- visit(candidate.getChannelSelection());
- visit(candidate.getColorMap());
- visit(candidate.getContrastEnhancement());
- visit(candidate.getGeometry());
- visit(candidate.getImageOutline());
- visit(candidate.getOpacity());
- visit(candidate.getShadedRelief());
+ visitNoNull(candidate.getGeometry());
+ visitNoNull(candidate.getOpacity());
+ final ChannelSelection channelSelection =
candidate.getChannelSelection();
+ final ColorMap colorMap = candidate.getColorMap();
+ final ContrastEnhancement contrastEnhancement =
candidate.getContrastEnhancement();
+ final Symbolizer imageOutline = candidate.getImageOutline();
+ final ShadedRelief shadedRelief = candidate.getShadedRelief();
+ if (channelSelection != null) visit(channelSelection);
+ if (colorMap != null) visit(colorMap);
+ if (contrastEnhancement != null) visit(contrastEnhancement);
+ if (imageOutline != null) visit(imageOutline);
+ if (shadedRelief != null) visit(shadedRelief);
}
public void visit(ExtensionSymbolizer candidate) {
- visit(candidate.getGeometry());
+ visitNoNull(candidate.getGeometry());
for (Expression exp : candidate.getParameters().values()) {
- visit(exp);
+ visitNoNull(exp);
}
}
public void visit(Graphic candidate) {
- visit(candidate.getAnchorPoint());
- visit(candidate.getDisplacement());
- visit(candidate.getOpacity());
- visit(candidate.getRotation());
- visit(candidate.getSize());
-
- for (GraphicalSymbol gs : candidate.graphicalSymbols()) {
- visit(gs);
+ visitNoNull(candidate.getOpacity());
+ visitNoNull(candidate.getRotation());
+ visitNoNull(candidate.getSize());
+
+ final AnchorPoint anchorPoint = candidate.getAnchorPoint();
+ final Displacement displacement = candidate.getDisplacement();
+ final List<GraphicalSymbol> graphicalSymbols =
candidate.graphicalSymbols();
+ if (anchorPoint != null) visit(anchorPoint);
+ if (displacement != null) visit(displacement);
+ if (graphicalSymbols != null) {
+ for (GraphicalSymbol gs : graphicalSymbols) {
+ visit(gs);
+ }
}
}
@@ -190,15 +212,21 @@ public abstract class SymbologyVisitor {
}
public void visit(Mark candidate) {
- visit(candidate.getExternalMark());
- visit(candidate.getFill());
- visit(candidate.getStroke());
- visit(candidate.getWellKnownName());
+ final ExternalMark externalMark = candidate.getExternalMark();
+ final Fill fill = candidate.getFill();
+ final Stroke stroke = candidate.getStroke();
+ if (externalMark != null) visit(externalMark);
+ if (fill != null) visit(fill);
+ if (stroke != null) visit(stroke);
+ visitNoNull(candidate.getWellKnownName());
}
public void visit(ExternalGraphic candidate) {
- for (ColorReplacement cr : candidate.getColorReplacements()) {
- visit(cr);
+ final Collection<ColorReplacement> colorReplacements =
candidate.getColorReplacements();
+ if (colorReplacements != null) {
+ for (ColorReplacement cr : colorReplacements) {
+ visit(cr);
+ }
}
}
@@ -206,37 +234,40 @@ public abstract class SymbologyVisitor {
}
public void visit(Stroke candidate) {
- visit(candidate.getColor());
- visit(candidate.getDashOffset());
- visit(candidate.getGraphicFill());
- visit(candidate.getGraphicStroke());
- visit(candidate.getLineCap());
- visit(candidate.getLineJoin());
- visit(candidate.getOpacity());
- visit(candidate.getWidth());
+ final GraphicFill graphicFill = candidate.getGraphicFill();
+ final GraphicStroke graphicStroke = candidate.getGraphicStroke();
+ visitNoNull(candidate.getColor());
+ visitNoNull(candidate.getDashOffset());
+ if (graphicFill != null) visit(graphicFill);
+ if (graphicStroke != null) visit(graphicStroke);
+ visitNoNull(candidate.getLineCap());
+ visitNoNull(candidate.getLineJoin());
+ visitNoNull(candidate.getOpacity());
+ visitNoNull(candidate.getWidth());
}
public void visit(Description candidate) {
}
public void visit(Displacement candidate) {
- visit(candidate.getDisplacementX());
- visit(candidate.getDisplacementY());
+ visitNoNull(candidate.getDisplacementX());
+ visitNoNull(candidate.getDisplacementY());
}
public void visit(Fill candidate) {
- visit(candidate.getColor());
- visit(candidate.getGraphicFill());
- visit(candidate.getOpacity());
+ final GraphicFill graphicFill = candidate.getGraphicFill();
+ if (graphicFill != null) visit(graphicFill);
+ visitNoNull(candidate.getColor());
+ visitNoNull(candidate.getOpacity());
}
public void visit(Font candidate) {
for (Expression exp : candidate.getFamily()) {
- visit(exp);
+ visitNoNull(exp);
}
- visit(candidate.getSize());
- visit(candidate.getStyle());
- visit(candidate.getWeight());
+ visitNoNull(candidate.getSize());
+ visitNoNull(candidate.getStyle());
+ visitNoNull(candidate.getWeight());
}
public void visit(GraphicFill candidate) {
@@ -245,8 +276,8 @@ public abstract class SymbologyVisitor {
public void visit(GraphicStroke candidate) {
visit((Graphic) candidate);
- visit(candidate.getGap());
- visit(candidate.getInitialGap());
+ visitNoNull(candidate.getGap());
+ visitNoNull(candidate.getInitialGap());
}
public void visit(LabelPlacement candidate) {
@@ -260,20 +291,22 @@ public abstract class SymbologyVisitor {
}
public void visit(PointPlacement candidate) {
- visit(candidate.getAnchorPoint());
- visit(candidate.getDisplacement());
- visit(candidate.getRotation());
+ final AnchorPoint anchorPoint = candidate.getAnchorPoint();
+ final Displacement displacement = candidate.getDisplacement();
+ if (anchorPoint != null) visit(anchorPoint);
+ if (displacement != null) visit(displacement);
+ visitNoNull(candidate.getRotation());
}
public void visit(AnchorPoint candidate) {
- visit(candidate.getAnchorPointX());
- visit(candidate.getAnchorPointY());
+ visitNoNull(candidate.getAnchorPointX());
+ visitNoNull(candidate.getAnchorPointY());
}
public void visit(LinePlacement candidate) {
- visit(candidate.getGap());
- visit(candidate.getInitialGap());
- visit(candidate.getPerpendicularOffset());
+ visitNoNull(candidate.getGap());
+ visitNoNull(candidate.getInitialGap());
+ visitNoNull(candidate.getPerpendicularOffset());
}
public void visit(GraphicLegend candidate) {
@@ -281,35 +314,40 @@ public abstract class SymbologyVisitor {
}
public void visit(Halo candidate) {
- visit(candidate.getFill());
- visit(candidate.getRadius());
+ final Fill fill = candidate.getFill();
+ if (fill != null) visit(fill);
+ visitNoNull(candidate.getRadius());
}
public void visit(ColorMap candidate) {
- visit(candidate.getFunction());
+ visitNoNull(candidate.getFunction());
}
public void visit(ColorReplacement candidate) {
- visit(candidate.getRecoding());
+ visitNoNull(candidate.getRecoding());
}
public void visit(ContrastEnhancement candidate) {
- visit(candidate.getGammaValue());
+ visitNoNull(candidate.getGammaValue());
}
public void visit(ChannelSelection candidate) {
- visit(candidate.getGrayChannel());
- for (SelectedChannelType sct : candidate.getRGBChannels()) {
- visit(sct);
+ final SelectedChannelType grayChannel = candidate.getGrayChannel();
+ final SelectedChannelType[] rgbChannels = candidate.getRGBChannels();
+ if (grayChannel != null) visit(grayChannel);
+ if (rgbChannels != null) {
+ for (SelectedChannelType sct : rgbChannels) {
+ visit(sct);
+ }
}
}
public void visit(SelectedChannelType candidate) {
- visit(candidate.getContrastEnhancement());
+ if (candidate.getContrastEnhancement() != null)
visit(candidate.getContrastEnhancement());
}
public void visit(ShadedRelief candidate) {
- visit(candidate.getReliefFactor());
+ visitNoNull(candidate.getReliefFactor());
}
public void visit(Filter candidate) {
@@ -342,52 +380,56 @@ public abstract class SymbologyVisitor {
}
}
+ protected final void visitNoNull(Filter candidate) {
+ if (candidate != null) visit(candidate);
+ }
+
public void visit(BinaryLogicOperator candidate) {
for (Filter f : candidate.getChildren()) {
- visit(f);
+ visitNoNull(f);
}
}
public void visit(Not candidate) {
- visit(candidate.getFilter());
+ visitNoNull(candidate.getFilter());
}
public void visit(PropertyIsBetween candidate) {
- visit(candidate.getExpression());
- visit(candidate.getLowerBoundary());
- visit(candidate.getUpperBoundary());
+ visitNoNull(candidate.getExpression());
+ visitNoNull(candidate.getLowerBoundary());
+ visitNoNull(candidate.getUpperBoundary());
}
public void visit(BinaryComparisonOperator candidate) {
- visit(candidate.getExpression1());
- visit(candidate.getExpression2());
+ visitNoNull(candidate.getExpression1());
+ visitNoNull(candidate.getExpression2());
}
public void visit(BinarySpatialOperator candidate) {
- visit(candidate.getExpression1());
- visit(candidate.getExpression2());
+ visitNoNull(candidate.getExpression1());
+ visitNoNull(candidate.getExpression2());
}
public void visit(DistanceBufferOperator candidate) {
- visit(candidate.getExpression1());
- visit(candidate.getExpression2());
+ visitNoNull(candidate.getExpression1());
+ visitNoNull(candidate.getExpression2());
}
public void visit(BinaryTemporalOperator candidate) {
- visit(candidate.getExpression1());
- visit(candidate.getExpression2());
+ visitNoNull(candidate.getExpression1());
+ visitNoNull(candidate.getExpression2());
}
public void visit(PropertyIsLike candidate) {
- visit(candidate.getExpression());
+ visitNoNull(candidate.getExpression());
}
public void visit(PropertyIsNull candidate) {
- visit(candidate.getExpression());
+ visitNoNull(candidate.getExpression());
}
public void visit(PropertyIsNil candidate) {
- visit(candidate.getExpression());
+ visitNoNull(candidate.getExpression());
}
public void visit(ExcludeFilter candidate) {
@@ -415,18 +457,22 @@ public abstract class SymbologyVisitor {
}
}
+ protected final void visitNoNull(Expression candidate) {
+ if (candidate != null) visit(candidate);
+ }
+
public void visit(PropertyName candidate) {
}
public void visit(Function candidate) {
for (Expression ex : candidate.getParameters()) {
- visit(ex);
+ visitNoNull(ex);
}
}
public void visit(BinaryExpression candidate) {
- visit(candidate.getExpression1());
- visit(candidate.getExpression2());
+ visitNoNull(candidate.getExpression1());
+ visitNoNull(candidate.getExpression2());
}
public void visit(NilExpression candidate) {
diff --git
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPresentation.java
b/core/sis-portrayal/src/test/java/org/apache/sis/test/suite/PortrayalTestSuite.java
similarity index 51%
copy from
core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPresentation.java
copy to
core/sis-portrayal/src/test/java/org/apache/sis/test/suite/PortrayalTestSuite.java
index 08c3612..0538531 100644
---
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/SEPresentation.java
+++
b/core/sis-portrayal/src/test/java/org/apache/sis/test/suite/PortrayalTestSuite.java
@@ -14,46 +14,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.internal.map;
+package org.apache.sis.test.suite;
+
+import org.apache.sis.test.TestSuite;
+import org.junit.BeforeClass;
+import org.junit.runners.Suite;
-import org.apache.sis.portrayal.MapLayer;
-import org.apache.sis.storage.Resource;
-import org.opengis.feature.Feature;
-import org.opengis.style.Symbolizer;
/**
- * A presentation build with a standard Symbology Encoding Symbolizer.
- *
- * <p>
- * NOTE: this class is a first draft subject to modifications.
- * </p>
+ * All tests from the {@code sis-portrayal} module, in rough dependency order.
*
* @author Johann Sorel (Geomatys)
* @version 2.0
* @since 2.0
* @module
*/
-public class SEPresentation extends Presentation {
-
- private Symbolizer symbolizer;
-
- public SEPresentation() {
- }
-
- public SEPresentation(MapLayer layer, Resource resource, Feature
candidate, Symbolizer symbolizer) {
- super(layer, resource, candidate);
- this.symbolizer = symbolizer;
- }
-
[email protected]({
+ org.apache.sis.internal.map.SEPortrayerTest.class,
+})
+public final strictfp class PortrayalTestSuite extends TestSuite {
/**
- * @return Symbogy Encoding symbolizer
+ * Verifies the list of tests before to run the suite.
+ * See {@link #verifyTestList(Class, Class[])} for more information.
*/
- public Symbolizer getSymbolizer() {
- return symbolizer;
+ @BeforeClass
+ public static void verifyTestList() {
+ assertNoMissingTest(PortrayalTestSuite.class);
+ verifyTestList(PortrayalTestSuite.class);
}
-
- public void setSymbolizer(Symbolizer symbolizer) {
- this.symbolizer = symbolizer;
- }
-
}