Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1015 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / operations / strategies / DefaultStrategy.java @ 13679

History | View | Annotate | Download (15.9 KB)

1 1260 fernando
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2 1100 fjp
 *
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 214 fernando
package com.iver.cit.gvsig.fmap.operations.strategies;
42
43 1828 fernando
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 9013 caballero
import javax.print.attribute.PrintRequestAttributeSet;
51
52 1828 fernando
import org.apache.log4j.Logger;
53
import org.cresques.cts.ICoordTrans;
54
55 652 fernando
import com.iver.cit.gvsig.fmap.DriverException;
56 214 fernando
import com.iver.cit.gvsig.fmap.ViewPort;
57 305 fjp
import com.iver.cit.gvsig.fmap.core.IGeometry;
58 8765 jjdelcerro
import com.iver.cit.gvsig.fmap.core.ISymbol;
59 1233 fjp
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
60 214 fernando
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
61 2183 fernando
import com.iver.cit.gvsig.fmap.layers.FBitSet;
62 562 fernando
import com.iver.cit.gvsig.fmap.layers.FLayer;
63 5490 caballero
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
64 3940 caballero
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
65 1691 fjp
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
66 1445 fjp
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
67 562 fernando
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
68 2613 caballero
import com.iver.cit.gvsig.fmap.layers.layerOperations.Selectable;
69 562 fernando
import com.iver.cit.gvsig.fmap.layers.layerOperations.SingleLayer;
70 321 fernando
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
71 5317 fjp
import com.iver.utiles.swing.threads.Cancellable;
72
import com.iver.utiles.swing.threads.CancellableMonitorable;
73 214 fernando
74
75
/**
76
 * Implementa la Strategy por defecto. Los m?todos que tendr?n en com?n la
77
 * mayor parte de las estrategias
78
 */
79
public class DefaultStrategy implements Strategy {
80 2979 fjp
    public static final int EQUALS = 0;
81
    public static final int DISJOINT = 1;
82
    public static final int INTERSECTS = 2;
83
    public static final int TOUCHES = 3;
84
    public static final int CROSSES = 4;
85
    public static final int WITHIN = 5;
86
    public static final int CONTAINS = 6;
87
    public static final int OVERLAPS = 7;
88 3940 caballero
89 528 vcaballero
        private static Logger logger = Logger.getLogger(DefaultStrategy.class.getName());
90 1704 fjp
        FLayer capa = null;
91 8765 jjdelcerro
92 214 fernando
        /**
93
         * Crea un nuevo DefaultStrategy.
94
         *
95
         * @param capa DOCUMENT ME!
96
         */
97 562 fernando
        public DefaultStrategy(FLayer capa) {
98 214 fernando
                this.capa = capa;
99 1034 vcaballero
100 562 fernando
                SingleLayer foo = (SingleLayer) capa;
101 1034 vcaballero
                ClassifiableVectorial vectorial = (ClassifiableVectorial) capa;
102 214 fernando
        }
103
104
        /**
105
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByRect(java.awt.geom.Rectangle2D)
106
         */
107 4347 azabala
        public FBitSet queryByRect(Rectangle2D rect, CancellableMonitorable cancel) throws DriverException {
108 562 fernando
                QueryByRectVisitor visitor = new QueryByRectVisitor();
109 980 fjp
110 235 vcaballero
                visitor.setRect(rect);
111 1034 vcaballero
112
                try {
113 4311 azabala
                        process(visitor, cancel);
114 929 fernando
                } catch (VisitException e) {
115 1034 vcaballero
                        throw new RuntimeException(
116
                                "QueryByRectVisitor lanza una VisitException?");
117 929 fernando
                }
118 562 fernando
119 235 vcaballero
                return visitor.getBitSet();
120 214 fernando
        }
121
122
        /**
123 305 fjp
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByShape(com.iver.cit.gvsig.fmap.fshape.IGeometry,
124 214 fernando
         *                 int)
125
         */
126 4347 azabala
        public FBitSet queryByShape(IGeometry g, int relationship, CancellableMonitorable cancel)
127 929 fernando
                throws DriverException, VisitException {
128 7011 fjp
                QueryByGeometryVisitor visitor = new QueryByGeometryVisitor(g, relationship);
129 235 vcaballero
                process(visitor);
130 562 fernando
131 235 vcaballero
                return visitor.getBitSet();
132 214 fernando
        }
133
134
        /**
135
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#getSelectionBounds()
136
         */
137
        public Rectangle2D getSelectionBounds() {
138
                return null;
139
        }
140
141
        /**
142
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#createIndex()
143
         */
144
        public void createIndex() {
145
        }
146
147
        /**
148 228 fernando
         * @see com.iver.cit.gvsig.fmap.operations.LayerOperations#draw(java.awt.image.BufferedImage,
149 8765 jjdelcerro
         *                 java.awt.Graphics2D, ISymbol)
150 214 fernando
         */
151 562 fernando
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
152 1034 vcaballero
                Cancellable cancel) throws DriverException {
153
                try {
154 3940 caballero
                        ReadableVectorial adapter = ((SingleLayer) capa).getSource();
155 1034 vcaballero
                        ICoordTrans ct = getCapa().getCoordTrans();
156 8765 jjdelcerro
//                        logger.info("adapter.start()");
157 1034 vcaballero
                        adapter.start();
158 214 fernando
159 8765 jjdelcerro
//                        logger.info("getCapa().getRecordset().start()");
160 3940 caballero
                        SelectableDataSource rsSel = ((AlphanumericData) getCapa()).getRecordset();
161 1691 fjp
                        if (rsSel != null)
162
                            rsSel.start();
163 1445 fjp
164 1034 vcaballero
                        int sc;
165
                        Rectangle2D extent = viewPort.getAdjustedExtent();
166
                        AffineTransform at = viewPort.getAffineTransform();
167 214 fernando
168 1034 vcaballero
                        sc = adapter.getShapeCount();
169 1484 fjp
                        // TODO: A revisar si es o no conveniente este sistema
170
                        // de comunicaci?n con los drivers.
171
                        DriverAttributes attr = adapter.getDriverAttributes();
172
                        boolean bMustClone = false;
173
                        if (attr != null)
174
                        {
175
                            if (attr.isLoadedInMemory())
176
                            {
177 3940 caballero
                                bMustClone = attr.isLoadedInMemory();
178 1484 fjp
                            }
179
                        }
180 1704 fjp
                        VectorialLegend l = (VectorialLegend) ((ClassifiableVectorial) capa).getLegend();
181 12976 fjp
            FBitSet bitSet = rsSel.getSelection();
182 1034 vcaballero
                        for (int i = 0; i < sc; i++) {
183
                                if (cancel.isCanceled()) {
184
                                        break;
185
                                }
186 562 fernando
187 3940 caballero
188 1034 vcaballero
                                IGeometry geom = adapter.getShape(i);
189 214 fernando
190 1034 vcaballero
                                if (geom == null) {
191
                                        continue;
192
                                }
193 562 fernando
194 1034 vcaballero
                                if (ct != null) {
195 1484 fjp
                                    if (bMustClone)
196 3940 caballero
                                        geom = geom.cloneGeometry();
197 1034 vcaballero
                                        geom.reProject(ct);
198
                                }
199 3940 caballero
200 1691 fjp
                                // if (geom.intersects(extent)) {
201 3940 caballero
                                if (geom.fastIntersects(extent.getMinX(), extent.getMinY(),
202 1691 fjp
                                         extent.getWidth(), extent.getHeight())) {
203 8765 jjdelcerro
                                        ISymbol symbol = l.getSymbol(i);
204 3940 caballero
205 2454 fjp
                    if (symbol ==null)
206
                        continue;
207 3302 fjp
                    if (bitSet != null)
208
                        if (bitSet.get(i)) {
209 8765 jjdelcerro
                                                    symbol = symbol.getSymbolForSelection();
210 3302 fjp
                                            }
211 8765 jjdelcerro
                    if (symbol != null)
212
                            geom.draw(g, viewPort, symbol);
213
214 1034 vcaballero
                                }
215 1691 fjp
                                /* else
216
                                {
217
                                    System.out.println("no pinto id=" + i);
218
                                } */
219 214 fernando
                        }
220
221 8765 jjdelcerro
//                        logger.info("getCapa().getRecordset().stop()");
222 1691 fjp
                        if (rsSel != null)
223
                            rsSel.stop();
224 1445 fjp
225 2183 fernando
226 8765 jjdelcerro
//                        logger.debug("adapter.stop()");
227 1034 vcaballero
                        adapter.stop();
228 1233 fjp
                        // TODO: A revisar si es o no conveniente este sistema
229
                        // de comunicaci?n con los drivers.
230 1484 fjp
                        // DriverAttributes attr = adapter.getDriverAttributes();
231
                        /* if (attr != null)
232 1233 fjp
                        {
233
                            if (attr.isLoadedInMemory())
234
                            {
235 3940 caballero
                                // Quitamos lo de la reproyecci?n al vuelo para que
236 1233 fjp
                                // solo se haga una vez.
237
                                getCapa().setCoordTrans(null);
238
                            }
239 1484 fjp
                        } */
240 214 fernando
241 1034 vcaballero
                } catch (DriverIOException e) {
242 652 fernando
                        throw new DriverException(e);
243 1828 fernando
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
244 1445 fjp
                    throw new DriverException(e);
245
                } catch (DriverException e) {
246
                    throw new DriverException(e);
247
        }
248 214 fernando
        }
249
250 5223 fjp
251 214 fernando
        /**
252 1034 vcaballero
         * Devuelve la capa.
253 214 fernando
         *
254
         * @return Returns the capa.
255
         */
256 562 fernando
        public FLayer getCapa() {
257 214 fernando
                return capa;
258
        }
259 216 fernando
260
        /**
261 562 fernando
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor,
262 1055 vcaballero
         *                 java.util.BitSet)
263 228 fernando
         */
264 562 fernando
        public void process(FeatureVisitor visitor, BitSet subset)
265 929 fernando
                throws DriverException, VisitException {
266 4311 azabala
                process(visitor, subset, null);
267
        }
268
269
        /**
270
         * DOCUMENT ME!
271
         *
272
         * @param visitor DOCUMENT ME!
273
         *
274
         * @throws DriverException DOCUMENT ME!
275
         * @throws VisitException
276
         *
277
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor)
278
         */
279
        public void process(FeatureVisitor visitor)
280
                throws DriverException, VisitException {
281 4347 azabala
                process(visitor, (CancellableMonitorable)null);
282 4311 azabala
        }
283
284
        /**
285
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByPoint(Point2D,
286
         *                 double)
287
         */
288 4347 azabala
        public FBitSet queryByPoint(Point2D p, double tolerance, CancellableMonitorable cancel)
289 4311 azabala
                throws DriverException {
290
        // TODO: OJO!!!!. Est? implementado como un rectangulo.
291
        // Lo correcto deber?a ser calculando las distancias reales
292
        // es decir, con un c?rculo.
293
        Rectangle2D recPoint = new Rectangle2D.Double(p.getX() - (tolerance / 2),
294
                p.getY() - (tolerance / 2), tolerance, tolerance);
295
                return queryByRect(recPoint);
296
        }
297
298
        /* (non-Javadoc)
299
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#print(java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort)
300
         */
301 9013 caballero
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintRequestAttributeSet properties)
302 4311 azabala
                throws DriverException {
303 9066 caballero
                if (capa instanceof FLyrVect) {
304
                        ((FLyrVect)capa).beforePrinting(properties);
305
                        draw(null, g, viewPort, cancel); // Quiero ejecutar el draw del padre, que es el que va sin acelaraci?n!!
306
                        ((FLyrVect)capa).afterPrinting();
307
                }else{
308
                        draw(null, g, viewPort, cancel); // Quiero ejecutar el draw del padre, que es el que va sin acelaraci?n!!
309
                }
310 4311 azabala
        }
311
312
        public void process(FeatureVisitor visitor, Rectangle2D rectangle) throws DriverException, VisitException {
313
                process(visitor, rectangle, null);
314
        }
315 8765 jjdelcerro
316 4311 azabala
        /**
317
         * Verifies cancelation events, and return a boolean flag
318 8765 jjdelcerro
         * if processes must be stopped for this cancelations events.
319
         *
320 4311 azabala
         * @param cancel
321
         * @param va
322
         * @param visitor
323
         * @return
324 8765 jjdelcerro
         * @throws DriverIOException
325 4311 azabala
         */
326
        protected boolean verifyCancelation(Cancellable cancel, ReadableVectorial va, FeatureVisitor visitor) throws DriverIOException{
327
                if(cancel != null){
328
                        if(cancel.isCanceled()){
329
                                va.stop();
330
                                visitor.stop(capa);
331 8765 jjdelcerro
//                                logger.info("visitor canceled");
332 4311 azabala
                                return true;
333
                        }
334
                }
335
                return false;
336
        }
337
338 4347 azabala
        public void process(FeatureVisitor visitor, BitSet subset, CancellableMonitorable cancel) throws DriverException, VisitException {
339 1034 vcaballero
                try {
340 8765 jjdelcerro
//                        logger.info("visitor.start()");
341 562 fernando
342 1034 vcaballero
                        if (visitor.start(capa)) {
343 3940 caballero
                                ReadableVectorial va = ((SingleLayer) capa).getSource();
344 1253 fernando
                                va.start();
345 1034 vcaballero
                                for (int i = 0; i < va.getShapeCount(); i++) {
346 8765 jjdelcerro
347 4311 azabala
                                        if(verifyCancelation(cancel, va, visitor))
348
                                                return;
349 1034 vcaballero
                                        if (subset.get(i)) {
350 4502 azabala
                                                if(cancel != null){
351
                                                        cancel.reportStep();
352
                                                }
353 1034 vcaballero
                                                visitor.visit(va.getShape(i), i);
354
                                        }
355 562 fernando
                                }
356 1253 fernando
                                va.stop();
357 562 fernando
358 8765 jjdelcerro
//                                logger.info("visitor.stop()");
359 1034 vcaballero
                                visitor.stop(capa);
360
                        }
361
                } catch (DriverIOException e) {
362
                        throw new DriverException(e);
363 229 vcaballero
                }
364 228 fernando
        }
365 562 fernando
366 4347 azabala
        public void process(FeatureVisitor visitor, CancellableMonitorable cancel) throws DriverException, VisitException {
367 1034 vcaballero
                try {
368 8765 jjdelcerro
//                        logger.info("visitor.start()");
369 562 fernando
370 1034 vcaballero
                        if (visitor.start(capa)) {
371 3940 caballero
                                ReadableVectorial va = ((SingleLayer) capa).getSource();
372 1293 fjp
                                ICoordTrans ct = getCapa().getCoordTrans();
373 1253 fernando
                                va.start();
374 1034 vcaballero
                                for (int i = 0; i < va.getShapeCount(); i++) {
375 4419 azabala
                                        if(cancel != null){
376
                                                cancel.reportStep();
377
                                        }
378 4311 azabala
                                        if(verifyCancelation(cancel, va, visitor))
379
                                                return;
380 1293 fjp
                                    IGeometry geom = va.getShape(i);
381
                                    if (ct != null) {
382
                                                geom.reProject(ct);
383
                                        }
384
385
                                        visitor.visit(geom, i);
386 1034 vcaballero
                                }
387 1253 fernando
                                va.stop();
388 8765 jjdelcerro
//                                logger.info("visitor.stop()");
389 1034 vcaballero
                                visitor.stop(capa);
390
                        }
391
                } catch (DriverIOException e) {
392 652 fernando
                        throw new DriverException(e);
393 1034 vcaballero
                }
394 232 vcaballero
        }
395 562 fernando
396 4347 azabala
        public void process(FeatureVisitor visitor, Rectangle2D rectangle, CancellableMonitorable cancel) throws DriverException, VisitException {
397 4200 azabala
                FilterRectVisitor filterVisitor = new FilterRectVisitor();
398
                filterVisitor.setRectangle(rectangle);
399
                filterVisitor.setWrappedVisitor(visitor);
400
                try {
401 4311 azabala
                        process(filterVisitor, cancel);
402 4200 azabala
                } catch (VisitException e) {
403
                        throw new RuntimeException(
404
                                "process(visitor,rectangle) lanza una VisitException?");
405 8765 jjdelcerro
                }
406 4200 azabala
        }
407 4311 azabala
408
        public FBitSet queryByPoint(Point2D p, double tolerance) throws DriverException {
409
                return queryByPoint(p, tolerance, null);
410
        }
411
412
        public FBitSet queryByRect(Rectangle2D rect) throws DriverException {
413
                return queryByRect(rect, null);
414
        }
415
416
        public FBitSet queryByShape(IGeometry g, int relationship) throws DriverException, VisitException {
417
                return queryByShape(g, relationship, null);
418
        }
419
420 5490 caballero
        /**
421
         * Tells when in a spatial query the use of an spatial index is an advanced,
422
         * or it would be better to use a secuential search.
423
         * <br>
424
         * The criteria to decide is the area of the query region. If it is less than
425
         * 1/4 of full extent layer region, the spatial index will be an improve.
426
         * Else, a secuential scan would be better
427
         * @param rectangle
428
         * @return
429
         * @throws DriverException
430
         */
431
        protected boolean isSpatialIndexNecessary(Rectangle2D extent) throws DriverException {
432
                FLyrVect lyr = (FLyrVect) getCapa();
433
                double areaExtent = extent.getWidth() * extent.getHeight();
434
                double areaFullExtent = lyr.getFullExtent().getWidth() *
435
                                                        lyr.getFullExtent().getHeight();
436
                return areaExtent < (areaFullExtent / 4.0);
437 8765 jjdelcerro
438 5490 caballero
        }
439
440 10716 jcampos
        /**
441
         * Similar to process, but calls visitWithSymbol in FeatureVisitor.
442
         * @param visitor
443
         * @param rectangle
444
         * @param cancel
445
         * @throws DriverException
446
         * @throws VisitException
447
         */
448
        public void processWithSymbols(ExtendsFeatureVisitor visitor, Rectangle2D extent, CancellableMonitorable cancel) throws DriverException, VisitException {
449
450
                if (visitor==null)
451
                        return;
452
453
                /*IGeometry geom = null;
454
                int index = -1;
455
                ISymbol symbol = null;
456
                visitor.visitWithSymbol(geom, index, symbol); // TEST */
457
458
                try {
459
                        ReadableVectorial adapter = ((SingleLayer) capa).getSource();
460
                        ICoordTrans ct = getCapa().getCoordTrans();
461
                        //logger.debug("adapter.start()");
462
                        adapter.start();
463
464
                        //logger.debug("getCapa().getRecordset().start()");
465
                        SelectableDataSource rsSel = ((AlphanumericData) getCapa()).getRecordset();
466
                        if (rsSel != null)
467
                            rsSel.start();
468
469
                        int sc = adapter.getShapeCount();
470
471
                        // TODO: A revisar si es o no conveniente este sistema
472
                        // de comunicaci?n con los drivers.
473
                        DriverAttributes attr = adapter.getDriverAttributes();
474
                        boolean bMustClone = false;
475
                        if (attr != null)
476
                        {
477
                            if (attr.isLoadedInMemory())
478
                            {
479
                                bMustClone = attr.isLoadedInMemory();
480
                            }
481
                        }
482
                        VectorialLegend l = (VectorialLegend) ((ClassifiableVectorial) capa).getLegend();
483
            FBitSet bitSet = null;
484
            if (getCapa() instanceof Selectable){
485
                Selectable selection = (Selectable) getCapa();
486
                bitSet = selection.getSelection();
487
            }
488
                        for (int i = 0; i < sc; i++) {
489
                                if (cancel!=null && cancel.isCanceled()) {
490
                                        break;
491
                                }
492
493
                                IGeometry geom = adapter.getShape(i);
494
495
                                if (geom == null) {
496
                                        continue;
497
                                }
498
499
                                if (ct != null) {
500
                                    if (bMustClone)
501
                                        geom = geom.cloneGeometry();
502
                                        geom.reProject(ct);
503
                                }
504
505
                                if (extent == null ||
506
                                                geom.fastIntersects(extent.getMinX(), extent.getMinY(),
507
                                             extent.getWidth(), extent.getHeight())) {
508
                                        ISymbol symbol = l.getSymbol(i);
509
510
                    if (symbol ==null)
511
                        continue;
512
                    if (bitSet != null)
513
                        if (bitSet.get(i)) {
514
                                                    symbol = symbol.getSymbolForSelection();
515
                                            }
516
                                        // send feature for process in visitor
517
                                        visitor.visitWithSymbol(geom, i, symbol);
518
519
                                }
520
                                /* else
521
                                {
522
                                    System.out.println("no pinto id=" + i);
523
                                } */
524
                        }
525
526
                        //logger.debug("getCapa().getRecordset().stop()");
527
                        if (rsSel != null)
528
                            rsSel.stop();
529
530
                        //logger.debug("adapter.stop()");
531
                        adapter.stop();
532
533
                } catch (DriverIOException e) {
534
                        throw new DriverException(e);
535
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
536
                    throw new DriverException(e);
537
                } catch (DriverException e) {
538
                    throw new DriverException(e);
539
        }
540
        }
541
542
543 214 fernando
}