this.verticalSpacing = legendStyle.verticalSpacing;
this.indentSize = legendStyle.indentSize;
this.imageHeight = legendStyle.imageHeight;
this.imageWidth = legendStyle.imageWidth;
final ViewportGraphics graphics = context.getGraphics();
if (fontStyle.getFont() != null) {
graphics.setFont(fontStyle.getFont());
}
List<Map<ILayer, LegendEntry[]>> layers = new ArrayList<Map<ILayer, LegendEntry[]>>();
int longestRow = 0; // used to calculate the width of the graphic
final int[] numberOfEntries = new int[1]; // total number of entries to
// draw
numberOfEntries[0] = 0;
/*
* Set up the layers that we want to draw so we can operate just on
* those ones. Layers at index 0 are on the bottom of the map, so we
* must iterate in reverse.
*
* While we are doing this, determine the longest row so we can properly
* draw the graphic's border.
*/
Dimension imageSize = new Dimension(imageWidth,imageHeight);
Dimension textSize = new Dimension(0, graphics.getFontHeight());
for (int i = context.getMapLayers().size() - 1; i >= 0; i--) {
ILayer layer = context.getMapLayers().get(i);
if (!(layer.getGeoResource() instanceof MapGraphicResource)
&& layer.isVisible()) {
if (layer.hasResource(MapGraphic.class)) {
// don't include mapgraphics
continue;
}
String layerName = layer.getName();
if (layerName == null) {
layerName = null;
}
LegendEntry layerEntry = new LegendEntry(layerName);
FeatureTypeStyle[] styles = locateStyle(layer);
LegendEntry[] entries = null;
if (styles == null) {
// we should have a label but no style
entries = new LegendEntry[] { layerEntry };
} else {
List<Rule> rules = rules(styles);
int ruleCount = rules.size();
if (ruleCount == 1
&& layer.getGeoResource().canResolve(
GridCoverage.class)) {
// grid coverage with single rule; lets see if it is a
// theming style
List<LegendEntry> cmEntries = ColorMapLegendCreator
.findEntries(styles, imageSize, textSize);
if (cmEntries != null) {
cmEntries.add(0, layerEntry); // add layer legend
// entry
entries = cmEntries
.toArray(new LegendEntry[cmEntries.size()]);
}
}
if (entries == null) {
List<LegendEntry> localEntries = new ArrayList<LegendEntry>();
if (ruleCount == 1) {
// only one rule so apply this to the layer legend
// entry
layerEntry.setRule(rules.get(0));
}
localEntries.add(layerEntry); // add layer legend entry
if (ruleCount > 1) {
// we have more than one rule so there is likely
// some
// themeing going on; add each of these rules
for (Rule rule : rules) {
LegendEntry rentry = new LegendEntry(rule);
localEntries.add(rentry);
}
}
entries = localEntries
.toArray(new LegendEntry[localEntries.size()]);
}
}
layers.add(Collections.singletonMap(layer, entries));
// compute maximum length for each entry
for (int j = 0; j < entries.length; j++) {
StringBuilder sb = new StringBuilder();
for (int k = 0; k < entries[j].getText().length; k++){
sb.append(entries[j].getText()[k]);
}
Rectangle2D bounds = graphics.getStringBounds(sb.toString());
int length = indentSize + imageWidth + horizontalSpacing
+ (int) bounds.getWidth();
if (length > longestRow) {
longestRow = length;
}
numberOfEntries[0]++;
}
}
}
if (numberOfEntries[0] == 0) {
// nothing to draw!
return;
}
final int rowHeight = Math.max(imageHeight, graphics.getFontHeight()); // space
// allocated
// to
// each
// layer
if (locationStyle.width == 0 || locationStyle.height == 0) {
// we want to change the location style as needed
// but not change the saved one so we create a copy here
locationStyle = new Rectangle(locationStyle);
if (locationStyle.width == 0) {
// we want to grow to whatever size we need
int width = longestRow + horizontalMargin * 2;
locationStyle.width = width;
}
if (locationStyle.height == 0) {
// we want to grow to whatever size we need
int height = rowHeight * numberOfEntries[0] + verticalMargin * 2;
for (int i = 0; i < layers.size(); i++) {
Map<ILayer, LegendEntry[]> map = layers.get(i);
final LegendEntry[] entries = map.values().iterator().next();
for (int j = 0; j < entries.length; j ++){
if (entries[j].getSpacingAfter() == null){
height += verticalSpacing;
}else{
height += entries[j].getSpacingAfter();
}
}
}
locationStyle.height = height- verticalSpacing;
}
}
// ensure box within the display
Dimension displaySize = context.getMapDisplay().getDisplaySize();
if (locationStyle.x < 0) {
locationStyle.x = displaySize.width - locationStyle.width
+ locationStyle.x;
}
if ((locationStyle.x + locationStyle.width + 6) > displaySize.width) {
locationStyle.x = displaySize.width - locationStyle.width - 5;
}
if (locationStyle.y < 0) {
locationStyle.y = displaySize.height - locationStyle.height - 5
+ locationStyle.y;
}
if ((locationStyle.y + locationStyle.height + 6) > displaySize.height) {
locationStyle.y = displaySize.height - locationStyle.height - 5;
}
graphics.setClip(new Rectangle(locationStyle.x, locationStyle.y,
locationStyle.width + 1, locationStyle.height + 1));
/*
* Draw the box containing the layers/icons
*/
drawOutline(graphics, context, locationStyle);
/*
* Draw the layer names/icons
*/
final int[] rowsDrawn = new int[1];
rowsDrawn[0] = 0;
final int[] x = new int[1];
x[0] = locationStyle.x + horizontalMargin;
final int[] y = new int[1];
y[0] = locationStyle.y + verticalMargin;
if (fontStyle.getFont() != null) {
graphics.setFont(fontStyle.getFont());
}
for (int i = 0; i < layers.size(); i++) {
Map<ILayer, LegendEntry[]> map = layers.get(i);
final ILayer layer = map.keySet().iterator().next();
final LegendEntry[] entries = map.values().iterator().next();
try {
layer.getGeoResources().get(0).getInfo(null);
} catch (Exception ex) {
}
PlatformGIS.syncInDisplayThread(new Runnable() {
public void run() {
for (int i = 0; i < entries.length; i++) {
BufferedImage awtIcon = null;
if (entries[i].getRule() != null) {
// generate icon from use
ImageDescriptor descriptor = LayerGeneratedGlyphDecorator
.generateStyledIcon(layer,
entries[i].getRule());
if (descriptor == null) {
descriptor = LayerGeneratedGlyphDecorator
.generateIcon((Layer) layer);
}
if (descriptor != null) {
awtIcon = AWTSWTImageUtils
.convertToAWT(descriptor.getImageData());
}
} else if (entries[i].getIcon() != null) {
// use set icon
awtIcon = AWTSWTImageUtils.convertToAWT(entries[i]
.getIcon().getImageData());
} else {
// no rule, no icon, try default for layer
ImageDescriptor descriptor = LayerGeneratedGlyphDecorator
.generateIcon((Layer) layer);
if (descriptor != null) {
awtIcon = AWTSWTImageUtils
.convertToAWT(descriptor.getImageData());
}
}
drawRow(graphics, x[0], y[0], awtIcon,
entries[i].getText(), i != 0, entries[i].getTextPosition());
y[0] += rowHeight;
if ((rowsDrawn[0] + 1) < numberOfEntries[0]) {
if (entries[i].getSpacingAfter() != null){
y[0] += entries[i].getSpacingAfter();
}else{
y[0] += verticalSpacing;
}
}
rowsDrawn[0]++;
}
}
});
}
// clear the clip so we don't affect other rendering processes
graphics.setClip(null);
}