Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / operations / strategies / DefaultStrategy.java @ 10627

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

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

    
55
import com.hardcode.gdbms.driver.exceptions.InitializeDriverException;
56
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
57
import com.hardcode.gdbms.engine.data.driver.DriverException;
58
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
59
import com.iver.cit.gvsig.exceptions.visitors.StopVisitorException;
60
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
61
import com.iver.cit.gvsig.fmap.ViewPort;
62
import com.iver.cit.gvsig.fmap.core.IGeometry;
63
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
64
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
65
import com.iver.cit.gvsig.fmap.layers.FBitSet;
66
import com.iver.cit.gvsig.fmap.layers.FLayer;
67
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
68
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
69
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
70
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
71
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
72
import com.iver.cit.gvsig.fmap.layers.layerOperations.Selectable;
73
import com.iver.cit.gvsig.fmap.layers.layerOperations.SingleLayer;
74
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
75
import com.iver.utiles.swing.threads.Cancellable;
76
import com.iver.utiles.swing.threads.CancellableMonitorable;
77

    
78

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

    
93
        private static Logger logger = Logger.getLogger(DefaultStrategy.class.getName());
94
        FLayer capa = null;
95

    
96
        /**
97
         * Crea un nuevo DefaultStrategy.
98
         *
99
         * @param capa DOCUMENT ME!
100
         */
101
        public DefaultStrategy(FLayer capa) {
102
                this.capa = capa;
103

    
104
                SingleLayer foo = (SingleLayer) capa;
105
                ClassifiableVectorial vectorial = (ClassifiableVectorial) capa;
106
        }
107

    
108
        /**
109
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByRect(java.awt.geom.Rectangle2D)
110
         */
111
        public FBitSet queryByRect(Rectangle2D rect, CancellableMonitorable cancel) throws ReadDriverException, VisitorException {
112
                QueryByRectVisitor visitor = new QueryByRectVisitor();
113

    
114
                visitor.setRect(rect);
115
                process(visitor, cancel);
116
                return visitor.getBitSet();
117
        }
118

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

    
128
                return visitor.getBitSet();
129
        }
130

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

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

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

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

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

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

    
189

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

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

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

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

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

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

    
223
//                        logger.info("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 (ExpansionFileReadException e) {
244
                        throw new ReadDriverException(getCapa().getName(),e);
245
                } catch (InitializeDriverException e) {
246
                        throw new ReadDriverException(getCapa().getName(),e);
247
                }
248
        }
249

    
250

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

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

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

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

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

    
309
        public void process(FeatureVisitor visitor, Rectangle2D rectangle) throws ReadDriverException, ExpansionFileReadException, VisitorException {
310
                process(visitor, rectangle, null);
311
        }
312

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

    
340
        public void process(FeatureVisitor visitor, BitSet subset, CancellableMonitorable cancel) throws ReadDriverException, ExpansionFileReadException, VisitorException {
341
//                try {
342
//                        logger.info("visitor.start()");
343

    
344
                        if (visitor.start(capa)) {
345
                                ReadableVectorial va = ((SingleLayer) capa).getSource();
346
                                try {
347
                                        va.start();
348
                                } catch (InitializeDriverException e) {
349
                                        throw new ReadDriverException(getCapa().getName(),e);
350
                                }
351
                                for (int i = 0; i < va.getShapeCount(); i++) {
352

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

    
364
//                                logger.info("visitor.stop()");
365
                                visitor.stop(capa);
366
                        }
367
//                } catch (ExpansionFileReadException e) {
368
//                        throw new ReadDriverException();
369
//                }
370
        }
371

    
372
        public void process(FeatureVisitor visitor, CancellableMonitorable cancel) throws ReadDriverException, VisitorException {
373
                try {
374
//                        logger.info("visitor.start()");
375

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

    
391
                                        visitor.visit(geom, i);
392
                                }
393
                                va.stop();
394
//                                logger.info("visitor.stop()");
395
                                visitor.stop(capa);
396
                        }
397
                } catch (ExpansionFileReadException e) {
398
                        throw new ReadDriverException(getCapa().getName(),e);
399
                } catch (InitializeDriverException e) {
400
                        throw new ReadDriverException(getCapa().getName(),e);
401
                }
402
        }
403

    
404
        public void process(FeatureVisitor visitor, Rectangle2D rectangle, CancellableMonitorable cancel) throws ReadDriverException, ExpansionFileReadException, VisitorException {
405
                FilterRectVisitor filterVisitor = new FilterRectVisitor();
406
                filterVisitor.setRectangle(rectangle);
407
                filterVisitor.setWrappedVisitor(visitor);
408
                process(filterVisitor, cancel);
409
        }
410

    
411
        public FBitSet queryByPoint(Point2D p, double tolerance) throws ReadDriverException, VisitorException {
412
                return queryByPoint(p, tolerance, null);
413
        }
414

    
415
        public FBitSet queryByRect(Rectangle2D rect) throws ReadDriverException, VisitorException {
416
                return queryByRect(rect, null);
417
        }
418

    
419
        public FBitSet queryByShape(IGeometry g, int relationship) throws ReadDriverException, VisitorException {
420
                return queryByShape(g, relationship, null);
421
        }
422

    
423
        /**
424
         * Tells when in a spatial query the use of an spatial index is an advanced,
425
         * or it would be better to use a secuential search.
426
         * <br>
427
         * The criteria to decide is the area of the query region. If it is less than
428
         * 1/4 of full extent layer region, the spatial index will be an improve.
429
         * Else, a secuential scan would be better
430
         * @param rectangle
431
         * @return
432
         * @throws ExpansionFileReadException
433
         * @throws DriverException
434
         */
435
        protected boolean isSpatialIndexNecessary(Rectangle2D extent) throws ReadDriverException, ExpansionFileReadException {
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
}