001: /* uDig - User Friendly Desktop Internet GIS client
002: * http://udig.refractions.net
003: * (C) 2004, Refractions Research Inc.
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation;
008: * version 2.1 of the License.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: */
015: package net.refractions.udig.tools.edit.commands;
016:
017: import net.refractions.udig.project.ILayer;
018: import net.refractions.udig.project.command.AbstractCommand;
019: import net.refractions.udig.project.command.UndoableMapCommand;
020: import net.refractions.udig.project.ui.tool.IToolContext;
021: import net.refractions.udig.tool.edit.internal.Messages;
022: import net.refractions.udig.tools.edit.EditState;
023: import net.refractions.udig.tools.edit.EditToolHandler;
024: import net.refractions.udig.tools.edit.preferences.PreferenceUtil;
025: import net.refractions.udig.tools.edit.support.EditBlackboard;
026: import net.refractions.udig.tools.edit.support.EditUtils;
027: import net.refractions.udig.tools.edit.support.Point;
028: import net.refractions.udig.tools.edit.support.Selection;
029: import net.refractions.udig.tools.edit.support.SnapBehaviour;
030:
031: import org.eclipse.core.runtime.IProgressMonitor;
032: import org.eclipse.core.runtime.SubProgressMonitor;
033:
034: import com.vividsolutions.jts.geom.Coordinate;
035:
036: /**
037: * This class manages the movement of a vertex. Once a vertex has been moved this command determines
038: * how much the vertex has moved from its original position so the incremental move can be undone.
039: * Additionally this command performs post-order snapping. It searches the layer below it for the
040: * closest vertex and snaps to that vertex.
041: *
042: * @author jones
043: * @since 1.1.0
044: */
045: public class SnapToVertexCommand extends AbstractCommand implements
046: UndoableMapCommand {
047:
048: private Point start;
049: private EditToolHandler handler;
050: private Selection toMove;
051: private Point lastPoint;
052: private MoveSelectionCommand command;
053: private EditState stateAfterSnap;
054: private boolean doSnap;
055: private SnapBehaviour snapBehaviour;
056:
057: public SnapToVertexCommand(Point lastPoint, Selection toMove,
058: EditToolHandler handler, Point start,
059: EditState stateAfterSnap, boolean doSnap) {
060: this .lastPoint = lastPoint;
061: this .toMove = toMove;
062: this .handler = handler;
063: this .start = start;
064: this .stateAfterSnap = stateAfterSnap;
065: this .doSnap = doSnap;
066: this .snapBehaviour = PreferenceUtil.instance()
067: .getSnapBehaviour();
068: }
069:
070: public void run(IProgressMonitor monitor) throws Exception {
071: if (command == null) {
072: ILayer selectedLayer = handler.getEditLayer();
073: EditBlackboard editBlackboard = handler
074: .getEditBlackboard(selectedLayer);
075:
076: Coordinate destinationCoord = null;
077: Point dest;
078: destinationCoord = calculateDestinationPoint(
079: editBlackboard, destinationCoord);
080:
081: dest = editBlackboard.toPoint(destinationCoord);
082: int deltaX = dest.getX() - lastPoint.getX(), deltaY = dest
083: .getY()
084: - lastPoint.getY();
085: editBlackboard.moveSelection(deltaX, deltaY, toMove);
086: editBlackboard.setCoords(dest, destinationCoord);
087:
088: deltaX = dest.getX() - start.getX();
089: deltaY = dest.getY() - start.getY();
090:
091: command = new MoveSelectionCommand(editBlackboard, deltaX,
092: deltaY, toMove);
093: command.setMap(getMap());
094:
095: } else {
096: command.run(new SubProgressMonitor(monitor, 1));
097: }
098: }
099:
100: private Coordinate calculateDestinationPoint(
101: EditBlackboard editBlackboard, Coordinate destinationCoord) {
102: if (doSnap) {
103: destinationCoord = EditUtils.instance.getClosestSnapPoint(
104: handler, editBlackboard, lastPoint, false,
105: snapBehaviour, stateAfterSnap);
106: }
107: Point dest;
108: if (destinationCoord == null) {
109: dest = editBlackboard.overVertex(lastPoint, PreferenceUtil
110: .instance().getVertexRadius(), true);
111: if (dest == null)
112: dest = lastPoint;
113: destinationCoord = editBlackboard.toCoord(dest);
114: }
115: return destinationCoord;
116: }
117:
118: public String getName() {
119: return Messages.SnapToVertexCommand_name;
120: }
121:
122: public void rollback(IProgressMonitor monitor) throws Exception {
123: command.rollback(new SubProgressMonitor(monitor, 1));
124: }
125:
126: }
|