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 1100 fjp
/* 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 214 fernando
package com.iver.cit.gvsig.fmap.operations.strategies;
42
43 2412 caballero
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 2979 fjp
import java.util.List;
50 2412 caballero
51
import org.apache.log4j.Logger;
52
import org.cresques.cts.ICoordTrans;
53
import org.geotools.resources.geometry.XRectangle2D;
54
55 3963 caballero
import com.hardcode.driverManager.DriverLoadException;
56 652 fernando
import com.iver.cit.gvsig.fmap.DriverException;
57 214 fernando
import com.iver.cit.gvsig.fmap.ViewPort;
58 597 fjp
import com.iver.cit.gvsig.fmap.core.FShape;
59 305 fjp
import com.iver.cit.gvsig.fmap.core.IGeometry;
60 458 fjp
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
61 214 fernando
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
62 1233 fjp
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
63 214 fernando
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
64
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
65 2979 fjp
import com.iver.cit.gvsig.fmap.layers.FBitSet;
66 562 fernando
import com.iver.cit.gvsig.fmap.layers.FLayer;
67 2979 fjp
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
68 3940 caballero
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
69 5224 fjp
import com.iver.cit.gvsig.fmap.layers.SpatialCache;
70 562 fernando
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 322 fernando
import com.iver.cit.gvsig.fmap.rendering.ClassifiedLegendInfo;
75
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
76 250 fjp
import com.iver.cit.gvsig.fmap.rendering.styling.FStyle2D;
77 5317 fjp
import com.iver.utiles.swing.threads.Cancellable;
78
import com.iver.utiles.swing.threads.CancellableMonitorable;
79 2979 fjp
import com.vividsolutions.jts.geom.Geometry;
80
import com.vividsolutions.jts.geom.IntersectionMatrix;
81 214 fernando
82
83
/**
84 1034 vcaballero
 * Esta clase definir? las operaciones de la interfaz FLyrVect de la manera m?s
85
 * ?ptima para los ficheros shp.
86 214 fernando
 */
87
public class ShpStrategy extends DefaultStrategy {
88 528 vcaballero
        private static Logger logger = Logger.getLogger(ShpStrategy.class.getName());
89 1034 vcaballero
90 214 fernando
        /**
91 1034 vcaballero
         * Crea una ShpStrategy.
92
         *
93 214 fernando
         * @param capa
94
         */
95 562 fernando
        public ShpStrategy(FLayer capa) {
96 214 fernando
                super(capa);
97
        }
98 1034 vcaballero
99 214 fernando
        /**
100 1034 vcaballero
         * @see com.iver.cit.gvsig.fmap.operations.LayerOperations#draw(java.awt.image.BufferedImage,
101
         *                 java.awt.Graphics2D, FStyle2D)
102 214 fernando
         */
103 1034 vcaballero
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
104
                Cancellable cancel) throws DriverException {
105
                try {
106 3940 caballero
                        ReadableVectorial adapter = ((SingleLayer) getCapa()).getSource();
107 1122 fjp
                        if (adapter.getShapeCount() <= 0)
108
                        {
109
                            logger.debug("Layer:" + getCapa().getName() + " sin registros");
110
                            return;
111
                        }
112 5490 caballero
113 3963 caballero
                        //Selectable selection = (Selectable) getCapa();
114 3560 fjp
            FLyrVect lyr = (FLyrVect) getCapa();
115 3963 caballero
                        Selectable selectable=lyr.getRecordset();
116
            ICoordTrans ct = getCapa().getCoordTrans();
117 3998 fjp
                        FBitSet bitSet = selectable.getSelection();
118 3980 caballero
                        BoundedShapes shapeBounds;
119
                        if (adapter instanceof BoundedShapes)
120
                                 shapeBounds = (BoundedShapes) adapter;
121
                        else
122
                                shapeBounds = (BoundedShapes) adapter.getDriver();
123 3601 fjp
                        // VectorialFileDriver driver = (VectorialFileDriver) adapter.getDriver();
124 3025 fjp
                        // logger.debug("adapter.start() -> Layer:" + getCapa().getName());
125 1034 vcaballero
                        adapter.start();
126 1128 vcaballero
                        IGeometry geom;
127
                        if (adapter.getShapeCount()>0){
128
                        geom = adapter.getShape(0);
129
                        }
130 1034 vcaballero
                        VectorialLegend l = (VectorialLegend) ((ClassifiableVectorial) getCapa()).getLegend();
131
132
                        if (l instanceof ClassifiedLegendInfo) {
133
                                ClassifiedLegendInfo clsfLegend = (ClassifiedLegendInfo) l;
134
                                FSymbol[] symbs = clsfLegend.getSymbols();
135 2412 caballero
                                //double rSym = 0;
136
                                //double maxRSym = -1;
137 1034 vcaballero
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 281 fjp
                        }
151 214 fernando
152 1034 vcaballero
                        Rectangle2D extent = viewPort.getAdjustedExtent();
153 2412 caballero
                        //AffineTransform at = viewPort.getAffineTransform();
154 1034 vcaballero
155
                        int sc;
156
157
                        Rectangle2D bounds;
158
159
160 3940 caballero
161 1034 vcaballero
                        long t1 = System.currentTimeMillis();
162 3025 fjp
                        // logger.debug("getCapa().getRecordset().start()");
163 3963 caballero
                        ((FLyrVect) getCapa()).getRecordset().start();
164 3940 caballero
165 1233 fjp
                        // 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 3940 caballero
                                bMustClone = attr.isLoadedInMemory();
174 1233 fjp
                            }
175
                        }
176 3940 caballero
177 3560 fjp
            List lstIndexes = null;
178 3940 caballero
179 3601 fjp
            // 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 5224 fjp
//          if (lyr.getSpatialIndex() != null)  AZABALA
185
            // long t11 = System.currentTimeMillis();
186 4976 azabala
            if(lyr.getISpatialIndex() != null)
187 3560 fjp
            {
188 4976 azabala
                    if(isSpatialIndexNecessary(extent)){
189 5490 caballero
                            lstIndexes = lyr.getISpatialIndex().query(extent);
190 5188 azabala
                            //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 3601 fjp
                    sc = lstIndexes.size();
201
                    bUseSpatialIndex = true;
202 4976 azabala
                    }//if
203 5490 caballero
            }//if
204 5224 fjp
            /* 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 5490 caballero
208 5226 fjp
            SpatialCache cache = lyr.createSpatialCache();
209 5224 fjp
            // lyr.setSpatialCacheEnabled(true);
210 3560 fjp
            int i;
211
                        for (int aux = 0; aux < sc; aux++) {
212 305 fjp
                                // Salimos si alguien cancela
213 4976 azabala
                                if(cancel != null){
214
                                        //azabala (por si acaso, al arreglar bug de process)
215 4895 azabala
                                        if (cancel.isCanceled()) {
216
                                                break;
217
                                        }
218 1034 vcaballero
                                }
219 3601 fjp
                if (bUseSpatialIndex)
220 3560 fjp
                {
221
                    Integer idRec = (Integer) lstIndexes.get(aux);
222
                    i = idRec.intValue();
223
                }
224 3601 fjp
                else
225
                {
226
                    i = aux;
227
                }
228 214 fernando
                                bounds = shapeBounds.getShapeBounds(i);
229 1034 vcaballero
                                if (ct != null) {
230 1233 fjp
                                        bounds = ct.convert(bounds);
231 1034 vcaballero
                                }
232
                                if (XRectangle2D.intersectInclusive(extent, bounds)) {
233 661 fjp
                                        FSymbol symbol = l.getSymbol(i);
234 1034 vcaballero
235
                                        if (bitSet.get(i)) {
236 661 fjp
                                                symbol = FSymbol.getSymbolForSelection(symbol);
237 3940 caballero
                                        }
238 1034 vcaballero
239 597 fjp
                                        boolean bPoint = (shapeBounds.getShapeType(i) == FShape.POINT);
240 239 fjp
241 1034 vcaballero
                                        if (bPoint ||
242
                                                        ((bounds.getHeight() > viewPort.getDist1pixel()) ||
243
                                                        (bounds.getWidth() > viewPort.getDist1pixel()))) {
244 3601 fjp
                                                geom = adapter.getShape(i);
245 3940 caballero
246 2859 fjp
                        // PRUEBA DE VELOCIDAD
247
                        // geom = ShapeFactory.createPolygon2D(new GeneralPathX(bounds));
248 239 fjp
249 1034 vcaballero
                                                if (ct != null) {
250 1233 fjp
                                                    if (bMustClone)
251
                                                        geom = geom.cloneGeometry();
252 1034 vcaballero
                                                        geom.reProject(ct);
253
                                                }
254 5224 fjp
                                                if (cache != null)
255
                                                {
256
                                                        // TODO: Comprobar aqu? tambi?n si esto es necesario.
257
                                                        if (lyr.isSpatialCacheEnabled())
258
                                                        {
259 5576 fjp
                                                                if (cache.getMaxFeatures() >= cache.size())
260 5224 fjp
                                                                {
261 5490 caballero
                                                                        //         Ya reproyectado todo
262 5224 fjp
                                                                        cache.insert(bounds, geom);
263
                                                                }
264
                                                        }
265
                                                }
266 5490 caballero
267 3940 caballero
                        // FJP: CAMBIO: Sabemos que vamos a dibujar sobre una
268 2859 fjp
                        // imagen, con coordenadas enteras, as?
269
                        // que lo tenemos en cuenta.
270
                                                // ANTES: geom.draw(g, viewPort, symbol);
271
                        // AHORA:
272 3025 fjp
                        geom.drawInts(g, viewPort, symbol);
273
                        // geom.draw(g, viewPort, symbol);
274 4135 fjp
                        /* if (lyr.isEditing())
275 4129 fjp
                        {
276
                                if (bitSet.get(i))
277
                                {
278
                                        Handler[] handlers = geom.getHandlers(IGeometry.SELECTHANDLER);
279
                                        FGraphicUtilities.DrawHandlers(g, viewPort.getAffineTransform(), handlers);
280
                                }
281 4135 fjp
                        } */
282 239 fjp
283 3940 caballero
284 4129 fjp
285 1034 vcaballero
                                        } else {
286
                                                Point2D.Double pOrig = new Point2D.Double(bounds.getMinX(),
287
                                                                bounds.getMinY());
288 2469 fjp
                                                Point2D pDest, pDest2;
289 1034 vcaballero
290 2469 fjp
                                                pDest = viewPort.getAffineTransform().transform(pOrig, null);
291
                        pDest2 = g.getTransform().transform(pDest, null);
292 1034 vcaballero
293 2469 fjp
                                                int pixX = (int) pDest2.getX();
294
                                                int pixY = (int) pDest2.getY();
295 2412 caballero
                                                if (symbol ==null)
296
                                                        continue;
297 1034 vcaballero
                                                if ((pixX > 0) && (pixX < image.getWidth())) {
298
                                                        if ((pixY > 0) && (pixY < image.getHeight())) {
299
                                                                image.setRGB(pixX, pixY, symbol.getRgb());
300
                                                        }
301
                                                }
302
                                        }
303 214 fernando
                                }
304
                        }
305 1034 vcaballero
306 3025 fjp
                        // logger.debug("getCapa().getRecordset().stop()");
307 3963 caballero
                        ((FLyrVect) getCapa()).getSource().getRecordset().stop();
308 214 fernando
309 1034 vcaballero
                        long t2 = System.currentTimeMillis();
310 3025 fjp
                        // logger.debug("adapter.stop()");
311 1034 vcaballero
                        adapter.stop();
312
313 3025 fjp
                        // System.out.println(t2 - t1);
314 1034 vcaballero
                } catch (DriverIOException e) {
315
                        throw new DriverException(e);
316 1828 fernando
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
317 1034 vcaballero
                        throw new DriverException(e);
318
                } catch (DriverException e) {
319
                        throw new DriverException(e);
320
                } catch (IOException e) {
321
                        throw new DriverException(e);
322 3963 caballero
                } catch (DriverLoadException e) {
323
                        // TODO Auto-generated catch block
324
                        e.printStackTrace();
325 1034 vcaballero
                }
326 214 fernando
        }
327 1034 vcaballero
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 3277 fjp
                // super.draw(null, g, viewPort, cancel); // Quiero ejecutar el draw del padre, que es el que va sin acelaraci?n!!
341
        try {
342 3940 caballero
            ReadableVectorial adapter = ((SingleLayer) getCapa()).getSource();
343 3277 fjp
            if (adapter.getShapeCount() <= 0)
344
            {
345
                logger.debug("Layer:" + getCapa().getName() + " sin registros");
346
                return;
347
            }
348 4213 caballero
            FLyrVect lyr = (FLyrVect) getCapa();
349
                        Selectable selectable=lyr.getRecordset();
350
            //Selectable selection = (Selectable) getCapa().;
351 3277 fjp
            ICoordTrans ct = getCapa().getCoordTrans();
352 4213 caballero
            BitSet bitSet = selectable.getSelection();
353 3277 fjp
            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 3940 caballero
376 3277 fjp
            // 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 3940 caballero
                    bMustClone = attr.isLoadedInMemory();
385 3277 fjp
                }
386
            }
387
388 3940 caballero
389 3277 fjp
            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 3940 caballero
                    }
402 3277 fjp
403
                    boolean bPoint = (shapeBounds.getShapeType(i) == FShape.POINT);
404
405
                    geom = driver.getShape(i);
406 3940 caballero
407 3277 fjp
                    // 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 3940 caballero
437 652 fernando
        }
438 5490 caballero
439 4419 azabala
        public FBitSet queryByShape(IGeometry g, int relationship) throws DriverException, VisitException{
440
                return queryByShape(g, relationship, null);
441
        }
442 3940 caballero
443 2979 fjp
    /* (non-Javadoc)
444
     * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByShape(com.iver.cit.gvsig.fmap.core.IGeometry, int)
445
     */
446 4419 azabala
    public FBitSet queryByShape(IGeometry g, int relationship, CancellableMonitorable cancel)
447 2979 fjp
    throws DriverException, VisitException {
448
        // Si hay un ?ndice espacial, lo usamos para hacer el query.
449
        FLyrVect lyr = (FLyrVect) capa;
450 4976 azabala
//        if (lyr.getSpatialIndex() == null) AZABALA
451
          if (lyr.getISpatialIndex() == null)
452 5532 jaume
            return super.queryByShape(g, relationship, null);
453 3940 caballero
454 3006 fjp
        long t1 = System.currentTimeMillis();
455 3940 caballero
        ReadableVectorial va = lyr.getSource();
456 2979 fjp
        ICoordTrans ct = lyr.getCoordTrans();
457
        Rectangle2D bounds = g.getBounds2D();
458 4976 azabala
//        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 2979 fjp
        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 4419 azabala
                    if(cancel != null){
475
                            cancel.reportStep();
476
                            if(cancel.isCanceled()){
477
                                    break;
478
                            }
479
                    }
480 2979 fjp
                idRec = (Integer) lstRecs.get(i);
481
                index = idRec.intValue();
482
                IGeometry geom = va.getShape(index);
483
                if (ct != null) {
484
                    geom.reProject(ct);
485 3940 caballero
                }
486 2979 fjp
                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 3006 fjp
                    // TODO: CREO QUE EL DISJOINT NO SE PUEDE METER AQUI
504 3940 caballero
                    m = jtsShape.relate(jtsGeom);
505 2979 fjp
                    if (m.isDisjoint()) {
506
                        bitset.set(index, true);
507
                    }
508
                    break;
509
510
                case EQUALS:
511 3940 caballero
                    m = jtsShape.relate(jtsGeom);
512 2979 fjp
                    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 3006 fjp
        long t2 = System.currentTimeMillis();
557
        logger.debug("queryByShape optimizado sobre la capa " + lyr.getName() + ". " + (t2-t1) + " mseg.");
558 2979 fjp
        return bitset;
559
    }
560 4347 azabala
    public FBitSet queryByRect(Rectangle2D rect, CancellableMonitorable cancel) throws DriverException {
561 2979 fjp
        // Si hay un ?ndice espacial, lo usamos para hacer el query.
562
        FLyrVect lyr = (FLyrVect) capa;
563 4976 azabala
//        if (lyr.getSpatialIndex() == null)
564
          if(lyr.getISpatialIndex() == null)
565 4311 azabala
            return super.queryByRect(rect, cancel);
566 2979 fjp
567 3940 caballero
        ReadableVectorial va = lyr.getSource();
568 2979 fjp
        ICoordTrans ct = lyr.getCoordTrans();
569
        Rectangle2D bounds = rect;
570 4976 azabala
//        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 2979 fjp
        Integer idRec;
577
        FBitSet bitset = new FBitSet();
578
        int index;
579
        try {
580
            va.start();
581 4115 fjp
            DriverAttributes attr = va.getDriverAttributes();
582
            boolean bMustClone = false;
583
            if (attr != null)
584
            {
585
                if (attr.isLoadedInMemory())
586
                {
587 4213 caballero
                    bMustClone = attr.isLoadedInMemory();
588 4115 fjp
                }
589
            }
590 2979 fjp
591
            for (int i=0; i < lstRecs.size(); i++)
592 5490 caballero
            {
593 4419 azabala
                    if(cancel != null){
594
                            cancel.reportStep();
595
                            if(cancel.isCanceled()){
596 4895 azabala
                                    va.stop();
597
                                    return bitset;
598 4419 azabala
                            }
599
                    }
600 2979 fjp
                idRec = (Integer) lstRecs.get(i);
601
                index = idRec.intValue();
602
                IGeometry geom = va.getShape(index);
603
                if (ct != null) {
604 4115 fjp
                    if (bMustClone)
605
                        geom = geom.cloneGeometry();
606 2979 fjp
                    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 3940 caballero
620 5490 caballero
621 4895 azabala
    public void process(FeatureVisitor visitor, Rectangle2D rectangle) throws DriverException, VisitException{
622
            process(visitor, rectangle, null);
623
    }
624 5490 caballero
625 4976 azabala
    /**
626 4895 azabala
     * Processes (by calling visitor.process() method) only those
627
     * features of the vectorial layer associated which intersects given
628
     * rectangle2d.
629 5490 caballero
     *
630 4895 azabala
     */
631 5490 caballero
632 4347 azabala
    public void process(FeatureVisitor visitor, Rectangle2D rectangle, CancellableMonitorable cancel) throws DriverException, VisitException {
633 4200 azabala
        FLyrVect lyr = (FLyrVect) capa;
634 4976 azabala
        //if we dont have spatial index or...
635
        if (lyr.getISpatialIndex() == null){
636 4311 azabala
            super.process(visitor, rectangle, cancel);
637 4295 azabala
            return;
638 5490 caballero
        }
639 4976 azabala
        //if spatial index is not worthy
640
        if(! isSpatialIndexNecessary(rectangle)){
641
                super.process(visitor, rectangle, cancel);
642
            return;
643
        }
644 4200 azabala
645
        ReadableVectorial va = lyr.getSource();
646
        ICoordTrans ct = lyr.getCoordTrans();
647
        Rectangle2D bounds = rectangle;
648 4976 azabala
        List lstRecs = lyr.getISpatialIndex().query(bounds);
649 4895 azabala
                Integer idRec;
650 4200 azabala
        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 5490 caballero
                    bMustClone = attr.isLoadedInMemory();
660 4200 azabala
                }
661
            }
662
663
            for (int i=0; i < lstRecs.size(); i++)
664
            {
665 4419 azabala
                    if(cancel != null){
666
                            cancel.reportStep();
667
                    }
668 4311 azabala
                    if(verifyCancelation(cancel, va, visitor))
669
                            return;
670 4200 azabala
                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 5490 caballero
                }
678 4200 azabala
                if (geom.intersects(rectangle))
679 5490 caballero
                    visitor.visit(geom, index);
680 4895 azabala
            }//for
681 4200 azabala
            va.stop();
682
        } catch (DriverIOException e) {
683
            // TODO Auto-generated catch block
684
            e.printStackTrace();
685
        }
686
        }
687
688 2979 fjp
    /* (non-Javadoc)
689
     * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByPoint(java.awt.geom.Point2D, double)
690
     */
691 4347 azabala
    public FBitSet queryByPoint(Point2D p, double tolerance, CancellableMonitorable cancel)
692 2979 fjp
    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 4311 azabala
        return queryByRect(recPoint, cancel);
699 2979 fjp
    }
700 214 fernando
}