Statistics
| Revision:

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

History | View | Annotate | Download (24 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.IGeometry;
60
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
61
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
62
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
63
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
64
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
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.SpatialCache;
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.ClassifiedLegendInfo;
75
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
76
import com.iver.cit.gvsig.fmap.rendering.styling.FStyle2D;
77
import com.iver.utiles.swing.threads.Cancellable;
78
import com.iver.utiles.swing.threads.CancellableMonitorable;
79
import com.vividsolutions.jts.geom.Geometry;
80
import com.vividsolutions.jts.geom.IntersectionMatrix;
81

    
82

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

    
90
        /**
91
         * Crea una ShpStrategy.
92
         *
93
         * @param capa
94
         */
95
        public ShpStrategy(FLayer capa) {
96
                super(capa);
97
        }
98

    
99
        /**
100
         * @see com.iver.cit.gvsig.fmap.operations.LayerOperations#draw(java.awt.image.BufferedImage,
101
         *                 java.awt.Graphics2D, FStyle2D)
102
         */
103
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
104
                Cancellable cancel) throws DriverException {
105
                try {
106
                        ReadableVectorial adapter = ((SingleLayer) getCapa()).getSource();
107
                        if (adapter.getShapeCount() <= 0)
108
                        {
109
                            logger.debug("Layer:" + getCapa().getName() + " sin registros");
110
                            return;
111
                        }
112

    
113
                        //Selectable selection = (Selectable) getCapa();
114
            FLyrVect lyr = (FLyrVect) getCapa();
115
                        Selectable selectable=lyr.getRecordset();
116
            ICoordTrans ct = getCapa().getCoordTrans();
117
                        FBitSet bitSet = selectable.getSelection();
118
                        BoundedShapes shapeBounds;
119
                        if (adapter instanceof BoundedShapes)
120
                                 shapeBounds = (BoundedShapes) adapter;
121
                        else
122
                                shapeBounds = (BoundedShapes) adapter.getDriver();
123
                        // VectorialFileDriver driver = (VectorialFileDriver) adapter.getDriver();
124
                        // logger.debug("adapter.start() -> Layer:" + getCapa().getName());
125
                        adapter.start();
126
                        IGeometry geom;
127
                        if (adapter.getShapeCount()>0){
128
                        geom = adapter.getShape(0);
129
                        }
130
                        VectorialLegend l = (VectorialLegend) ((ClassifiableVectorial) getCapa()).getLegend();
131

    
132
                        if (l instanceof ClassifiedLegendInfo) {
133
                                ClassifiedLegendInfo clsfLegend = (ClassifiedLegendInfo) l;
134
                                FSymbol[] symbs = clsfLegend.getSymbols();
135
                                //double rSym = 0;
136
                                //double maxRSym = -1;
137

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

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

    
152
                        Rectangle2D extent = viewPort.getAdjustedExtent();
153
                        //AffineTransform at = viewPort.getAffineTransform();
154

    
155
                        int sc;
156

    
157
                        Rectangle2D bounds;
158

    
159

    
160

    
161
                        long t1 = System.currentTimeMillis();
162
                        // logger.debug("getCapa().getRecordset().start()");
163
                        ((FLyrVect) getCapa()).getRecordset().start();
164

    
165
                        // TODO: A revisar si es o no conveniente este sistema
166
                        // de comunicaci?n con los drivers.
167
                        DriverAttributes attr = adapter.getDriverAttributes();
168
                        boolean bMustClone = false;
169
                        if (attr != null)
170
                        {
171
                            if (attr.isLoadedInMemory())
172
                            {
173
                                bMustClone = attr.isLoadedInMemory();
174
                            }
175
                        }
176

    
177
            List lstIndexes = null;
178

    
179
            // If area of needed extent is less than fullExtent / 4,
180
            // it will be worthy to use SpatialIndex.
181
            // Otherwhise, we will not use it.
182
                        boolean bUseSpatialIndex = false;
183
            sc = adapter.getShapeCount();
184
//          if (lyr.getSpatialIndex() != null)  AZABALA
185
            // long t11 = System.currentTimeMillis();
186
            if(lyr.getISpatialIndex() != null)
187
            {
188
                    if(isSpatialIndexNecessary(extent)){
189
                            lstIndexes = lyr.getISpatialIndex().query(extent);
190
                            //If the layer is reprojected, spatial index was created
191
                            //in its own projection, so we must to apply an inverse transform
192
                            if (ct != null) {
193
                                    Rectangle2D newExtent = ct.getInverted().convert(extent);
194
                                    //Rectangle2D newExtent = ct.convert(extent);
195
                                    //lstIndexes = lyr.getISpatialIndex().query(extent);
196
                                    lstIndexes = lyr.getISpatialIndex().query(newExtent);
197
                            }else{
198
                                    lstIndexes = lyr.getISpatialIndex().query(extent);
199
                            }
200
                    sc = lstIndexes.size();
201
                    bUseSpatialIndex = true;
202
                    }//if
203
            }//if
204
            /* long t12 = System.currentTimeMillis();
205
            System.out.println("Tiempo en mirar el ?ndice espacial y recuperar los ?ndices:" + (t12-t11));
206
            System.out.println("Numero de ?ndices:" + sc); */
207

    
208
            SpatialCache cache = lyr.createSpatialCache();
209
            // lyr.setSpatialCacheEnabled(true);
210
            int i;
211
                        for (int aux = 0; aux < sc; aux++) {
212
                                // Salimos si alguien cancela
213
                                if(cancel != null){
214
                                        //azabala (por si acaso, al arreglar bug de process)
215
                                        if (cancel.isCanceled()) {
216
                                                break;
217
                                        }
218
                                }
219
                if (bUseSpatialIndex)
220
                {
221
                    Integer idRec = (Integer) lstIndexes.get(aux);
222
                    i = idRec.intValue();
223
                }
224
                else
225
                {
226
                    i = aux;
227
                }
228
                                bounds = shapeBounds.getShapeBounds(i);
229
                                if (ct != null) {
230
                                        bounds = ct.convert(bounds);
231
                                }
232
                                if (XRectangle2D.intersectInclusive(extent, bounds)) {
233
                                        FSymbol symbol = l.getSymbol(i);
234

    
235
                                        if (bitSet.get(i)) {
236
                                                symbol = FSymbol.getSymbolForSelection(symbol);
237
                                        }
238

    
239
                                        boolean bPoint = (shapeBounds.getShapeType(i) == FShape.POINT);
240

    
241
                                        if (bPoint ||
242
                                                        ((bounds.getHeight() > viewPort.getDist1pixel()) ||
243
                                                        (bounds.getWidth() > viewPort.getDist1pixel()))) {
244
                                                geom = adapter.getShape(i);
245

    
246
                        // PRUEBA DE VELOCIDAD
247
                        // geom = ShapeFactory.createPolygon2D(new GeneralPathX(bounds));
248

    
249
                                                if (ct != null) {
250
                                                    if (bMustClone)
251
                                                        geom = geom.cloneGeometry();
252
                                                        geom.reProject(ct);
253
                                                }
254
                                                if (cache != null)
255
                                                {
256
                                                        // TODO: Comprobar aqu? tambi?n si esto es necesario.
257
                                                        if (lyr.isSpatialCacheEnabled())
258
                                                        {
259
                                                                if (cache.getMaxFeatures() >= cache.size())
260
                                                                {
261
                                                                        //         Ya reproyectado todo
262
                                                                        cache.insert(bounds, geom);
263
                                                                }
264
                                                        }
265
                                                }
266

    
267
                        // FJP: CAMBIO: Sabemos que vamos a dibujar sobre una
268
                        // imagen, con coordenadas enteras, as?
269
                        // que lo tenemos en cuenta.
270
                                                // ANTES: geom.draw(g, viewPort, symbol);
271
                        // AHORA:
272
                        geom.drawInts(g, viewPort, symbol);
273
                        // geom.draw(g, viewPort, symbol);
274
                        /* if (lyr.isEditing())
275
                        {
276
                                if (bitSet.get(i))
277
                                {
278
                                        Handler[] handlers = geom.getHandlers(IGeometry.SELECTHANDLER);
279
                                        FGraphicUtilities.DrawHandlers(g, viewPort.getAffineTransform(), handlers);
280
                                }
281
                        } */
282

    
283

    
284

    
285
                                        } else {
286
                                                Point2D.Double pOrig = new Point2D.Double(bounds.getMinX(),
287
                                                                bounds.getMinY());
288
                                                Point2D pDest, pDest2;
289

    
290
                                                pDest = viewPort.getAffineTransform().transform(pOrig, null);
291
                        pDest2 = g.getTransform().transform(pDest, null);
292

    
293
                                                int pixX = (int) pDest2.getX();
294
                                                int pixY = (int) pDest2.getY();
295
                                                if (symbol ==null)
296
                                                        continue;
297
                                                if ((pixX > 0) && (pixX < image.getWidth())) {
298
                                                        if ((pixY > 0) && (pixY < image.getHeight())) {
299
                                                                image.setRGB(pixX, pixY, symbol.getRgb());
300
                                                        }
301
                                                }
302
                                        }
303
                                }
304
                        }
305

    
306
                        // logger.debug("getCapa().getRecordset().stop()");
307
                        ((FLyrVect) getCapa()).getSource().getRecordset().stop();
308

    
309
                        long t2 = System.currentTimeMillis();
310
                        // logger.debug("adapter.stop()");
311
                        adapter.stop();
312

    
313
                        // System.out.println(t2 - t1);
314
                } catch (DriverIOException e) {
315
                        throw new DriverException(e);
316
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
317
                        throw new DriverException(e);
318
                } catch (DriverException e) {
319
                        throw new DriverException(e);
320
                } catch (IOException e) {
321
                        throw new DriverException(e);
322
                } catch (DriverLoadException e) {
323
                        // TODO Auto-generated catch block
324
                        e.printStackTrace();
325
                }
326
        }
327

    
328
        /**
329
         * M?todo utilizado para dibujar sobre el graphics que se pasa como
330
         * par?metro, pensado para utilizarse para imprimir.
331
         *
332
         * @param g Graphics2D
333
         * @param viewPort ViewPort.
334
         * @param cancel
335
         *
336
         * @throws DriverException
337
         */
338
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel)
339
                throws DriverException {
340
                // super.draw(null, g, viewPort, cancel); // Quiero ejecutar el draw del padre, que es el que va sin acelaraci?n!!
341
        try {
342
            ReadableVectorial adapter = ((SingleLayer) getCapa()).getSource();
343
            if (adapter.getShapeCount() <= 0)
344
            {
345
                logger.debug("Layer:" + getCapa().getName() + " sin registros");
346
                return;
347
            }
348
            FLyrVect lyr = (FLyrVect) getCapa();
349
                        Selectable selectable=lyr.getRecordset();
350
            //Selectable selection = (Selectable) getCapa().;
351
            ICoordTrans ct = getCapa().getCoordTrans();
352
            BitSet bitSet = selectable.getSelection();
353
            BoundedShapes shapeBounds = (BoundedShapes) adapter.getDriver();
354
            VectorialFileDriver driver = (VectorialFileDriver) adapter.getDriver();
355
            // logger.debug("adapter.start() -> Layer:" + getCapa().getName());
356
            adapter.start();
357
            IGeometry geom;
358
            if (adapter.getShapeCount()>0){
359
            geom = adapter.getShape(0);
360
            }
361
            VectorialLegend l = (VectorialLegend) ((ClassifiableVectorial) getCapa()).getLegend();
362

    
363
            Rectangle2D extent = viewPort.getAdjustedExtent();
364
            //AffineTransform at = viewPort.getAffineTransform();
365

    
366
            int sc;
367

    
368
            Rectangle2D bounds;
369

    
370
            sc = adapter.getShapeCount();
371

    
372
            long t1 = System.currentTimeMillis();
373
            // logger.debug("getCapa().getRecordset().start()");
374
            ((AlphanumericData) getCapa()).getRecordset().start();
375

    
376
            // TODO: A revisar si es o no conveniente este sistema
377
            // de comunicaci?n con los drivers.
378
            DriverAttributes attr = adapter.getDriverAttributes();
379
            boolean bMustClone = false;
380
            if (attr != null)
381
            {
382
                if (attr.isLoadedInMemory())
383
                {
384
                    bMustClone = attr.isLoadedInMemory();
385
                }
386
            }
387

    
388

    
389
            for (int i = 0; i < sc; i++) {
390
                bounds = shapeBounds.getShapeBounds(i);
391

    
392
                if (ct != null) {
393
                    bounds = ct.convert(bounds);
394
                }
395

    
396
                if (XRectangle2D.intersectInclusive(extent, bounds)) {
397
                    FSymbol symbol = l.getSymbol(i);
398

    
399
                    if (bitSet.get(i)) {
400
                        symbol = FSymbol.getSymbolForSelection(symbol);
401
                    }
402

    
403
                    boolean bPoint = (shapeBounds.getShapeType(i) == FShape.POINT);
404

    
405
                    geom = driver.getShape(i);
406

    
407
                    // PRUEBA DE VELOCIDAD
408
                    // geom = ShapeFactory.createPolygon2D(new GeneralPathX(bounds));
409

    
410
                    if (ct != null) {
411
                        if (bMustClone)
412
                            geom = geom.cloneGeometry();
413
                        geom.reProject(ct);
414
                    }
415
                    geom.draw(g, viewPort, symbol);
416
                }
417
            }
418

    
419
            // logger.debug("getCapa().getRecordset().stop()");
420
            ((AlphanumericData) getCapa()).getRecordset().stop();
421

    
422
            long t2 = System.currentTimeMillis();
423
            // logger.debug("adapter.stop()");
424
            adapter.stop();
425

    
426
            // System.out.println(t2 - t1);
427
        } catch (DriverIOException e) {
428
            throw new DriverException(e);
429
        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
430
            throw new DriverException(e);
431
        } catch (DriverException e) {
432
            throw new DriverException(e);
433
        } catch (IOException e) {
434
            throw new DriverException(e);
435
        }
436

    
437
        }
438

    
439
        public FBitSet queryByShape(IGeometry g, int relationship) throws DriverException, VisitException{
440
                return queryByShape(g, relationship, null);
441
        }
442

    
443
    /* (non-Javadoc)
444
     * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByShape(com.iver.cit.gvsig.fmap.core.IGeometry, int)
445
     */
446
    public FBitSet queryByShape(IGeometry g, int relationship, CancellableMonitorable cancel)
447
    throws DriverException, VisitException {
448
        // Si hay un ?ndice espacial, lo usamos para hacer el query.
449
        FLyrVect lyr = (FLyrVect) capa;
450
//        if (lyr.getSpatialIndex() == null) AZABALA
451
          if (lyr.getISpatialIndex() == null)
452
            return super.queryByShape(g, relationship, null);
453

    
454
        long t1 = System.currentTimeMillis();
455
        ReadableVectorial va = lyr.getSource();
456
        ICoordTrans ct = lyr.getCoordTrans();
457
        Rectangle2D bounds = g.getBounds2D();
458
//        AZABALA
459
//        Coordinate c1 = new Coordinate(bounds.getMinX(), bounds.getMinY());
460
//        Coordinate c2 = new Coordinate(bounds.getMaxX(), bounds.getMaxY());
461
//        Envelope env = new Envelope(c1, c2);
462
//        List lstRecs = lyr.getSpatialIndex().query(env);
463
        List lstRecs = lyr.getISpatialIndex().query(bounds);
464
        Integer idRec;
465
        FBitSet bitset = new FBitSet();
466
        Geometry jtsShape = g.toJTSGeometry();
467
        IntersectionMatrix m;
468
        int index;
469
        try {
470
            va.start();
471

    
472
            for (int i=0; i < lstRecs.size(); i++)
473
            {
474
                    if(cancel != null){
475
                            cancel.reportStep();
476
                            if(cancel.isCanceled()){
477
                                    break;
478
                            }
479
                    }
480
                idRec = (Integer) lstRecs.get(i);
481
                index = idRec.intValue();
482
                IGeometry geom = va.getShape(index);
483
                if (ct != null) {
484
                    geom.reProject(ct);
485
                }
486
                Geometry jtsGeom = geom.toJTSGeometry();
487
                switch (relationship) {
488
                case CONTAINS:
489
                    m = jtsShape.relate(jtsGeom);
490
                    if (m.isContains()) {
491
                        bitset.set(index, true);
492
                    }
493
                    break;
494

    
495
                case CROSSES:
496
                    m = jtsShape.relate(jtsGeom);
497
                    if (m.isCrosses(jtsGeom.getDimension(), jtsShape.getDimension())) {
498
                        bitset.set(index, true);
499
                    }
500
                    break;
501

    
502
                case DISJOINT:
503
                    // TODO: CREO QUE EL DISJOINT NO SE PUEDE METER AQUI
504
                    m = jtsShape.relate(jtsGeom);
505
                    if (m.isDisjoint()) {
506
                        bitset.set(index, true);
507
                    }
508
                    break;
509

    
510
                case EQUALS:
511
                    m = jtsShape.relate(jtsGeom);
512
                    if (m.isEquals(jtsGeom.getDimension(), jtsShape.getDimension())) {
513
                        bitset.set(index, true);
514
                    }
515
                    break;
516

    
517
                case INTERSECTS:
518
                    m = jtsShape.relate(jtsGeom);
519
                    if (m.isIntersects()) {
520
                        bitset.set(index, true);
521
                    }
522
                    break;
523

    
524
                case OVERLAPS:
525
                    m = jtsShape.relate(jtsGeom);
526
                    if (m.isOverlaps(jtsGeom.getDimension(), jtsShape.getDimension()))
527
                    {
528
                        bitset.set(index, true);
529
                    }
530

    
531
                    break;
532

    
533
                case TOUCHES:
534
                    m = jtsShape.relate(jtsGeom);
535
                    if (m.isTouches(jtsGeom.getDimension(), jtsShape.getDimension()))
536
                    {
537
                        bitset.set(index, true);
538
                    }
539

    
540
                    break;
541

    
542
                case WITHIN:
543
                    m = jtsShape.relate(jtsGeom);
544
                    if (m.isWithin()) {
545
                        bitset.set(index, true);
546
                    }
547

    
548
                    break;
549
                }
550
            }
551
            va.stop();
552
        } catch (DriverIOException e) {
553
            // TODO Auto-generated catch block
554
            e.printStackTrace();
555
        }
556
        long t2 = System.currentTimeMillis();
557
        logger.debug("queryByShape optimizado sobre la capa " + lyr.getName() + ". " + (t2-t1) + " mseg.");
558
        return bitset;
559
    }
560
    public FBitSet queryByRect(Rectangle2D rect, CancellableMonitorable cancel) throws DriverException {
561
        // Si hay un ?ndice espacial, lo usamos para hacer el query.
562
        FLyrVect lyr = (FLyrVect) capa;
563
//        if (lyr.getSpatialIndex() == null)
564
          if(lyr.getISpatialIndex() == null)
565
            return super.queryByRect(rect, cancel);
566

    
567
        ReadableVectorial va = lyr.getSource();
568
        ICoordTrans ct = lyr.getCoordTrans();
569
        Rectangle2D bounds = rect;
570
//        Coordinate c1 = new Coordinate(bounds.getMinX(), bounds.getMinY());
571
//        Coordinate c2 = new Coordinate(bounds.getMaxX(), bounds.getMaxY());
572
//        Envelope env = new Envelope(c1, c2);
573
//        List lstRecs = lyr.getSpatialIndex().query(env);
574
//        AZABALA
575
        List lstRecs = lyr.getISpatialIndex().query(bounds);
576
        Integer idRec;
577
        FBitSet bitset = new FBitSet();
578
        int index;
579
        try {
580
            va.start();
581
            DriverAttributes attr = va.getDriverAttributes();
582
            boolean bMustClone = false;
583
            if (attr != null)
584
            {
585
                if (attr.isLoadedInMemory())
586
                {
587
                    bMustClone = attr.isLoadedInMemory();
588
                }
589
            }
590

    
591
            for (int i=0; i < lstRecs.size(); i++)
592
            {
593
                    if(cancel != null){
594
                            cancel.reportStep();
595
                            if(cancel.isCanceled()){
596
                                    va.stop();
597
                                    return bitset;
598
                            }
599
                    }
600
                idRec = (Integer) lstRecs.get(i);
601
                index = idRec.intValue();
602
                IGeometry geom = va.getShape(index);
603
                if (ct != null) {
604
                    if (bMustClone)
605
                        geom = geom.cloneGeometry();
606
                    geom.reProject(ct);
607
                }
608
                if (geom.intersects(rect))
609
                    bitset.set(index, true);
610
            }
611
            va.stop();
612
        } catch (DriverIOException e) {
613
            // TODO Auto-generated catch block
614
            e.printStackTrace();
615
        }
616
        return bitset;
617

    
618
    }
619

    
620

    
621
    public void process(FeatureVisitor visitor, Rectangle2D rectangle) throws DriverException, VisitException{
622
            process(visitor, rectangle, null);
623
    }
624

    
625
    /**
626
     * Processes (by calling visitor.process() method) only those
627
     * features of the vectorial layer associated which intersects given
628
     * rectangle2d.
629
     *
630
     */
631

    
632
    public void process(FeatureVisitor visitor, Rectangle2D rectangle, CancellableMonitorable cancel) throws DriverException, VisitException {
633
        FLyrVect lyr = (FLyrVect) capa;
634
        //if we dont have spatial index or...
635
        if (lyr.getISpatialIndex() == null){
636
            super.process(visitor, rectangle, cancel);
637
            return;
638
        }
639
        //if spatial index is not worthy
640
        if(! isSpatialIndexNecessary(rectangle)){
641
                super.process(visitor, rectangle, cancel);
642
            return;
643
        }
644

    
645
        ReadableVectorial va = lyr.getSource();
646
        ICoordTrans ct = lyr.getCoordTrans();
647
        Rectangle2D bounds = rectangle;
648
        List lstRecs = lyr.getISpatialIndex().query(bounds);
649
                Integer idRec;
650
        int index;
651
        try {
652
            va.start();
653
            DriverAttributes attr = va.getDriverAttributes();
654
            boolean bMustClone = false;
655
            if (attr != null)
656
            {
657
                if (attr.isLoadedInMemory())
658
                {
659
                    bMustClone = attr.isLoadedInMemory();
660
                }
661
            }
662

    
663
            for (int i=0; i < lstRecs.size(); i++)
664
            {
665
                    if(cancel != null){
666
                            cancel.reportStep();
667
                    }
668
                    if(verifyCancelation(cancel, va, visitor))
669
                            return;
670
                idRec = (Integer) lstRecs.get(i);
671
                index = idRec.intValue();
672
                IGeometry geom = va.getShape(index);
673
                if (ct != null) {
674
                    if (bMustClone)
675
                        geom = geom.cloneGeometry();
676
                    geom.reProject(ct);
677
                }
678
                if (geom.intersects(rectangle))
679
                    visitor.visit(geom, index);
680
            }//for
681
            va.stop();
682
        } catch (DriverIOException e) {
683
            // TODO Auto-generated catch block
684
            e.printStackTrace();
685
        }
686
        }
687

    
688
    /* (non-Javadoc)
689
     * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByPoint(java.awt.geom.Point2D, double)
690
     */
691
    public FBitSet queryByPoint(Point2D p, double tolerance, CancellableMonitorable cancel)
692
    throws DriverException {
693
        // TODO: OJO!!!!. Est? implementado como un rectangulo.
694
        // Lo correcto deber?a ser calculando las distancias reales
695
        // es decir, con un c?rculo.
696
        Rectangle2D recPoint = new Rectangle2D.Double(p.getX() - (tolerance / 2),
697
                p.getY() - (tolerance / 2), tolerance, tolerance);
698
        return queryByRect(recPoint, cancel);
699
    }
700
}