Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / extRasterTools-SE / src / org / gvsig / rastertools / vectorizacion / process / ContourLinesProcess.java @ 28155

History | View | Annotate | Download (13.9 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
                        DataManager datamanager = DALLocator.getDataManager();
112
                        FilesystemServerExplorerParameters explorerParams;
113

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

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

    
120
                        newParams.setDefaultFeatureType(featureType);
121
                        newParams.setDynValue("srs", CRSFactory.getCRS("EPSG:23030"));
122
                        explorer.add(newParams, true);
123
                        DataManager manager = DALLocator.getDataManager();
124
                        
125
                        fsWriter = (FeatureStore)manager.createStore(newParams);
126
                        fsWriter.edit(FeatureStore.MODE_APPEND);
127
                } catch (DataException e) {
128
                        RasterToolsUtil.messageBoxError("error_loading_store", this, e);
129
                } catch (ValidateDataParametersException e) {
130
                        RasterToolsUtil.messageBoxError("error_loading_store", this, e);
131
                }
132
        }
133

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

    
145
                        if( min <= max && distance > 0 ) {
146
                                if( min < grid.getMinValue() )
147
                                        min += distance * (int)((grid.getMinValue() - min) / distance);
148

    
149
                                if( max > grid.getMaxValue() )
150
                                        max = grid.getMaxValue();
151

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

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

    
182
                iNX = grid.getNX();
183
                iNY = grid.getNY();
184

    
185
                m_Row = new char[iNY][iNX];
186
                m_Col = new char[iNY][iNX];
187

    
188
                if( dDistance <= 0 )
189
                        dDistance= 1;
190

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

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

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

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

    
247
                info.x = x;
248
                info.y = y;
249
                info.iDir = 0;
250
                info.doRow = doRow;
251

    
252
                do{
253
                        d = grid.getCellValue(info.y, info.x);
254
                        d = (d - z) / (d - grid.getCellValue(zy, zx));
255

    
256
                        xPos = xMin + grid.getCellSize() * (info.x + d * (zx - info.x) + 0.5);
257
                        yPos = yMax - grid.getCellSize() * (info.y + d * (zy - info.y) + 0.5);
258

    
259
                        if (bIsFirstPoint) {
260
                                genPathX.moveTo(xPos, yPos);
261
                                bIsFirstPoint = false;
262
                        } else
263
                                genPathX.lineTo(xPos, yPos);
264

    
265
                        if( !findNextContour(info) )
266
                                doContinue        = findNextContour(info);
267

    
268
                        info.iDir = (info.iDir + 5) % 8;
269

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

    
280
                }
281
                while(doContinue);
282

    
283
                values[0] = new Double(ID);
284
                values[1] = new Double(z);
285

    
286
                line = geomManager.createCurve(genPathX, SUBTYPES.GEOM2D);
287
                addGeometry(line, values);
288
        }
289

    
290
        private boolean findNextContour(NextContourInfo info) {
291
                boolean        doContinue;
292

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

    
408
                return(doContinue);
409
        }
410

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

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

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

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

    
445
                EditableFeatureAttributeDescriptor efad1=eft.add("ID", DataTypes.DOUBLE);
446
                efad1.setPrecision(5);
447
                EditableFeatureAttributeDescriptor efad2=eft.add("NAME", DataTypes.DOUBLE);
448
                efad2.setPrecision(5);
449

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