Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / extRasterTools-SE / src / org / gvsig / rastertools / vectorizacion / process / ContourLinesProcess.java @ 27723

History | View | Annotate | Download (13.8 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
*
3
* Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
4
*
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
*/
19
package org.gvsig.rastertools.vectorizacion.process;
20

    
21
import java.io.File;
22
import java.sql.Types;
23

    
24
import org.gvsig.fmap.crs.CRSFactory;
25
import org.gvsig.fmap.dal.DALLocator;
26
import org.gvsig.fmap.dal.DataManager;
27
import org.gvsig.fmap.dal.DataTypes;
28
import org.gvsig.fmap.dal.exception.DataException;
29
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
30
import org.gvsig.fmap.dal.feature.EditableFeature;
31
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
32
import org.gvsig.fmap.dal.feature.EditableFeatureType;
33
import org.gvsig.fmap.dal.feature.FeatureStore;
34
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
35
import org.gvsig.fmap.dal.feature.impl.DefaultEditableFeatureType;
36
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
37
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
38
import org.gvsig.fmap.geom.Geometry;
39
import org.gvsig.fmap.geom.GeometryLocator;
40
import org.gvsig.fmap.geom.GeometryManager;
41
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
42
import org.gvsig.fmap.geom.exception.CreateGeometryException;
43
import org.gvsig.fmap.geom.primitive.GeneralPathX;
44
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
45
import org.gvsig.raster.RasterProcess;
46
import org.gvsig.raster.buffer.RasterBufferInvalidException;
47
import org.gvsig.raster.datastruct.Extent;
48
import org.gvsig.raster.grid.Grid;
49
import org.gvsig.raster.grid.GridException;
50
import org.gvsig.raster.grid.GridExtent;
51
import org.gvsig.raster.process.RasterTask;
52
import org.gvsig.raster.process.RasterTaskQueue;
53
import org.gvsig.raster.util.RasterToolsUtil;
54

    
55
/**
56
 * Este proceso vectoriza la capa de entrada que debe estar ya preprocesada.
57
 * 03/07/2008
58
 * @author Victor Olaya (volaya@ya.com)
59
 * @author Nacho Brodin nachobrodin@gmail.com
60
 */
61
public class ContourLinesProcess extends RasterProcess {
62
        private static final GeometryManager  geomManager                   = GeometryLocator.getGeometryManager();
63
        private FLyrRasterSE                  lyr                 = null;
64
        private double                        min                 = 0;
65
        private double                        max                 = 0;
66
        private double                        distance            = 0;
67
        private Extent                        extent              = null;
68
        private String                        fileName            = null;
69

    
70
        private char[][]                      m_Row               = null;
71
        private char[][]                      m_Col               = null;
72
        private Grid                          grid                = null;
73
        private FeatureStore                  fsWriter            = null;
74
        private int                           m_iGeometry         = 0;
75
        private double                        percent             = 0;
76

    
77
        private class NextContourInfo {
78
                public int iDir;
79
                public int x;
80
                public int y;
81
                public boolean doRow;
82
        }
83

    
84
        /**
85
         * Par?metros obligatorios al proceso:
86
         * <UL>
87
         * <LI></LI>
88
         * <LI>filename: Nombre del fichero de salida</LI>
89
         * <LI></LI>
90
         * <LI></LI>
91
         * <LI></LI>
92
         * <LI></LI>
93
         * </UL>
94
         */
95
        public void init() {
96
                lyr = getLayerParam("layer");
97
                fileName = getStringParam("filename");
98
                min = getDoubleParam("min");
99
                max = getDoubleParam("max");
100
                distance = getDoubleParam("distance");
101
                extent = getExtentParam("extent");
102

    
103
                try{
104
                EditableFeatureType featureType = getFeatureType();
105

    
106
                EditableFeatureAttributeDescriptor efad=featureType.add("GEOMETRY", DataTypes.GEOMETRY);
107
                efad.setGeometryType(Geometry.TYPES.CURVE);
108
                efad.setSRS(CRSFactory.getCRS("EPSG:23030"));
109
                featureType.setDefaultGeometryAttributeName("GEOMETRY");
110

    
111

    
112
                DataManager datamanager=DALLocator.getDataManager();
113
                FilesystemServerExplorerParameters explorerParams;
114

    
115
                explorerParams = (FilesystemServerExplorerParameters) datamanager.createServerExplorerParameters(FilesystemServerExplorer.NAME);
116

    
117
                explorerParams.setRoot(new File(fileName).getParent());
118
                FilesystemServerExplorer explorer=(FilesystemServerExplorer) datamanager.createServerExplorer(explorerParams);
119
                NewFeatureStoreParameters newParams = (NewFeatureStoreParameters) explorer.getAddParameters(new File(fileName));
120

    
121
                newParams.setDefaultFeatureType(featureType);
122
                explorer.add(newParams, true);
123
                DataManager manager = DALLocator.getDataManager();
124
                fsWriter=(FeatureStore)manager.createStore(newParams);
125
                if(fileName.endsWith(".dxf")) {
126
                } else if(fileName.endsWith(".shp")) {
127
                }
128
                        fsWriter.edit(FeatureStore.MODE_APPEND);
129
                } catch (DataException e) {
130
                        e.printStackTrace();
131
                } catch (ValidateDataParametersException e) {
132
                        // TODO Auto-generated catch block
133
                        e.printStackTrace();
134
                }
135
        }
136

    
137
        /**
138
         * Tarea de recorte
139
         */
140
        public void process() throws InterruptedException {
141
                GridExtent ge = null;
142
                insertLineLog("Contour Lines");
143
                if(extent != null)
144
                        ge = new GridExtent(extent, lyr.getCellSize());
145
                try {
146
                        grid = new Grid(lyr.getDataSource(), new int[]{0}, ge);
147

    
148
                        if( min <= max && distance > 0 ) {
149
                                if( min < grid.getMinValue() )
150
                                        min += distance * (int)((grid.getMinValue() - min) / distance);
151

    
152
                                if( max > grid.getMaxValue() )
153
                                        max = grid.getMaxValue();
154

    
155
                                createContours(min, max, distance);
156
                                fsWriter.finishEditing();
157
                        }
158
                } catch (RasterBufferInvalidException e) {
159
                        RasterToolsUtil.messageBoxError("error_loading_grid", this, e);
160
                } catch (GridException e) {
161
                        RasterToolsUtil.messageBoxError("error_loading_grid", this, e);
162
                } catch (DataException e) {
163
                        RasterToolsUtil.messageBoxError("", this, e);
164
                } catch (CreateGeometryException e) {
165
                        RasterToolsUtil.messageBoxError("", this, e);
166
                } finally {
167
                        if (incrementableTask != null) {
168
                                incrementableTask.processFinalize();
169
                                incrementableTask = null;
170
                        }
171
                }
172
                if(externalActions != null)
173
                        externalActions.end(fileName);
174
        }
175

    
176
        private void createContours(double dMin, double dMax, double dDistance)  throws InterruptedException, GridException, DataException, CreateGeometryException {
177
                int x, y;
178
                int i;
179
                int ID;
180
                int iNX,iNY;
181
                double dZ;
182
                double dValue = 0;
183
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
184

    
185
                iNX = grid.getNX();
186
                iNY = grid.getNY();
187

    
188
                m_Row = new char[iNY][iNX];
189
                m_Col = new char[iNY][iNX];
190

    
191
                if( dDistance <= 0 )
192
                        dDistance= 1;
193

    
194
                percent = 0;
195
                for(dZ = dMin, ID = 0; dZ <= dMax; dZ += dDistance) {
196
                        double increment = (25 / (iNY * (((dMax - dMin) / dDistance) + 1)));
197
                        for(y = 0; y < iNY - 1; y++) {
198
                                percent += increment;
199
                                for(x = 0; x < iNX - 1; x++) {
200
                                        dValue = grid.getCellValue(y, x);
201
                                        if( dValue >= dZ ) {
202
                                                m_Row[y][x]        = (char) (grid.getCellValue(y, x + 1) <  dZ ? 1 : 0);
203
                                                m_Col[y][x]        = (char) (grid.getCellValue(y + 1, x) <  dZ ? 1 : 0);
204
                                        }
205
                                        else {
206
                                                m_Row[y][x]        = (char) (grid.getCellValue(y, x + 1) >= dZ ? 1 : 0);
207
                                                m_Col[y][x]        = (char) (grid.getCellValue(y + 1, x) >= dZ ? 1 : 0);
208
                                        }
209
                                }
210
                                if(task.getEvent() != null)
211
                                        task.manageEvent(task.getEvent());
212
                        }
213

    
214
                        increment = (75 / (iNY * (((dMax - dMin) / dDistance) + 1)));
215
                        for(y = 0; y < iNY - 1; y++) {
216
                                percent += increment;
217
                                for(x = 0; x < iNX - 1; x++) {
218
                                        if(m_Row[y][x] != 0) {
219
                                                for(i = 0; i < 2; i++)
220
                                                        findContour(x, y, dZ, true, ID++);
221
                                                m_Row[y][x]        = 0;
222
                                        }
223

    
224
                                        if(m_Col[y][x] != 0) {
225
                                                for(i=0; i<2; i++)
226
                                                        findContour(x, y, dZ, false, ID++);
227
                                                m_Col[y][x]        = 0;
228
                                        }
229
                                }
230
                                if(task.getEvent() != null)
231
                                        task.manageEvent(task.getEvent());
232
                        }
233
                }
234
        }
235

    
236
        private void findContour(int x, int y, double z, boolean doRow, int ID)  throws GridException, InterruptedException, DataException, CreateGeometryException {
237
                boolean doContinue = true;
238
                boolean bIsFirstPoint = true;
239
                int        zx        = doRow ? x + 1 : x;
240
                int zy        = doRow ? y : y + 1;
241
                double d = 0;
242
                double        xPos, yPos;
243
                double         xMin = grid.getGridExtent().getMin().getX();
244
                double         yMax = grid.getGridExtent().getMax().getY();
245
                Geometry line;
246
                Object values[] = new Object[2];
247
                NextContourInfo info = new NextContourInfo();
248
                GeneralPathX genPathX = new GeneralPathX();
249

    
250
                info.x = x;
251
                info.y = y;
252
                info.iDir = 0;
253
                info.doRow = doRow;
254

    
255
                do{
256
                        d = grid.getCellValue(info.y, info.x);
257
                        d = (d - z) / (d - grid.getCellValue(zy, zx));
258

    
259
                        xPos = xMin + grid.getCellSize() * (info.x + d * (zx - info.x) + 0.5);
260
                        yPos = yMax - grid.getCellSize() * (info.y + d * (zy - info.y) + 0.5);
261

    
262
                        if (bIsFirstPoint) {
263
                                genPathX.moveTo(xPos, yPos);
264
                                bIsFirstPoint = false;
265
                        } else
266
                                genPathX.lineTo(xPos, yPos);
267

    
268
                        if( !findNextContour(info) )
269
                                doContinue        = findNextContour(info);
270

    
271
                        info.iDir = (info.iDir + 5) % 8;
272

    
273
                        if(info.doRow) {
274
                                m_Row[info.y][info.x]        = 0;
275
                                zx = info.x + 1;
276
                                zy = info.y;
277
                        } else {
278
                                m_Col[info.y][info.x]        = 0;
279
                                zx = info.x;
280
                                zy = info.y + 1;
281
                        }
282

    
283
                }
284
                while(doContinue);
285

    
286
                values[0] = new Double(ID);
287
                values[1] = new Double(z);
288

    
289
                line = geomManager.createCurve(genPathX, SUBTYPES.GEOM2D);
290
                addGeometry(line, values);
291
        }
292

    
293
        private boolean findNextContour(NextContourInfo info) {
294
                boolean        doContinue;
295

    
296
                if(info.doRow)
297
                        switch(info.iDir) {
298
                        case 0:
299
                                if(m_Row[info.y + 1][info.x] != 0) {
300
                                        info.y++;
301
                                        info.iDir = 0;
302
                                        doContinue = true;
303
                                        break;
304
                                }
305
                        case 1:
306
                                if(m_Col[info.y][info.x + 1] != 0) {
307
                                        info.x++;
308
                                        info.iDir = 1;
309
                                        info.doRow = false;
310
                                        doContinue = true;
311
                                        break;
312
                                }
313
                        case 2:
314
                        case 3:
315
                                if(info.y-1 >= 0)
316
                                        if(m_Col[info.y - 1][info.x + 1] != 0) {
317
                                                info.x++;
318
                                                info.y--;
319
                                                info.doRow = false;
320
                                                info.iDir = 3;
321
                                                doContinue = true;
322
                                                break;
323
                                        }
324
                        case 4:
325
                                if(info.y-1>=0)
326
                                        if(m_Row[info.y - 1][info.x]!= 0) {
327
                                                info.y--;
328
                                                info.iDir = 4;
329
                                                doContinue = true;
330
                                                break;
331
                                        }
332
                        case 5:
333
                                if(info.y-1>=0)
334
                                        if(m_Col[info.y - 1][info.x] != 0) {
335
                                                info.y--;
336
                                                info.doRow = false;
337
                                                info.iDir = 5 ;
338
                                                doContinue = true;
339
                                                break;
340
                                        }
341
                        case 6:
342
                        case 7:
343
                                if(m_Col[info.y][info.x]!= 0) {
344
                                        info.doRow = false;
345
                                        info.iDir = 7;
346
                                        doContinue = true;
347
                                        break;
348
                                }
349
                        default:
350
                                info.iDir = 0;
351
                                doContinue = false;
352
                        }
353
                else
354
                        switch(info.iDir) {
355
                        case 0:
356
                        case 1:
357
                                if(m_Row[info.y + 1][info.x] != 0) {
358
                                        info.y++;
359
                                        info.doRow = true;
360
                                        info.iDir = 1;
361
                                        doContinue = true;
362
                                        break;
363
                                }
364
                        case 2:
365
                                if(m_Col[info.y][info.x + 1] != 0) {
366
                                        info.x++;
367
                                        info.iDir = 2;
368
                                        doContinue = true;
369
                                        break;
370
                                }
371
                        case 3:
372
                                if(m_Row[info.y][info.x] != 0) {
373
                                        info.doRow = true;
374
                                        info.iDir = 3;
375
                                        doContinue = true;
376
                                        break;
377
                                }
378
                        case 4:
379
                        case 5:
380
                                if(info.x-1>=0)
381
                                        if(m_Row[info.y][info.x - 1] != 0) {
382
                                                info.x--;
383
                                                info.doRow = true;
384
                                                info.iDir = 5;
385
                                                doContinue = true;
386
                                                break;
387
                                        }
388
                        case 6:
389
                                if(info.x-1>=0)
390
                                        if(m_Col[info.y][info.x - 1] != 0) {
391
                                                info.x--;
392
                                                info.iDir = 6;
393
                                                doContinue = true;
394
                                                break;
395
                                        }
396
                        case 7:
397
                                if(info.x-1 >= 0)
398
                                        if(m_Row[info.y + 1][info.x - 1] != 0) {
399
                                                info.x--;
400
                                                info.y++;
401
                                                info.doRow = true;
402
                                                info.iDir = 7;
403
                                                doContinue = true;
404
                                                break;
405
                                        }
406
                        default:
407
                                info.iDir = 0;
408
                                doContinue = false;
409
                        }
410

    
411
                return(doContinue);
412
        }
413

    
414
        /*
415
         * (non-Javadoc)
416
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
417
         */
418
        public int getPercent() {
419
                return (int)percent;
420
        }
421

    
422
        /*
423
         * (non-Javadoc)
424
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
425
         */
426
        public String getTitle() {
427
                return RasterToolsUtil.getText(this, "vectorization");
428
        }
429

    
430
//        public void addShape(FShape shape, Value[] value)  throws Exception {
431
//                if (shape == null)
432
//                        return;
433
//                IGeometry geom = ShapeFactory.createGeometry(shape);
434
//                addGeometry(geom, value);
435
//        }
436

    
437
        public void addGeometry(Geometry geom, Object[] value) throws DataException {
438
                m_iGeometry++;
439
                EditableFeature ef=fsWriter.createNewFeature();
440
                ef.set("ID", value[0]);
441
                ef.set("NAME",value[1]);
442
                ef.setGeometry("GEOMETRY", geom);
443
                fsWriter.insert(ef);
444
        }
445
        private EditableFeatureType getFeatureType(){
446
                EditableFeatureType eft=new DefaultEditableFeatureType();
447

    
448
                EditableFeatureAttributeDescriptor efad1=eft.add("ID", DataTypes.DOUBLE);
449
                efad1.setPrecision(5);
450
                EditableFeatureAttributeDescriptor efad2=eft.add("NAME", DataTypes.DOUBLE);
451
                efad2.setPrecision(5);
452

    
453
                return eft;
454
        }
455
        /**
456
                 * Returns the length of field
457
                 * @param dataType
458
                 * @return length of field
459
                 */
460
        public int getDataTypeLength(int dataType) {
461
                switch (dataType) {
462
                case Types.NUMERIC:
463
                case Types.DOUBLE:
464
                case Types.REAL:
465
                case Types.FLOAT:
466
                case Types.BIGINT:
467
                case Types.INTEGER:
468
                case Types.DECIMAL:
469
                        return 20;
470
                case Types.CHAR:
471
                case Types.VARCHAR:
472
                case Types.LONGVARCHAR:
473
                        return 254;
474
                case Types.DATE:
475
                        return 8;
476
                case Types.BOOLEAN:
477
                case Types.BIT:
478
                        return 1;
479
                }
480
                return 0;
481
        }
482
}