Skip to content

Commit

Permalink
[GEOS-9092] Complete icon export for graphic strokes, fills and text …
Browse files Browse the repository at this point in the history
…shields
  • Loading branch information
aaime committed Jan 10, 2019
1 parent 6ad2b67 commit 524301a
Show file tree
Hide file tree
Showing 8 changed files with 316 additions and 33 deletions.
13 changes: 11 additions & 2 deletions src/wms/src/main/java/org/geoserver/wms/icons/IconProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,20 @@ public boolean isExternal() {

@Override
public String href(String baseURL, String workspace, String styleName) {
String stylePathFragment;
if (workspace != null) {
styleName = workspace + "/" + styleName;
stylePathFragment =
ResponseUtils.urlEncode(workspace)
+ "/"
+ ResponseUtils.urlEncode(styleName);
} else {
stylePathFragment = ResponseUtils.urlEncode(styleName);
}
return ResponseUtils.buildURL(
baseURL, "kml/icon/" + styleName, styleProperties, URLType.RESOURCE);
baseURL,
"kml/icon/" + stylePathFragment,
styleProperties,
URLType.RESOURCE);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@
import org.geotools.styling.ExternalGraphic;
import org.geotools.styling.Fill;
import org.geotools.styling.Graphic;
import org.geotools.styling.LineSymbolizer;
import org.geotools.styling.Mark;
import org.geotools.styling.PointSymbolizer;
import org.geotools.styling.PolygonSymbolizer;
import org.geotools.styling.Stroke;
import org.geotools.styling.Style;
import org.geotools.styling.Symbolizer;
import org.geotools.styling.TextSymbolizer2;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.filter.expression.Expression;
import org.opengis.style.GraphicalSymbol;
Expand All @@ -30,6 +34,7 @@
* @author David Winslow, OpenGeo
*/
public final class IconPropertyExtractor {
public static final String NON_POINT_GRAPHIC_KEY = "npg";
private List<List<MiniRule>> style;

private IconPropertyExtractor(List<List<MiniRule>> style) {
Expand All @@ -49,6 +54,37 @@ public static IconProperties extractProperties(Style style, SimpleFeature featur
return new IconPropertyExtractor(MiniRule.minify(style)).propertiesFor(feature);
}

/** Extracts a Graphic object from the given symbolizer */
public static Graphic getGraphic(Symbolizer symbolizer, boolean includeNonPointGraphics) {
// try point first
if (symbolizer instanceof PointSymbolizer) {
return ((PointSymbolizer) symbolizer).getGraphic();
}
if (!includeNonPointGraphics) {
return null;
}
// try in other symbolizers
if (symbolizer instanceof PolygonSymbolizer) {
final Fill fill = ((PolygonSymbolizer) symbolizer).getFill();
if (fill != null && fill.getGraphicFill() != null) {
return fill.getGraphicFill();
}
final Stroke stroke = ((PolygonSymbolizer) symbolizer).getStroke();
if (stroke != null) {
return stroke.getGraphicStroke();
}
} else if (symbolizer instanceof LineSymbolizer) {
final Stroke stroke = ((LineSymbolizer) symbolizer).getStroke();
if (stroke != null) {
return stroke.getGraphicStroke();
}
} else if (symbolizer instanceof TextSymbolizer2) {
return ((TextSymbolizer2) symbolizer).getGraphic();
}

return null;
}

private class FeatureProperties {
private static final String URL = ".url";
private static final String WIDTH = ".width";
Expand Down Expand Up @@ -126,7 +162,7 @@ public IconProperties isExternalGraphic(MiniRule rule) {
if (rule.symbolizers.size() != 1) {
return null;
}
Graphic g = rule.symbolizers.get(0).getGraphic();
Graphic g = getGraphic(rule.symbolizers.get(0), true);
if (g == null) {
return null;
}
Expand Down Expand Up @@ -154,9 +190,10 @@ public IconProperties isExternalGraphic(MiniRule rule) {
}

public IconProperties embeddedIconProperties() {
Map<String, String> props = new TreeMap<String, String>();
Map<String, String> props = new TreeMap<>();
Double size = null;
boolean allRotated = true;
boolean nonPointGraphic = false;
for (int i = 0; i < style.size(); i++) {
List<MiniRule> rules = style.get(i);
for (int j = 0; j < rules.size(); j++) {
Expand All @@ -171,15 +208,18 @@ public IconProperties embeddedIconProperties() {
if (matches) {
for (int k = 0; k < rule.symbolizers.size(); k++) {
props.put(i + "." + j + "." + k, "");
PointSymbolizer sym = rule.symbolizers.get(k);
if (sym.getGraphic() != null) {
addGraphicProperties(
i + "." + j + "." + k, sym.getGraphic(), props);
final Double gRotation = graphicRotation(sym.getGraphic());
Symbolizer sym = rule.symbolizers.get(k);
Graphic graphic = getGraphic(sym, false);
if (graphic == null) {
graphic = getGraphic(sym, true);
nonPointGraphic |= graphic != null;
}
if (graphic != null) {
addGraphicProperties(i + "." + j + "." + k, graphic, props);
final Double gRotation = graphicRotation(graphic);
allRotated &= gRotation != null;

final Double gSize =
Icons.graphicSize(sym.getGraphic(), gRotation, feature);
final Double gSize = Icons.graphicSize(graphic, gRotation, feature);
if (size == null || (gSize != null && gSize > size)) {
size = gSize;
}
Expand All @@ -188,6 +228,11 @@ public IconProperties embeddedIconProperties() {
}
}
}

if (nonPointGraphic) {
props.put(NON_POINT_GRAPHIC_KEY, "true");
}

if (size != null) size = size / 16d;
// If all the symbols in the stack were rotated, force it to be oriented to a bearing.
final Double rotation = allRotated ? 0d : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.geotools.styling.Style;
import org.geotools.styling.StyleFactory;
import org.geotools.styling.Symbol;
import org.geotools.styling.Symbolizer;
import org.opengis.filter.FilterFactory;
import org.opengis.filter.expression.Expression;
import org.opengis.style.GraphicalSymbol;
Expand Down Expand Up @@ -51,12 +52,12 @@ private List<List<MiniRule>> injectProperties(List<List<MiniRule>> ftStyles) {
List<MiniRule> resultRules = new ArrayList<MiniRule>();
for (int ruleIdx = 0; ruleIdx < origRules.size(); ruleIdx++) {
MiniRule origRule = origRules.get(ruleIdx);
List<PointSymbolizer> resultSymbolizers = new ArrayList<PointSymbolizer>();
List<Symbolizer> resultSymbolizers = new ArrayList<>();
for (int symbIdx = 0; symbIdx < origRule.symbolizers.size(); symbIdx++) {
String key = ftIdx + "." + ruleIdx + "." + symbIdx;
if (properties.containsKey(key)) {
PointSymbolizer ptSym = origRule.symbolizers.get(symbIdx);
resultSymbolizers.add(injectPointSymbolizer(key, ptSym));
Symbolizer sym = origRule.symbolizers.get(symbIdx);
resultSymbolizers.add(injectPointSymbolizer(key, sym));
}
}
resultRules.add(new MiniRule(null, false, resultSymbolizers));
Expand All @@ -78,10 +79,11 @@ private Expression getLiteral(String key) {
return filterFactory.literal(properties.get(key));
}

private PointSymbolizer injectPointSymbolizer(String key, PointSymbolizer original) {
private PointSymbolizer injectPointSymbolizer(String key, Symbolizer original) {
PointSymbolizer copy = styleFactory.createPointSymbolizer();
if (original.getGraphic() != null) {
copy.setGraphic(injectGraphic(key, original.getGraphic()));
Graphic graphic = IconPropertyExtractor.getGraphic(original, true);
if (graphic != null) {
copy.setGraphic(injectGraphic(key, graphic));
}
return copy;
}
Expand Down Expand Up @@ -281,7 +283,11 @@ private Fill injectFill(String key, Fill fill) {
}

public static Style injectProperties(Style style, Map<String, String> properties) {
List<List<MiniRule>> ftStyles = MiniRule.minify(style);
boolean includeNonPointGraphics =
Boolean.valueOf(
properties.getOrDefault(
IconPropertyExtractor.NON_POINT_GRAPHIC_KEY, "false"));
List<List<MiniRule>> ftStyles = MiniRule.minify(style, includeNonPointGraphics);
StyleFactory factory = CommonFactoryFinder.getStyleFactory();
return MiniRule.makeStyle(
factory, new IconPropertyInjector(properties).injectProperties(ftStyles));
Expand Down
26 changes: 16 additions & 10 deletions src/wms/src/main/java/org/geoserver/wms/icons/MiniRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.util.ArrayList;
import java.util.List;
import org.geotools.styling.FeatureTypeStyle;
import org.geotools.styling.PointSymbolizer;
import org.geotools.styling.Graphic;
import org.geotools.styling.Rule;
import org.geotools.styling.Style;
import org.geotools.styling.StyleFactory;
Expand All @@ -23,29 +23,35 @@
public class MiniRule {
public final Filter filter;
public final boolean isElseFilter;
public final List<PointSymbolizer> symbolizers;
public final List<Symbolizer> symbolizers;
private String name;

public MiniRule(Filter filter, boolean isElseFilter, List<PointSymbolizer> symbolizers) {
public MiniRule(Filter filter, boolean isElseFilter, List<Symbolizer> symbolizers) {
this.filter = filter;
this.isElseFilter = isElseFilter;
this.symbolizers = symbolizers;
}

public static List<List<MiniRule>> minify(Style style) {
List<List<MiniRule>> ftStyles = new ArrayList<List<MiniRule>>();
return minify(style, false);
}

public static List<List<MiniRule>> minify(Style style, boolean includeNonPointGraphics) {
List<List<MiniRule>> ftStyles = new ArrayList<>();
for (FeatureTypeStyle ftStyle : style.featureTypeStyles()) {
List<MiniRule> rules = new ArrayList<MiniRule>();
List<MiniRule> rules = new ArrayList<>();
for (Rule rule : ftStyle.rules()) {
List<PointSymbolizer> pointSymbolizers = new ArrayList<PointSymbolizer>();
List<Symbolizer> graphicSymbolizers = new ArrayList<>();
for (Symbolizer symbolizer : rule.symbolizers()) {
if (symbolizer instanceof PointSymbolizer) {
pointSymbolizers.add((PointSymbolizer) symbolizer);
Graphic graphic =
IconPropertyExtractor.getGraphic(symbolizer, includeNonPointGraphics);
if (graphic != null) {
graphicSymbolizers.add(symbolizer);
}
}
if (!pointSymbolizers.isEmpty()) {
if (!graphicSymbolizers.isEmpty()) {
MiniRule miniRule =
new MiniRule(rule.getFilter(), rule.isElseFilter(), pointSymbolizers);
new MiniRule(rule.getFilter(), rule.isElseFilter(), graphicSymbolizers);
miniRule.setName(rule.getName());
rules.add(miniRule);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ public class JSONLegendGraphicBuilder extends LegendGraphicBuilder {

public static final String STROKE_LINECAP = "stroke-linecap";

public static final String GRAPHIC = "graphic";

static Map<Class, String> symbolizerNames = new HashMap<>();

static {
Expand Down Expand Up @@ -272,7 +274,7 @@ public JSONObject buildLegendGraphic(GetLegendGraphicRequest request) {
}

// style and rule to use for the current layer
miniStyle = MiniRule.minify(gt2Style);
miniStyle = MiniRule.minify(gt2Style, true);

layerName = legend.getLayerName().getLocalPart();

Expand Down Expand Up @@ -884,7 +886,9 @@ private JSONObject processTextSymbolizer(JSONObject ret, TextSymbolizer symboliz
if (symbolizer instanceof TextSymbolizer2) {
// handle font graphic
TextSymbolizer2 tSymb = (TextSymbolizer2) symbolizer;
ret = processGraphic(ret, tSymb.getGraphic());
JSONObject graphic = new JSONObject();
graphic = processGraphic(graphic, tSymb.getGraphic());
ret.element(GRAPHIC, graphic);
}
JSONObject jPlacement = new JSONObject();
LabelPlacement placement = symbolizer.getLabelPlacement();
Expand Down

0 comments on commit 524301a

Please sign in to comment.