001: package net.refractions.udig.tools.edit.commands;
002:
003: import java.util.ArrayList;
004: import java.util.List;
005:
006: import net.refractions.udig.project.ILayer;
007: import net.refractions.udig.project.command.AbstractCommand;
008: import net.refractions.udig.project.command.UndoableComposite;
009: import net.refractions.udig.project.command.UndoableMapCommand;
010: import net.refractions.udig.project.internal.ProjectPlugin;
011: import net.refractions.udig.project.ui.render.displayAdapter.MapMouseEvent;
012: import net.refractions.udig.project.ui.tool.IToolContext;
013: import net.refractions.udig.tool.edit.internal.Messages;
014: import net.refractions.udig.tools.edit.EditPlugin;
015: import net.refractions.udig.tools.edit.EditToolHandler;
016: import net.refractions.udig.tools.edit.support.EditBlackboard;
017:
018: import org.eclipse.core.runtime.IProgressMonitor;
019: import org.geotools.data.FeatureSource;
020: import org.geotools.data.FeatureStore;
021: import org.geotools.feature.Feature;
022: import org.geotools.feature.FeatureCollection;
023: import org.geotools.feature.FeatureIterator;
024: import org.geotools.filter.BBoxExpression;
025: import org.geotools.filter.Filter;
026: import org.geotools.filter.FilterFactory;
027: import org.geotools.filter.FilterFactoryFinder;
028: import org.geotools.filter.FilterType;
029: import org.geotools.filter.GeometryFilter;
030: import org.geotools.geometry.jts.JTS;
031: import org.geotools.geometry.jts.ReferencedEnvelope;
032: import org.opengis.referencing.operation.MathTransform;
033:
034: import com.vividsolutions.jts.geom.Envelope;
035: import com.vividsolutions.jts.geom.Geometry;
036:
037: /**
038: * Adds any geometries containing the given point which are not already on the edit blackboard.
039: *
040: * @author chorner
041: * @since 1.1.0
042: */
043: public class AddMissingGeomsCommand extends AbstractCommand implements
044: UndoableMapCommand {
045:
046: private EditToolHandler handler;
047: private Class[] acceptableClasses;
048: private boolean onlyAdd;
049: private MapMouseEvent event;
050: private short filterType;
051:
052: private UndoableMapCommand command;
053:
054: public AddMissingGeomsCommand(EditToolHandler handler,
055: MapMouseEvent e, Class[] acceptableClasses,
056: short filterType, boolean onlyAdd) {
057: this .handler = handler;
058: this .event = e;
059: Class[] c = new Class[0];
060: if (acceptableClasses != null) {
061: c = new Class[acceptableClasses.length];
062: System.arraycopy(acceptableClasses, 0, c, 0, c.length);
063: }
064: this .acceptableClasses = c;
065:
066: this .filterType = filterType;
067: this .onlyAdd = onlyAdd;
068: }
069:
070: public void run(IProgressMonitor monitor) throws Exception {
071: if (command == null) {
072: EditBlackboard editBlackboard = handler
073: .getEditBlackboard(handler.getEditLayer());
074: editBlackboard.startBatchingEvents();
075: try {
076: Feature feature = null;
077: ILayer editLayer = handler.getEditLayer();
078: try {
079: FeatureStore store = editLayer.getResource(
080: FeatureStore.class, null);
081: ReferencedEnvelope bbox = handler.getContext()
082: .getBoundingBox(event.getPoint(), 7);
083: Filter createBBoxFilter = createBBoxFilter(bbox,
084: editLayer, filterType);
085: FeatureCollection collection = store
086: .getFeatures(createBBoxFilter);
087: FeatureIterator reader = collection.features();
088: try {
089: boolean hasFeature = false;
090: try {
091: hasFeature = reader.hasNext();
092: } catch (Exception e) {
093: reader.close();
094: createBBoxFilter = createBBoxFilter(bbox,
095: editLayer, FilterType.GEOMETRY_BBOX);
096: collection = store
097: .getFeatures(createBBoxFilter);
098: reader = collection.features();
099: hasFeature = reader.hasNext();
100: }
101: if (hasFeature) {
102: List<UndoableMapCommand> commands = new ArrayList<UndoableMapCommand>();
103: while (reader.hasNext()) {
104: feature = reader.next();
105: for (Class<Geometry> clazz : acceptableClasses) {
106: if (onlyAdd
107: || handler.getCurrentGeom() != null
108: && (event.isShiftDown() || event
109: .isControlDown())) {
110: setAndRun(monitor,
111: new AddGeomCommand(
112: handler,
113: feature, null));
114: } else {
115: if (clazz
116: .isAssignableFrom(feature
117: .getDefaultGeometry()
118: .getClass())) {
119: if (!editBlackboard
120: .contains(feature
121: .getID())) {
122: commands
123: .add(new AddGeomCommand(
124: handler,
125: feature,
126: null));
127: EditPlugin
128: .trace(
129: EditPlugin.SELECTION,
130: "Feature is one of the acceptable classes " + feature.getID(), null); //$NON-NLS-1$
131: }
132: } else {
133: EditPlugin
134: .trace(
135: EditPlugin.SELECTION,
136: "Feature is not one of the acceptable classes " + feature.getID(), null); //$NON-NLS-1$
137: }
138: }
139: }
140: }
141: UndoableComposite undoableComposite = new UndoableComposite(
142: commands);
143: undoableComposite
144: .setName(Messages.AddMissingGeomsCommand_name);
145: setAndRun(monitor, undoableComposite);
146: }
147: } finally {
148: collection.close(reader);
149: }
150: } catch (Exception e2) {
151: EditPlugin.log("", e2); //$NON-NLS-1$
152: }
153: } finally {
154: editBlackboard.fireBatchedEvents();
155: }
156: } else {
157: command.run(monitor);
158: }
159: }
160:
161: public String getName() {
162: return Messages.AddMissingGeomsCommand_name;
163: }
164:
165: public void rollback(IProgressMonitor monitor) throws Exception {
166: command.rollback(monitor);
167: }
168:
169: /**
170: * Creates A geometry filter for the given layer.
171: *
172: * @param boundingBox in the same crs as the viewport model.
173: * @return a Geometry filter in the correct CRS or null if an exception occurs.
174: */
175: public Filter createBBoxFilter(Envelope boundingBox, ILayer layer,
176: short filterType) {
177: FilterFactory factory = FilterFactoryFinder
178: .createFilterFactory();
179: GeometryFilter bboxFilter = null;
180: if (!layer.hasResource(FeatureSource.class))
181: return Filter.ALL;
182: try {
183:
184: Envelope bbox;
185: try {
186: MathTransform transform = layer.mapToLayerTransform();
187: bbox = JTS.transform(boundingBox, transform);
188: } catch (Exception e) {
189: bbox = boundingBox;
190: }
191: BBoxExpression bb = factory.createBBoxExpression(bbox);
192: bboxFilter = factory.createGeometryFilter(filterType);
193: bboxFilter.addRightGeometry(bb);
194:
195: String geom = layer.getSchema().getDefaultGeometry()
196: .getName();
197:
198: bboxFilter.addLeftGeometry(factory
199: .createAttributeExpression(geom));
200: } catch (Exception e) {
201: ProjectPlugin.getPlugin().log(e);
202: }
203: return bboxFilter;
204: }
205:
206: private void setAndRun(IProgressMonitor monitor,
207: UndoableMapCommand undoableComposite) throws Exception {
208: command = undoableComposite;
209: command.setMap(getMap());
210: command.run(monitor);
211: }
212: }
|