Statistics
| Revision:

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

History | View | Annotate | Download (12.7 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.io.IOException;
33
import java.sql.Types;
34
import java.util.ArrayList;
35
import java.util.Arrays;
36
import java.util.Collection;
37

    
38
import javax.swing.JOptionPane;
39

    
40
import org.gvsig.exceptions.BaseException;
41
import org.gvsig.fmap.algorithm.contouring.ContourCalculator;
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.GraphException;
47
import org.gvsig.graph.core.NetworkUtils;
48
import org.gvsig.gui.beans.swing.JFileChooser;
49

    
50
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
51
import com.hardcode.gdbms.engine.values.NumericValue;
52
import com.hardcode.gdbms.engine.values.Value;
53
import com.hardcode.gdbms.engine.values.ValueFactory;
54
import com.iver.andami.PluginServices;
55
import com.iver.andami.plugins.Extension;
56
import com.iver.andami.ui.mdiManager.IWindow;
57
import com.iver.cit.gvsig.fmap.MapContext;
58
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
59
import com.iver.cit.gvsig.fmap.core.FMultiPoint2D;
60
import com.iver.cit.gvsig.fmap.core.FPoint2D;
61
import com.iver.cit.gvsig.fmap.core.FShape;
62
import com.iver.cit.gvsig.fmap.core.IFeature;
63
import com.iver.cit.gvsig.fmap.core.IGeometry;
64
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
65
import com.iver.cit.gvsig.fmap.drivers.ConcreteMemoryDriver;
66
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
67
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition;
68
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
69
import com.iver.cit.gvsig.fmap.drivers.shp.IndexedShpDriver;
70
import com.iver.cit.gvsig.fmap.edition.DefaultRowEdited;
71
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
72
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter;
73
import com.iver.cit.gvsig.fmap.layers.FLayer;
74
import com.iver.cit.gvsig.fmap.layers.FLayers;
75
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
76
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
77
import com.iver.cit.gvsig.fmap.layers.LayersIterator;
78
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
79
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
80
import com.iver.cit.gvsig.project.documents.view.gui.View;
81
import com.iver.utiles.GenericFileFilter;
82
import com.vividsolutions.jts.geom.CoordinateList;
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
        private GeometryFactory jtsFactory = new GeometryFactory();
97
        
98
        public void execute(String actionCommand) {
99
                for (FLyrVect lyr : pointLayers) {
100
                        try {
101
                                doTIN(lyr);
102
                        } catch (BaseException e) {
103
                                // TODO Auto-generated catch block
104
                                e.printStackTrace();
105
                        }
106
                }
107

    
108
        }
109
        
110
        private void doTIN(FLyrVect lyrVect) throws BaseException {
111
                ReadableVectorial rv = lyrVect.getSource();
112
                
113
                JFileChooser fileChooser = new JFileChooser("OPEN_LAYER_FILE_CHOOSER_ID", lastPath);
114
                fileChooser.setFileFilter(new GenericFileFilter(".shp", "Shape files", true));
115
                fileChooser.setMultiSelectionEnabled(false);
116
                fileChooser.setDialogTitle(ps.getText("choose_file_to_save_triangles"));
117
                int result = fileChooser.showSaveDialog((Component) PluginServices.getMDIManager().getActiveWindow());
118
                if (result == JFileChooser.CANCEL_OPTION)
119
                        return;
120
                File triShpFile = fileChooser.getSelectedFile();
121
                try {
122
                        if (!triShpFile.getCanonicalPath().toLowerCase().endsWith(".shp"))
123
                                triShpFile = new File(triShpFile.getAbsolutePath() + ".shp");
124
                } catch (IOException e) {
125
                        e.printStackTrace();
126
                        throw new GraphException(e);
127
                }
128

    
129
//                fileChooser.setDialogTitle(PluginServices.getPluginServices(TinExtension.class)
130
//                                .getText("choose_file_to_save_contours"));
131
//                result = fileChooser.showSaveDialog((Component) PluginServices.getMDIManager());
132
//                if (result == JFileChooser.CANCEL_OPTION)
133
//                        return;
134
//                File contourShpFile = fileChooser.getSelectedFile();
135
                SelectableDataSource rs = lyrVect.getRecordset();
136
                String[] selecValues = rs.getFieldNames();
137
                String strField = (String) JOptionPane.showInputDialog(null, "choose_field", "choose_field", JOptionPane.QUESTION_MESSAGE, null, selecValues, null);
138
                
139
                int idField = rs.getFieldIndexByName(strField);
140
                String aux = JOptionPane.showInputDialog("input_contour_desired_heights_separated_by_commas (;)");
141
                if (aux == null)
142
                        return;
143
                double[] heights = NetworkUtils.string2doubleArray(aux, ";");
144
                Arrays.sort(heights);
145

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

    
194
                memDriver.getTableModel().setColumnIdentifiers(arrayFields.toArray());
195

    
196
//                memDriver.getf
197
                memDriver.setShapeType(FShape.LINE);
198
                
199
                int i = 0;
200
                ContourCalculator contourCalculator = new ContourCalculator(tin);
201
                for (int indexContour = 0; indexContour < heights.length; indexContour++) {                        
202
                        double height = heights[indexContour];
203
                        Collection<LineString> contour = contourCalculator.getContour(height);
204

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

    
246
                        triShpWriter.process(new DefaultRowEdited(feat, IRowEdited.STATUS_ADDED, i++));
247
                        
248
                        
249
                }
250
                triShpWriter.postProcess();
251
                
252
                
253
                VectorialFileDriver shpDriver = new IndexedShpDriver();
254
                FLyrVect lyrTri = (FLyrVect) LayerFactory.createLayer("Triangles", shpDriver, triShpFile, mapContext.getProjection());
255
                mapContext.getLayers().addLayer(lyrTri);
256
                
257

    
258
        }
259
        
260
        private ShpWriter createShapeTriangles(File file) throws BaseException {
261
        
262
                
263
                FieldDescription[] fieldsDescrip = new FieldDescription[1];
264
                
265
                FieldDescription f1 = new FieldDescription();
266
                f1.setFieldName("Id");
267
                f1.setFieldType(Types.INTEGER);
268
                f1.setFieldLength(8);
269
                f1.setFieldDecimalCount(0);
270
                fieldsDescrip[0] = f1;
271

    
272
                SHPLayerDefinition lyrDefPolygon = new SHPLayerDefinition();
273
                lyrDefPolygon.setFieldsDesc(fieldsDescrip);
274

    
275
                lyrDefPolygon.setFile(file);
276
                lyrDefPolygon.setName(file.getName());
277
                lyrDefPolygon.setShapeType(FShape.LINE | FShape.Z);
278
                ShpWriter writer = new ShpWriter();
279
                writer.setFile(file);
280
                writer.initialize(lyrDefPolygon);
281
                writer.preProcess();
282
                writer.postProcess();
283
                return writer;
284
        }
285

    
286
        private ShpWriter createShapeContours(File file) throws BaseException {
287
        
288
                
289
                FieldDescription[] fieldsDescrip = new FieldDescription[2];
290
                
291
                FieldDescription f1 = new FieldDescription();
292
                f1.setFieldName("Id");
293
                f1.setFieldType(Types.INTEGER);
294
                f1.setFieldLength(8);
295
                f1.setFieldDecimalCount(0);
296
                fieldsDescrip[0] = f1;
297

    
298
                FieldDescription f5 = new FieldDescription();
299
                f5.setFieldName("Height");
300
                f5.setFieldType(Types.DOUBLE);
301
                f5.setFieldDecimalCount(3);
302
                f5.setFieldLength(16);
303
                fieldsDescrip[1] = f5;
304

    
305

    
306
        
307
                SHPLayerDefinition lyrDef = new SHPLayerDefinition();
308
                lyrDef.setFieldsDesc(fieldsDescrip);
309

    
310
                lyrDef.setFile(file);
311
                lyrDef.setName(file.getName());
312
                lyrDef.setShapeType(FShape.LINE);
313
                ShpWriter writer = new ShpWriter();
314
                writer.setFile(file);
315
                writer.initialize(lyrDef);
316
                writer.preProcess();
317
                writer.postProcess();
318
                return writer;
319
        }
320

    
321

    
322
        public void initialize() {
323
                // TODO Auto-generated method stub
324

    
325
        }
326

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

    
356
        public boolean isVisible() {
357
                IWindow wnd = PluginServices.getMDIManager().getActiveWindow();
358
                if (wnd instanceof View)
359
                        return true;
360
                return false;
361
        }
362

    
363
}
364