Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extTopology / src / com / iver / cit / gvsig / cad / SplitGeometryCADTool.java @ 21266

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.Image;
54
import java.awt.event.InputEvent;
55
import java.awt.event.MouseEvent;
56
import java.awt.geom.Point2D;
57
import java.util.ArrayList;
58
import java.util.List;
59

    
60
import org.gvsig.jts.JtsUtil;
61

    
62
import statemap.State;
63

    
64
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
65
import com.iver.andami.PluginServices;
66
import com.iver.cit.gvsig.cad.sm.SplitGeometryCADToolContext;
67
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
68
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileWriteException;
69
import com.iver.cit.gvsig.exceptions.validate.ValidateRowException;
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.core.v02.FConverter;
76
import com.iver.cit.gvsig.fmap.edition.DefaultRowEdited;
77
import com.iver.cit.gvsig.fmap.edition.EditionEvent;
78
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
79
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter;
80
import com.iver.cit.gvsig.fmap.layers.FBitSet;
81
import com.iver.cit.gvsig.gui.cad.DefaultCADTool;
82
import com.iver.cit.gvsig.gui.cad.exception.CommandException;
83
import com.iver.cit.gvsig.layers.VectorialLayerEdited;
84
import com.vividsolutions.jts.geom.Coordinate;
85
import com.vividsolutions.jts.geom.Geometry;
86
import com.vividsolutions.jts.geom.GeometryCollection;
87
import com.vividsolutions.jts.geom.LineString;
88

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

    
104

    
105

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

    
143
        public boolean isDigitizingFinished() {
144
                return digitizingFinished;
145
        }
146
        
147
        public String toString() {
148
                return SplitGeometryCADTool.SPLIT_GEOMETRY_TOOL_NAME;
149
        }
150
        
151
        
152
        
153
        public void finishDigitizedLine(){
154
        }
155
        
156
        public ArrayList getSelectedRows(){
157
                ArrayList selection = super.getSelectedRows();
158
                if(selection != null ){
159
                        if( selection.size() == 0){
160
                                VectorialEditableAdapter vea = getVLE().getVEA();
161
                                try {
162
                                        FBitSet bitset = vea.getSelection();
163
                                        for (int j = bitset.nextSetBit(0);j >= 0;j = bitset.nextSetBit(j + 1)){
164
                                                IRowEdited rowEd =vea.getRow(j);
165
                                                selection.add(rowEd);
166
                                        }
167
                                } catch (ExpansionFileReadException e) {
168
                                        e.printStackTrace();
169
                                } catch (ReadDriverException e) {
170
                                        e.printStackTrace();
171
                                }
172
                        }//selection size
173
                }
174
                return selection;
175
        }
176
        
177
        public void splitSelectedGeometryWithDigitizedLine(){
178
                Point2D[] clickedPts = new Point2D[this.clickedPoints.size()];
179
                clickedPoints.toArray(clickedPts);
180
                Coordinate[] digitizedCoords = JtsUtil.getPoint2DAsCoordinates(clickedPts);
181
                LineString splittingLs = JtsUtil.GEOMETRY_FACTORY.createLineString(digitizedCoords);
182
                
183
                
184
                ArrayList selectedRows = getSelectedRows();
185
                ArrayList<IRowEdited> splittedSelectionGeoms = new
186
                        ArrayList<IRowEdited>();
187
                IRowEdited editedRow = null;
188
                VectorialLayerEdited vle = getVLE();
189
                VectorialEditableAdapter vea = vle.getVEA();
190
//                vea.startComplexRow();
191
                for (int i = 0; i < selectedRows.size(); i++) {
192
                        editedRow = (IRowEdited) selectedRows.get(i);
193
                        IFeature feat = (IFeature) editedRow.getLinkedRow().cloneRow();
194
                        IGeometry ig = feat.getGeometry();
195
                        Geometry jtsGeo = ig.toJTSGeometry();
196
                        Geometry splittedGeo = JtsUtil.split(jtsGeo, splittingLs);
197
                        if(splittedGeo instanceof GeometryCollection){
198
                                //first of all we delete the existing geometry
199
                                try {
200
                                        vea.removeRow(editedRow.getIndex(), 
201
                                                        PluginServices.getText(this,"deleted_feature"),
202
                                                        EditionEvent.GRAPHIC);
203
                                        
204
                                        //and then, we add new features for each splitted geometry
205
                                        GeometryCollection gc = (GeometryCollection)splittedGeo;
206
                                        for(int j = 0; j < gc.getNumGeometries(); j++){
207
                                                Geometry g = gc.getGeometryN(j);
208
                                                System.out.println("g"+j+":"+g.toText());
209
                                                IGeometry fmapGeo = FConverter.jts_to_igeometry(g);
210
                                                DefaultFeature newFeature = new DefaultFeature(fmapGeo, feat.getAttributes(), vea.getNewFID());
211
                                                int calculatedIndex = vea.addRow(newFeature, getName(), EditionEvent.GRAPHIC);
212
                                                
213
                                                DefaultRowEdited newRowEdited = new DefaultRowEdited(newFeature,
214
                                                                                                                IRowEdited.STATUS_ADDED, 
215
                                                                                                                        calculatedIndex);
216
                                                splittedSelectionGeoms.add(newRowEdited);
217
                                        }//for j
218
                                } catch (ExpansionFileReadException e) {
219
                                        e.printStackTrace();
220
                                } catch (ExpansionFileWriteException e) {
221
                                        e.printStackTrace();
222
                                } catch (ReadDriverException e) {
223
                                        e.printStackTrace();
224
                                } catch (ValidateRowException e) {
225
                                        e.printStackTrace();
226
                                }
227
                        }//if splittedGeo
228
                }
229
//                vea.endComplexRow(description);
230
//                vle.setSelectionCache(VectorialLayerEdited.SAVEPREVIOUS,
231
//                                splittedSelectionGeoms);
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
}