Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / operations / strategies / DefaultStrategy.java @ 7011

History | View | Annotate | Download (12.9 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 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
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.operations.strategies;
42

    
43
import java.awt.Graphics2D;
44
import java.awt.geom.AffineTransform;
45
import java.awt.geom.Point2D;
46
import java.awt.geom.Rectangle2D;
47
import java.awt.image.BufferedImage;
48
import java.util.BitSet;
49

    
50
import org.apache.log4j.Logger;
51
import org.cresques.cts.ICoordTrans;
52

    
53
import com.iver.cit.gvsig.fmap.DriverException;
54
import com.iver.cit.gvsig.fmap.ViewPort;
55
import com.iver.cit.gvsig.fmap.core.IGeometry;
56
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
57
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
58
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
59
import com.iver.cit.gvsig.fmap.layers.FBitSet;
60
import com.iver.cit.gvsig.fmap.layers.FLayer;
61
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
62
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
63
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
64
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
65
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
66
import com.iver.cit.gvsig.fmap.layers.layerOperations.Selectable;
67
import com.iver.cit.gvsig.fmap.layers.layerOperations.SingleLayer;
68
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
69
import com.iver.cit.gvsig.fmap.rendering.styling.FStyle2D;
70
import com.iver.utiles.swing.threads.Cancellable;
71
import com.iver.utiles.swing.threads.CancellableMonitorable;
72

    
73

    
74
/**
75
 * Implementa la Strategy por defecto. Los m?todos que tendr?n en com?n la
76
 * mayor parte de las estrategias
77
 */
78
public class DefaultStrategy implements Strategy {
79
    public static final int EQUALS = 0;
80
    public static final int DISJOINT = 1;
81
    public static final int INTERSECTS = 2;
82
    public static final int TOUCHES = 3;
83
    public static final int CROSSES = 4;
84
    public static final int WITHIN = 5;
85
    public static final int CONTAINS = 6;
86
    public static final int OVERLAPS = 7;
87

    
88
        private static Logger logger = Logger.getLogger(DefaultStrategy.class.getName());
89
        FLayer capa = null;
90
        
91
        /**
92
         * Crea un nuevo DefaultStrategy.
93
         *
94
         * @param capa DOCUMENT ME!
95
         */
96
        public DefaultStrategy(FLayer capa) {
97
                this.capa = capa;
98

    
99
                SingleLayer foo = (SingleLayer) capa;
100
                ClassifiableVectorial vectorial = (ClassifiableVectorial) capa;
101
        }
102

    
103
        /**
104
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByRect(java.awt.geom.Rectangle2D)
105
         */
106
        public FBitSet queryByRect(Rectangle2D rect, CancellableMonitorable cancel) throws DriverException {
107
                QueryByRectVisitor visitor = new QueryByRectVisitor();
108

    
109
                visitor.setRect(rect);
110

    
111
                try {
112
                        process(visitor, cancel);
113
                } catch (VisitException e) {
114
                        throw new RuntimeException(
115
                                "QueryByRectVisitor lanza una VisitException?");
116
                }
117

    
118
                return visitor.getBitSet();
119
        }
120

    
121
        /**
122
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByShape(com.iver.cit.gvsig.fmap.fshape.IGeometry,
123
         *                 int)
124
         */
125
        public FBitSet queryByShape(IGeometry g, int relationship, CancellableMonitorable cancel)
126
                throws DriverException, VisitException {
127
                QueryByGeometryVisitor visitor = new QueryByGeometryVisitor(g, relationship);
128
                process(visitor);
129

    
130
                return visitor.getBitSet();
131
        }
132

    
133
        /**
134
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#getSelectionBounds()
135
         */
136
        public Rectangle2D getSelectionBounds() {
137
                return null;
138
        }
139

    
140
        /**
141
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#createIndex()
142
         */
143
        public void createIndex() {
144
        }
145

    
146
        /**
147
         * @see com.iver.cit.gvsig.fmap.operations.LayerOperations#draw(java.awt.image.BufferedImage,
148
         *                 java.awt.Graphics2D, FStyle2D)
149
         */
150
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
151
                Cancellable cancel) throws DriverException {
152
                try {
153
                        ReadableVectorial adapter = ((SingleLayer) capa).getSource();
154
                        ICoordTrans ct = getCapa().getCoordTrans();
155
                        logger.debug("adapter.start()");
156
                        adapter.start();
157

    
158
                        logger.debug("getCapa().getRecordset().start()");
159
                        SelectableDataSource rsSel = ((AlphanumericData) getCapa()).getRecordset();
160
                        if (rsSel != null)
161
                            rsSel.start();
162

    
163
                        int sc;
164
                        Rectangle2D extent = viewPort.getAdjustedExtent();
165
                        AffineTransform at = viewPort.getAffineTransform();
166

    
167
                        sc = adapter.getShapeCount();
168
                        // TODO: A revisar si es o no conveniente este sistema
169
                        // de comunicaci?n con los drivers.
170
                        DriverAttributes attr = adapter.getDriverAttributes();
171
                        boolean bMustClone = false;
172
                        if (attr != null)
173
                        {
174
                            if (attr.isLoadedInMemory())
175
                            {
176
                                bMustClone = attr.isLoadedInMemory();
177
                            }
178
                        }
179
                        VectorialLegend l = (VectorialLegend) ((ClassifiableVectorial) capa).getLegend();
180
            FBitSet bitSet = null;
181
            if (getCapa() instanceof Selectable){
182
                Selectable selection = (Selectable) getCapa();
183
                bitSet = selection.getSelection();
184
            }
185
                        for (int i = 0; i < sc; i++) {
186
                                if (cancel.isCanceled()) {
187
                                        break;
188
                                }
189

    
190

    
191
                                IGeometry geom = adapter.getShape(i);
192

    
193
                                if (geom == null) {
194
                                        continue;
195
                                }
196

    
197
                                if (ct != null) {
198
                                    if (bMustClone)
199
                                        geom = geom.cloneGeometry();
200
                                        geom.reProject(ct);
201
                                }
202

    
203
                                // if (geom.intersects(extent)) {
204
                                if (geom.fastIntersects(extent.getMinX(), extent.getMinY(),
205
                                         extent.getWidth(), extent.getHeight())) {
206
                                        FSymbol symbol = l.getSymbol(i);
207

    
208
                    if (symbol ==null)
209
                        continue;
210
                    if (bitSet != null)
211
                        if (bitSet.get(i)) {
212
                                                    symbol = FSymbol.getSymbolForSelection(symbol);
213
                                            }
214
                                        geom.draw(g, viewPort, symbol);
215
                                        
216
                                }
217
                                /* else
218
                                {
219
                                    System.out.println("no pinto id=" + i);
220
                                } */
221
                        }
222

    
223
                        logger.debug("getCapa().getRecordset().stop()");
224
                        if (rsSel != null)
225
                            rsSel.stop();
226

    
227

    
228
                        logger.debug("adapter.stop()");
229
                        adapter.stop();
230
                        // TODO: A revisar si es o no conveniente este sistema
231
                        // de comunicaci?n con los drivers.
232
                        // DriverAttributes attr = adapter.getDriverAttributes();
233
                        /* if (attr != null)
234
                        {
235
                            if (attr.isLoadedInMemory())
236
                            {
237
                                // Quitamos lo de la reproyecci?n al vuelo para que
238
                                // solo se haga una vez.
239
                                getCapa().setCoordTrans(null);
240
                            }
241
                        } */
242

    
243
                } catch (DriverIOException e) {
244
                        throw new DriverException(e);
245
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
246
                    throw new DriverException(e);
247
                } catch (DriverException e) {
248
                    throw new DriverException(e);
249
        }
250
        }
251

    
252

    
253
        /**
254
         * Devuelve la capa.
255
         *
256
         * @return Returns the capa.
257
         */
258
        public FLayer getCapa() {
259
                return capa;
260
        }
261

    
262
        /**
263
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor,
264
         *                 java.util.BitSet)
265
         */
266
        public void process(FeatureVisitor visitor, BitSet subset)
267
                throws DriverException, VisitException {
268
                process(visitor, subset, null);
269
        }
270

    
271
        /**
272
         * DOCUMENT ME!
273
         *
274
         * @param visitor DOCUMENT ME!
275
         *
276
         * @throws DriverException DOCUMENT ME!
277
         * @throws VisitException
278
         *
279
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor)
280
         */
281
        public void process(FeatureVisitor visitor)
282
                throws DriverException, VisitException {
283
                process(visitor, (CancellableMonitorable)null);
284
        }
285

    
286
        /**
287
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByPoint(Point2D,
288
         *                 double)
289
         */
290
        public FBitSet queryByPoint(Point2D p, double tolerance, CancellableMonitorable cancel)
291
                throws DriverException {
292
        // TODO: OJO!!!!. Est? implementado como un rectangulo.
293
        // Lo correcto deber?a ser calculando las distancias reales
294
        // es decir, con un c?rculo.
295
        Rectangle2D recPoint = new Rectangle2D.Double(p.getX() - (tolerance / 2),
296
                p.getY() - (tolerance / 2), tolerance, tolerance);
297
                return queryByRect(recPoint);
298
        }
299

    
300
        /* (non-Javadoc)
301
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#print(java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort)
302
         */
303
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel)
304
                throws DriverException {
305
                draw(null, g, viewPort, cancel); // Quiero ejecutar el draw del padre, que es el que va sin acelaraci?n!!
306
        }
307

    
308
        public void process(FeatureVisitor visitor, Rectangle2D rectangle) throws DriverException, VisitException {
309
                process(visitor, rectangle, null);
310
        }
311
        
312
        /**
313
         * Verifies cancelation events, and return a boolean flag
314
         * if processes must be stopped for this cancelations events. 
315
         * 
316
         * @param cancel
317
         * @param va
318
         * @param visitor
319
         * @return
320
         * @throws DriverIOException 
321
         */
322
        protected boolean verifyCancelation(Cancellable cancel, ReadableVectorial va, FeatureVisitor visitor) throws DriverIOException{
323
                if(cancel != null){
324
                        if(cancel.isCanceled()){
325
                                va.stop();
326
                                visitor.stop(capa);
327
                                logger.debug("visitor canceled");
328
                                return true;
329
                        }
330
                }
331
                return false;
332
        }
333

    
334
        public void process(FeatureVisitor visitor, BitSet subset, CancellableMonitorable cancel) throws DriverException, VisitException {
335
                try {
336
                        logger.debug("visitor.start()");
337

    
338
                        if (visitor.start(capa)) {
339
                                ReadableVectorial va = ((SingleLayer) capa).getSource();
340
                                va.start();
341
                                for (int i = 0; i < va.getShapeCount(); i++) {
342
                                        
343
                                        if(verifyCancelation(cancel, va, visitor))
344
                                                return;
345
                                        if (subset.get(i)) {
346
                                                if(cancel != null){
347
                                                        cancel.reportStep();
348
                                                }
349
                                                visitor.visit(va.getShape(i), i);
350
                                        }
351
                                }
352
                                va.stop();
353

    
354
                                logger.debug("visitor.stop()");
355
                                visitor.stop(capa);
356
                        }
357
                } catch (DriverIOException e) {
358
                        throw new DriverException(e);
359
                }
360
        }
361

    
362
        public void process(FeatureVisitor visitor, CancellableMonitorable cancel) throws DriverException, VisitException {
363
                try {
364
                        logger.debug("visitor.start()");
365

    
366
                        if (visitor.start(capa)) {
367
                                ReadableVectorial va = ((SingleLayer) capa).getSource();
368
                                ICoordTrans ct = getCapa().getCoordTrans();
369
                                va.start();
370
                                for (int i = 0; i < va.getShapeCount(); i++) {
371
                                        if(cancel != null){
372
                                                cancel.reportStep();
373
                                        }
374
                                        if(verifyCancelation(cancel, va, visitor))
375
                                                return;
376
                                    IGeometry geom = va.getShape(i);
377
                                    if (ct != null) {
378
                                                geom.reProject(ct);
379
                                        }
380

    
381
                                        visitor.visit(geom, i);
382
                                }
383
                                va.stop();
384
                                logger.debug("visitor.stop()");
385
                                visitor.stop(capa);
386
                        }
387
                } catch (DriverIOException e) {
388
                        throw new DriverException(e);
389
                }
390
        }
391

    
392
        public void process(FeatureVisitor visitor, Rectangle2D rectangle, CancellableMonitorable cancel) throws DriverException, VisitException {
393
                FilterRectVisitor filterVisitor = new FilterRectVisitor();
394
                filterVisitor.setRectangle(rectangle);
395
                filterVisitor.setWrappedVisitor(visitor);
396
                try {
397
                        process(filterVisitor, cancel);
398
                } catch (VisitException e) {
399
                        throw new RuntimeException(
400
                                "process(visitor,rectangle) lanza una VisitException?");
401
                }                
402
        }
403

    
404
        public FBitSet queryByPoint(Point2D p, double tolerance) throws DriverException {
405
                return queryByPoint(p, tolerance, null);
406
        }
407

    
408
        public FBitSet queryByRect(Rectangle2D rect) throws DriverException {
409
                return queryByRect(rect, null);
410
        }
411

    
412
        public FBitSet queryByShape(IGeometry g, int relationship) throws DriverException, VisitException {
413
                return queryByShape(g, relationship, null);
414
        }
415

    
416
        /**
417
         * Tells when in a spatial query the use of an spatial index is an advanced,
418
         * or it would be better to use a secuential search.
419
         * <br>
420
         * The criteria to decide is the area of the query region. If it is less than
421
         * 1/4 of full extent layer region, the spatial index will be an improve.
422
         * Else, a secuential scan would be better
423
         * @param rectangle
424
         * @return
425
         * @throws DriverException
426
         */
427
        protected boolean isSpatialIndexNecessary(Rectangle2D extent) throws DriverException {
428
                FLyrVect lyr = (FLyrVect) getCapa();
429
                double areaExtent = extent.getWidth() * extent.getHeight();
430
                double areaFullExtent = lyr.getFullExtent().getWidth() *
431
                                                        lyr.getFullExtent().getHeight();
432
                return areaExtent < (areaFullExtent / 4.0);
433
        
434
        }
435

    
436
}