Commit ecb9d144 authored by Nico Mack's avatar Nico Mack

Refactored Legend Corona from TULIP-GIS package

parent 4da1fb4e
/*******************************************************************************
* Copyright Luxembourg Institute of Science and Technology, 2017. All rights reserved.
*
* This file is part of TULIP.
*
* TULIP is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, version 3 of the
* License.
*
* TULIP 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 Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
******************************************************************************/
package lu.list.itis.dkd.tui.widget.corona;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import lu.list.itis.dkd.tui.content.InformationReceiver;
import lu.list.itis.dkd.tui.utility.ImageUtilities;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.utility.PolarCoordinateHelper;
import lu.list.itis.dkd.tui.utility.ScreenCoordinates;
import lu.list.itis.dkd.tui.widget.corona.builder.BaseLegendBuilder;
//***************************************************************************
//* Class Definition and Members *
//***************************************************************************
public class Legend extends SelectableCorona implements InformationReceiver<Image> {
private Shape labelShape;
private String colourScale;
private Shape scaledLabel;
private BufferedImage image;
private Point imageCentre;
private Color fillColour;
private Color strokeColour;
private int strokeWidth;
private int insetBorder;
private Stroke borderStroke;
private double gap;
//***************************************************************************
//* Class Definition and Members *
//***************************************************************************
//---------------------------------------------------------------------------
//***************************************************************************
//* Constructor(s) *
//***************************************************************************
//---------------------------------------------------------------------------
public Legend(BaseLegendBuilder<?> builder) {
super(builder);
labelShape = builder.labelShape;
colourScale = builder.colourScale;
scaledLabel = builder.labelShape;
fillColour = builder.fillColour;
strokeColour = builder.strokeColour;
strokeWidth = builder.strokeWidth;
borderStroke = (builder.strokeWidth > 0) ? new BasicStroke(builder.strokeWidth) : null;
insetBorder = builder.insetBorder;
this.setOpacity(0);
gap = this.determineGap();
}
// ---------------------------------------------------------------------------
/**
* Copy constructor to clone corona.
*
* @param original
* specifies the original corona to create an exact copy from.
*/
// ---------------------------------------------------------------------------
public Legend(Legend original) {
super(original);
labelShape = original.labelShape;
colourScale = original.colourScale;
scaledLabel = original.labelShape;
fillColour = original.fillColour;
strokeColour = original.strokeColour;
borderStroke = (original.strokeWidth > 0) ? new BasicStroke(original.strokeWidth) : null;
image = (original.image != null) ? ImageUtilities.deepCopy(original.image) : null;
this.setOpacity(0);
gap = this.determineGap();
}
//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives *
//***************************************************************************
//---------------------------------------------------------------------------
private double determineGap () {
if ((labelShape == null) || (this.initialTranslation == null))
return 0;
Rectangle2D bounds = labelShape.getBounds2D();
double diagonal = PolarCoordinateHelper.euclideanDistance (bounds.getWidth(), bounds.getHeight());
Point zero = new Point (0f,0f,0f,this.initialTranslation.getState().getClass());
Point position = PolarCoordinateHelper.carthesianToPolar(zero, this.initialTranslation);
double gap = Math.abs(position.getX() - (diagonal / 2));
return gap;
}
//---------------------------------------------------------------------------
//***************************************************************************
//* Class Body *
//***************************************************************************
// ---------------------------------------------------------------------------
public String getColourScale () {
return this.colourScale;
}
// ---------------------------------------------------------------------------
public void setOpacity(float newOpacity) {
this.opacity = newOpacity;
}
// ---------------------------------------------------------------------------
public void paint (Graphics2D canvas) {
if (!isSelected || !active)
return;
Graphics2D localCanvas = (Graphics2D) canvas.create();
if (this.opacity < 1.0f)
localCanvas.setComposite(AlphaComposite.SrcOver.derive(this.opacity));
Point drawingPoint = this.getDrawingPoint(null);
AffineTransform rotation = this.getTransform(null);
rotation.transform(new Point(), drawingPoint);
if (scaledLabel != null) {
Shape transformedLabel = rotation.createTransformedShape(scaledLabel);
if (fillColour != null) {
localCanvas.setPaint(fillColour);
localCanvas.fill(transformedLabel);
}
if (strokeColour != null) {
localCanvas.setPaint(strokeColour);
if (borderStroke != null)
localCanvas.setStroke(borderStroke);
localCanvas.draw(transformedLabel);
}
}
if ((image != null) && (imageCentre != null)) {
localCanvas.drawImage(image, (int) (drawingPoint.x - imageCentre.getX()), (int) (drawingPoint.y - imageCentre.getY()), null);
}
localCanvas.dispose();
}
// ---------------------------------------------------------------------------
@Override
public void setInformation(Image information) {
if (information instanceof BufferedImage) {
this.image = (BufferedImage)information;
if (labelShape != null) {
Rectangle2D bounds = labelShape.getBounds2D();
imageCentre = new Point ((float)image.getWidth() / 2, (float)image.getHeight() / 2, 0f, ScreenCoordinates.class);
Point zero = new Point (0f,0f,0f,this.initialTranslation.getState().getClass());
Point polar = PolarCoordinateHelper.carthesianToPolar(zero, this.initialTranslation);
polar.setAngle(polar.getAngle() + this.initialTranslation.getAngle());
int inset = 2 * insetBorder;
double diagonal = PolarCoordinateHelper.euclideanDistance (image.getWidth() + inset, image.getHeight() + inset);
polar.x = polar.y = (float)(this.gap + (diagonal / 2));
this.initialTranslation = PolarCoordinateHelper.polarToCarthesian(zero, polar);
double horizontalScale = (this.image.getWidth() + inset) / bounds.getWidth();
double verticalScale = (this.image.getHeight() + inset) / bounds.getHeight();
AffineTransform scaler = AffineTransform.getTranslateInstance(0 - bounds.getX(), 0 - bounds.getY());
Shape scaled = scaler.createTransformedShape(labelShape);
scaler = AffineTransform.getScaleInstance(horizontalScale,verticalScale);
scaled = scaler.createTransformedShape(scaled);
bounds = scaled.getBounds2D();
scaler = AffineTransform.getTranslateInstance(-(bounds.getWidth() / 2), -(bounds.getHeight() / 2));
this.scaledLabel = scaler.createTransformedShape(scaled);
}
}
}
// ---------------------------------------------------------------------------
public Legend clone () {
return new Legend(this);
}
}
/*******************************************************************************
* Copyright Luxembourg Institute of Science and Technology, 2017. All rights reserved.
*
* This file is part of TULIP.
*
* TULIP is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, version 3 of the
* License.
*
* TULIP 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 Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
******************************************************************************/
package lu.list.itis.dkd.tui.widget.corona.builder;
import java.awt.Color;
import java.awt.Shape;
import org.jdom2.Element;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapCallback;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapContext;
import lu.list.itis.dkd.tui.bootstrapping.BootstrappingUtils;
import lu.list.itis.dkd.tui.bootstrapping.ShapeBootstrapper;
import lu.list.itis.dkd.tui.exception.BuildException;
import lu.list.itis.dkd.tui.utility.CpsNamespace;
import lu.list.itis.dkd.tui.utility.Externalization;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.widget.corona.Legend;
//***************************************************************************
//* Class Definition and Members *
//***************************************************************************
public class BaseLegendBuilder<B extends BaseLegendBuilder<B>> extends BaseSelectableCoronaBuilder<B> {
public int index;
public Shape labelShape;
public String colourScale;
public Color fillColour;
public Color strokeColour;
public int strokeWidth;
public int insetBorder;
// ***************************************************************************
// * Constants *
// ***************************************************************************
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
protected BaseLegendBuilder(Point point) {
super(point);
}
protected BaseLegendBuilder(Element rootElement)
throws BuildException {
super(rootElement, null, null);
}
public BaseLegendBuilder(Element rootElement, BootstrapContext context, BootstrapCallback callback)
throws BuildException {
super(rootElement, context, callback);
this.buildFromBootstrap(rootElement, context, callback);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitives *
// ***************************************************************************
// ---------------------------------------------------------------------------
private void buildFromBootstrap(@Nullable Element rootElement, BootstrapContext context, BootstrapCallback callback) throws BuildException {
index = BootstrappingUtils.getContentAsInteger(rootElement, Externalization.INDEX_NODE, BootstrappingUtils.MANDATORY, null, context);
colourScale = BootstrappingUtils.getContentAsString (rootElement, CpsNamespace.COLOUR_SCALE_NODE, BootstrappingUtils.OPTIONAL, null, context);
labelShape = ShapeBootstrapper.getShape(rootElement.getChild(Externalization.LABEL_SHAPE_NODE), context, callback);
fillColour = BootstrappingUtils.getContentAsColour (rootElement, Externalization.FILL_COLOUR_ELEMENT, BootstrappingUtils.OPTIONAL, null, context);
strokeColour = BootstrappingUtils.getContentAsColour (rootElement, Externalization.STROKE_COLOUR_ELEMENT, BootstrappingUtils.OPTIONAL, null, context);
strokeWidth = BootstrappingUtils.getContentAsInteger(rootElement, Externalization.STROKE_WIDTH_NODE, BootstrappingUtils.OPTIONAL, 1, context);
insetBorder = BootstrappingUtils.getContentAsInteger(rootElement, Externalization.INSET_BORDER_NODE, BootstrappingUtils.OPTIONAL, 0, context);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
@Override
public Legend build() throws BuildException {
return new Legend(this);
}
}
/**
* Copyright Luxembourg Institute of Science and Technology, 2019. All rights reserved. If you wish
* to use this code for any purpose, please contact the author(s).
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lu.list.itis.dkd.tui.widget.corona.builder;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapCallback;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapContext;
import lu.list.itis.dkd.tui.exception.BuildException;
import lu.list.itis.dkd.tui.widget.corona.Legend;
import org.jdom2.Element;
/**
* @author Nico Mack [nico.mack@list.lu]
* @since 1.6
* @version 1.0.0
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class LegendBuilder<B extends LegendBuilder<B>> extends BaseLegendBuilder<B> {
// ***************************************************************************
// * Constants *
// ***************************************************************************
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
* @param rootElement
* @throws BuildException
*/
// ---------------------------------------------------------------------------
public LegendBuilder(Element rootElement) throws BuildException {
super(rootElement);
}
// ---------------------------------------------------------------------------
public LegendBuilder(Element rootElement, BootstrapContext context, BootstrapCallback callback) throws BuildException {
super(rootElement, context, callback);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public Legend build() {
return new Legend(this);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment