Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGraph / src / org / gvsig / graph / TinExtension.java @ 22687

History | View | Annotate | Download (12.4 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22

    
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2008 Software Colaborativo (www.scolab.es)   development
26
*/
27
 
28
package org.gvsig.graph;
29

    
30
import java.awt.Component;
31
import java.io.File;
32
import java.sql.Types;
33
import java.util.ArrayList;
34
import java.util.Arrays;
35
import java.util.Collection;
36

    
37
import javax.swing.JOptionPane;
38

    
39
import org.gvsig.exceptions.BaseException;
40
import org.gvsig.fmap.algorithm.contouring.ContourCalculator;
41
import org.gvsig.fmap.algorithm.triangulation.PirolTriangulator;
42
import org.gvsig.fmap.algorithm.triangulation.TIN;
43
import org.gvsig.fmap.algorithm.triangulation.Triangle;
44
import org.gvsig.fmap.algorithm.triangulation.Vertex;
45
import org.gvsig.fmap.algorithm.triangulation.WatsonTriangulator;
46
import org.gvsig.graph.core.NetworkUtils;
47
import org.gvsig.gui.beans.swing.JFileChooser;
48

    
49
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
50
import com.hardcode.gdbms.engine.values.NumericValue;
51
import com.hardcode.gdbms.engine.values.Value;
52
import com.hardcode.gdbms.engine.values.ValueFactory;
53
import com.iver.andami.PluginServices;
54
import com.iver.andami.plugins.Extension;
55
import com.iver.andami.ui.mdiManager.IWindow;
56
import com.iver.cit.gvsig.fmap.MapContext;
57
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
58
import com.iver.cit.gvsig.fmap.core.FMultiPoint2D;
59
import com.iver.cit.gvsig.fmap.core.FPoint2D;
60
import com.iver.cit.gvsig.fmap.core.FShape;
61
import com.iver.cit.gvsig.fmap.core.IFeature;
62
import com.iver.cit.gvsig.fmap.core.IGeometry;
63
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
64
import com.iver.cit.gvsig.fmap.drivers.ConcreteMemoryDriver;
65
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
66
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition;
67
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
68
import com.iver.cit.gvsig.fmap.drivers.shp.IndexedShpDriver;
69
import com.iver.cit.gvsig.fmap.edition.DefaultRowEdited;
70
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
71
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter;
72
import com.iver.cit.gvsig.fmap.layers.FLayer;
73
import com.iver.cit.gvsig.fmap.layers.FLayers;
74
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
75
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
76
import com.iver.cit.gvsig.fmap.layers.LayersIterator;
77
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
78
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
79
import com.iver.cit.gvsig.project.documents.view.gui.View;
80
import com.iver.utiles.GenericFileFilter;
81
import com.vividsolutions.jts.geom.CoordinateList;
82
import com.vividsolutions.jts.geom.Geometry;
83
import com.vividsolutions.jts.geom.GeometryFactory;
84
import com.vividsolutions.jts.geom.LineString;
85
import com.vividsolutions.jts.geom.LinearRing;
86
import com.vividsolutions.jts.geom.Polygon;
87
import com.vividsolutions.jts.operation.polygonize.Polygonizer;
88

    
89
public class TinExtension extends Extension {
90
        
91
        private static String     lastPath        = null;
92
        private PluginServices ps=PluginServices.getPluginServices(this);
93

    
94
        private ArrayList<FLyrVect> pointLayers = null;
95
        
96
        public void execute(String actionCommand) {
97
                for (FLyrVect lyr : pointLayers) {
98
                        try {
99
                                doTIN(lyr);
100
                        } catch (BaseException e) {
101
                                // TODO Auto-generated catch block
102
                                e.printStackTrace();
103
                        }
104
                }
105

    
106
        }
107
        
108
        private void doTIN(FLyrVect lyrVect) throws BaseException {
109
                ReadableVectorial rv = lyrVect.getSource();
110
                
111
                JFileChooser fileChooser = new JFileChooser("OPEN_LAYER_FILE_CHOOSER_ID", lastPath);
112
                fileChooser.setFileFilter(new GenericFileFilter(".shp", "Shape files", true));
113
                fileChooser.setMultiSelectionEnabled(false);
114
                fileChooser.setDialogTitle(ps.getText("choose_file_to_save_triangles"));
115
                int result = fileChooser.showSaveDialog((Component) PluginServices.getMDIManager().getActiveWindow());
116
                if (result == JFileChooser.CANCEL_OPTION)
117
                        return;
118
                File triShpFile = fileChooser.getSelectedFile();
119
                
120

    
121
//                fileChooser.setDialogTitle(PluginServices.getPluginServices(TinExtension.class)
122
//                                .getText("choose_file_to_save_contours"));
123
//                result = fileChooser.showSaveDialog((Component) PluginServices.getMDIManager());
124
//                if (result == JFileChooser.CANCEL_OPTION)
125
//                        return;
126
//                File contourShpFile = fileChooser.getSelectedFile();
127
                SelectableDataSource rs = lyrVect.getRecordset();
128
                String[] selecValues = rs.getFieldNames();
129
                String strField = (String) JOptionPane.showInputDialog(null, "choose_field", "choose_field", JOptionPane.QUESTION_MESSAGE, null, selecValues, null);
130
                
131
                int idField = rs.getFieldIndexByName(strField);
132
                String aux = JOptionPane.showInputDialog("input_contour_desired_heights_separated_by_commas (;)");
133
                if (aux == null)
134
                        return;
135
                double[] heights = NetworkUtils.string2doubleArray(aux, ";");
136
                Arrays.sort(heights);
137

    
138
                ShpWriter triShpWriter = createShapeTriangles(triShpFile);
139
//                ShpWriter contourShpWriter = createShapeContours(triShpFile);
140
                
141
                long t1 = System.currentTimeMillis();
142
                WatsonTriangulator triangulator = new WatsonTriangulator();
143
//                ChewTriangulator triangulator = new ChewTriangulator();
144
//                PirolTriangulator triangulator = new PirolTriangulator();
145
                rv.start();
146
                for (int i=0; i < rv.getShapeCount(); i++) {
147
                        IFeature feat = rv.getFeature(i);
148
                        IGeometry geom = feat.getGeometry();
149
                        Object shp = geom.getInternalShape();
150
                        if (shp instanceof FPoint2D)
151
                        {
152
                                FPoint2D p = (FPoint2D) geom.getInternalShape();
153
                                NumericValue val = (NumericValue) feat.getAttribute(idField);
154
                                triangulator.addVertex(new Vertex(p.getX(), p.getY(), val.doubleValue()));
155
                        }
156
                        if (shp instanceof FMultiPoint2D)
157
                        {
158
                                FMultiPoint2D multi = (FMultiPoint2D) shp;
159
                                for (int j=0; j < multi.getNumPoints(); j++) {
160
                                        FPoint2D p = multi.getPoint(j);
161
                                        NumericValue val = (NumericValue) feat.getAttribute(idField);
162
                                        triangulator.addVertex(new Vertex(p.getX(), p.getY(), val.doubleValue()));
163
                                }
164
                        }
165
                        
166
                }
167
                rv.stop();
168
                
169
                TIN tin = triangulator.calculateTriangulation();
170
                
171
                
172
                GeometryFactory geomFact = new GeometryFactory();
173
                
174
                View view = (View) PluginServices.getMDIManager().getActiveWindow();
175
                MapContext mapContext = view.getMapControl().getMapContext();
176
//                GraphicLayer graphicLayer = view.getMapControl().getMapContext().getGraphicsLayer();
177
//                FSymbol symbol = new FSymbol(FShape.LINE);
178
//                int idSym = graphicLayer.addSymbol(symbol);
179
                
180
                ConcreteMemoryDriver memDriver = new ConcreteMemoryDriver();
181
                ArrayList<String> arrayFields = new ArrayList<String>();
182
                arrayFields.add("ID");
183
                arrayFields.add("VALUE");
184

    
185
                memDriver.getTableModel().setColumnIdentifiers(arrayFields.toArray());
186

    
187
//                memDriver.getf
188
                memDriver.setShapeType(FShape.LINE);
189
                
190
                int i = 0;
191
                ContourCalculator contourCalculator = new ContourCalculator(tin);
192
                for (int indexContour = 0; indexContour < heights.length; indexContour++) {                        
193
                        double height = heights[indexContour];
194
                        Collection<LineString> contour = contourCalculator.getContour(height);
195

    
196
                        Geometry seqGeom = contourCalculator.getContourPolygon(contour);
197
                        IGeometry geom = FConverter.jts_to_igeometry(seqGeom);
198
                        Value[] row = new Value[2];
199
                        row[0] = ValueFactory.createValue(i++);
200
                        row[1] = ValueFactory.createValue(height);
201
                        memDriver.addGeometry(geom, row);
202
                        
203
                        Polygonizer pol = new Polygonizer();
204
                        pol.add(contour);
205
                        Collection<Polygon> polygons = pol.getPolygons();
206
                        
207
                        for (Polygon p : polygons) {                                
208
                                geom = FConverter.jts_to_igeometry(p);
209
                                row = new Value[2];
210
                                row[0] = ValueFactory.createValue(i++);
211
                                row[1] = ValueFactory.createValue(height);
212
                                memDriver.addGeometry(geom, row);
213
                                
214
        //                        FGraphic graf = new FGraphic(geom, idSym);
215
        //                        graphicLayer.addGraphic(graf);
216
                        }
217
                } // indexContour
218
                FLayer lyrContour = LayerFactory.createLayer("Contours", memDriver, mapContext.getProjection());
219
                mapContext.getLayers().addLayer(lyrContour);
220
                
221
                Value[] att = new Value[1];
222
                i=0;
223
                triShpWriter.preProcess();
224
                for (Triangle tri: tin.getTriangles()) {
225
                        CoordinateList auxC = new CoordinateList();
226
                        auxC.add(tri.getV1(), true);
227
                        auxC.add(tri.getV2(), true);
228
                        auxC.add(tri.getV3(), true);
229
                        auxC.add(tri.getV1(), true);
230
                        LinearRing ring = geomFact.createLinearRing(auxC.toCoordinateArray());
231
                        IGeometry geom = FConverter.jts_to_igeometry(ring);
232
//                        FGraphic graf = new FGraphic(geom, idSym);
233
//                        graphicLayer.addGraphic(graf);
234
                        att[0] = ValueFactory.createValue(i);
235
                        DefaultFeature feat = new DefaultFeature(geom, att, i + "");
236

    
237
                        triShpWriter.process(new DefaultRowEdited(feat, IRowEdited.STATUS_ADDED, i++));
238
                        
239
                        
240
                }
241
                triShpWriter.postProcess();
242
                
243
                
244
                VectorialFileDriver shpDriver = new IndexedShpDriver();
245
                FLyrVect lyrTri = (FLyrVect) LayerFactory.createLayer("Triangles", shpDriver, triShpFile, mapContext.getProjection());
246
                mapContext.getLayers().addLayer(lyrTri);
247
                
248

    
249
        }
250
        
251
        private ShpWriter createShapeTriangles(File file) throws BaseException {
252
        
253
                
254
                FieldDescription[] fieldsDescrip = new FieldDescription[1];
255
                
256
                FieldDescription f1 = new FieldDescription();
257
                f1.setFieldName("Id");
258
                f1.setFieldType(Types.INTEGER);
259
                f1.setFieldLength(8);
260
                f1.setFieldDecimalCount(0);
261
                fieldsDescrip[0] = f1;
262

    
263
                SHPLayerDefinition lyrDefPolygon = new SHPLayerDefinition();
264
                lyrDefPolygon.setFieldsDesc(fieldsDescrip);
265

    
266
                lyrDefPolygon.setFile(file);
267
                lyrDefPolygon.setName(file.getName());
268
                lyrDefPolygon.setShapeType(FShape.LINE | FShape.Z);
269
                ShpWriter writer = new ShpWriter();
270
                writer.setFile(file);
271
                writer.initialize(lyrDefPolygon);
272
                writer.preProcess();
273
                writer.postProcess();
274
                return writer;
275
        }
276

    
277
        private ShpWriter createShapeContours(File file) throws BaseException {
278
        
279
                
280
                FieldDescription[] fieldsDescrip = new FieldDescription[2];
281
                
282
                FieldDescription f1 = new FieldDescription();
283
                f1.setFieldName("Id");
284
                f1.setFieldType(Types.INTEGER);
285
                f1.setFieldLength(8);
286
                f1.setFieldDecimalCount(0);
287
                fieldsDescrip[0] = f1;
288

    
289
                FieldDescription f5 = new FieldDescription();
290
                f5.setFieldName("Height");
291
                f5.setFieldType(Types.DOUBLE);
292
                f5.setFieldDecimalCount(3);
293
                f5.setFieldLength(16);
294
                fieldsDescrip[1] = f5;
295

    
296

    
297
        
298
                SHPLayerDefinition lyrDef = new SHPLayerDefinition();
299
                lyrDef.setFieldsDesc(fieldsDescrip);
300

    
301
                lyrDef.setFile(file);
302
                lyrDef.setName(file.getName());
303
                lyrDef.setShapeType(FShape.LINE);
304
                ShpWriter writer = new ShpWriter();
305
                writer.setFile(file);
306
                writer.initialize(lyrDef);
307
                writer.preProcess();
308
                writer.postProcess();
309
                return writer;
310
        }
311

    
312

    
313
        public void initialize() {
314
                // TODO Auto-generated method stub
315

    
316
        }
317

    
318
        public boolean isEnabled() {
319
                IWindow wnd = PluginServices.getMDIManager().getActiveWindow();
320
                View view = (View) wnd;
321
                FLayers lyrs = view.getMapControl().getMapContext().getLayers();
322
                LayersIterator it = new LayersIterator(lyrs) {
323
                        public boolean evaluate(FLayer layer) {
324
                                return layer.isActive();
325
                        }
326
                };
327
                pointLayers = new ArrayList<FLyrVect>();
328
                while (it.hasNext()) {
329
                        FLayer lyr = it.nextLayer();
330
                        if (lyr instanceof FLyrVect) {
331
                                FLyrVect lyrVect = (FLyrVect) lyr;
332
                                try {
333
                                        if ((lyrVect.getShapeType() == FShape.POINT) || (lyrVect.getShapeType() == FShape.MULTIPOINT)) {
334
                                                pointLayers.add(lyrVect);
335
                                        }
336
                                } catch (ReadDriverException e) {
337
                                        // TODO Auto-generated catch block
338
                                        e.printStackTrace();
339
                                }
340
                        }
341
                }
342
                if (pointLayers.size() >= 1)
343
                        return true;
344
                return false;
345
        }
346

    
347
        public boolean isVisible() {
348
                IWindow wnd = PluginServices.getMDIManager().getActiveWindow();
349
                if (wnd instanceof View)
350
                        return true;
351
                return false;
352
        }
353

    
354
}
355