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.ArrayList;
037: import java.util.Collection;
038: import java.util.Iterator;
039:
040: import org.openjump.core.geomutils.GeoUtils;
041:
042: import com.vividsolutions.jts.geom.CoordinateSequence;
043: import com.vividsolutions.jts.geom.DefaultCoordinateSequenceFactory;
044: import com.vividsolutions.jts.geom.Geometry;
045: import com.vividsolutions.jts.geom.GeometryCollection;
046: import com.vividsolutions.jts.geom.GeometryFactory;
047: import com.vividsolutions.jts.geom.LineString;
048: import com.vividsolutions.jts.geom.LinearRing;
049: import com.vividsolutions.jts.geom.MultiLineString;
050: import com.vividsolutions.jts.geom.MultiPolygon;
051: import com.vividsolutions.jts.geom.Polygon;
052: import com.vividsolutions.jump.I18N;
053: import com.vividsolutions.jump.feature.Feature;
054: import com.vividsolutions.jump.workbench.WorkbenchContext;
055: import com.vividsolutions.jump.workbench.model.Layer;
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.ui.EditTransaction;
061: import com.vividsolutions.jump.workbench.ui.MenuNames;
062: import com.vividsolutions.jump.workbench.ui.MultiInputDialog;
063:
064: public class ReducePointsISAPlugIn extends AbstractPlugIn {
065:
066: private final static String sSimplifyISA = I18N
067: .get("org.openjump.core.ui.plugin.tools.ReducePointsISAPlugIn.Simplify-ISA-algorithm");
068: private final static String sPointsReducedFrom = I18N
069: .get("org.openjump.core.ui.plugin.tools.ReducePointsISAPlugIn.Points-reduced-from");
070: private final static String sTo = I18N
071: .get("org.openjump.core.ui.plugin.tools.ReducePointsISAPlugIn.to");
072: private final static String sReducePointsInSelectedFeatures = I18N
073: .get("org.openjump.core.ui.plugin.tools.ReducePointsISAPlugIn.Reduce-points-in-selected-features");
074: private final static String sTheReducePointsTolerance = I18N
075: .get("org.openjump.core.ui.plugin.tools.ReducePointsISAPlugIn.The-reduce-points-tolerance");
076:
077: private WorkbenchContext workbenchContext;
078: private final static String TOLERANCE = I18N
079: .get("org.openjump.core.ui.plugin.tools.ReducePointsISAPlugIn.Tolerance");;
080: private double tolerance = 0.1;
081: PlugInContext gContext;
082:
083: public void initialize(PlugInContext context) throws Exception {
084: workbenchContext = context.getWorkbenchContext();
085: /*
086: gContext = context;
087: FeatureInstaller featureInstaller = new FeatureInstaller(workbenchContext);
088: JPopupMenu popupMenu = LayerViewPanel.popupMenu();
089: featureInstaller.addPopupMenuItem(popupMenu,
090: this, sSimplifyISA,
091: false, null,
092: this.createEnableCheck(workbenchContext));
093: */
094:
095: context.getFeatureInstaller().addMainMenuItemWithJava14Fix(
096: this ,
097: new String[] { MenuNames.TOOLS,
098: MenuNames.TOOLS_GENERALIZATION }, sSimplifyISA,
099: false, null, this .createEnableCheck(workbenchContext));
100:
101: }
102:
103: public boolean execute(final PlugInContext context)
104: throws Exception {
105: final ArrayList transactions = new ArrayList();
106: reportNothingToUndoYet(context);
107: MultiInputDialog dialog = new MultiInputDialog(context
108: .getWorkbenchFrame(), getName(), true);
109: setDialogValues(dialog, context);
110: dialog.setVisible(true);
111: if (!dialog.wasOKPressed()) {
112: return false;
113: }
114: getDialogValues(dialog);
115:
116: Collection layers = context.getLayerViewPanel()
117: .getSelectionManager().getLayersWithSelectedItems();
118: Collection selectedFeatures = context.getLayerViewPanel()
119: .getSelectionManager().getFeaturesWithSelectedItems();
120: int startNumPts = 0;
121: for (Iterator i = selectedFeatures.iterator(); i.hasNext();) {
122: Geometry geo = ((Feature) i.next()).getGeometry();
123: startNumPts += geo.getNumPoints();
124: }
125:
126: Geometry geo = ((Feature) selectedFeatures.iterator().next())
127: .getGeometry();
128: for (Iterator j = layers.iterator(); j.hasNext();) {
129: Layer layer = (Layer) j.next();
130: transactions.add(createTransaction(layer, tolerance));
131: }
132:
133: EditTransaction.commit(transactions);
134:
135: selectedFeatures = context.getLayerViewPanel()
136: .getSelectionManager().getFeaturesWithSelectedItems();
137: int endNumPts = 0;
138: for (Iterator i = selectedFeatures.iterator(); i.hasNext();) {
139: geo = ((Feature) i.next()).getGeometry();
140: endNumPts += geo.getNumPoints();
141: }
142: context.getWorkbenchFrame().setStatusMessage(
143: sPointsReducedFrom + " " + startNumPts + " " + sTo
144: + " " + endNumPts);
145: return true;
146: }
147:
148: private void setDialogValues(MultiInputDialog dialog,
149: PlugInContext context) {
150: dialog.addLabel(sReducePointsInSelectedFeatures);
151: dialog.addDoubleField(TOLERANCE, tolerance, 6,
152: sTheReducePointsTolerance);
153: }
154:
155: private void getDialogValues(MultiInputDialog dialog) {
156: tolerance = dialog.getDouble(TOLERANCE);
157: }
158:
159: private EditTransaction createTransaction(Layer layer,
160: final double tolerance) {
161: EditTransaction transaction = EditTransaction
162: .createTransactionOnSelection(
163: new EditTransaction.SelectionEditor() {
164: public Geometry edit(
165: Geometry geometryWithSelectedItems,
166: Collection selectedItems) {
167: Geometry geo = reducePoints(
168: geometryWithSelectedItems,
169: tolerance);
170: return geo;
171: }
172: }, workbenchContext.getLayerViewPanel(),
173: workbenchContext.getLayerViewPanel()
174: .getContext(), getName(), layer, false,
175: false);
176: return transaction;
177: }
178:
179: private Geometry reducePoints(Geometry geometry, double tolerance) {
180: if (geometry instanceof GeometryCollection) {
181: GeometryFactory geoFac = geometry.getFactory();
182: GeometryCollection gc = (GeometryCollection) geometry;
183: Geometry[] geos = new Geometry[gc.getNumGeometries()];
184: if (!gc.isEmpty()) {
185: for (int i = 0; i < gc.getNumGeometries(); i++) {
186: geos[i] = reduceGeo(gc.getGeometryN(i), tolerance);
187: }
188: return new GeometryCollection(geos, geoFac);
189: } else {
190: return geometry;
191: }
192: } else {
193: return reduceGeo(geometry, tolerance);
194: }
195: }
196:
197: private Geometry reduceGeo(Geometry geometry, double tolerance) {
198: if (geometry instanceof LineString) //open poly
199: {
200: return GeoUtils.reducePoints(geometry, tolerance);
201: } else if (geometry instanceof LinearRing) //closed poly (no holes)
202: {
203: return GeoUtils.reducePoints(geometry, tolerance);
204: } else if (geometry instanceof Polygon) //poly with 0 or more holes
205: {
206: return GeoUtils.reducePoints(geometry, tolerance);
207: } else if (geometry instanceof MultiLineString) {
208: MultiLineString mls = (MultiLineString) geometry;
209: LineString[] lineStrings = new LineString[mls
210: .getNumGeometries()];
211: GeometryFactory geoFac = geometry.getFactory();
212:
213: if (!mls.isEmpty()) {
214: for (int i = 0; i < mls.getNumGeometries(); i++) {
215: lineStrings[i] = (LineString) GeoUtils
216: .reducePoints(mls.getGeometryN(i),
217: tolerance);
218: }
219: return new MultiLineString(lineStrings, geoFac);
220: } else {
221: return geometry;
222: }
223: } else if (geometry instanceof MultiPolygon) {
224: MultiPolygon mp = (MultiPolygon) geometry;
225: Polygon[] polys = new Polygon[mp.getNumGeometries()];
226: GeometryFactory geoFac = geometry.getFactory();
227: DefaultCoordinateSequenceFactory dcsf = DefaultCoordinateSequenceFactory
228: .instance();
229:
230: if (!mp.isEmpty()) {
231: for (int i = 0; i < mp.getNumGeometries(); i++) {
232: Polygon poly = (Polygon) GeoUtils.reducePoints(mp
233: .getGeometryN(i), tolerance);
234: CoordinateSequence cs = dcsf.create(poly
235: .getCoordinates());
236: polys[i] = new Polygon(new LinearRing(cs, geoFac),
237: null, geoFac);
238: }
239: return new MultiPolygon(polys, geoFac);
240: } else {
241: return geometry;
242: }
243: } else {
244: return geometry;
245: }
246: }
247:
248: public MultiEnableCheck createEnableCheck(
249: final WorkbenchContext workbenchContext) {
250: EnableCheckFactory checkFactory = new EnableCheckFactory(
251: workbenchContext);
252: return new MultiEnableCheck()
253: .add(
254: checkFactory
255: .createWindowWithLayerViewPanelMustBeActiveCheck())
256: .add(
257: checkFactory
258: .createAtLeastNFeaturesMustHaveSelectedItemsCheck(1))
259: .add(
260: checkFactory
261: .createSelectedItemsLayersMustBeEditableCheck());
262: }
263: }
|