Statistics
| Revision:

root / trunk / extensions / extTopology / src / com / iver / cit / gvsig / cad / SplitGeometryCADTool.java @ 26320

History | View | Annotate | Download (10 KB)

1
/*
2
 * Created on 10-abr-2006
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
/* CVS MESSAGES:
45
*
46
* $Id: 
47
* $Log: 
48
*/
49
package com.iver.cit.gvsig.cad;
50

    
51
import java.awt.Graphics;
52
import java.awt.Graphics2D;
53
import java.awt.event.InputEvent;
54
import java.awt.event.MouseEvent;
55
import java.awt.geom.Point2D;
56
import java.util.ArrayList;
57
import java.util.Collections;
58
import java.util.List;
59

    
60
import org.apache.log4j.Logger;
61
import org.gvsig.fmap.core.NewFConverter;
62
import org.gvsig.jts.JtsUtil;
63

    
64
import statemap.State;
65

    
66
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
67
import com.iver.andami.PluginServices;
68
import com.iver.cit.gvsig.cad.sm.SplitGeometryCADToolContext;
69
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
70
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
71
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
72
import com.iver.cit.gvsig.fmap.core.IFeature;
73
import com.iver.cit.gvsig.fmap.core.IGeometry;
74
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
75
import com.iver.cit.gvsig.fmap.edition.DefaultRowEdited;
76
import com.iver.cit.gvsig.fmap.edition.EditionEvent;
77
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
78
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter;
79
import com.iver.cit.gvsig.gui.cad.DefaultCADTool;
80
import com.iver.cit.gvsig.gui.cad.exception.CommandException;
81
import com.iver.cit.gvsig.layers.VectorialLayerEdited;
82

    
83
import com.vividsolutions.jts.geom.Coordinate;
84
import com.vividsolutions.jts.geom.Geometry;
85
import com.vividsolutions.jts.geom.GeometryCollection;
86
import com.vividsolutions.jts.geom.LineString;
87

    
88
/**
89
 * CAD Tool which splits the selected geometries of a vectorial editing
90
 * layer with a digitized polyline.
91
 * 
92
 * 
93
 * @author Alvaro Zabala
94
 *
95
 */
96
public class SplitGeometryCADTool extends DefaultCADTool {
97
        
98
        private static Logger logger = Logger.getLogger(SplitGeometryCADTool.class.getName());
99
        
100
        /**
101
         * String representation of this tool (used for example to active the tool
102
         * in mapcontrol)
103
         */
104
        public static final String SPLIT_GEOMETRY_TOOL_NAME = "_split_geometry";
105

    
106

    
107

    
108
        /**
109
         * finite state machine for this CAD tool
110
         */
111
        protected SplitGeometryCADToolContext _fsm;
112
        
113
        
114
        
115
        /**
116
         * Flag to mark if the digitized line has been finished.
117
         */
118
        protected boolean digitizingFinished = false;
119
        
120
        /**
121
         * Collection of digitized geometries
122
         */
123
        protected List<Point2D> clickedPoints;
124
        
125
        
126
        /**
127
         * Default Constructor
128
         */
129
        public SplitGeometryCADTool(){
130
                
131
        }
132
        
133
        
134
        /**
135
         * Initialization method.
136
         */
137
        public void init() {
138
                digitizingFinished = false;
139
                _fsm = new SplitGeometryCADToolContext(this);
140
                setNextTool(SplitGeometryCADTool.SPLIT_GEOMETRY_TOOL_NAME);
141
        }
142
        
143
        
144

    
145
        public boolean isDigitizingFinished() {
146
                return digitizingFinished;
147
        }
148
        
149
        public String toString() {
150
                return SplitGeometryCADTool.SPLIT_GEOMETRY_TOOL_NAME;
151
        }
152
        
153
        
154
        
155
        public void finishDigitizedLine(){
156
        }
157
        
158
        public ArrayList getSelectedRows(){
159
                return (ArrayList) CADUtil.getSelectedFeatures(getVLE());
160
        }
161
        
162
        public void splitSelectedGeometryWithDigitizedLine(){
163
                Point2D[] clickedPts = new Point2D[this.clickedPoints.size()];
164
                clickedPoints.toArray(clickedPts);
165
                Coordinate[] digitizedCoords = JtsUtil.getPoint2DAsCoordinates(clickedPts);
166
                LineString splittingLs = JtsUtil.GEOMETRY_FACTORY.createLineString(digitizedCoords);
167
                
168
                ArrayList selectedRows = getSelectedRows();
169
//                ArrayList<IRowEdited> splitSelectionGeoms = new
170
//                        ArrayList<IRowEdited>();
171
                IRowEdited editedRow = null;
172
                VectorialLayerEdited vle = getVLE();
173
                VectorialEditableAdapter vea = vle.getVEA();
174
                getCadToolAdapter().getMapControl().getMapContext().beginAtomicEvent();
175
                vea.startComplexRow();
176
                List<Integer> indices = new ArrayList<Integer>();
177
                for (int i = 0; i < selectedRows.size(); i++) {
178
                        editedRow = (IRowEdited) selectedRows.get(i);
179
                        IFeature feat = (IFeature) editedRow.getLinkedRow().cloneRow();
180
                        IGeometry ig = feat.getGeometry();
181
                        Geometry jtsGeo = NewFConverter.toJtsGeometry(ig);
182
                        try {
183
                        Geometry splitGeo = JtsUtil.split(jtsGeo, splittingLs);
184
                        if(splitGeo instanceof GeometryCollection
185
                                        && ((GeometryCollection)splitGeo).getNumGeometries()>1){
186
                                
187
                                //Saving originals polygons index
188
                                indices.add(new Integer(editedRow.getIndex()));
189
                                
190
                                //and then, we add new features for each split geometry
191
                                GeometryCollection gc = (GeometryCollection)splitGeo;
192
                                for(int j = 0; j < gc.getNumGeometries(); j++){
193
                                        Geometry g = gc.getGeometryN(j);
194
                                        IGeometry fmapGeo = NewFConverter.toFMap(g);
195
                                        String newFID = vea.getNewFID();
196
                                        DefaultFeature df = new DefaultFeature(fmapGeo, feat.getAttributes(), newFID);
197
                                        int newIdx = CADUtil.addFeature(vle, df, getName());
198
                                        
199
//                                        DefaultRowEdited newRowEdited = new DefaultRowEdited(df,
200
//                                                                IRowEdited.STATUS_ADDED, 
201
//                                                                        newIdx);
202
//                                        splitSelectionGeoms.add(newRowEdited);
203
                                }//for j
204
                        }//if splitGeo
205
                        } catch (Exception ex) {
206
                                PluginServices.getLogger().error("Error splitting geom "+editedRow.getIndex(), ex);
207
                        }
208
                }
209
                
210
                // Vector index ordered highest to lowest
211
                Collections.sort(indices, Collections.reverseOrder());
212
                // Clear polygon erasing their lines in the table
213
                for(int i = 0; i< indices.size();i++) {
214
                        
215
                        try {
216
                                vea.removeRow(((Integer)indices.get(i)).intValue(), 
217
                                                PluginServices.getText(this,"deleted_feature"),
218
                                                EditionEvent.GRAPHIC);
219
                        } catch (ExpansionFileReadException e) {
220
                                logger.error("Error ExpansionFileReadException en la funcion split");
221
                        } catch (ReadDriverException e) {
222
                                logger.error("Error ReadDriverException en la funcion split");
223
                        }
224
                }
225
                vea.endComplexRow(getName());
226
                try {
227
                        vle.clearSelection(false);
228
                } catch (ReadDriverException e) {
229
                        PluginServices.getLogger().error("Error clearing selection", e);
230
                }
231
                getCadToolAdapter().getMapControl().getMapContext().endAtomicEvent();
232
        }
233
                
234
        public void end(){
235
                getCadToolAdapter().refreshEditedLayer();
236
                init();
237
        }
238
        
239
        
240
        public void addOption(String s) {
241
                State actualState = _fsm.getPreviousState();
242
                String status = actualState.getName();
243
                if (s.equals(PluginServices.getText(this, "cancel"))) {
244
                        init();
245
                        return;
246
                }
247
                if (status.equals("TopologicalEdition.FirstPoint")) {
248
                        return;
249
                }
250
                init();
251

    
252
        }
253

    
254
        public void addPoint(double x, double y, InputEvent event) {
255
                
256
                State actualState = _fsm.getPreviousState();
257
                String status = actualState.getName();
258
                if (status.equals("SplitGeometry.FirstPoint")) {
259
                        clickedPoints = new ArrayList<Point2D>();
260
                        clickedPoints.add(new Point2D.Double(x,y));
261
                } else if (status.equals("SplitGeometry.DigitizingLine")) {
262
                        clickedPoints.add(new Point2D.Double(x,y));
263
                        if (event != null && ((MouseEvent) event).getClickCount() == 2) {
264
                                digitizingFinished = true;
265
                                finishDigitizedLine();
266
                                splitSelectedGeometryWithDigitizedLine();
267
                                end();
268
                        }
269
                }
270
        }
271

    
272
        public void addValue(double d) {
273
        }
274
        
275
        
276
        /**
277
         * Draws a polyline with the clicked digitized points in the specified graphics.
278
         * 
279
         * @param g2 graphics on to draw the polyline
280
         * @param x last x mouse pointer position
281
         * @param y last y mouse pointer position
282
         */
283
        protected void drawPolyLine(Graphics2D g, double x, double y) {
284
                GeneralPathX gpx = 
285
                        new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, 
286
                                                                        clickedPoints.size());
287
                Point2D firstPoint = clickedPoints.get(0);
288
                gpx.moveTo(firstPoint.getX(), firstPoint.getY());
289
                for (int i = 1; i < clickedPoints.size(); i++) {
290
                        Point2D clickedPoint = clickedPoints.get(i);
291
                        gpx.lineTo(clickedPoint.getX(), clickedPoint.getY());
292
                        
293
                }
294
                gpx.lineTo(x, y);
295
                ShapeFactory.createPolyline2D(gpx).draw((Graphics2D) g,
296
                                        getCadToolAdapter().getMapControl().getViewPort(),
297
                                        DefaultCADTool.geometrySelectSymbol);
298
        }
299

    
300
        
301
        
302
        
303
        public void drawOperation(Graphics g, double x, double y) {
304
                State actualState = _fsm.getState();
305
        String status = actualState.getName();
306

    
307
        if (status.equals("SplitGeometry.FirstPoint") ) {
308
                return;
309
        } else if ((status.equals("SplitGeometry.DigitizingLine"))) {
310
                drawPolyLine((Graphics2D) g, x, y);
311
         }
312
//        else{
313
//                        try {
314
//                                Image imgSel = getVLE().getSelectionImage();
315
//                                if (imgSel != null)
316
//                                        g.drawImage(imgSel, 0, 0, null);
317
//                        } catch (Exception e) {
318
//                                e.printStackTrace();
319
//                        }
320
//         }
321
        }
322

    
323
        public String getName() {
324
                return PluginServices.getText(this, SPLIT_GEOMETRY_TOOL_NAME);
325
        }
326

    
327
        
328
        public void transition(double x, double y, InputEvent event) {
329
                try {
330
                        _fsm.addPoint(x, y, event);
331
                } catch (Exception e) {
332
                        init();
333
                }
334

    
335
        }
336
        
337

    
338
        public void transition(double d) {
339
                _fsm.addValue(d);
340
        }
341

    
342
        public void transition(String s) throws CommandException {
343
                if (!super.changeCommand(s)) {
344
                        _fsm.addOption(s);
345
                }
346
        }
347
        
348
}