// License: GPL. For details, see LICENSE file.
package cadastre_fr;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JOptionPane;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.actions.mapmode.MapMode;
import org.openstreetmap.josm.data.coor.EastNorth;
import org.openstreetmap.josm.gui.MapView;
import org.openstreetmap.josm.tools.ImageProvider;
public class WMSAdjustAction extends MapMode implements
MouseListener, MouseMotionListener {
private static final long serialVersionUID = 1L;
private WMSLayer modifiedLayer = null;
private boolean rasterMoved;
private EastNorth prevEastNorth;
enum Mode { moveXY, moveZ, rotate }
private static Mode mode = null;
private static EastNorth[] croppedRaster = new EastNorth[5];;
/**
* Constructs a new {@code WMSAdjustAction} map mode.
*/
public WMSAdjustAction() {
super(tr("Adjust WMS"), "adjustxywms",
tr("Adjust the position of the WMS layer (saved for raster images only)"),
ImageProvider.getCursor("normal", "move"));
}
@Override public void enterMode() {
if (Main.map != null) {
if (Main.getLayerManager().getActiveLayer() instanceof WMSLayer) {
modifiedLayer = (WMSLayer) Main.getLayerManager().getActiveLayer();
super.enterMode();
Main.map.mapView.addMouseListener(this);
Main.map.mapView.addMouseMotionListener(this);
rasterMoved = false;
modifiedLayer.adjustModeEnabled = true;
} else {
// This mode works only if active layer is a cadastre layer
if (Boolean.TRUE.equals(getValue("active"))) {
exitMode();
}
Main.map.selectMapMode((MapMode) Main.map.getDefaultButtonAction());
}
}
}
@Override public void exitMode() {
super.exitMode();
Main.map.mapView.removeMouseListener(this);
Main.map.mapView.removeMouseMotionListener(this);
if (rasterMoved && CacheControl.cacheEnabled && modifiedLayer.isRaster()) {
int reply = JOptionPane.showConfirmDialog(null,
"Save the changes in cache ?",
"Update cache",
JOptionPane.YES_NO_OPTION);
if (reply == JOptionPane.OK_OPTION) {
saveModifiedLayers();
}
}
rasterMoved = false;
if (modifiedLayer != null) {
modifiedLayer.adjustModeEnabled = false;
modifiedLayer = null;
}
}
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1)
return;
requestFocusInMapView();
boolean ctrl = (e.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0;
// boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
if (shift && !ctrl && modifiedLayer.isRaster())
mode = Mode.moveZ;
else if (shift && ctrl && modifiedLayer.isRaster())
mode = Mode.rotate;
else
mode = Mode.moveXY;
rasterMoved = true;
prevEastNorth = Main.map.mapView.getEastNorth(e.getX(), e.getY());
Main.map.mapView.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
}
@Override public void mouseDragged(MouseEvent e) {
EastNorth newEastNorth = Main.map.mapView.getEastNorth(e.getX(), e.getY());
if (mode == Mode.rotate) {
rotateFrameOnly(prevEastNorth, newEastNorth);
} else {
if (mode == Mode.moveXY) {
displace(prevEastNorth, newEastNorth);
} else if (mode == Mode.moveZ) {
resize(newEastNorth);
}
prevEastNorth = newEastNorth;
}
Main.map.mapView.repaint();
}
public static void paintAdjustFrames(Graphics2D g, final MapView mv) {
if (mode == Mode.rotate && croppedRaster != null) {
g.setColor(Color.red);
for (int i = 0; i < 4; i++) {
g.drawLine(mv.getPoint(croppedRaster[i]).x,
mv.getPoint(croppedRaster[i]).y,
mv.getPoint(croppedRaster[i+1]).x,
mv.getPoint(croppedRaster[i+1]).y);
}
}
}
private void displace(EastNorth start, EastNorth end) {
modifiedLayer.displace(end.east()-start.east(), end.north()-start.north());
}
private void resize(EastNorth newEastNorth) {
EastNorth center = modifiedLayer.getRasterCenter();
double dPrev = prevEastNorth.distance(center.east(), center.north());
double dNew = newEastNorth.distance(center.east(), center.north());
modifiedLayer.resize(center, dNew/dPrev);
}
private void rotate(EastNorth start, EastNorth end) {
EastNorth pivot = modifiedLayer.getRasterCenter();
double startAngle = Math.atan2(start.east()-pivot.east(), start.north()-pivot.north());
double endAngle = Math.atan2(end.east()-pivot.east(), end.north()-pivot.north());
double rotationAngle = endAngle - startAngle;
modifiedLayer.rotate(pivot, rotationAngle);
}
private void rotateFrameOnly(EastNorth start, EastNorth end) {
if (start != null && end != null) {
EastNorth pivot = modifiedLayer.getRasterCenter();
double startAngle = Math.atan2(start.east()-pivot.east(), start.north()-pivot.north());
double endAngle = Math.atan2(end.east()-pivot.east(), end.north()-pivot.north());
double rotationAngle = endAngle - startAngle;
if (modifiedLayer.getImage(0).orgCroppedRaster != null) {
for (int i = 0; i < 4; i++) {
croppedRaster[i] = modifiedLayer.getImage(0).orgCroppedRaster[i].rotate(pivot, rotationAngle);
}
croppedRaster[4] = croppedRaster[0];
}
}
}
@Override public void mouseReleased(MouseEvent e) {
if (mode == Mode.rotate) {
EastNorth newEastNorth = Main.map.mapView.getEastNorth(e.getX(), e.getY());
rotate(prevEastNorth, newEastNorth);
Main.map.mapView.repaint();
}
Main.map.mapView.setCursor(Cursor.getDefaultCursor());
prevEastNorth = null;
mode = null;
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override public void mouseClicked(MouseEvent e) {
}
private void saveModifiedLayers() {
modifiedLayer.grabThread.saveNewCache();
}
}