001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * JUMP is Copyright (C) 2003 Vivid Solutions
006: *
007: * This program implements extensions to JUMP and is
008: * Copyright (C) 2004 Integrated Systems Analysts, Inc.
009: *
010: * This program is free software; you can redistribute it and/or
011: * modify it under the terms of the GNU General Public License
012: * as published by the Free Software Foundation; either version 2
013: * of the License, or (at your option) any later version.
014: *
015: * This program is distributed in the hope that it will be useful,
016: * but WITHOUT ANY WARRANTY; without even the implied warranty of
017: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
018: * GNU General Public License for more details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with this program; if not, write to the Free Software
022: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
023: *
024: * For more information, contact:
025: *
026: * Integrated Systems Analysts, Inc.
027: * 630C Anchors St., Suite 101
028: * Fort Walton Beach, Florida
029: * USA
030: *
031: * (850)862-7321
032: */
033:
034: package org.openjump.core.ui.plugin.mousemenu;
035:
036: import java.util.ArrayList;
037: import java.util.Collection;
038: import java.util.Iterator;
039:
040: import javax.swing.ImageIcon;
041: import javax.swing.JPopupMenu;
042: import com.vividsolutions.jts.geom.Coordinate;
043: import com.vividsolutions.jts.geom.CoordinateFilter;
044: import com.vividsolutions.jts.geom.Geometry;
045: import com.vividsolutions.jump.I18N;
046: import com.vividsolutions.jump.geom.CoordUtil;
047: import com.vividsolutions.jump.workbench.WorkbenchContext;
048: import com.vividsolutions.jump.workbench.model.Layer;
049: import com.vividsolutions.jump.workbench.plugin.AbstractPlugIn;
050: import com.vividsolutions.jump.workbench.plugin.EnableCheckFactory;
051: import com.vividsolutions.jump.workbench.plugin.MultiEnableCheck;
052: import com.vividsolutions.jump.workbench.plugin.PlugInContext;
053: import com.vividsolutions.jump.workbench.ui.EditTransaction;
054: import com.vividsolutions.jump.workbench.ui.LayerViewPanel;
055: import com.vividsolutions.jump.workbench.ui.MultiInputDialog;
056: import com.vividsolutions.jump.workbench.ui.plugin.FeatureInstaller;
057:
058: public class MoveAlongAnglePlugIn extends AbstractPlugIn {
059:
060: private final static String sMoveAlongAngle = I18N
061: .get("org.openjump.core.ui.plugin.mousemenu.MoveAlongAnglePlugIn.Move-Along-Angle");
062: private final static String sMoveSelectedFeaturesAlongAngle = I18N
063: .get("org.openjump.core.ui.plugin.mousemenu.MoveAlongAnglePlugIn.Move-Selected-Features-Along-Angle");
064: private final static String sTheDistanceInMapUnitsToMove = I18N
065: .get("org.openjump.core.ui.plugin.mousemenu.MoveAlongAnglePlugIn.The-distance-in-map-units-to-move");
066: private final static String sTheAngleInDegreesToMove = I18N
067: .get("org.openjump.core.ui.plugin.mousemenu.MoveAlongAnglePlugIn.The-angle-in-degrees-to-move");
068: private final static String sWillCovert = I18N
069: .get("org.openjump.core.ui.plugin.mousemenu.MoveAlongAnglePlugIn.Will-convert-input-value-from-feet-to-meters");
070:
071: private WorkbenchContext workbenchContext;
072: private final static String ANGLE = I18N
073: .get("org.openjump.core.ui.plugin.mousemenu.MoveAlongAnglePlugIn.Move-Angle");
074: private final static String DISTANCE = I18N
075: .get("org.openjump.core.ui.plugin.mousemenu.MoveAlongAnglePlugIn.Move-Distance");
076: private final double Deg2Rad = 0.0174532925199432; //pi/180
077: private MultiInputDialog dialog;
078: private double moveAngle = 0.0;
079: private double moveDistance = 1.0;
080:
081: private final static String CONVERTTOMETERS = I18N
082: .get("org.openjump.core.ui.plugin.mousemenu.MoveAlongAnglePlugIn.Convert-Feet-to-Meters");
083: private double conversionFactor = 1.0;
084:
085: public void initialize(PlugInContext context) throws Exception {
086: workbenchContext = context.getWorkbenchContext();
087: FeatureInstaller featureInstaller = new FeatureInstaller(
088: workbenchContext);
089: JPopupMenu popupMenu = LayerViewPanel.popupMenu();
090: featureInstaller.addPopupMenuItem(popupMenu, this ,
091: sMoveAlongAngle, false, null, //to do: add icon
092: this .createEnableCheck(workbenchContext));
093: }
094:
095: public boolean execute(final PlugInContext context)
096: throws Exception {
097: final ArrayList transactions = new ArrayList();
098: reportNothingToUndoYet(context);
099: MultiInputDialog dialog = new MultiInputDialog(context
100: .getWorkbenchFrame(), getName(), true);
101: setDialogValues(dialog, context);
102: dialog.setVisible(true);
103: if (!dialog.wasOKPressed()) {
104: return false;
105: }
106: getDialogValues(dialog);
107:
108: double angle = Deg2Rad * moveAngle;
109: double x = Math.cos(angle) * moveDistance * conversionFactor;
110: double y = Math.sin(angle) * moveDistance * conversionFactor;
111: Coordinate displacement = new Coordinate(x, y);
112: workbenchContext = context.getWorkbenchContext();
113: for (Iterator i = workbenchContext.getLayerViewPanel()
114: .getSelectionManager().getLayersWithSelectedItems()
115: .iterator(); i.hasNext();) {
116: Layer layerWithSelectedItems = (Layer) i.next();
117: transactions.add(createTransaction(layerWithSelectedItems,
118: displacement));
119: }
120: EditTransaction.commit(transactions);
121: return true;
122: }
123:
124: private void setDialogValues(MultiInputDialog dialog,
125: PlugInContext context) {
126: dialog.setSideBarImage(new ImageIcon(getClass().getResource(
127: "Compass.png")));
128: dialog.setSideBarDescription(sMoveSelectedFeaturesAlongAngle);
129: dialog.addDoubleField(DISTANCE, moveDistance, 6,
130: sTheDistanceInMapUnitsToMove);
131: dialog.addDoubleField(ANGLE, moveAngle, 6,
132: sTheAngleInDegreesToMove);
133: dialog.addCheckBox(CONVERTTOMETERS,
134: (!(conversionFactor == 1.0)), sWillCovert);
135: }
136:
137: private void getDialogValues(MultiInputDialog dialog) {
138: if (dialog.getCheckBox(CONVERTTOMETERS).isSelected())
139: conversionFactor = 0.3048;
140: else
141: conversionFactor = 1.0;
142: moveDistance = dialog.getDouble(DISTANCE);
143: moveAngle = dialog.getDouble(ANGLE);
144: }
145:
146: private EditTransaction createTransaction(Layer layer,
147: final Coordinate displacement) {
148: EditTransaction transaction = EditTransaction
149: .createTransactionOnSelection(
150: new EditTransaction.SelectionEditor() {
151: public Geometry edit(
152: Geometry geometryWithSelectedItems,
153: Collection selectedItems) {
154: for (Iterator j = selectedItems
155: .iterator(); j.hasNext();) {
156: Geometry item = (Geometry) j.next();
157: move(item, displacement);
158: }
159:
160: return geometryWithSelectedItems;
161: }
162: }, workbenchContext.getLayerViewPanel(),
163: workbenchContext.getLayerViewPanel()
164: .getContext(), getName(), layer, false,
165: false);// isRollingBackInvalidEdits(), false);
166: return transaction;
167: }
168:
169: private void move(Geometry geometry, final Coordinate displacement) {
170: geometry.apply(new CoordinateFilter() {
171: public void filter(Coordinate coordinate) {
172: coordinate.setCoordinate(CoordUtil.add(coordinate,
173: displacement));
174: }
175: });
176: }
177:
178: public MultiEnableCheck createEnableCheck(
179: final WorkbenchContext workbenchContext) {
180: EnableCheckFactory checkFactory = new EnableCheckFactory(
181: workbenchContext);
182: return new MultiEnableCheck()
183: .add(
184: checkFactory
185: .createWindowWithLayerViewPanelMustBeActiveCheck())
186: .add(
187: checkFactory
188: .createAtLeastNFeaturesMustHaveSelectedItemsCheck(1))
189: .add(
190: checkFactory
191: .createSelectedItemsLayersMustBeEditableCheck());
192:
193: }
194: }
|