/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program 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. * This program 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 this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.snap.rcp.sync; import com.bc.ceres.glayer.swing.LayerCanvas; import com.bc.ceres.grender.Rendering; import com.bc.ceres.grender.Viewport; import org.esa.snap.core.datamodel.GeoCoding; import org.esa.snap.core.datamodel.GeoPos; import org.esa.snap.core.datamodel.PixelPos; import org.esa.snap.core.datamodel.Product; import org.esa.snap.ui.product.ProductSceneView; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; /** * @author Marco Peters * @since BEAM 4.6 */ class ImageCursorOverlay implements LayerCanvas.Overlay { private static final int MAX_CROSSHAIR_SIZE = 20; private final ProductSceneView sceneView; private GeoPos geoPosition; private BasicStroke cursorStroke; private Color cursorColor; ImageCursorOverlay(ProductSceneView sceneView, GeoPos geoPos) { this.sceneView = sceneView; geoPosition = geoPos; cursorStroke = new BasicStroke(1F); cursorColor = Color.WHITE; } public void setGeoPosition(GeoPos geoPosition) { this.geoPosition = geoPosition; } @Override public void paintOverlay(LayerCanvas canvas, Rendering rendering) { if (geoPosition == null || !geoPosition.isValid()) { return; } final GeoCoding geoCoding = sceneView.getRaster().getGeoCoding(); if (!geoCoding.canGetPixelPos()) { return; } final Product product = sceneView.getRaster().getProduct(); final PixelPos pixelPos = geoCoding.getPixelPos(geoPosition, null); if (!pixelPos.isValid() || !product.containsPixel(pixelPos)) { return; } final Viewport viewport = canvas.getViewport(); drawCursor(rendering.getGraphics(), viewport, pixelPos); } private void drawCursor(Graphics2D graphics, Viewport viewport, PixelPos pixelPos) { AffineTransform i2mTransform = sceneView.getBaseImageLayer().getImageToModelTransform(); AffineTransform m2vTransform = viewport.getModelToViewTransform(); AffineTransform i2vTransform = new AffineTransform(m2vTransform); i2vTransform.concatenate(i2mTransform); Point centerPixel = new Point((int) Math.floor(pixelPos.x), (int) Math.floor(pixelPos.y)); Rectangle pixelImageRect = new Rectangle(centerPixel, new Dimension(1, 1)); Rectangle2D pixelViewRect = i2vTransform.createTransformedShape(pixelImageRect).getBounds2D(); graphics.setStroke(cursorStroke); graphics.setColor(cursorColor); graphics.setXORMode(Color.BLACK); graphics.draw(pixelViewRect); if (pixelViewRect.getBounds2D().getWidth() < MAX_CROSSHAIR_SIZE) { drawCrosshair(graphics, i2vTransform, centerPixel, pixelViewRect); } } private void drawCrosshair(Graphics2D graphics, AffineTransform i2vTransform, Point centerPixel, Rectangle2D pixelViewRect) { Rectangle surroundImageRect = new Rectangle(centerPixel.x - 1, centerPixel.y - 1, 3, 3); Rectangle2D surroundViewRect = i2vTransform.createTransformedShape(surroundImageRect).getBounds2D(); double scale = MAX_CROSSHAIR_SIZE / surroundViewRect.getBounds2D().getWidth(); if (scale > 1) { double newWidth = surroundViewRect.getWidth() * scale; double newHeight = surroundViewRect.getHeight() * scale; double newX = surroundViewRect.getCenterX() - newWidth / 2; double newY = surroundViewRect.getCenterY() - newHeight / 2; surroundViewRect.setRect(newX, newY, newWidth, newHeight); } graphics.draw(surroundViewRect); Line2D.Double northLine = new Line2D.Double(surroundViewRect.getCenterX(), surroundViewRect.getMinY(), surroundViewRect.getCenterX(), pixelViewRect.getMinY()); Line2D.Double eastLine = new Line2D.Double(surroundViewRect.getMaxX(), surroundViewRect.getCenterY(), pixelViewRect.getMaxX(), surroundViewRect.getCenterY()); Line2D.Double southLine = new Line2D.Double(surroundViewRect.getCenterX(), surroundViewRect.getMaxY(), surroundViewRect.getCenterX(), pixelViewRect.getMaxY()); Line2D.Double westLine = new Line2D.Double(surroundViewRect.getMinX(), surroundViewRect.getCenterY(), pixelViewRect.getMinX(), surroundViewRect.getCenterY()); graphics.draw(northLine); graphics.draw(eastLine); graphics.draw(southLine); graphics.draw(westLine); } }