Statistics
| Revision:

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

History | View | Annotate | Download (13.2 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 javax.print.attribute.PrintRequestAttributeSet;
51

    
52
import org.apache.log4j.Logger;
53
import org.cresques.cts.ICoordTrans;
54

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

    
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
    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

    
89
        private static Logger logger = Logger.getLogger(DefaultStrategy.class.getName());
90
        FLayer capa = null;
91

    
92
        /**
93
         * Crea un nuevo DefaultStrategy.
94
         *
95
         * @param capa DOCUMENT ME!
96
         */
97
        public DefaultStrategy(FLayer capa) {
98
                this.capa = capa;
99

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

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

    
110
                visitor.setRect(rect);
111

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

    
119
                return visitor.getBitSet();
120
        }
121

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

    
131
                return visitor.getBitSet();
132
        }
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
         * @see com.iver.cit.gvsig.fmap.operations.LayerOperations#draw(java.awt.image.BufferedImage,
149
         *                 java.awt.Graphics2D, ISymbol)
150
         */
151
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
152
                Cancellable cancel) throws DriverException {
153
                try {
154
                        ReadableVectorial adapter = ((SingleLayer) capa).getSource();
155
                        ICoordTrans ct = getCapa().getCoordTrans();
156
//                        logger.info("adapter.start()");
157
                        adapter.start();
158

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

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

    
168
                        sc = adapter.getShapeCount();
169
                        // 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
                                bMustClone = attr.isLoadedInMemory();
178
                            }
179
                        }
180
                        VectorialLegend l = (VectorialLegend) ((ClassifiableVectorial) capa).getLegend();
181
            FBitSet bitSet = null;
182
            if (getCapa() instanceof Selectable){
183
                Selectable selection = (Selectable) getCapa();
184
                bitSet = selection.getSelection();
185
            }
186
                        for (int i = 0; i < sc; i++) {
187
                                if (cancel.isCanceled()) {
188
                                        break;
189
                                }
190

    
191

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

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

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

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

    
209
                    if (symbol ==null)
210
                        continue;
211
                    if (bitSet != null)
212
                        if (bitSet.get(i)) {
213
                                                    symbol = symbol.getSymbolForSelection();
214
                                            }
215
                    if (symbol != null)
216
                            geom.draw(g, viewPort, symbol);
217

    
218
                                }
219
                                /* else
220
                                {
221
                                    System.out.println("no pinto id=" + i);
222
                                } */
223
                        }
224

    
225
//                        logger.info("getCapa().getRecordset().stop()");
226
                        if (rsSel != null)
227
                            rsSel.stop();
228

    
229

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

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

    
254

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

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

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

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

    
302
        /* (non-Javadoc)
303
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#print(java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort)
304
         */
305
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintRequestAttributeSet properties)
306
                throws DriverException {
307
                if (capa instanceof FLyrVect) {
308
                        ((FLyrVect)capa).beforePrinting(properties);
309
                        draw(null, g, viewPort, cancel); // Quiero ejecutar el draw del padre, que es el que va sin acelaraci?n!!
310
                        ((FLyrVect)capa).afterPrinting();
311
                }else{
312
                        draw(null, g, viewPort, cancel); // Quiero ejecutar el draw del padre, que es el que va sin acelaraci?n!!
313
                }
314
        }
315

    
316
        public void process(FeatureVisitor visitor, Rectangle2D rectangle) throws DriverException, VisitException {
317
                process(visitor, rectangle, null);
318
        }
319

    
320
        /**
321
         * Verifies cancelation events, and return a boolean flag
322
         * if processes must be stopped for this cancelations events.
323
         *
324
         * @param cancel
325
         * @param va
326
         * @param visitor
327
         * @return
328
         * @throws DriverIOException
329
         */
330
        protected boolean verifyCancelation(Cancellable cancel, ReadableVectorial va, FeatureVisitor visitor) throws DriverIOException{
331
                if(cancel != null){
332
                        if(cancel.isCanceled()){
333
                                va.stop();
334
                                visitor.stop(capa);
335
//                                logger.info("visitor canceled");
336
                                return true;
337
                        }
338
                }
339
                return false;
340
        }
341

    
342
        public void process(FeatureVisitor visitor, BitSet subset, CancellableMonitorable cancel) throws DriverException, VisitException {
343
                try {
344
//                        logger.info("visitor.start()");
345

    
346
                        if (visitor.start(capa)) {
347
                                ReadableVectorial va = ((SingleLayer) capa).getSource();
348
                                va.start();
349
                                for (int i = 0; i < va.getShapeCount(); i++) {
350

    
351
                                        if(verifyCancelation(cancel, va, visitor))
352
                                                return;
353
                                        if (subset.get(i)) {
354
                                                if(cancel != null){
355
                                                        cancel.reportStep();
356
                                                }
357
                                                visitor.visit(va.getShape(i), i);
358
                                        }
359
                                }
360
                                va.stop();
361

    
362
//                                logger.info("visitor.stop()");
363
                                visitor.stop(capa);
364
                        }
365
                } catch (DriverIOException e) {
366
                        throw new DriverException(e);
367
                }
368
        }
369

    
370
        public void process(FeatureVisitor visitor, CancellableMonitorable cancel) throws DriverException, VisitException {
371
                try {
372
//                        logger.info("visitor.start()");
373

    
374
                        if (visitor.start(capa)) {
375
                                ReadableVectorial va = ((SingleLayer) capa).getSource();
376
                                ICoordTrans ct = getCapa().getCoordTrans();
377
                                va.start();
378
                                for (int i = 0; i < va.getShapeCount(); i++) {
379
                                        if(cancel != null){
380
                                                cancel.reportStep();
381
                                        }
382
                                        if(verifyCancelation(cancel, va, visitor))
383
                                                return;
384
                                    IGeometry geom = va.getShape(i);
385
                                    if (ct != null) {
386
                                                geom.reProject(ct);
387
                                        }
388

    
389
                                        visitor.visit(geom, i);
390
                                }
391
                                va.stop();
392
//                                logger.info("visitor.stop()");
393
                                visitor.stop(capa);
394
                        }
395
                } catch (DriverIOException e) {
396
                        throw new DriverException(e);
397
                }
398
        }
399

    
400
        public void process(FeatureVisitor visitor, Rectangle2D rectangle, CancellableMonitorable cancel) throws DriverException, VisitException {
401
                FilterRectVisitor filterVisitor = new FilterRectVisitor();
402
                filterVisitor.setRectangle(rectangle);
403
                filterVisitor.setWrappedVisitor(visitor);
404
                try {
405
                        process(filterVisitor, cancel);
406
                } catch (VisitException e) {
407
                        throw new RuntimeException(
408
                                "process(visitor,rectangle) lanza una VisitException?");
409
                }
410
        }
411

    
412
        public FBitSet queryByPoint(Point2D p, double tolerance) throws DriverException {
413
                return queryByPoint(p, tolerance, null);
414
        }
415

    
416
        public FBitSet queryByRect(Rectangle2D rect) throws DriverException {
417
                return queryByRect(rect, null);
418
        }
419

    
420
        public FBitSet queryByShape(IGeometry g, int relationship) throws DriverException, VisitException {
421
                return queryByShape(g, relationship, null);
422
        }
423

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

    
442
        }
443

    
444
}