/*
* Geotoolkit - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2015, Geomatys
*
* This library 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 2.1 of the License.
*
* This library 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.
*/
package org.geotoolkit.gui.javafx.render2d;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.NumberFormat;
import java.util.logging.Level;
import javafx.beans.property.SimpleObjectProperty;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Node;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javax.measure.Unit;
import org.apache.sis.measure.Units;
import org.geotoolkit.display.PortrayalException;
import org.geotoolkit.display2d.canvas.J2DCanvas;
import org.geotoolkit.display2d.ext.scalebar.DefaultScaleBarTemplate;
import org.geotoolkit.display2d.ext.scalebar.J2DScaleBarUtilities;
import org.geotoolkit.display2d.ext.scalebar.ScaleBarTemplate;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;
import org.apache.sis.util.logging.Logging;
/**
* Decoration displaying a scale bar
*
* @author Johann Sorel (Geomatys)
*/
public class FXScaleBarDecoration extends BorderPane implements FXMapDecoration {
private final SimpleObjectProperty<FXMap> map2D = new SimpleObjectProperty<>();
private final ImageView view = new ImageView();
private ScaleBarTemplate templateMain = new DefaultScaleBarTemplate(null,
new Dimension(220,40),10,
false, 4, NumberFormat.getNumberInstance(),
Color.DARK_GRAY, Color.GRAY, Color.WHITE,
10,true,false, new Font("Serial", Font.BOLD, 10),true,
Units.KILOMETRE);
private ScaleBarTemplate templateSecond = new DefaultScaleBarTemplate(null,
new Dimension(220,40),10,
false, 4, NumberFormat.getNumberInstance(),
Color.DARK_GRAY, Color.GRAY, Color.WHITE,
10,true,false, new Font("Serial", Font.BOLD, 10),true,
Units.METRE);
private final BufferedImage buffer = new BufferedImage(400, 40, BufferedImage.TYPE_INT_ARGB);
private CoordinateReferenceSystem lastObjCRS = null;
private CoordinateReferenceSystem lastDisplayCRS = null;
private Point2D lastCenter = null;
public FXScaleBarDecoration(){
setBottom(new BorderPane(null, null, null, null, view));
DropShadow ds = new DropShadow();
ds.setOffsetY(1.0);
ds.setOffsetX(1.0);
ds.setRadius(12);
ds.setColor(javafx.scene.paint.Color.WHITE);
ds.setSpread(0.5);
view.setEffect(ds);
}
/**
* {@inheritDoc }
*/
@Override
public void refresh() {
}
/**
* {@inheritDoc }
*/
@Override
public void dispose() {
}
/**
* {@inheritDoc }
*/
@Override
public void setMap2D(FXMap map) {
map2D.set(map);
if(map!=null){
map.getCanvas().addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if(J2DCanvas.TRANSFORM_KEY.equals(evt.getPropertyName())){
update();
}
}
});
}
}
/**
* {@inheritDoc }
*/
@Override
public FXMap getMap2D() {
return map2D.get();
}
/**
* {@inheritDoc }
*/
@Override
public Node getComponent() {
return this;
}
public void setMainUnit(final Unit unit) {
templateMain = new DefaultScaleBarTemplate(null,
templateMain.getSize(),10,
false, 4, NumberFormat.getNumberInstance(),
Color.DARK_GRAY, Color.GRAY, Color.WHITE,
10,true,false, new Font("Serial", Font.BOLD, 10),true,
unit);
update();
}
public Unit getMainUnit(){
return templateMain.getUnit();
}
public void setSecondaryUnit(final Unit unit) {
templateSecond = new DefaultScaleBarTemplate(null,
templateMain.getSize(),10,
false, 4, NumberFormat.getNumberInstance(),
Color.DARK_GRAY, Color.GRAY, Color.WHITE,
10,true,false, new Font("Serial", Font.BOLD, 10),true,
unit);
update();
}
public Unit getSecondaryUnit(){
return templateSecond.getUnit();
}
private void update() {
FXMap map = map2D.getValue();
if(map2D.getValue()==null) return;
final double[] center;
final Point2D centerPoint;
final CoordinateReferenceSystem objCRS;
final CoordinateReferenceSystem dispCRS;
try {
center = map.getCanvas().getObjectiveCenter().getCoordinate();
centerPoint = new Point2D.Double(center[0], center[1]);
objCRS = map.getCanvas().getObjectiveCRS();
dispCRS = map.getCanvas().getDisplayCRS();
} catch (NoninvertibleTransformException | TransformException ex) {
Logging.getLogger("org.geotoolkit.gui.javafx.render2d").log(Level.WARNING, null, ex);
return;
}
if(!centerPoint.equals(lastCenter) || !dispCRS.equals(lastDisplayCRS) || !objCRS.equals(lastObjCRS) ){
final Graphics2D g2d = buffer.createGraphics();
g2d.setBackground(new Color(0f,0f,0f,0f));
g2d.clearRect(0, 0, buffer.getWidth(), buffer.getHeight());
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
try {
final double l = J2DScaleBarUtilities.paint(objCRS, dispCRS, centerPoint, g2d, 10, 0, templateMain);
if(l<1.0){
//use secondary unit
g2d.setBackground(new Color(0f,0f,0f,0f));
g2d.clearRect(0, 0, buffer.getWidth(), buffer.getHeight());
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
J2DScaleBarUtilities.paint(objCRS, dispCRS, centerPoint, g2d, 10, 0, templateSecond);
}
} catch (PortrayalException ex) {
ex.printStackTrace();
}
lastCenter = centerPoint;
lastObjCRS = objCRS;
lastDisplayCRS = dispCRS;
view.setImage(SwingFXUtils.toFXImage(buffer, null));
}
}
}