Statistics
| Revision:

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

History | View | Annotate | Download (12.4 KB)

1 22366 fpenarrubia
/* 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 22583 fpenarrubia
import java.awt.Component;
31
import java.io.File;
32
import java.sql.Types;
33 22366 fpenarrubia
import java.util.ArrayList;
34 22583 fpenarrubia
import java.util.Arrays;
35 22366 fpenarrubia
import java.util.Collection;
36
37 22583 fpenarrubia
import javax.swing.JOptionPane;
38
39 22366 fpenarrubia
import org.gvsig.exceptions.BaseException;
40
import org.gvsig.fmap.algorithm.contouring.ContourCalculator;
41 22583 fpenarrubia
import org.gvsig.fmap.algorithm.triangulation.PirolTriangulator;
42 22366 fpenarrubia
import org.gvsig.fmap.algorithm.triangulation.TIN;
43 22583 fpenarrubia
import org.gvsig.fmap.algorithm.triangulation.Triangle;
44 22366 fpenarrubia
import org.gvsig.fmap.algorithm.triangulation.Vertex;
45
import org.gvsig.fmap.algorithm.triangulation.WatsonTriangulator;
46 22583 fpenarrubia
import org.gvsig.graph.core.NetworkUtils;
47
import org.gvsig.gui.beans.swing.JFileChooser;
48 22366 fpenarrubia
49
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
50
import com.hardcode.gdbms.engine.values.NumericValue;
51 22583 fpenarrubia
import com.hardcode.gdbms.engine.values.Value;
52
import com.hardcode.gdbms.engine.values.ValueFactory;
53 22366 fpenarrubia
import com.iver.andami.PluginServices;
54
import com.iver.andami.plugins.Extension;
55
import com.iver.andami.ui.mdiManager.IWindow;
56 22583 fpenarrubia
import com.iver.cit.gvsig.fmap.MapContext;
57
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
58 22366 fpenarrubia
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 22583 fpenarrubia
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 22366 fpenarrubia
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 22583 fpenarrubia
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
76 22366 fpenarrubia
import com.iver.cit.gvsig.fmap.layers.LayersIterator;
77
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
78 22583 fpenarrubia
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
79 22366 fpenarrubia
import com.iver.cit.gvsig.project.documents.view.gui.View;
80 22583 fpenarrubia
import com.iver.utiles.GenericFileFilter;
81
import com.vividsolutions.jts.geom.CoordinateList;
82 22687 fpenarrubia
import com.vividsolutions.jts.geom.Geometry;
83 22583 fpenarrubia
import com.vividsolutions.jts.geom.GeometryFactory;
84 22366 fpenarrubia
import com.vividsolutions.jts.geom.LineString;
85 22583 fpenarrubia
import com.vividsolutions.jts.geom.LinearRing;
86 22687 fpenarrubia
import com.vividsolutions.jts.geom.Polygon;
87
import com.vividsolutions.jts.operation.polygonize.Polygonizer;
88 22366 fpenarrubia
89
public class TinExtension extends Extension {
90 22583 fpenarrubia
91
        private static String     lastPath        = null;
92
        private PluginServices ps=PluginServices.getPluginServices(this);
93 22366 fpenarrubia
94 22583 fpenarrubia
        private ArrayList<FLyrVect> pointLayers = null;
95
96 22366 fpenarrubia
        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 22583 fpenarrubia
                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 22366 fpenarrubia
                long t1 = System.currentTimeMillis();
142 22687 fpenarrubia
                WatsonTriangulator triangulator = new WatsonTriangulator();
143 22583 fpenarrubia
//                ChewTriangulator triangulator = new ChewTriangulator();
144 22687 fpenarrubia
//                PirolTriangulator triangulator = new PirolTriangulator();
145 22366 fpenarrubia
                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 22583 fpenarrubia
                                NumericValue val = (NumericValue) feat.getAttribute(idField);
154 22366 fpenarrubia
                                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 22583 fpenarrubia
                                        NumericValue val = (NumericValue) feat.getAttribute(idField);
162 22366 fpenarrubia
                                        triangulator.addVertex(new Vertex(p.getX(), p.getY(), val.doubleValue()));
163
                                }
164
                        }
165
166
                }
167
                rv.stop();
168
169
                TIN tin = triangulator.calculateTriangulation();
170 22583 fpenarrubia
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 22687 fpenarrubia
//                memDriver.getf
188 22583 fpenarrubia
                memDriver.setShapeType(FShape.LINE);
189 22687 fpenarrubia
190 22583 fpenarrubia
                int i = 0;
191 22366 fpenarrubia
                ContourCalculator contourCalculator = new ContourCalculator(tin);
192 22583 fpenarrubia
                for (int indexContour = 0; indexContour < heights.length; indexContour++) {
193
                        double height = heights[indexContour];
194
                        Collection<LineString> contour = contourCalculator.getContour(height);
195 22687 fpenarrubia
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 22583 fpenarrubia
203 22687 fpenarrubia
                        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 22583 fpenarrubia
                                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 22366 fpenarrubia
221 22583 fpenarrubia
                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 22366 fpenarrubia
                }
241 22583 fpenarrubia
                triShpWriter.postProcess();
242 22366 fpenarrubia
243 22583 fpenarrubia
244
                VectorialFileDriver shpDriver = new IndexedShpDriver();
245
                FLyrVect lyrTri = (FLyrVect) LayerFactory.createLayer("Triangles", shpDriver, triShpFile, mapContext.getProjection());
246
                mapContext.getLayers().addLayer(lyrTri);
247
248 22366 fpenarrubia
249
        }
250 22583 fpenarrubia
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 22366 fpenarrubia
263 22583 fpenarrubia
                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 22366 fpenarrubia
        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
}