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.tools;
035:
036: import java.util.Collection;
037: import java.util.Iterator;
038: import java.util.Vector;
039: import com.vividsolutions.jts.geom.Coordinate;
040: import com.vividsolutions.jts.geom.CoordinateList;
041: import com.vividsolutions.jts.geom.Geometry;
042: import com.vividsolutions.jts.geom.GeometryFactory;
043: import com.vividsolutions.jts.geom.LineString;
044: import com.vividsolutions.jump.I18N;
045: import com.vividsolutions.jump.feature.Feature;
046: import com.vividsolutions.jump.feature.FeatureDataset;
047: import com.vividsolutions.jump.workbench.WorkbenchContext;
048: import com.vividsolutions.jump.workbench.model.LayerManager;
049: import com.vividsolutions.jump.workbench.model.StandardCategoryNames;
050: import com.vividsolutions.jump.workbench.plugin.AbstractPlugIn;
051: import com.vividsolutions.jump.workbench.plugin.EnableCheckFactory;
052: import com.vividsolutions.jump.workbench.plugin.MultiEnableCheck;
053: import com.vividsolutions.jump.workbench.plugin.PlugInContext;
054: import com.vividsolutions.jump.workbench.ui.EditTransaction;
055: import com.vividsolutions.jump.workbench.ui.MenuNames;
056: import com.vividsolutions.jump.workbench.ui.MultiInputDialog;
057:
058: public class BlendLineStringsPlugIn extends AbstractPlugIn {
059:
060: private WorkbenchContext workbenchContext;
061:
062: private String sToolTipText = "huhu! :)";
063: private String sTheBlendTolerance = I18N
064: .get("org.openjump.core.ui.plugin.tools.BlendLineStringsPlugIn.The-blend-tolerance");
065: private String sNew = I18N
066: .get("org.openjump.core.ui.plugin.tools.BlendLineStringsPlugIn.New");
067: private String TOLERANCE = I18N
068: .get("org.openjump.core.ui.plugin.tools.BlendLineStringsPlugIn.Tolerance");
069: private String sName = I18N
070: .get("org.openjump.core.ui.plugin.tools.BlendLineStringsPlugIn.Blend-LineStrings");
071:
072: private double blendTolerance = 0.1;
073:
074: public void initialize(PlugInContext context) throws Exception {
075: workbenchContext = context.getWorkbenchContext();
076: context.getFeatureInstaller().addMainMenuItem(
077: this ,
078: new String[] { MenuNames.TOOLS,
079: MenuNames.TOOLS_EDIT_GEOMETRY }, sName, false,
080: null, this .createEnableCheck(workbenchContext));
081: }
082:
083: public boolean execute(final PlugInContext context)
084: throws Exception {
085: sToolTipText = "huhu! :)";
086: sTheBlendTolerance = I18N
087: .get("org.openjump.core.ui.plugin.tools.BlendLineStringsPlugIn.The-blend-tolerance");
088: sNew = I18N
089: .get("org.openjump.core.ui.plugin.tools.BlendLineStringsPlugIn.New");
090: TOLERANCE = I18N
091: .get("org.openjump.core.ui.plugin.tools.BlendLineStringsPlugIn.Tolerance");
092: sName = I18N
093: .get("org.openjump.core.ui.plugin.tools.BlendLineStringsPlugIn.Blend-LineStrings");
094:
095: reportNothingToUndoYet(context);
096:
097: MultiInputDialog dialog = new MultiInputDialog(context
098: .getWorkbenchFrame(), getName(), true);
099: setDialogValues(dialog, context);
100: dialog.setVisible(true);
101: if (!dialog.wasOKPressed()) {
102: return false;
103: }
104: getDialogValues(dialog);
105: //context.getLayerViewPanel().setToolTipText(sToolTipText);
106: Collection selectedFeatures = context.getLayerViewPanel()
107: .getSelectionManager().getFeaturesWithSelectedItems();
108: Feature currFeature = ((Feature) selectedFeatures.iterator()
109: .next());
110: Collection selectedCategories = context.getLayerNamePanel()
111: .getSelectedCategories();
112: LayerManager layerManager = context.getLayerManager();
113: FeatureDataset newFeatures = new FeatureDataset(currFeature
114: .getSchema());
115: Vector inputLS = new Vector(selectedFeatures.size());
116:
117: for (Iterator j = selectedFeatures.iterator(); j.hasNext();) {
118: Feature f = (Feature) j.next();
119: Geometry geo = f.getGeometry();
120:
121: if (geo instanceof LineString) {
122: inputLS.add(geo);
123: }
124: }
125:
126: Vector outputLS = new Vector(inputLS.size()); //contains all the blended linestrings
127:
128: while (inputLS.size() > 0) {
129: //start a new blended linestring
130: LineString ls = (LineString) inputLS.get(0);
131: CoordinateList blendedCoords = new CoordinateList(ls
132: .getCoordinates());
133: inputLS.removeElementAt(0);
134: //sequence through remaining input linestrings
135: //and find those which can be added to either
136: //the beginning or end of the current blended coordinate list
137: int currIndex = 0; //index of current linestring in input vector
138: while (currIndex < inputLS.size()) {
139: ls = (LineString) inputLS.get(currIndex);
140: CoordinateList lsCoords = new CoordinateList(ls
141: .getCoordinates());
142: if (blended(blendedCoords, lsCoords)) {
143: inputLS.removeElementAt(currIndex);
144: currIndex = 0; //start at top since some that were rejected before might add to new string
145: } else {
146: currIndex++;
147: }
148: }
149:
150: outputLS
151: .add(new GeometryFactory()
152: .createLineString(blendedCoords
153: .toCoordinateArray()));
154: }
155:
156: for (Iterator i = outputLS.iterator(); i.hasNext();) {
157: Feature newFeature = (Feature) currFeature.clone();
158: newFeature.setGeometry((LineString) i.next());
159: newFeatures.add(newFeature);
160: }
161:
162: layerManager
163: .addLayer(
164: selectedCategories.isEmpty() ? StandardCategoryNames.WORKING
165: : selectedCategories.iterator().next()
166: .toString(), layerManager
167: .uniqueLayerName(sNew), newFeatures);
168:
169: layerManager.getLayer(0).setFeatureCollectionModified(true);
170: layerManager.getLayer(0).setEditable(true);
171:
172: return true;
173: }
174:
175: private boolean blended(CoordinateList blendedCoords,
176: CoordinateList lsCoords) {
177: Coordinate start = blendedCoords.getCoordinate(0);
178: Coordinate end = blendedCoords.getCoordinate(blendedCoords
179: .size() - 1);
180: Coordinate first = lsCoords.getCoordinate(0);
181: Coordinate last = lsCoords.getCoordinate(lsCoords.size() - 1);
182: if (start.distance(first) < blendTolerance) {
183: for (int i = 1; i < lsCoords.size(); i++) {
184: blendedCoords.add(0, lsCoords.getCoordinate(i));
185: }
186: } else if (start.distance(last) < blendTolerance) {
187: for (int i = lsCoords.size() - 2; i >= 0; i--) {
188: blendedCoords.add(0, lsCoords.getCoordinate(i));
189: }
190: } else if (end.distance(first) < blendTolerance) {
191: for (int i = 1; i < lsCoords.size(); i++) {
192: blendedCoords.add(lsCoords.getCoordinate(i));
193: }
194: } else if (end.distance(last) < blendTolerance) {
195: for (int i = lsCoords.size() - 2; i >= 0; i--) {
196: blendedCoords.add(lsCoords.getCoordinate(i));
197: }
198: } else {
199: return false;
200: }
201: return true;
202: }
203:
204: private void setDialogValues(MultiInputDialog dialog,
205: PlugInContext context) {
206: dialog.addDoubleField(TOLERANCE, blendTolerance, 6,
207: sTheBlendTolerance);
208: }
209:
210: private void getDialogValues(MultiInputDialog dialog) {
211: blendTolerance = dialog.getDouble(TOLERANCE);
212: }
213:
214: public MultiEnableCheck createEnableCheck(
215: final WorkbenchContext workbenchContext) {
216: EnableCheckFactory checkFactory = new EnableCheckFactory(
217: workbenchContext);
218: return new MultiEnableCheck()
219: .add(
220: checkFactory
221: .createWindowWithLayerViewPanelMustBeActiveCheck())
222: .add(
223: checkFactory
224: .createOnlyOneLayerMayHaveSelectedFeaturesCheck())
225: .add(
226: checkFactory
227: .createAtLeastNFeaturesMustHaveSelectedItemsCheck(2));
228: }
229: }
|