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) Stefan Steiniger.
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: * Stefan Steiniger
026: * perriger@gmx.de
027: */
028: /*****************************************************
029: * created: 30.05.2005
030: * last modified: 31.05.2005
031: *
032: *
033: * @author sstein
034: *
035: * description:
036: * simplifies a selected line, criterion is a maximal line displacement <p>
037: * It is used the JTS 1.5 douglas peucker simplification with topology
038: * preservation for polygons and DouglasPeuckerSimplifier for linestrings.<p>
039: * n.b.: the jts-algorithm handles all geometry types
040: *
041: *****************************************************/package org.openjump.core.ui.plugin.tools;
042:
043: /*
044: import mapgen.algorithms.jtssimplify.DouglasPeuckerSimplifier;
045: import mapgen.algorithms.jtssimplify.TopologyPreservingSimplifier;
046: */
047: import com.vividsolutions.jts.geom.Geometry;
048: import com.vividsolutions.jts.geom.LineString;
049: import com.vividsolutions.jts.geom.Polygon;
050: import com.vividsolutions.jts.simplify.DouglasPeuckerSimplifier;
051: import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
052: import com.vividsolutions.jump.I18N;
053: import com.vividsolutions.jump.feature.Feature;
054: import com.vividsolutions.jump.task.TaskMonitor;
055: import com.vividsolutions.jump.workbench.WorkbenchContext;
056: import com.vividsolutions.jump.workbench.plugin.AbstractPlugIn;
057: import com.vividsolutions.jump.workbench.plugin.EnableCheckFactory;
058: import com.vividsolutions.jump.workbench.plugin.MultiEnableCheck;
059: import com.vividsolutions.jump.workbench.plugin.PlugInContext;
060: import com.vividsolutions.jump.workbench.plugin.ThreadedPlugIn;
061: import com.vividsolutions.jump.workbench.ui.EditTransaction;
062: import com.vividsolutions.jump.workbench.ui.GUIUtil;
063: import com.vividsolutions.jump.workbench.ui.MenuNames;
064: import com.vividsolutions.jump.workbench.ui.MultiInputDialog;
065: import com.vividsolutions.jump.workbench.ui.plugin.FeatureInstaller;
066:
067: import java.util.Iterator;
068: import com.vividsolutions.jump.workbench.model.Layer;
069: import java.util.Collection;
070:
071: /**
072: * @description:
073: * simplifies a selected line, criterion is a maximal line displacement <p>
074: * it is used the JTS 1.5 douglas peucker simplification with topology
075: * preservation for polygons and DouglasPeuckerSimplifier for linestrings
076: * n.b.: the jts-algorithm handles all geometry types
077: *
078: * @author sstein
079: *
080: **/
081: public class LineSimplifyJTS15AlgorithmPlugIn extends AbstractPlugIn
082: implements ThreadedPlugIn {
083:
084: private final static String sSimplifyJTSAlgorithm = I18N
085: .get("org.openjump.core.ui.plugin.tools.LineSimplifyJTS15AlgorithmPlugIn.Simplify-JTS-algorithm");
086: private final static String sGeometryNotLineOrPolygon = I18N
087: .get("org.openjump.core.ui.plugin.tools.LineSimplifyJTS15AlgorithmPlugIn.geometry-not-line-or-polygon");
088: private final static String sidebarText = I18N
089: .get("org.openjump.core.ui.plugin.tools.LineSimplifyJTS15AlgorithmPlugIn.Line-simplification-for-a-selected-line-or-polygon");
090: private final static String sItem = I18N
091: .get("org.openjump.core.ui.plugin.tools.LineSimplifyJTS15AlgorithmPlugIn.Item");
092: private final static String sSimplificationFinalized = I18N
093: .get("org.openjump.core.ui.plugin.tools.LineSimplifyJTS15AlgorithmPlugIn.simplification-finalized");
094: private static String T3 = I18N
095: .get("org.openjump.core.ui.plugin.tools.LineSimplifyJTS15AlgorithmPlugIn.Maximum-point-displacement-in-model-units");
096: double maxPDisp = 0;
097: private int geomType = 0; // 1 = line, 2= polygon, 0 = others,
098:
099: public void initialize(PlugInContext context) throws Exception {
100: FeatureInstaller featureInstaller = new FeatureInstaller(
101: context.getWorkbenchContext());
102: featureInstaller.addMainMenuItem(this , //exe
103: new String[] { MenuNames.TOOLS,
104: MenuNames.TOOLS_GENERALIZATION }, //menu path
105: sSimplifyJTSAlgorithm, //name methode .getName recieved by AbstractPlugIn
106: false, //checkbox
107: null, //icon
108: createEnableCheck(context.getWorkbenchContext())); //enable check
109: }
110:
111: public static MultiEnableCheck createEnableCheck(
112: WorkbenchContext workbenchContext) {
113: EnableCheckFactory checkFactory = new EnableCheckFactory(
114: workbenchContext);
115:
116: return new MultiEnableCheck()
117: .add(
118: checkFactory
119: .createWindowWithLayerNamePanelMustBeActiveCheck())
120: .add(
121: checkFactory
122: .createAtLeastNItemsMustBeSelectedCheck(1))
123: .add(
124: checkFactory
125: .createSelectedItemsLayersMustBeEditableCheck());
126: }
127:
128: public boolean execute(PlugInContext context) throws Exception {
129: this .reportNothingToUndoYet(context);
130: MultiInputDialog dialog = new MultiInputDialog(context
131: .getWorkbenchFrame(), getName(), true);
132: setDialogValues(dialog, context);
133: GUIUtil.centreOnWindow(dialog);
134: dialog.setVisible(true);
135: if (!dialog.wasOKPressed()) {
136: return false;
137: }
138: getDialogValues(dialog);
139: return true;
140: }
141:
142: private void setDialogValues(MultiInputDialog dialog,
143: PlugInContext context) {
144: dialog.setSideBarDescription(sidebarText);
145: dialog.addDoubleField(T3, 1.0, 5);
146: }
147:
148: private void getDialogValues(MultiInputDialog dialog) {
149: this .maxPDisp = dialog.getDouble(T3);
150:
151: }
152:
153: protected Layer layer(PlugInContext context) {
154: return (Layer) context.getLayerViewPanel()
155: .getSelectionManager().getLayersWithSelectedItems()
156: .iterator().next();
157: }
158:
159: public void run(TaskMonitor monitor, PlugInContext context)
160: throws Exception {
161:
162: monitor.allowCancellationRequests();
163: this .simplify(context, this .maxPDisp, monitor);
164: System.gc();
165: }
166:
167: private boolean simplify(PlugInContext context, double maxDisp,
168: TaskMonitor monitor) throws Exception {
169:
170: System.gc(); //flush garbage collector
171: // --------------------------
172: //-- get selected items
173: final Collection features = context.getLayerViewPanel()
174: .getSelectionManager().getFeaturesWithSelectedItems();
175:
176: EditTransaction transaction = new EditTransaction(features,
177: this .getName(), layer(context), this
178: .isRollingBackInvalidEdits(context), false,
179: context.getWorkbenchFrame());
180:
181: int count = 0;
182: int noItems = features.size();
183: Geometry resultgeom = null;
184: //--get single object in selection to analyse
185: for (Iterator iter = features.iterator(); iter.hasNext();) {
186: count++;
187: //System.out.println("========= simplify item: " + count + " ============ ");
188: Feature f = (Feature) iter.next();
189: Geometry geom = f.getGeometry(); //= erste Geometrie
190: LineString line = null;
191: Polygon poly = null;
192: if (geom instanceof LineString) {
193: line = (LineString) geom;
194: this .geomType = 1;
195: } else if (geom instanceof Polygon) {
196: poly = (Polygon) geom;
197: line = poly.getExteriorRing();
198: this .geomType = 2;
199: } else {
200: this .geomType = 0;
201: context.getWorkbenchFrame().warnUser(
202: sGeometryNotLineOrPolygon);
203: }
204: /****************************************/
205: if (this .geomType > 0) {
206: //-- update geometry --------
207: if (this .geomType == 1) { //linestring
208: resultgeom = DouglasPeuckerSimplifier.simplify(
209: line, Math.abs(maxDisp));
210: } else if (this .geomType == 2) { //polygon
211: //poly = (Polygon)geom.clone();
212: resultgeom = TopologyPreservingSimplifier.simplify(
213: poly, Math.abs(maxDisp));
214: }
215: String mytext = sItem + ": " + count + " / " + noItems
216: + " : " + sSimplificationFinalized;
217: //context.getWorkbenchFrame().setStatusMessage(mytext);
218: monitor.report(mytext);
219: //-- commit changes to undo history
220: transaction.setGeometry(count - 1, resultgeom);
221: }//end if : polygon or linestring
222: } //end for loop over selected objects
223: transaction.commit();
224: return true;
225: }
226:
227: }
|