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.behaviour;
016:
017: import com.vividsolutions.jts.geom.MultiPolygon;
018: import com.vividsolutions.jts.geom.Polygon;
019:
020: import net.refractions.udig.core.StaticBlockingProvider;
021: import net.refractions.udig.project.ILayer;
022: import net.refractions.udig.project.command.UndoableMapCommand;
023: import net.refractions.udig.project.ui.render.displayAdapter.MapMouseEvent;
024: import net.refractions.udig.tools.edit.EditPlugin;
025: import net.refractions.udig.tools.edit.EditState;
026: import net.refractions.udig.tools.edit.EditToolHandler;
027: import net.refractions.udig.tools.edit.EventBehaviour;
028: import net.refractions.udig.tools.edit.EventType;
029: import net.refractions.udig.tools.edit.commands.InsertVertexCommand;
030: import net.refractions.udig.tools.edit.preferences.PreferenceUtil;
031: import net.refractions.udig.tools.edit.support.ClosestEdge;
032: import net.refractions.udig.tools.edit.support.EditGeom;
033: import net.refractions.udig.tools.edit.support.EditUtils;
034: import net.refractions.udig.tools.edit.support.Point;
035: import net.refractions.udig.tools.edit.support.PrimitiveShape;
036:
037: /**
038: * <p>Requirements:
039: * <ul>
040: * <li>event type == RELEASE</li>
041: * <li>edit state == MODIFYING </li>
042: * <li>no modifiers down</li>
043: * <li>button 1 released</li>
044: * <li>no buttons down</li>
045: * <li>current shape and geom are set</li>
046: * <li>mouse is not over a vertex of the current shape</li>
047: * <li>mouse is over an edge </li>
048: * </ul>
049: * </p>
050: * <p>Action:
051: * <ul>
052: * <li>Adds a vertex at the location where the mouse event occurred</li>
053: * </ul>
054: * </p>
055: * @author jones
056: * @since 1.1.0
057: */
058: public class AddVertexOnEdgeBehaviour implements EventBehaviour {
059:
060: public boolean isValid(EditToolHandler handler, MapMouseEvent e,
061: EventType eventType) {
062: boolean legalEventType = eventType == EventType.RELEASED;
063: boolean shapeAndGeomNotNull = handler.getCurrentShape() != null;
064: boolean button1Released = e.button == MapMouseEvent.BUTTON1;
065:
066: boolean legalState = handler.getCurrentState() == EditState.NONE
067: || handler.getCurrentState() == EditState.MODIFYING;
068: return legalState && legalEventType && shapeAndGeomNotNull
069: && button1Released && !e.buttonsDown()
070: && !e.modifiersDown() && !overShapeVertex(handler, e)
071: && isOverEdge(handler, e);
072: }
073:
074: private boolean isOverEdge(EditToolHandler handler, MapMouseEvent e) {
075: ILayer selectedLayer = handler.getEditLayer();
076: Class type = selectedLayer.getSchema().getDefaultGeometry()
077: .getType();
078: boolean polygonLayer = Polygon.class.isAssignableFrom(type)
079: || MultiPolygon.class.isAssignableFrom(type);
080:
081: ClosestEdge edge = handler.getCurrentGeom().getClosestEdge(
082: Point.valueOf(e.x, e.y), polygonLayer);
083: if (edge == null)
084: return false;
085: return edge.getDistanceToEdge() <= PreferenceUtil.instance()
086: .getVertexRadius();
087: }
088:
089: private boolean overShapeVertex(EditToolHandler handler,
090: MapMouseEvent e) {
091:
092: Point vertexOver = handler.getEditBlackboard(
093: handler.getEditLayer()).overVertex(
094: Point.valueOf(e.x, e.y),
095: PreferenceUtil.instance().getVertexRadius());
096:
097: return handler.getCurrentShape().hasVertex(vertexOver);
098: }
099:
100: public UndoableMapCommand getCommand(EditToolHandler handler,
101: MapMouseEvent e, EventType eventType) {
102: if (!isValid(handler, e, eventType))
103: throw new IllegalStateException("isValid() return false"); //$NON-NLS-1$
104: EditGeom geom = handler.getCurrentGeom();
105: ILayer editLayer = handler.getEditLayer();
106: Class type = editLayer.getSchema().getDefaultGeometry()
107: .getType();
108: boolean polygonLayer = Polygon.class.isAssignableFrom(type)
109: || MultiPolygon.class.isAssignableFrom(type);
110: ClosestEdge edge = geom.getClosestEdge(Point.valueOf(e.x, e.y),
111: polygonLayer);
112: return new InsertVertexCommand(handler, handler
113: .getEditBlackboard(editLayer), handler.getContext()
114: .getMapDisplay(),
115: new StaticBlockingProvider<PrimitiveShape>(edge
116: .getPart()), edge.getPointOnLine(), edge
117: .getIndexOfPrevious() + 1, true);
118: }
119:
120: public void handleError(EditToolHandler handler, Throwable error,
121: UndoableMapCommand command) {
122: EditPlugin.log("", error); //$NON-NLS-1$
123: }
124:
125: }
|