Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.mapfish.print.scalebar.ScalebarDrawer Maven / Gradle / Ivy
/*
* Copyright (C) 2013 Camptocamp
*
* This file is part of MapFish Print
*
* MapFish Print is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MapFish Print is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MapFish Print. If not, see .
*/
package org.mapfish.print.scalebar;
import com.itextpdf.awt.geom.AffineTransform;
import java.util.List;
import org.mapfish.print.ChunkDrawer;
import org.mapfish.print.PDFCustomBlocks;
import org.mapfish.print.config.layout.ScalebarBlock;
import com.itextpdf.text.Font;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
/**
* Base class for drawing a scale bar.
*/
public abstract class ScalebarDrawer extends ChunkDrawer {
protected final ScalebarBlock block;
protected final List labels;
protected final int barSize;
private final int labelDistance;
protected final int subIntervals;
protected final float intervalWidth;
private final Font pdfFont;
private final float leftLabelMargin;
private final float rightLabelMargin;
private final float maxLabelWidth;
private final float maxLabelHeight;
public ScalebarDrawer(PDFCustomBlocks customBlocks, ScalebarBlock block, List labels, int barSize,
int labelDistance, int subIntervals, float intervalWidth, Font pdfFont,
float leftLabelMargin, float rightLabelMargin, float maxLabelWidth, float maxLabelHeight
) {
super(customBlocks);
this.block = block;
this.labels = labels;
this.barSize = barSize;
this.labelDistance = labelDistance;
this.subIntervals = subIntervals;
this.intervalWidth = intervalWidth;
this.pdfFont = pdfFont;
this.leftLabelMargin = leftLabelMargin;
this.rightLabelMargin = rightLabelMargin;
this.maxLabelWidth = maxLabelWidth;
this.maxLabelHeight = maxLabelHeight;
}
public static ScalebarDrawer create(PDFCustomBlocks customBlocks, ScalebarBlock block, Type type, List labels,
int barSize, int labelDistance,
int subIntervals, float intervalWidth, Font pdfFont, float leftLabelMargin,
float rightLabelMargin, float maxLabelWidth, float maxLabelHeight) {
switch (type) {
case BAR:
return new BarScalebarDrawer(customBlocks, block, labels, barSize, labelDistance, subIntervals, intervalWidth, pdfFont, leftLabelMargin, rightLabelMargin, maxLabelWidth, maxLabelHeight);
case BAR_SUB:
return new BarSubScalebarDrawer(customBlocks, block, labels, barSize, labelDistance, subIntervals, intervalWidth, pdfFont, leftLabelMargin, rightLabelMargin, maxLabelWidth, maxLabelHeight);
case LINE:
return new LineScalebarDrawer(customBlocks, block, labels, barSize, labelDistance, subIntervals, intervalWidth, pdfFont, leftLabelMargin, rightLabelMargin, maxLabelWidth, maxLabelHeight);
default:
throw new RuntimeException("Unknown type: " + type);
}
}
public void renderImpl(Rectangle rectangle, PdfContentByte dc) {
dc.saveState();
try {
//sets the transformation for drawing the labels and do it
final AffineTransform rotate = getRotationTransform(block.getBarDirection());
final AffineTransform labelTransform = AffineTransform.getTranslateInstance(
rectangle.getLeft(),
rectangle.getBottom());
labelTransform.concatenate(rotate);
labelTransform.translate(leftLabelMargin, maxLabelHeight);
dc.transform(labelTransform);
dc.setColorStroke(block.getColorVal());
dc.setFontAndSize(pdfFont.getCalculatedBaseFont(false), pdfFont.getSize());
drawLabels(dc);
dc.restoreState();
dc.saveState();
//sets the transformation for drawing the bar and do it
final AffineTransform lineTransform = AffineTransform.getTranslateInstance(
rectangle.getLeft(),
rectangle.getBottom());
lineTransform.concatenate(rotate);
lineTransform.translate(leftLabelMargin, labelDistance + maxLabelHeight);
dc.transform(lineTransform);
dc.setLineWidth((float) block.getLineWidth());
dc.setColorStroke(block.getColorVal());
drawBar(dc);
} finally {
dc.restoreState();
}
}
private AffineTransform getRotationTransform(Direction direction) {
AffineTransform rotate;
switch (direction) {
case UP:
rotate = new AffineTransform(1, 0, 0, 1, 0, 0);
break;
case DOWN:
rotate = new AffineTransform(-1, 0, 0, -1, getTotalWidth(), getTotalHeight());
break;
case LEFT:
rotate = new AffineTransform(0, 1, -1, 0, getTotalHeight(), 0);
break;
case RIGHT:
rotate = new AffineTransform(0, -1, 1, 0, 0, getTotalWidth());
break;
default:
throw new RuntimeException("Unknown orientation: " + direction);
}
return rotate;
}
private float getTotalWidth() {
return intervalWidth * block.getIntervals() + leftLabelMargin + rightLabelMargin;
}
private float getTotalHeight() {
return barSize + labelDistance + maxLabelHeight;
}
/**
* Draws the labels. The transformation is setup in a manner where the
* position of the labels is at (label.paperOffset,0).
*/
private void drawLabels(PdfContentByte dc) {
float prevPos = getTotalWidth();
for (int i = labels.size() - 1; i >= 0; --i) {
Label label = labels.get(i);
final float offsetH;
final float offsetV;
if (block.getTextDirection().getAngle() == block.getBarDirection().getAngle()) {
//same direction
offsetH = -label.width / 2;
offsetV = -maxLabelHeight;
} else if (block.getTextDirection().getAngle() == -block.getBarDirection().getAngle()) {
//opposite direction
offsetH = label.width / 2;
offsetV = 0;
} else if (block.getTextDirection().getAngle() - block.getBarDirection().getAngle() < 0) {
offsetH = label.width / 2;
offsetV = -label.height;
} else {
offsetH = -label.width / 2;
offsetV = 0;
}
if (label.paperOffset + Math.abs(offsetH) <= prevPos - 1) {
dc.beginText();
dc.showTextAligned(PdfContentByte.ALIGN_LEFT, label.label,
label.paperOffset + offsetH, offsetV, (float) (block.getBarDirection().getAngle() - block.getTextDirection().getAngle()));
dc.endText();
prevPos = label.paperOffset - Math.abs(offsetH);
} else {
//the label would be written over the previous one => ignore it
label.label = null;
}
}
}
/**
* Draws the bar itself. The transformation is setup in a manner where the
* bar starts at (0,0) and ends at (intervals*intervalWidth, lineWidth)
*/
protected abstract void drawBar(PdfContentByte dc);
}