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.commands;
016:
017: import java.io.IOException;
018: import java.util.Collections;
019: import java.util.HashSet;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Set;
023:
024: import net.refractions.udig.core.IBlockingProvider;
025: import net.refractions.udig.project.ILayer;
026: import net.refractions.udig.project.command.AbstractCommand;
027: import net.refractions.udig.project.command.MapCommand;
028: import net.refractions.udig.project.command.UndoableCommand;
029: import net.refractions.udig.tool.edit.internal.Messages;
030: import net.refractions.udig.tools.edit.EditToolHandler;
031: import net.refractions.udig.tools.edit.support.EditBlackboard;
032: import net.refractions.udig.tools.edit.support.EditGeom;
033: import net.refractions.udig.tools.edit.support.GeometryCreationUtil;
034: import net.refractions.udig.tools.edit.support.Point;
035: import net.refractions.udig.tools.edit.support.PrimitiveShape;
036: import net.refractions.udig.tools.edit.support.ShapeType;
037:
038: import org.eclipse.core.runtime.IProgressMonitor;
039: import org.eclipse.core.runtime.SubProgressMonitor;
040: import org.geotools.data.FeatureStore;
041: import org.geotools.feature.Feature;
042: import org.geotools.feature.IllegalAttributeException;
043: import org.geotools.feature.collection.AbstractFeatureCollection;
044: import org.geotools.filter.FidFilter;
045: import org.geotools.filter.Filter;
046: import org.geotools.filter.FilterFactory;
047: import org.geotools.filter.FilterFactoryFinder;
048:
049: import com.vividsolutions.jts.geom.Coordinate;
050: import com.vividsolutions.jts.geom.Geometry;
051: import com.vividsolutions.jts.geom.GeometryFactory;
052: import com.vividsolutions.jts.geom.LineString;
053: import com.vividsolutions.jts.geom.MultiLineString;
054:
055: /**
056: * Splits a line at the selected Vertices.
057: *
058: * @author Jesse
059: * @since 1.1.0
060: */
061: public class SplitLineCommand extends AbstractCommand implements
062: MapCommand, UndoableCommand {
063:
064: private EditBlackboard editBlackboard;
065: private IBlockingProvider<PrimitiveShape> shapeProvider;
066: private Set<Point> points;
067: private PrimitiveShape oldshape;
068: private IBlockingProvider<Feature> featureProvider;
069: private IBlockingProvider<ILayer> layerProvider;
070: private Feature oldFeature;
071: private ILayer layer;
072: private Set<String> newFids = new HashSet<String>();
073: private boolean currentShapeSet = false;
074: private Geometry oldGeometry;
075: private EditGeom first;
076:
077: /**
078: * New instance
079: *
080: * @param editBlackboard the blackboard that the feature is on.
081: * @param provider the
082: * @param feature
083: * @param evaluationObject
084: * @param points
085: */
086: public SplitLineCommand(EditBlackboard editBlackboard,
087: IBlockingProvider<PrimitiveShape> provider,
088: IBlockingProvider<Feature> featureProvider,
089: IBlockingProvider<ILayer> layerProvider, Set<Point> points) {
090: this .editBlackboard = editBlackboard;
091: this .shapeProvider = provider;
092: this .layerProvider = layerProvider;
093: this .featureProvider = featureProvider;
094: this .points = points;
095: }
096:
097: public void run(IProgressMonitor monitor) throws Exception {
098: editBlackboard.startBatchingEvents();
099:
100: oldshape = shapeProvider
101: .get(new SubProgressMonitor(monitor, 1));
102: oldFeature = featureProvider.get(new SubProgressMonitor(
103: monitor, 1));
104: oldGeometry = oldFeature.getDefaultGeometry();
105: layer = layerProvider.get(new SubProgressMonitor(monitor, 1));
106:
107: editBlackboard.removeGeometries(Collections.singleton(oldshape
108: .getEditGeom()));
109: ShapeType shapeType = oldshape.getEditGeom().getShapeType();
110: EditGeom current = editBlackboard.newGeom(oldshape
111: .getEditGeom().getFeatureIDRef().get(), shapeType);
112: first = current;
113:
114: final Set<EditGeom> addedGeoms = new HashSet<EditGeom>();
115: for (int i = 0; i < oldshape.getNumPoints(); i++) {
116: addCoords(current.getShell(), i);
117: if (current.getShell().getNumPoints() > 1
118: && i < oldshape.getNumPoints() - 1
119: && points.contains(oldshape.getPoint(i))) {
120:
121: current = editBlackboard
122: .newGeom(
123: "newFeature" + System.currentTimeMillis(), shapeType); //$NON-NLS-1$
124: List<Coordinate> coords = oldshape.getCoordsAt(i);
125: editBlackboard.addCoordinate(coords
126: .get(coords.size() - 1), current.getShell());
127: addedGeoms.add(current);
128: }
129: }
130:
131: editBlackboard.removeGeometries(addedGeoms);
132:
133: if (getCurrentShape() == oldshape) {
134: currentShapeSet = true;
135: setCurrentShape(first.getShell());
136: }
137:
138: final FeatureStore store = layer.getResource(
139: FeatureStore.class, new SubProgressMonitor(monitor, 1));
140:
141: modifyOldFeature(store);
142:
143: createAndAddFeatures(addedGeoms, store);
144:
145: editBlackboard.fireBatchedEvents();
146: }
147:
148: @SuppressWarnings({"unchecked"})
149: private void modifyOldFeature(final FeatureStore store)
150: throws IOException, IllegalAttributeException {
151: FilterFactory fac = FilterFactoryFinder.createFilterFactory();
152: Filter filter = fac.createFidFilter(oldFeature.getID());
153:
154: Geometry g = GeometryCreationUtil.createGeom(LineString.class,
155: first.getShell());
156: if (store.getSchema().getDefaultGeometry().getType()
157: .isAssignableFrom(MultiLineString.class))
158: g = new GeometryFactory()
159: .createMultiLineString(new LineString[] { (LineString) g });
160:
161: store.modifyFeatures(store.getSchema().getDefaultGeometry(), g,
162: filter);
163: oldFeature.setDefaultGeometry(g);
164: }
165:
166: /**
167: *
168: * @param addedGeoms
169: * @param store
170: * @throws IOException
171: */
172: @SuppressWarnings("unchecked")
173: private void createAndAddFeatures(final Set<EditGeom> addedGeoms,
174: final FeatureStore store) throws IOException {
175: newFids = store.addFeatures(new AbstractFeatureCollection(store
176: .getSchema()) {
177:
178: @Override
179: public int size() {
180: return addedGeoms.size() - 1;
181: }
182:
183: @Override
184: protected Iterator openIterator() {
185: final Iterator<EditGeom> iter = addedGeoms.iterator();
186: return new Iterator() {
187: GeometryFactory factory = new GeometryFactory();
188:
189: public boolean hasNext() {
190: return iter.hasNext();
191: }
192:
193: @SuppressWarnings("unchecked")
194: public Object next() {
195: Object[] attrs = oldFeature
196: .getAttributes(new Object[store
197: .getSchema()
198: .getAttributeCount()]);
199: try {
200: Feature feature = store.getSchema().create(
201: attrs);
202: Geometry geom = GeometryCreationUtil
203: .createGeom(LineString.class, iter
204: .next().getShell());
205: if (getSchema().getDefaultGeometry()
206: .getType().isAssignableFrom(
207: MultiLineString.class))
208: geom = factory
209: .createMultiLineString(new LineString[] { (LineString) geom });
210: feature.setDefaultGeometry(geom);
211: return feature;
212: } catch (IllegalAttributeException e) {
213: throw (RuntimeException) new RuntimeException()
214: .initCause(e);
215: }
216: }
217:
218: public void remove() {
219: }
220:
221: };
222: }
223:
224: @Override
225: protected void closeIterator(Iterator close) {
226: }
227:
228: });
229: }
230:
231: private void setCurrentShape(PrimitiveShape shape) {
232: getMap().getBlackboard().put(EditToolHandler.CURRENT_SHAPE,
233: shape);
234: }
235:
236: private PrimitiveShape getCurrentShape() {
237: return (PrimitiveShape) getMap().getBlackboard().get(
238: EditToolHandler.CURRENT_SHAPE);
239: }
240:
241: private void addCoords(PrimitiveShape current, int i) {
242: List<Coordinate> coords = oldshape.getCoordsAt(i);
243: for (Coordinate coordinate : coords) {
244: editBlackboard.addCoordinate(coordinate, current);
245: }
246: }
247:
248: public String getName() {
249: return Messages.SplitLineCommand_name;
250: }
251:
252: public void rollback(IProgressMonitor monitor) throws Exception {
253: editBlackboard.removeGeometries(Collections.singleton(first));
254:
255: EditGeom newGeom = editBlackboard.newGeom(oldshape
256: .getEditGeom().getFeatureIDRef().get(), oldshape
257: .getEditGeom().getShapeType());
258:
259: for (int i = 0; i < oldshape.getNumCoords(); i++) {
260: editBlackboard.addCoordinate(oldshape.getCoord(i), newGeom
261: .getShell());
262: }
263:
264: if (currentShapeSet)
265: setCurrentShape(newGeom.getShell());
266:
267: FeatureStore store = layer.getResource(FeatureStore.class,
268: new SubProgressMonitor(monitor, 1));
269: FilterFactory filterFac = FilterFactoryFinder
270: .createFilterFactory();
271: FidFilter filter = filterFac.createFidFilter();
272: filter.addAllFids(newFids);
273: store.removeFeatures(filter);
274: store.modifyFeatures(store.getSchema().getDefaultGeometry(),
275: oldFeature.getDefaultGeometry(), filterFac
276: .createFidFilter(oldFeature.getID()));
277: oldFeature.setDefaultGeometry(oldGeometry);
278: newFids.clear();
279: }
280:
281: }
|