Statistics
| Revision:

svn-gvsig-desktop / branches / v10 / extensions / DielmoOpenLidar / src / com / dielmo / gvsig / lidar / Strategies / LiDARStrategy.java @ 25419

History | View | Annotate | Download (12.6 KB)

1
/* DielmoOpenLiDAR
2
 *
3
 * Copyright (C) 2008 DIELMO 3D S.L. (DIELMO) and Infrastructures  
4
 * and Transports Department 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
 * For more information, contact:
22
 *
23
 * DIELMO 3D S.L.
24
 * Plaza Vicente Andr?s Estell?s 1 Bajo E
25
 * 46950 Xirivella, Valencia
26
 * SPAIN
27
 *   
28
 * +34 963137212
29
 * dielmo@dielmo.com
30
 * www.dielmo.com
31
 * 
32
 * or
33
 * 
34
 * Generalitat Valenciana
35
 * Conselleria d'Infraestructures i Transport
36
 * Av. Blasco Ib??ez, 50
37
 * 46010 VALENCIA
38
 * SPAIN
39
 *
40
 * +34 963862235
41
 * gvsig@gva.es
42
 * www.gvsig.gva.es
43
 */
44

    
45
/*
46
 * AUTHORS (In addition to DIELMO and CIT):
47
 *  
48
 */
49

    
50
package com.dielmo.gvsig.lidar.Strategies;
51

    
52
import java.awt.Graphics2D;
53
import java.awt.geom.Point2D;
54
import java.awt.geom.Rectangle2D;
55
import java.awt.image.BufferedImage;
56

    
57
import org.cresques.cts.ICoordTrans;
58

    
59
import com.iver.andami.PluginServices;
60
import com.iver.cit.gvsig.fmap.DriverException;
61
import com.iver.cit.gvsig.fmap.ViewPort;
62
import com.iver.cit.gvsig.fmap.core.FPoint2D;
63
import com.iver.cit.gvsig.fmap.core.IGeometry;
64
import com.iver.cit.gvsig.fmap.core.ISymbol;
65
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
66
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
67
import com.iver.cit.gvsig.fmap.layers.FBitSet;
68
import com.iver.cit.gvsig.fmap.layers.FLayer;
69
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
70
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
71
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
72
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
73
import com.iver.cit.gvsig.fmap.layers.layerOperations.SingleLayer;
74
import com.iver.cit.gvsig.fmap.operations.strategies.DefaultStrategy;
75
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
76
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
77
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
78
import com.iver.cit.gvsig.project.documents.view.gui.View;
79
import com.iver.utiles.swing.threads.Cancellable;
80
import com.iver.utiles.swing.threads.CancellableMonitorable;
81

    
82
/**
83
 * Esta clase se encargar? de dibujar las capas LiDAR
84
 * 
85
 * @author Jos? Carlos Garcia
86
 */
87
public class LiDARStrategy extends DefaultStrategy {
88
        
89
        int maxGrosor;
90
        ViewPort viewportCapa;
91
        
92
        /**
93
         * Crea un nuevo LiDARStrategy.
94
         * 
95
         * @param layer
96
         */
97
        public LiDARStrategy(FLayer layer, int grosor) {
98
                super(layer);
99
                viewportCapa = ((View) PluginServices.getMDIManager().getActiveWindow()).getMapControl().getViewPort();
100
                maxGrosor=grosor;
101
        }
102

    
103
        /**
104
         * Recorre las features de la capa vectorial invocando el m?todo visit del
105
         * visitador que se pasa como par?metro, que es el que realizar? la
106
         * operaci?n relacionada con la geometry.
107
         * 
108
         * @param visitor
109
         * @param cancel
110
         * @throws DriverException
111
         * @throws VisitException
112
         */
113
        public void process(FeatureVisitor visitor, CancellableMonitorable cancel) throws DriverException, VisitException {
114
                try {
115

    
116
                        FLayer capa = getCapa();
117
                        if (visitor.start(capa)) {
118
                                ReadableVectorial va = ((SingleLayer) capa).getSource();
119
                                ICoordTrans ct = getCapa().getCoordTrans();
120
                                va.start();
121
                                
122
                                if(va.getFullExtent().intersects(viewportCapa.getAdjustedExtent())){
123
                                
124
                                        for (int i = 0; i < va.getShapeCount(); i++) {
125
                                                if(cancel != null){
126
                                                        cancel.reportStep();
127
                                                }
128
                                                if(verifyCancelation(cancel, va, visitor))
129
                                                        return;
130
                                            IGeometry geom = va.getShape(i);
131
                                            if (ct != null) {
132
                                                        geom.reProject(ct);
133
                                                }
134
        
135
                                                visitor.visit(geom, i);
136
                                        }        
137
                                }
138
                                
139
                                va.stop();
140
//                                logger.info("visitor.stop()");
141
                                visitor.stop(capa);
142
                        }
143
                } catch (DriverIOException e) {
144
                        throw new DriverException(e);
145
                }
146
        }
147
        
148
        /**
149
         * Dibuja la capa vectorial asociada al Strategy en la imagen que se pasa
150
         * como par?metro.
151
         *
152
         * @param image
153
         * @param g
154
         * @param viewPort
155
         * @param cancel
156
         *
157
         * @throws DriverException
158
         */
159
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
160
                        Cancellable cancel) throws DriverException {
161
                try {
162
                        ReadableVectorial rvLiDAR = ((SingleLayer) getCapa()).getSource();
163
                        ICoordTrans ct = getCapa().getCoordTrans();
164
                        // logger.info("adapter.start()");
165
                        rvLiDAR.start();
166

    
167
                        // logger.info("getCapa().getRecordset().start()");
168
                        SelectableDataSource dsLidar = ((AlphanumericData) getCapa())
169
                                        .getRecordset();
170
                        if (dsLidar != null)
171
                                dsLidar.start();
172

    
173
                        int numRowsLidar;
174
                        Rectangle2D extent = viewPort.getAdjustedExtent();
175
                        Rectangle2D fullExtent = getCapa().getFullExtent();
176
                        if (!extent.intersects(fullExtent))
177
                                return;
178
                        // ati = viewPort.getAffineTransform();
179

    
180
                        numRowsLidar = rvLiDAR.getShapeCount();
181
                        // TODO: A revisar si es o no conveniente este sistema
182
                        // de comunicaci?n con los drivers.
183
                        DriverAttributes attr = rvLiDAR.getDriverAttributes();
184
                        boolean bMustClone = false;
185
                        if (attr != null) {
186
                                if (attr.isLoadedInMemory()) {
187
                                        bMustClone = attr.isLoadedInMemory();
188
                                }
189
                        }
190

    
191
                        VectorialLegend l = (VectorialLegend) ((ClassifiableVectorial) getCapa()).getLegend();
192
                        FBitSet bitSet = dsLidar.getSelection();
193

    
194
                        //ajustamos el increment en funci?n del tama?o de pixel de la vista
195
                        double resolucion = viewPort.getDist1pixel();
196
                        
197
                        int increment = 0;
198
                        if (resolucion < 25)
199
                                increment = (int) Math.floor(resolucion*(resolucion/3));
200
                        else                                        
201
                                increment = (int) Math.ceil(numRowsLidar / ((fullExtent.getWidth()/resolucion) * (fullExtent.getHeight()/resolucion))*(resolucion/30));
202
                        
203
//                        if (incrementAux > increment)
204
//                                increment = incrementAux;
205
                        
206
                        if (increment < 1)
207
                                increment = 1;
208

    
209
                        //para que al menos pinte 5 puntos
210
                        if (increment > numRowsLidar/5)
211
                                increment = (int) Math.floor(numRowsLidar/5);
212

    
213
                        int incrementAux = increment;
214
                        int incrementFast = 400;
215
                        
216
                        if (incrementFast < incrementAux)
217
                                incrementFast = incrementAux;
218
                        
219
                        // limites de incremento.
220
                        int limiteIncremento = incrementFast*10;
221
                        int limiteIncrementoFast=incrementFast*11;
222
                        
223
                
224
                        //ajustamos el grosor del punto en funci?n del tama?o de pixel de la vista
225
                        int grosor;
226
                        if (resolucion > 0 && resolucion < 25)
227
                                grosor = (int) Math.round(1/(resolucion*1.5));
228
                        else
229
                                if(resolucion >= 25 && resolucion < 250)
230
                                        grosor=1;
231
                                else
232
                                        if(resolucion >= 250)
233
                                                grosor=0;
234
                                        else {
235
                                                
236
                                                grosor=maxGrosor;
237
                                        }
238
                                
239
                        // maximo 10 de grosor
240
                        if (grosor > maxGrosor)
241
                                grosor = maxGrosor; 
242
                        
243
                        // minimo 0 de grosor
244
                        if(grosor<0)
245
                                grosor=0;
246

    
247
                        int ii,jj,pixX,pixY;
248
                        
249
                        //contIN es el contador de puntos que caen dentro de la vista
250
                        long contIN=0;
251
                        
252
                        //contIN es el contador de puntos que caen fuera de la vista
253
                        long contOUT=0;
254
                        
255
                        // recorremos por incrementos
256
                        for (int i = 0; i < numRowsLidar; i += increment) {
257

    
258
                                // si se cancela salir del bucle
259
                                if (cancel.isCanceled()) {
260
                                        break;
261
                                }
262
                                
263
                                // obtener la geometria del punto i
264
                                IGeometry geom = rvLiDAR.getShape(i);
265

    
266
                                if (geom == null) {
267
                                        continue;
268
                                }
269

    
270
                                if (ct != null) {
271
                                        if (bMustClone)
272
                                                geom = geom.cloneGeometry();
273
                                        geom.reProject(ct);
274
                                }
275

    
276
                                ISymbol symbol = l.getSymbol(i);
277

    
278
                                if (symbol == null)
279
                                        continue;
280
                                if (bitSet != null)
281
                                        if (bitSet.get(i)) {
282
                                                symbol = symbol.getSymbolForSelection();
283
                                        }
284

    
285
                                if (symbol != null) {
286
                                        // geom.draw(g, viewPort, symbol);
287
                                        FPoint2D p = (FPoint2D) geom.getInternalShape();
288
                                        Point2D.Double pOrig = new Point2D.Double(p.getX(), p.getY());
289
                                        Point2D pDest, pDest2;
290

    
291
                                        pDest = viewPort.getAffineTransform().transform(pOrig,null);
292
                                        pDest2 = g.getTransform().transform(pDest, null);
293

    
294
                                        pixX = (int) pDest2.getX();
295
                                        pixY = (int) pDest2.getY();
296
                                        if (symbol == null)
297
                                                continue;
298
                                        
299
                                        // pinta el pixel del grosor correspendiente
300
                                        if ((pixX > grosor) && (pixX < image.getWidth()-grosor) && (pixY > grosor) && (pixY < image.getHeight()-grosor)) {
301
                                                if (grosor == 0)
302
                                                        image.setRGB(pixX, pixY, symbol.getOnePointRgb());
303
                                                else{
304
                                                        for (ii=-grosor;ii<=grosor;ii++){
305
                                                                for (jj=-grosor;jj<=grosor;jj++){
306
                                                                        image.setRGB(pixX+ii, pixY+jj, symbol.getOnePointRgb());
307
                                                                }
308
                                                        }
309
                                                }
310
                                        }
311
                                        
312
                                        // si cae dentro de la vista
313
                                        if ((pixX > 1-incrementFast) && (pixX < image.getWidth()+incrementFast) && (pixY > 1-incrementFast) && (pixY < image.getHeight()-1+incrementFast)) {
314
                                                
315
                                                // El primer punto despues de no entrar ningun punto tras limiteIncrementoFast cambiara el incremento
316
                                                // y retrasara el indice de recorrido de puntos.
317
                                                if (contIN == 0){
318
                                                        
319
                                                        increment = incrementAux;
320
                                                        if (i>limiteIncremento)
321
                                                                i=i-limiteIncremento;
322
                                                }
323

    
324
                                                // si el punto cae dentro de la vista +/- incrementFast incrementamos contIN.
325
                                                contIN ++;
326
                                                contOUT=0;
327
                                                
328
                                        } else { // si caen fuera de la vista y supera el limiteIncrementoFast indicado nos pasamos al incremento rapido
329
                                                if (contOUT == limiteIncrementoFast){
330
                                                        
331
                                                        contIN=0;
332
                                                        increment = incrementFast;
333
                                                }
334
                                                
335
                                                contOUT++;
336
                                        }
337
                                }
338
                        }
339
/*
340
                        increment = incrementAux;
341
                        if (increment > 10)
342
                        {
343
                                for (int i = sc-increment/2; i > 0; i -= increment) {
344
                                        if (cancel.isCanceled()) {
345
                                                break;
346
                                        }
347
                                        IGeometry geom = adapter.getShape(i);
348
        
349
                                        if (geom == null) {
350
                                                continue;
351
                                        }
352
        
353
                                        if (ct != null) {
354
                                                if (bMustClone)
355
                                                        geom = geom.cloneGeometry();
356
                                                geom.reProject(ct);
357
                                        }
358
        
359
                                        ISymbol symbol = l.getSymbol(i);
360
        
361
                                        if (symbol == null)
362
                                                continue;
363
                                        if (bitSet != null)
364
                                                if (bitSet.get(i)) {
365
                                                        symbol = symbol.getSymbolForSelection();
366
                                                }
367
                                        if (symbol != null) {
368
                                                // geom.draw(g, viewPort, symbol);
369
                                                FPoint2D p = (FPoint2D) geom.getInternalShape();
370
                                                Point2D.Double pOrig = new Point2D.Double(p.getX(), p.getY());
371
                                                Point2D pDest, pDest2;
372
        
373
                                                pDest = viewPort.getAffineTransform().transform(pOrig,
374
                                                                null);
375
                                                pDest2 = g.getTransform().transform(pDest, null);
376
        
377
                                                pixX = (int) pDest2.getX();
378
                                                pixY = (int) pDest2.getY();
379
                                                if (symbol == null)
380
                                                        continue;
381
                                                
382
                                                if ((pixX > grosor) && (pixX < image.getWidth()-grosor) && (pixY > grosor) && (pixY < image.getHeight()-grosor)) 
383
                                                {
384
                                                        for (ii=-grosor;ii<=grosor;ii++)
385
                                                        {
386
                                                                for (jj=-grosor;jj<=grosor;jj++)
387
                                                                {
388
                                                                        image.setRGB(pixX+ii, pixY+jj, symbol.getOnePointRgb());
389
                                                                }
390
                                                        }
391
                                                }
392
                                                
393
                                                if ((pixX > 1-incrementFast) && (pixX < image.getWidth()+incrementFast) && (pixY > 1-incrementFast) && (pixY < image.getHeight()-1+incrementFast)) 
394
                                                {
395
                                                        if (contIN == 0)
396
                                                        {
397
                                                                increment = incrementAux;
398
                                                                if (i>incrementFast*10)
399
                                                                        i=i-incrementFast*10;
400
                                                        }
401
                                                        
402
                                                        contIN ++;
403
                                                        contOUT=0;
404
                                                }
405
                                                else
406
                                                {
407
                                                        if (contOUT == incrementFast*11)
408
                                                        {
409
                                                                contIN=0;
410
                                                                increment = incrementFast;
411
                                                        }
412
                                                        
413
                                                        contOUT++;
414
                                                }
415
                                        }
416
                                }
417
                        }
418
                        */
419
                        // logger.info("getCapa().getRecordset().stop()");
420
                        if (dsLidar != null)
421
                                dsLidar.stop();
422

    
423
                        // logger.debug("adapter.stop()");
424
                        rvLiDAR.stop();
425
                        // TODO: A revisar si es o no conveniente este sistema
426
                        // de comunicaci?n con los drivers.
427
                        // DriverAttributes attr = adapter.getDriverAttributes();
428
                        /*
429
                         * if (attr != null) { if (attr.isLoadedInMemory()) { // Quitamos lo
430
                         * de la reproyecci?n al vuelo para que // solo se haga una vez.
431
                         * getCapa().setCoordTrans(null); } }
432
                         */
433

    
434
                } catch (DriverIOException e) {
435
                        throw new DriverException(e);
436
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
437
                        throw new DriverException(e);
438
                } catch (DriverException e) {
439
                        throw new DriverException(e);
440
                }
441
        }
442
}