Statistics
| Revision:

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

History | View | Annotate | Download (23.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.Point2D;
45
import java.awt.geom.Rectangle2D;
46
import java.awt.image.BufferedImage;
47
import java.io.IOException;
48
import java.util.BitSet;
49
import java.util.List;
50

    
51
import org.apache.log4j.Logger;
52
import org.cresques.cts.ICoordTrans;
53
import org.geotools.resources.geometry.XRectangle2D;
54

    
55
import com.hardcode.driverManager.DriverLoadException;
56
import com.iver.cit.gvsig.fmap.DriverException;
57
import com.iver.cit.gvsig.fmap.ViewPort;
58
import com.iver.cit.gvsig.fmap.core.FShape;
59
import com.iver.cit.gvsig.fmap.core.Handler;
60
import com.iver.cit.gvsig.fmap.core.IGeometry;
61
import com.iver.cit.gvsig.fmap.core.v02.FGraphicUtilities;
62
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
63
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
64
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
65
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
66
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
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.FLyrVect;
70
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
71
import com.iver.cit.gvsig.fmap.layers.VectorialAdapter;
72
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
73
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
74
import com.iver.cit.gvsig.fmap.layers.layerOperations.Selectable;
75
import com.iver.cit.gvsig.fmap.layers.layerOperations.SingleLayer;
76
import com.iver.cit.gvsig.fmap.operations.Cancellable;
77
import com.iver.cit.gvsig.fmap.operations.CancellableMonitorable;
78
import com.iver.cit.gvsig.fmap.rendering.ClassifiedLegendInfo;
79
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
80
import com.iver.cit.gvsig.fmap.rendering.styling.FStyle2D;
81
import com.vividsolutions.jts.geom.Coordinate;
82
import com.vividsolutions.jts.geom.Envelope;
83
import com.vividsolutions.jts.geom.Geometry;
84
import com.vividsolutions.jts.geom.IntersectionMatrix;
85

    
86

    
87
/**
88
 * Esta clase definir? las operaciones de la interfaz FLyrVect de la manera m?s
89
 * ?ptima para los ficheros shp.
90
 */
91
public class ShpStrategy extends DefaultStrategy {
92
        private static Logger logger = Logger.getLogger(ShpStrategy.class.getName());
93

    
94
        /**
95
         * Crea una ShpStrategy.
96
         *
97
         * @param capa
98
         */
99
        public ShpStrategy(FLayer capa) {
100
                super(capa);
101
        }
102

    
103
        /**
104
         * @see com.iver.cit.gvsig.fmap.operations.LayerOperations#draw(java.awt.image.BufferedImage,
105
         *                 java.awt.Graphics2D, FStyle2D)
106
         */
107
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
108
                Cancellable cancel) throws DriverException {
109
                try {
110
                        ReadableVectorial adapter = ((SingleLayer) getCapa()).getSource();
111
                        if (adapter.getShapeCount() <= 0)
112
                        {
113
                            logger.debug("Layer:" + getCapa().getName() + " sin registros");
114
                            return;
115
                        }
116
                        
117
                        //Selectable selection = (Selectable) getCapa();
118
            FLyrVect lyr = (FLyrVect) getCapa();
119
                        Selectable selectable=lyr.getRecordset();
120
            ICoordTrans ct = getCapa().getCoordTrans();
121
                        FBitSet bitSet = selectable.getSelection();
122
                        BoundedShapes shapeBounds;
123
                        if (adapter instanceof BoundedShapes)
124
                                 shapeBounds = (BoundedShapes) adapter;
125
                        else
126
                                shapeBounds = (BoundedShapes) adapter.getDriver();
127
                        // VectorialFileDriver driver = (VectorialFileDriver) adapter.getDriver();
128
                        // logger.debug("adapter.start() -> Layer:" + getCapa().getName());
129
                        adapter.start();
130
                        IGeometry geom;
131
                        if (adapter.getShapeCount()>0){
132
                        geom = adapter.getShape(0);
133
                        }
134
                        VectorialLegend l = (VectorialLegend) ((ClassifiableVectorial) getCapa()).getLegend();
135

    
136
                        if (l instanceof ClassifiedLegendInfo) {
137
                                ClassifiedLegendInfo clsfLegend = (ClassifiedLegendInfo) l;
138
                                FSymbol[] symbs = clsfLegend.getSymbols();
139
                                //double rSym = 0;
140
                                //double maxRSym = -1;
141

    
142
                                for (int i = 0; i < symbs.length; i++) {
143
                                        // TODO: REVISAR LOS SIMBOLOS Y SUS TAMA?OS
144

    
145
                                        /* Style2D pointSymbol = symbs[i].getPointStyle2D();
146
                                           if (pointSymbol instanceof MarkStyle2D)
147
                                           {
148
                                                   MarkStyle2D mrk2D = (MarkStyle2D) pointSymbol;
149
                                                   rSym = viewPort.toMapDistance(mrk2D.getSize());
150
                                                   if (maxRSym < rSym)
151
                                                           maxRSym = rSym;
152
                                           }*/
153
                                }
154
                        }
155

    
156
                        Rectangle2D extent = viewPort.getAdjustedExtent();
157
                        //AffineTransform at = viewPort.getAffineTransform();
158

    
159
                        int sc;
160

    
161
                        Rectangle2D bounds;
162

    
163

    
164

    
165
                        long t1 = System.currentTimeMillis();
166
                        // logger.debug("getCapa().getRecordset().start()");
167
                        ((FLyrVect) getCapa()).getRecordset().start();
168

    
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

    
181
            List lstIndexes = null;
182

    
183
            // If area of needed extent is less than fullExtent / 4,
184
            // it will be worthy to use SpatialIndex.
185
            // Otherwhise, we will not use it.
186
                        boolean bUseSpatialIndex = false;
187
            sc = adapter.getShapeCount();
188
            if (lyr.getSpatialIndex() != null)
189
            {
190
                double areaExtent = extent.getWidth() * extent.getHeight();
191
                double areaFullExtent = lyr.getFullExtent().getWidth() *
192
                                                lyr.getFullExtent().getHeight();
193
                if (areaExtent < (areaFullExtent / 4.0))
194
                {
195
                    Coordinate c1 = new Coordinate(extent.getMinX(), extent.getMinY());
196
                    Coordinate c2 = new Coordinate(extent.getMaxX(), extent.getMaxY());
197
                    Envelope env = new Envelope(c1, c2);
198
                    lstIndexes = lyr.getSpatialIndex().query(env);
199
                    sc = lstIndexes.size();
200
                    bUseSpatialIndex = true;
201
                }
202
            }
203
            int i;
204

    
205
                        for (int aux = 0; aux < sc; aux++) {
206
                                // Salimos si alguien cancela
207
                                if(cancel != null){//azabala (por si acaso, al arreglar bug de process)
208
                                        if (cancel.isCanceled()) {
209
                                                break;
210
                                        }
211
                                }
212
                if (bUseSpatialIndex)
213
                {
214
                    Integer idRec = (Integer) lstIndexes.get(aux);
215
                    i = idRec.intValue();
216
                }
217
                else
218
                {
219
                    i = aux;
220
                }
221

    
222
                                bounds = shapeBounds.getShapeBounds(i);
223

    
224
                                if (ct != null) {
225
                                        bounds = ct.convert(bounds);
226
                                }
227

    
228
                                if (XRectangle2D.intersectInclusive(extent, bounds)) {
229
                                        FSymbol symbol = l.getSymbol(i);
230

    
231
                                        if (bitSet.get(i)) {
232
                                                symbol = FSymbol.getSymbolForSelection(symbol);
233
                                        }
234

    
235
                                        boolean bPoint = (shapeBounds.getShapeType(i) == FShape.POINT);
236

    
237
                                        if (bPoint ||
238
                                                        ((bounds.getHeight() > viewPort.getDist1pixel()) ||
239
                                                        (bounds.getWidth() > viewPort.getDist1pixel()))) {
240
                                                geom = adapter.getShape(i);
241

    
242
                        // PRUEBA DE VELOCIDAD
243
                        // geom = ShapeFactory.createPolygon2D(new GeneralPathX(bounds));
244

    
245
                                                if (ct != null) {
246
                                                    if (bMustClone)
247
                                                        geom = geom.cloneGeometry();
248
                                                        geom.reProject(ct);
249
                                                }
250
                        // FJP: CAMBIO: Sabemos que vamos a dibujar sobre una
251
                        // imagen, con coordenadas enteras, as?
252
                        // que lo tenemos en cuenta.
253
                                                // ANTES: geom.draw(g, viewPort, symbol);
254
                        // AHORA:
255
                        geom.drawInts(g, viewPort, symbol);
256
                        // geom.draw(g, viewPort, symbol);
257
                        /* if (lyr.isEditing())
258
                        {
259
                                if (bitSet.get(i))
260
                                {
261
                                        Handler[] handlers = geom.getHandlers(IGeometry.SELECTHANDLER);
262
                                        FGraphicUtilities.DrawHandlers(g, viewPort.getAffineTransform(), handlers);
263
                                }
264
                        } */
265

    
266

    
267

    
268
                                        } else {
269
                                                Point2D.Double pOrig = new Point2D.Double(bounds.getMinX(),
270
                                                                bounds.getMinY());
271
                                                Point2D pDest, pDest2;
272

    
273
                                                pDest = viewPort.getAffineTransform().transform(pOrig, null);
274
                        pDest2 = g.getTransform().transform(pDest, null);
275

    
276
                                                int pixX = (int) pDest2.getX();
277
                                                int pixY = (int) pDest2.getY();
278
                                                if (symbol ==null)
279
                                                        continue;
280
                                                if ((pixX > 0) && (pixX < image.getWidth())) {
281
                                                        if ((pixY > 0) && (pixY < image.getHeight())) {
282
                                                                image.setRGB(pixX, pixY, symbol.getRgb());
283
                                                        }
284
                                                }
285
                                        }
286
                                }
287
                        }
288

    
289
                        // logger.debug("getCapa().getRecordset().stop()");
290
                        ((FLyrVect) getCapa()).getSource().getRecordset().stop();
291

    
292
                        long t2 = System.currentTimeMillis();
293
                        // logger.debug("adapter.stop()");
294
                        adapter.stop();
295

    
296
                        // System.out.println(t2 - t1);
297
                } catch (DriverIOException e) {
298
                        throw new DriverException(e);
299
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
300
                        throw new DriverException(e);
301
                } catch (DriverException e) {
302
                        throw new DriverException(e);
303
                } catch (IOException e) {
304
                        throw new DriverException(e);
305
                } catch (DriverLoadException e) {
306
                        // TODO Auto-generated catch block
307
                        e.printStackTrace();
308
                }
309
        }
310

    
311
        /**
312
         * M?todo utilizado para dibujar sobre el graphics que se pasa como
313
         * par?metro, pensado para utilizarse para imprimir.
314
         *
315
         * @param g Graphics2D
316
         * @param viewPort ViewPort.
317
         * @param cancel
318
         *
319
         * @throws DriverException
320
         */
321
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel)
322
                throws DriverException {
323
                // super.draw(null, g, viewPort, cancel); // Quiero ejecutar el draw del padre, que es el que va sin acelaraci?n!!
324
        try {
325
            ReadableVectorial adapter = ((SingleLayer) getCapa()).getSource();
326
            if (adapter.getShapeCount() <= 0)
327
            {
328
                logger.debug("Layer:" + getCapa().getName() + " sin registros");
329
                return;
330
            }
331
            FLyrVect lyr = (FLyrVect) getCapa();
332
                        Selectable selectable=lyr.getRecordset();
333
            //Selectable selection = (Selectable) getCapa().;
334
            ICoordTrans ct = getCapa().getCoordTrans();
335
            BitSet bitSet = selectable.getSelection();
336
            BoundedShapes shapeBounds = (BoundedShapes) adapter.getDriver();
337
            VectorialFileDriver driver = (VectorialFileDriver) adapter.getDriver();
338
            // logger.debug("adapter.start() -> Layer:" + getCapa().getName());
339
            adapter.start();
340
            IGeometry geom;
341
            if (adapter.getShapeCount()>0){
342
            geom = adapter.getShape(0);
343
            }
344
            VectorialLegend l = (VectorialLegend) ((ClassifiableVectorial) getCapa()).getLegend();
345

    
346
            Rectangle2D extent = viewPort.getAdjustedExtent();
347
            //AffineTransform at = viewPort.getAffineTransform();
348

    
349
            int sc;
350

    
351
            Rectangle2D bounds;
352

    
353
            sc = adapter.getShapeCount();
354

    
355
            long t1 = System.currentTimeMillis();
356
            // logger.debug("getCapa().getRecordset().start()");
357
            ((AlphanumericData) getCapa()).getRecordset().start();
358

    
359
            // TODO: A revisar si es o no conveniente este sistema
360
            // de comunicaci?n con los drivers.
361
            DriverAttributes attr = adapter.getDriverAttributes();
362
            boolean bMustClone = false;
363
            if (attr != null)
364
            {
365
                if (attr.isLoadedInMemory())
366
                {
367
                    bMustClone = attr.isLoadedInMemory();
368
                }
369
            }
370

    
371

    
372
            for (int i = 0; i < sc; i++) {
373
                bounds = shapeBounds.getShapeBounds(i);
374

    
375
                if (ct != null) {
376
                    bounds = ct.convert(bounds);
377
                }
378

    
379
                if (XRectangle2D.intersectInclusive(extent, bounds)) {
380
                    FSymbol symbol = l.getSymbol(i);
381

    
382
                    if (bitSet.get(i)) {
383
                        symbol = FSymbol.getSymbolForSelection(symbol);
384
                    }
385

    
386
                    boolean bPoint = (shapeBounds.getShapeType(i) == FShape.POINT);
387

    
388
                    geom = driver.getShape(i);
389

    
390
                    // PRUEBA DE VELOCIDAD
391
                    // geom = ShapeFactory.createPolygon2D(new GeneralPathX(bounds));
392

    
393
                    if (ct != null) {
394
                        if (bMustClone)
395
                            geom = geom.cloneGeometry();
396
                        geom.reProject(ct);
397
                    }
398
                    geom.draw(g, viewPort, symbol);
399
                }
400
            }
401

    
402
            // logger.debug("getCapa().getRecordset().stop()");
403
            ((AlphanumericData) getCapa()).getRecordset().stop();
404

    
405
            long t2 = System.currentTimeMillis();
406
            // logger.debug("adapter.stop()");
407
            adapter.stop();
408

    
409
            // System.out.println(t2 - t1);
410
        } catch (DriverIOException e) {
411
            throw new DriverException(e);
412
        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
413
            throw new DriverException(e);
414
        } catch (DriverException e) {
415
            throw new DriverException(e);
416
        } catch (IOException e) {
417
            throw new DriverException(e);
418
        }
419

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

    
426
    /* (non-Javadoc)
427
     * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByShape(com.iver.cit.gvsig.fmap.core.IGeometry, int)
428
     */
429
    public FBitSet queryByShape(IGeometry g, int relationship, CancellableMonitorable cancel)
430
    throws DriverException, VisitException {
431
        // Si hay un ?ndice espacial, lo usamos para hacer el query.
432
        FLyrVect lyr = (FLyrVect) capa;
433
        if (lyr.getSpatialIndex() == null)
434
            return super.queryByShape(g, relationship);
435

    
436
        long t1 = System.currentTimeMillis();
437
        ReadableVectorial va = lyr.getSource();
438
        ICoordTrans ct = lyr.getCoordTrans();
439
        Rectangle2D bounds = g.getBounds2D();
440
        Coordinate c1 = new Coordinate(bounds.getMinX(), bounds.getMinY());
441
        Coordinate c2 = new Coordinate(bounds.getMaxX(), bounds.getMaxY());
442
        Envelope env = new Envelope(c1, c2);
443

    
444
        List lstRecs = lyr.getSpatialIndex().query(env);
445
        Integer idRec;
446
        FBitSet bitset = new FBitSet();
447
        Geometry jtsShape = g.toJTSGeometry();
448
        IntersectionMatrix m;
449
        int index;
450
        try {
451
            va.start();
452

    
453
            for (int i=0; i < lstRecs.size(); i++)
454
            {
455
                    if(cancel != null){
456
                            cancel.reportStep();
457
                            if(cancel.isCanceled()){
458
                                    break;
459
                            }
460
                    }
461
                idRec = (Integer) lstRecs.get(i);
462
                index = idRec.intValue();
463
                IGeometry geom = va.getShape(index);
464
                if (ct != null) {
465
                    geom.reProject(ct);
466
                }
467
                Geometry jtsGeom = geom.toJTSGeometry();
468
                switch (relationship) {
469
                case CONTAINS:
470
                    m = jtsShape.relate(jtsGeom);
471
                    if (m.isContains()) {
472
                        bitset.set(index, true);
473
                    }
474
                    break;
475

    
476
                case CROSSES:
477
                    m = jtsShape.relate(jtsGeom);
478
                    if (m.isCrosses(jtsGeom.getDimension(), jtsShape.getDimension())) {
479
                        bitset.set(index, true);
480
                    }
481
                    break;
482

    
483
                case DISJOINT:
484
                    // TODO: CREO QUE EL DISJOINT NO SE PUEDE METER AQUI
485
                    m = jtsShape.relate(jtsGeom);
486
                    if (m.isDisjoint()) {
487
                        bitset.set(index, true);
488
                    }
489
                    break;
490

    
491
                case EQUALS:
492
                    m = jtsShape.relate(jtsGeom);
493
                    if (m.isEquals(jtsGeom.getDimension(), jtsShape.getDimension())) {
494
                        bitset.set(index, true);
495
                    }
496
                    break;
497

    
498
                case INTERSECTS:
499
                    m = jtsShape.relate(jtsGeom);
500
                    if (m.isIntersects()) {
501
                        bitset.set(index, true);
502
                    }
503
                    break;
504

    
505
                case OVERLAPS:
506
                    m = jtsShape.relate(jtsGeom);
507
                    if (m.isOverlaps(jtsGeom.getDimension(), jtsShape.getDimension()))
508
                    {
509
                        bitset.set(index, true);
510
                    }
511

    
512
                    break;
513

    
514
                case TOUCHES:
515
                    m = jtsShape.relate(jtsGeom);
516
                    if (m.isTouches(jtsGeom.getDimension(), jtsShape.getDimension()))
517
                    {
518
                        bitset.set(index, true);
519
                    }
520

    
521
                    break;
522

    
523
                case WITHIN:
524
                    m = jtsShape.relate(jtsGeom);
525
                    if (m.isWithin()) {
526
                        bitset.set(index, true);
527
                    }
528

    
529
                    break;
530
                }
531
            }
532
            va.stop();
533
        } catch (DriverIOException e) {
534
            // TODO Auto-generated catch block
535
            e.printStackTrace();
536
        }
537
        long t2 = System.currentTimeMillis();
538
        logger.debug("queryByShape optimizado sobre la capa " + lyr.getName() + ". " + (t2-t1) + " mseg.");
539
        return bitset;
540
    }
541
    public FBitSet queryByRect(Rectangle2D rect, CancellableMonitorable cancel) throws DriverException {
542
        // Si hay un ?ndice espacial, lo usamos para hacer el query.
543
        FLyrVect lyr = (FLyrVect) capa;
544
        if (lyr.getSpatialIndex() == null)
545
            return super.queryByRect(rect, cancel);
546

    
547
        ReadableVectorial va = lyr.getSource();
548
        ICoordTrans ct = lyr.getCoordTrans();
549
        Rectangle2D bounds = rect;
550
        Coordinate c1 = new Coordinate(bounds.getMinX(), bounds.getMinY());
551
        Coordinate c2 = new Coordinate(bounds.getMaxX(), bounds.getMaxY());
552
        Envelope env = new Envelope(c1, c2);
553

    
554
        List lstRecs = lyr.getSpatialIndex().query(env);
555
        Integer idRec;
556
        FBitSet bitset = new FBitSet();
557
        int index;
558
        try {
559
            va.start();
560
            DriverAttributes attr = va.getDriverAttributes();
561
            boolean bMustClone = false;
562
            if (attr != null)
563
            {
564
                if (attr.isLoadedInMemory())
565
                {
566
                    bMustClone = attr.isLoadedInMemory();
567
                }
568
            }
569

    
570
            for (int i=0; i < lstRecs.size(); i++)
571
            {        
572
                    if(cancel != null){
573
                            cancel.reportStep();
574
                            if(cancel.isCanceled()){
575
                                    va.stop();
576
                                    return bitset;
577
                            }
578
                    }
579
                idRec = (Integer) lstRecs.get(i);
580
                index = idRec.intValue();
581
                IGeometry geom = va.getShape(index);
582
                if (ct != null) {
583
                    if (bMustClone)
584
                        geom = geom.cloneGeometry();
585
                    geom.reProject(ct);
586
                }
587
                if (geom.intersects(rect))
588
                    bitset.set(index, true);
589
            }
590
            va.stop();
591
        } catch (DriverIOException e) {
592
            // TODO Auto-generated catch block
593
            e.printStackTrace();
594
        }
595
        return bitset;
596

    
597
    }
598
    
599

    
600
    public void process(FeatureVisitor visitor, Rectangle2D rectangle) throws DriverException, VisitException{
601
            process(visitor, rectangle, null);
602
    }
603
    
604
    
605
    /**
606
     * Processes (by calling visitor.process() method) only those
607
     * features of the vectorial layer associated which intersects given
608
     * rectangle2d.
609
     * 
610
     */
611
   
612
    public void process(FeatureVisitor visitor, Rectangle2D rectangle, CancellableMonitorable cancel) throws DriverException, VisitException {
613
        FLyrVect lyr = (FLyrVect) capa;
614
        if (lyr.getSpatialIndex() == null){
615
            super.process(visitor, rectangle, cancel);
616
            return;
617
        }    
618

    
619
        ReadableVectorial va = lyr.getSource();
620
        ICoordTrans ct = lyr.getCoordTrans();
621
        Rectangle2D bounds = rectangle;
622
        Coordinate c1 = new Coordinate(bounds.getMinX(), bounds.getMinY());
623
        Coordinate c2 = new Coordinate(bounds.getMaxX(), bounds.getMaxY());
624
        Envelope env = new Envelope(c1, c2);
625
        List lstRecs = lyr.getSpatialIndex().query(env);        
626
                Integer idRec;
627
        int index;
628
        try {
629
            va.start();
630
            DriverAttributes attr = va.getDriverAttributes();
631
            boolean bMustClone = false;
632
            if (attr != null)
633
            {
634
                if (attr.isLoadedInMemory())
635
                {
636
                    bMustClone = attr.isLoadedInMemory();               
637
                }
638
            }
639

    
640
            for (int i=0; i < lstRecs.size(); i++)
641
            {
642
                    if(cancel != null){
643
                            cancel.reportStep();
644
                    }
645
                    if(verifyCancelation(cancel, va, visitor))
646
                            return;
647
                idRec = (Integer) lstRecs.get(i);
648
                index = idRec.intValue();
649
                IGeometry geom = va.getShape(index);
650
                if (ct != null) {
651
                    if (bMustClone)
652
                        geom = geom.cloneGeometry();
653
                    geom.reProject(ct);
654
                }                 
655
                if (geom.intersects(rectangle))
656
                    visitor.visit(geom, index);               
657
            }//for
658
            va.stop();
659
        } catch (DriverIOException e) {
660
            // TODO Auto-generated catch block
661
            e.printStackTrace();
662
        }
663
        }
664

    
665
    /* (non-Javadoc)
666
     * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByPoint(java.awt.geom.Point2D, double)
667
     */
668
    public FBitSet queryByPoint(Point2D p, double tolerance, CancellableMonitorable cancel)
669
    throws DriverException {
670
        // TODO: OJO!!!!. Est? implementado como un rectangulo.
671
        // Lo correcto deber?a ser calculando las distancias reales
672
        // es decir, con un c?rculo.
673
        Rectangle2D recPoint = new Rectangle2D.Double(p.getX() - (tolerance / 2),
674
                p.getY() - (tolerance / 2), tolerance, tolerance);
675
        return queryByRect(recPoint, cancel);
676
    }
677
}