Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / layers / vectorial / FLyrVect.java @ 38581

History | View | Annotate | Download (34.4 KB)

1 34515 cordinyana
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2 21200 vcaballero
 *
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 34515 cordinyana
 *   Av. Blasco Ib??ez, 50
24 21200 vcaballero
 *   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 org.gvsig.fmap.mapcontext.layers.vectorial;
42
43
import java.awt.Graphics2D;
44 21888 vcaballero
import java.awt.Point;
45 21200 vcaballero
import java.awt.geom.AffineTransform;
46
import java.awt.geom.Point2D;
47
import java.awt.image.BufferedImage;
48 25920 jmvivo
import java.util.Set;
49
import java.util.TreeSet;
50 21200 vcaballero
51
import org.cresques.cts.ICoordTrans;
52 33657 cordinyana
import org.slf4j.LoggerFactory;
53
54 29272 jldominguez
import org.gvsig.compat.print.PrintAttributes;
55 26225 jmvivo
import org.gvsig.fmap.dal.DataStore;
56 24691 vcaballero
import org.gvsig.fmap.dal.exception.DataException;
57 24504 jmvivo
import org.gvsig.fmap.dal.exception.ReadException;
58 27974 jmvivo
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
59 26225 jmvivo
import org.gvsig.fmap.dal.feature.FeatureQuery;
60
import org.gvsig.fmap.dal.feature.FeatureSet;
61
import org.gvsig.fmap.dal.feature.FeatureStore;
62
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
63
import org.gvsig.fmap.dal.feature.FeatureType;
64 26904 jpiera
import org.gvsig.fmap.dal.feature.exception.CreateGeometryException;
65 21200 vcaballero
import org.gvsig.fmap.geom.Geometry;
66 26904 jpiera
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
67
import org.gvsig.fmap.geom.Geometry.TYPES;
68 33429 cordinyana
import org.gvsig.fmap.geom.GeometryLocator;
69
import org.gvsig.fmap.geom.GeometryManager;
70 27414 jpiera
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
71 26904 jpiera
import org.gvsig.fmap.geom.primitive.Circle;
72 21426 vcaballero
import org.gvsig.fmap.geom.primitive.Envelope;
73 27974 jmvivo
import org.gvsig.fmap.geom.type.GeometryType;
74 28091 vcaballero
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
75
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
76 30011 cordinyana
import org.gvsig.fmap.mapcontext.MapContextLocator;
77 37491 jpiera
import org.gvsig.fmap.mapcontext.MapContextManager;
78 21200 vcaballero
import org.gvsig.fmap.mapcontext.ViewPort;
79 26225 jmvivo
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
80
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
81
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
82 27620 vcaballero
import org.gvsig.fmap.mapcontext.exceptions.ReprojectLayerException;
83 26225 jmvivo
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
84 34978 fdiaz
import org.gvsig.fmap.mapcontext.exceptions.StopEditionLayerException;
85 26225 jmvivo
import org.gvsig.fmap.mapcontext.layers.FLayer;
86
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
87
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
88
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
89
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
90
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
91 30011 cordinyana
import org.gvsig.fmap.mapcontext.rendering.legend.LegendException;
92
import org.gvsig.fmap.mapcontext.rendering.legend.events.FeatureDrawnNotification;
93 21200 vcaballero
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
94 25038 jmvivo
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
95
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendContentsChangedListener;
96 30011 cordinyana
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent;
97 21200 vcaballero
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
98 26225 jmvivo
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
99 32880 jjdelcerro
import org.gvsig.metadata.exceptions.MetadataException;
100 24797 vcaballero
import org.gvsig.tools.ToolsLocator;
101 33429 cordinyana
import org.gvsig.tools.dynobject.DynObjectSet;
102 32880 jjdelcerro
import org.gvsig.tools.dynobject.DynStruct;
103 23303 jmvivo
import org.gvsig.tools.exception.BaseException;
104 28091 vcaballero
import org.gvsig.tools.locator.LocatorException;
105 25242 jmvivo
import org.gvsig.tools.observer.Observable;
106
import org.gvsig.tools.observer.Observer;
107 32880 jjdelcerro
import org.gvsig.tools.persistence.PersistenceManager;
108 24797 vcaballero
import org.gvsig.tools.persistence.PersistentState;
109 32880 jjdelcerro
import org.gvsig.tools.persistence.exception.PersistenceException;
110 35763 fdiaz
import org.gvsig.tools.persistence.exception.PersistenceRuntimeException;
111 25058 jmvivo
import org.gvsig.tools.task.Cancellable;
112 21200 vcaballero
113
/**
114 34515 cordinyana
 * Capa b?sica Vectorial.
115 33739 fdiaz
 *
116 34515 cordinyana
 * @author Fernando Gonz?lez Cort?s
117 21200 vcaballero
 */
118
119 33739 fdiaz
public class FLyrVect extends FLyrDefault implements VectorLayer,
120
    LegendContentsChangedListener, Observer {
121 33331 jjdelcerro
122 33739 fdiaz
    final static private org.slf4j.Logger logger =
123
        LoggerFactory.getLogger(FLyrVect.class);
124
    private final GeometryManager geomManager =
125
        GeometryLocator.getGeometryManager();
126 21200 vcaballero
127 33739 fdiaz
    /** Leyenda de la capa vectorial */
128
    private IVectorLegend legend;
129
    private int typeShape = -1;
130
    private FeatureStore featureStore = null;
131
    private SpatialCache spatialCache = new SpatialCache();
132 21200 vcaballero
133 33739 fdiaz
    /**
134
     * An implementation of gvSIG spatial index
135
     */
136
    // protected ISpatialIndex spatialIndex = null;
137
    private IVectorLegend loadLegend = null;
138 21200 vcaballero
139 33739 fdiaz
    private boolean isLabeled;
140
    protected ILabelingStrategy strategy;
141 36248 fdiaz
//        private ReprojectDefaultGeometry reprojectTransform;
142 21200 vcaballero
143 33739 fdiaz
    public FLyrVect() {
144
        super();
145
    }
146 38581 jjdelcerro
147
        public String getTocImageIcon() {
148
                return MapContextLocator.getMapContextManager().getIconLayer(this.getDataStore());
149
        }
150 21200 vcaballero
151 33739 fdiaz
    /**
152
     * Devuelve el VectorialAdapater de la capa.
153
     *
154
     * @return VectorialAdapter.
155
     */
156
    public DataStore getDataStore() {
157
        if (!this.isAvailable()) {
158
            return null;
159
        }
160
        return featureStore;
161
    }
162 36248 fdiaz
163 33739 fdiaz
    /**
164 38581 jjdelcerro
     * Inserta el DataStore a la capa.
165 33739 fdiaz
     *
166
     * @param va
167
     *            VectorialAdapter.
168
     *
169 34515 cordinyana
     * @deprecated esto deber?a se ser protected
170 33739 fdiaz
     */
171
    public void setDataStore(DataStore dataStore) throws LoadLayerException {
172
        if (this.featureStore != null && this.featureStore != dataStore) {
173
            this.featureStore.deleteObserver(this);
174
        }
175 33339 jpiera
176 33739 fdiaz
        featureStore = (FeatureStore) dataStore;
177 22207 jmvivo
178 37491 jpiera
        MapContextManager mapContextManager =
179
            MapContextLocator.getMapContextManager();
180
181
        //Set the legend
182 34303 fdiaz
        IVectorLegend legend =
183 37491 jpiera
            (IVectorLegend)mapContextManager.getLegend(dataStore);
184 22207 jmvivo
185 33739 fdiaz
        if (legend == null) {
186
            throw new LegendLayerException(this.getName());
187
        }
188 25795 jmvivo
189 34303 fdiaz
        this.setLegend(legend);
190 22207 jmvivo
191 37491 jpiera
        //Set the labeling strategy
192
        ILabelingStrategy labeler =
193
            (ILabelingStrategy) mapContextManager.getLabelingStrategy(dataStore);
194 26225 jmvivo
195 33739 fdiaz
        if (labeler != null) {
196
            labeler.setLayer(this);
197
            this.setLabelingStrategy(labeler);
198 34515 cordinyana
            this.setIsLabeled(true); // TODO: ac? no s'hauria de detectar si t?
199 33739 fdiaz
                                     // etiquetes?????
200
        }
201 22207 jmvivo
202 33739 fdiaz
        this.delegate(dataStore);
203 21200 vcaballero
204 33739 fdiaz
        dataStore.addObserver(this);
205 26313 vcaballero
206 35183 cordinyana
        ToolsLocator.getDisposableManager().bind(dataStore);
207 33739 fdiaz
    }
208 21426 vcaballero
209 33739 fdiaz
    public Envelope getFullEnvelope() throws ReadException {
210
        Envelope rAux;
211
        try {
212
            rAux = getFeatureStore().getEnvelope();
213
        } catch (BaseException e) {
214
            throw new ReadException(getName(), e);
215
        }
216 21200 vcaballero
217 33739 fdiaz
        // Esto es para cuando se crea una capa nueva con el fullExtent de ancho
218
        // y alto 0.
219 36231 fdiaz
        if (rAux == null || rAux.isEmpty() || rAux.getMaximum(0) - rAux.getMinimum(0) == 0
220 33739 fdiaz
            && rAux.getMaximum(1) - rAux.getMinimum(1) == 0) {
221
            try {
222
                rAux =
223 36219 fdiaz
                    geomManager.createEnvelope(0, 0, 90, 90, SUBTYPES.GEOM2D);
224 33739 fdiaz
            } catch (CreateEnvelopeException e) {
225
                logger.error("Error creating the envelope", e);
226
                e.printStackTrace();
227
            }
228
        }
229 34515 cordinyana
        // Si existe reproyecci?n, reproyectar el extent
230 33739 fdiaz
        ICoordTrans ct = getCoordTrans();
231 38210 cordinyana
        if (ct != null) {
232
                rAux = rAux.convert(ct);
233 33739 fdiaz
        }
234
        return rAux;
235 38581 jjdelcerro
236 33739 fdiaz
    }
237 26778 jmvivo
238 33739 fdiaz
    /**
239
     * Draws using IFeatureIterator. This method will replace the old draw(...)
240
     * one.
241
     *
242
     * @autor jaume dominguez faus - jaume.dominguez@iver.es
243
     * @param image
244
     * @param g
245
     * @param viewPort
246
     * @param cancel
247
     * @param scale
248
     * @throws ReadDriverException
249
     */
250
    public void draw(BufferedImage image,
251
        Graphics2D g,
252
        ViewPort viewPort,
253
        Cancellable cancel,
254
        double scale) throws ReadException {
255 25207 jmvivo
256 33739 fdiaz
        if (legend == null) {
257
            return;
258
        }
259 21200 vcaballero
260 33739 fdiaz
        if (!this.isWithinScale(scale)) {
261
            return;
262
        }
263
        if (cancel.isCanceled()) {
264
            return;
265
        }
266 29801 vcaballero
267 33739 fdiaz
        if (spatialCache.isEnabled()) {
268
            spatialCache.clearAll();
269
            legend.addDrawingObserver(this);
270
        }
271 21200 vcaballero
272 37298 jpiera
        FeatureQuery featureQuery = null;
273 33739 fdiaz
        try {
274 37298 jpiera
            FeatureAttributeDescriptor featureAttributeDescriptor =
275
                getFeatureStore().getDefaultFeatureType().getDefaultTimeAttribute();
276
277
            if ((viewPort.getTime() != null) && (featureAttributeDescriptor != null)){
278
                featureQuery = getFeatureStore().createFeatureQuery();
279
                IntersectsTimeEvaluator intersectsTimeEvaluator =
280
                    new IntersectsTimeEvaluator(viewPort.getTime(), featureAttributeDescriptor.getName());
281
                featureQuery.addFilter(intersectsTimeEvaluator);
282
            }
283
        } catch (DataException e1) {
284
            logger.error("Impossible to get the temporal filter", e1);
285
        }
286
287
        try {
288 33739 fdiaz
            legend.draw(image,
289
                g,
290
                viewPort,
291
                cancel,
292
                scale,
293
                null,
294
                getCoordTrans(),
295 35198 jpiera
                getFeatureStore(),
296 37835 jpiera
                featureQuery);
297 21200 vcaballero
298 33739 fdiaz
        } catch (LegendException e) {
299
            this.setVisible(false);
300
            this.setActive(false);
301
            throw new ReadException(getName(), e);
302
        } finally {
303
            if (spatialCache.isEnabled()) {
304
                legend.deleteDrawingObserver(this);
305
            }
306
        }
307
    }
308 21200 vcaballero
309 33739 fdiaz
    public void print(Graphics2D g,
310
        ViewPort viewPort,
311
        Cancellable cancel,
312
        double scale,
313
        PrintAttributes properties) throws ReadException {
314
        if (!this.isWithinScale(scale)) {
315
            return;
316
        }
317
        if (cancel.isCanceled()) {
318
            return;
319
        }
320 21200 vcaballero
321 33739 fdiaz
        try {
322
            legend.print(g,
323
                viewPort,
324
                cancel,
325
                scale,
326
                null,
327
                getCoordTrans(),
328
                getFeatureStore(),
329 35198 jpiera
                null,
330 33739 fdiaz
                properties);
331 21200 vcaballero
332 33739 fdiaz
        } catch (LegendException e) {
333
            this.setVisible(false);
334
            this.setActive(false);
335
            throw new ReadException(getName(), e);
336
        }
337
    }
338 21200 vcaballero
339 33739 fdiaz
    public void setLegend(IVectorLegend legend) throws LegendLayerException {
340
        if (this.legend == legend) {
341
            return;
342
        }
343
        if (this.legend != null && this.legend.equals(legend)) {
344
            return;
345
        }
346
        IVectorLegend oldLegend = this.legend;
347
        this.legend = legend;
348
        if (oldLegend != null) {
349
            oldLegend.removeLegendListener(this);
350
            oldLegend.deleteDrawingObserver(this);
351
        }
352
        if (legend != null) {
353
            this.legend.addDrawingObserver(this);
354
            this.legend.addLegendListener(this);
355
        }
356
        LegendChangedEvent e =
357
            LegendChangedEvent.createLegendChangedEvent(oldLegend, this.legend);
358
        e.setLayer(this);
359 38210 cordinyana
        updateDrawVersion();
360 33739 fdiaz
        callLegendChanged(e);
361
    }
362 30173 jldominguez
363 33739 fdiaz
    /**
364
     * Devuelve la Leyenda de la capa.
365
     *
366
     * @return Leyenda.
367
     */
368
    public ILegend getLegend() {
369
        return legend;
370
    }
371 30173 jldominguez
372 33739 fdiaz
    public int getShapeType() throws ReadException {
373 35763 fdiaz
            if (typeShape == -1) {
374
                    FeatureType featureType = null;
375
                    try {
376
                            if( getDataStore()!=null ){
377
                                    featureType =
378
                                            (((FeatureStore) getDataStore()).getDefaultFeatureType());
379
                            }
380
                    } catch (DataException e) {
381
                            throw new ReadException(getName(), e);
382
                    }
383
                    if( featureType!=null ){
384
                            int indexGeom = featureType.getDefaultGeometryAttributeIndex();
385
                            typeShape =
386
                                    featureType.getAttributeDescriptor(indexGeom).getGeometryType();
387
                    }
388
            }
389
            return typeShape;
390 33739 fdiaz
    }
391 30173 jldominguez
392 37328 cordinyana
    /**
393
     * Returns the layer's geometry type
394
     *
395
     * @return the geometry type
396
     *
397
     * @throws ReadException
398
     *             if there is an error getting the geometry type
399
     */
400
    public GeometryType getGeometryType() throws ReadException {
401
        FeatureType featureType = null;
402
        try {
403
            if (getDataStore() != null) {
404
                featureType =
405
                    (((FeatureStore) getDataStore()).getDefaultFeatureType());
406
            }
407
        } catch (DataException e) {
408
            throw new ReadException(getName(), e);
409
        }
410
        return featureType == null ? null : featureType
411
            .getDefaultGeometryAttribute().getGeomType();
412
    }
413
414 33739 fdiaz
    public void saveToState(PersistentState state) throws PersistenceException {
415 30173 jldominguez
416 33739 fdiaz
        if (!this.isAvailable()) {
417
            return;
418
        }
419 30173 jldominguez
420 33739 fdiaz
        super.saveToState(state);
421 30173 jldominguez
422 33739 fdiaz
        if (getLegend() != null) {
423
            state.set("legend", getLegend());
424
        }
425 28545 vcaballero
426 33739 fdiaz
        FeatureStore fst = null;
427
        fst = getFeatureStore();
428 23183 vcaballero
429 33739 fdiaz
        if (fst != null) {
430
            state.set("featureStore", fst);
431
        }
432 21200 vcaballero
433 33739 fdiaz
        state.set("isLabeled", isLabeled);
434 21200 vcaballero
435 33739 fdiaz
        if (strategy != null) {
436
            state.set("labelingStrategy", strategy);
437
        }
438 21200 vcaballero
439 33739 fdiaz
        if (getLinkProperties() != null) {
440
            state.set("linkProperties", getLinkProperties());
441
        }
442 21200 vcaballero
443 33739 fdiaz
        // state.set("bHasJoin", bHasJoin);
444
        state.set("typeShape", typeShape);
445
    }
446 21200 vcaballero
447
448 33739 fdiaz
    public void loadFromState(PersistentState state) throws PersistenceException {
449 21200 vcaballero
450 33739 fdiaz
        super.loadFromState(state);
451 35763 fdiaz
        DataStore store = null;
452 33739 fdiaz
        try {
453 35763 fdiaz
                store = (DataStore) state.get("featureStore");
454
        } catch (PersistenceRuntimeException e) {
455
                        this.setAvailable(false);
456
                        return;
457
                }
458
        try {
459 33739 fdiaz
            this.setDataStore(store);
460
        } catch (LoadLayerException e) {
461
            throw new PersistenceException("While loading FLyrVect from state.",
462
                e);
463
        }
464 21200 vcaballero
465 33739 fdiaz
        IVectorLegend lgnd = (IVectorLegend) state.get("legend");
466
        try {
467
            this.setLegend(lgnd);
468
        } catch (LegendLayerException e) {
469
            throw new PersistenceException("While loading FLyrVect from state.",
470
                e);
471
        }
472 21200 vcaballero
473 33739 fdiaz
        Boolean isLbl = new Boolean(false);
474
        ILabelingStrategy lblst = null;
475 21200 vcaballero
476 33739 fdiaz
        try {
477
            isLbl = (Boolean) state.get("isLabeled");
478
            if (isLbl.booleanValue()) {
479
                lblst = (ILabelingStrategy) state.get("labelingStrategy");
480
            }
481
        } catch (Exception ex) {
482
            throw new PersistenceException("While loading FLyrVect from state.",
483
                ex);
484
        }
485 21200 vcaballero
486 33739 fdiaz
        /*
487
         * String _labelFieldName = null;
488
         * String _labelfield = null;
489
         */
490 21200 vcaballero
491 33739 fdiaz
        if (isLbl.booleanValue()) {
492
            this.setIsLabeled(true);
493
            this.setLabelingStrategy(lblst);
494
        } else {
495
            this.setIsLabeled(false);
496
            this.setLabelingStrategy(null);
497
        }
498 21200 vcaballero
499 33739 fdiaz
        typeShape = state.getInt("typeShape");
500 21200 vcaballero
501 33739 fdiaz
    }
502 25754 vcaballero
503 33739 fdiaz
    /**
504 34515 cordinyana
     * Sobreimplementaci?n del m?todo toString para que las bases de datos
505 33739 fdiaz
     * identifiquen la capa.
506
     *
507
     * @return DOCUMENT ME!
508
     */
509
    public String toString() {
510
        /*
511
         * Se usa internamente para que la parte de datos identifique de forma
512 34515 cordinyana
         * un?voca las tablas
513 33739 fdiaz
         */
514
        String ret = super.toString();
515 25754 vcaballero
516 33739 fdiaz
        return "layer" + ret.substring(ret.indexOf('@') + 1);
517
    }
518 21200 vcaballero
519 33739 fdiaz
    public void setEditing(boolean b) throws StartEditionLayerException {
520
        super.setEditing(b);
521 34978 fdiaz
        FeatureStore fs = getFeatureStore();
522 33739 fdiaz
        if (b) {
523
            try {
524 34978 fdiaz
                fs.edit();
525 33739 fdiaz
            } catch (ReadException e) {
526
                throw new StartEditionLayerException(getName(), e);
527
            } catch (DataException e) {
528
                throw new StartEditionLayerException(getName(), e);
529
            }
530
        }
531
        setSpatialCacheEnabled(b);
532
        callEditionChanged(LayerEvent.createEditionChangedEvent(this, "edition"));
533
    }
534 21200 vcaballero
535 33739 fdiaz
    /**
536
     * @deprecated Use {@link #getSpatialCache()}
537
     */
538
    public void clearSpatialCache() {
539
        spatialCache.clearAll();
540
    }
541 21200 vcaballero
542 33739 fdiaz
    /**
543
     * @deprecated Use {@link #getSpatialCache()}
544
     */
545
    public boolean isSpatialCacheEnabled() {
546
        return spatialCache.isEnabled();
547
    }
548 21200 vcaballero
549 33739 fdiaz
    /**
550
     * @deprecated Use {@link #getSpatialCache()}
551
     */
552
    public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
553
        spatialCache.setEnabled(spatialCacheEnabled);
554
    }
555 21200 vcaballero
556 33739 fdiaz
    public SpatialCache getSpatialCache() {
557
        return spatialCache;
558
    }
559 21200 vcaballero
560 33739 fdiaz
    /**
561
     * Siempre es un numero mayor de 1000
562
     *
563
     * @param maxFeatures
564
     */
565
    public void setMaxFeaturesInEditionCache(int maxFeatures) {
566
        if (maxFeatures > spatialCache.getMaxFeatures()) {
567
            spatialCache.setMaxFeatures(maxFeatures);
568
        }
569 21200 vcaballero
570 33739 fdiaz
    }
571 21200 vcaballero
572 33739 fdiaz
    /**
573
     * This method returns a boolean that is used by the FPopMenu
574
     * to make visible the properties menu or not. It is visible by
575
     * default, and if a later don't have to show this menu only
576
     * has to override this method.
577
     *
578
     * @return
579
     *         If the properties menu is visible (or not)
580
     */
581
    public boolean isPropertiesMenuVisible() {
582
        return true;
583
    }
584 21200 vcaballero
585 33739 fdiaz
    public void reload() throws ReloadLayerException {
586
        super.reload();
587
        try {
588
            getFeatureStore().refresh();
589
        } catch (Exception e) {
590
            throw new ReloadLayerException(getName(), e);
591
        }
592
    }
593 21200 vcaballero
594 33739 fdiaz
    protected void setLoadSelection(Object xml) {
595
        // this.loadSelection = xml;
596
    }
597 21200 vcaballero
598 33739 fdiaz
    protected void setLoadLegend(IVectorLegend legend) {
599
        this.loadLegend = legend;
600
    }
601 21200 vcaballero
602 33739 fdiaz
    protected void putLoadSelection() {
603
        // if (this.loadSelection == null) return;
604
        // try {
605
        // this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection);
606
        // } catch (ReadDriverException e) {
607
        // throw new XMLException(e);
608
        // }
609
        // this.loadSelection = null;
610 21200 vcaballero
611 33739 fdiaz
    }
612 21200 vcaballero
613 33739 fdiaz
    protected void putLoadLegend() throws LegendLayerException {
614
        if (this.loadLegend == null) {
615
            return;
616
        }
617
        this.setLegend(this.loadLegend);
618
        this.loadLegend = null;
619
    }
620 30173 jldominguez
621 33739 fdiaz
    protected void cleanLoadOptions() {
622
        this.loadLegend = null;
623
    }
624 33619 jjdelcerro
625 33739 fdiaz
    public boolean isWritable() {
626
        return getFeatureStore().allowWrite();
627
    }
628 21200 vcaballero
629 33739 fdiaz
    public FLayer cloneLayer() throws Exception {
630
        FLyrVect clonedLayer = new FLyrVect();
631
        clonedLayer.setDataStore(getDataStore());
632
        // if (isJoined()) {
633
        // clonedLayer.setIsJoined(true);
634
        // }
635
        clonedLayer.setVisible(isVisible());
636
        // clonedLayer.setISpatialIndex(getISpatialIndex());
637
        clonedLayer.setName(getName());
638
        clonedLayer.setCoordTrans(getCoordTrans());
639 21200 vcaballero
640 33739 fdiaz
        clonedLayer.setLegend((IVectorLegend) getLegend().cloneLegend());
641 21200 vcaballero
642 33739 fdiaz
        clonedLayer.setIsLabeled(isLabeled());
643
        ILabelingStrategy labelingStrategy = getLabelingStrategy();
644
        if (labelingStrategy != null) {
645
            clonedLayer.setLabelingStrategy(labelingStrategy);
646
        }
647 21200 vcaballero
648 33739 fdiaz
        return clonedLayer;
649
    }
650 21200 vcaballero
651 33739 fdiaz
    protected boolean isOnePoint(AffineTransform graphicsTransform,
652
        ViewPort viewPort,
653
        double dpi,
654
        CartographicSupport csSym,
655
        Geometry geom,
656
        int[] xyCoords) {
657
        return isOnePoint(graphicsTransform, viewPort, geom, xyCoords)
658
            && csSym.getCartographicSize(viewPort, dpi, geom) <= 1;
659
    }
660 21200 vcaballero
661 33739 fdiaz
    private boolean isOnePoint(AffineTransform graphicsTransform,
662
        ViewPort viewPort,
663
        Geometry geom,
664
        int[] xyCoords) {
665
        boolean onePoint = false;
666
        int type = geom.getType();
667
        if (type == Geometry.TYPES.NULL) {
668
            return false;
669
        }
670
        if (type != Geometry.TYPES.POINT && type != Geometry.TYPES.MULTIPOINT) {
671 21200 vcaballero
672 33739 fdiaz
            Envelope geomBounds = geom.getEnvelope();
673 21200 vcaballero
674 33739 fdiaz
            // ICoordTrans ct = getCoordTrans();
675 21200 vcaballero
676 33739 fdiaz
            // Se supone que la geometria ya esta reproyectada
677
            // if (ct!=null) {
678
            // // geomBounds = ct.getInverted().convert(geomBounds);
679
            // geomBounds = geomBounds.convert(ct);
680
            // }
681 21200 vcaballero
682 33739 fdiaz
            double dist1Pixel = viewPort.getDist1pixel();
683 21200 vcaballero
684 33739 fdiaz
            onePoint =
685
                (geomBounds.getLength(0) <= dist1Pixel && geomBounds.getLength(1) <= dist1Pixel);
686 21200 vcaballero
687 33739 fdiaz
            if (onePoint) {
688
                // avoid out of range exceptions
689
                org.gvsig.fmap.geom.primitive.Point p;
690
                try {
691
                    p =
692
                        geomManager.createPoint(geomBounds.getMinimum(0),
693
                            geomBounds.getMinimum(1),
694
                            SUBTYPES.GEOM2D);
695
                    p.transform(viewPort.getAffineTransform());
696
                    p.transform(graphicsTransform);
697
                    xyCoords[0] = (int) p.getX();
698
                    xyCoords[1] = (int) p.getY();
699
                } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
700
                    logger.error("Error creating a point", e);
701
                }
702 22240 jmvivo
703 33739 fdiaz
            }
704 24711 vcaballero
705 33739 fdiaz
        }
706
        return onePoint;
707
    }
708 24711 vcaballero
709 33739 fdiaz
    public boolean isLabeled() {
710
        return isLabeled;
711
    }
712 24711 vcaballero
713 33739 fdiaz
    public void setIsLabeled(boolean isLabeled) {
714
        this.isLabeled = isLabeled;
715
    }
716 33429 cordinyana
717 33739 fdiaz
    public ILabelingStrategy getLabelingStrategy() {
718
        return strategy;
719
    }
720
721
    public void setLabelingStrategy(ILabelingStrategy strategy) {
722
        this.strategy = strategy;
723
        if (strategy == null) {
724
            return;
725
        }
726
        strategy.setLayer(this);
727 38210 cordinyana
        updateDrawVersion();
728 33739 fdiaz
    }
729
730
    public void drawLabels(BufferedImage image,
731
        Graphics2D g,
732
        ViewPort viewPort,
733
        Cancellable cancel,
734
        double scale,
735
        double dpi) throws ReadException {
736
        if (strategy != null && isWithinScale(scale)) {
737
            strategy.draw(image, g, viewPort, cancel, dpi);
738
        }
739
    }
740
741
    public void printLabels(Graphics2D g,
742
        ViewPort viewPort,
743
        Cancellable cancel,
744
        double scale,
745
        PrintAttributes properties) throws ReadException {
746
        if (strategy != null) {
747
            strategy.print(g, viewPort, cancel, properties);
748
        }
749
    }
750
751
    /**
752
     * Return true, because a Vectorial Layer supports HyperLink
753 38581 jjdelcerro
     *
754
     * @deprecated the hiperlink functionaliti is out the layer now
755 33739 fdiaz
     */
756
    public boolean allowLinks() {
757 38581 jjdelcerro
        return false;
758 33739 fdiaz
    }
759
760
    public void load() throws LoadLayerException {
761
        super.load();
762
    }
763
764
    public FeatureStore getFeatureStore() {
765
        return (FeatureStore) getDataStore();
766
    }
767
768 35485 jjdelcerro
    /**
769
     * @deprecated use instead {@link #queryByPoint(org.gvsig.fmap.geom.primitive.Point, double, FeatureType)}
770
     */
771 33739 fdiaz
    public FeatureSet queryByPoint(Point2D mapPoint,
772
        double tol,
773
        FeatureType featureType) throws DataException {
774 35485 jjdelcerro
        logger.warn("Deprecated use of queryByPoint.");
775 33739 fdiaz
        GeometryManager manager = GeometryLocator.getGeometryManager();
776
        org.gvsig.fmap.geom.primitive.Point center;
777
        try {
778
            center =
779
                (org.gvsig.fmap.geom.primitive.Point) manager.create(TYPES.POINT,
780
                    SUBTYPES.GEOM2D);
781
            center.setX(mapPoint.getX());
782
            center.setY(mapPoint.getY());
783
            Circle circle =
784
                (Circle) manager.create(TYPES.CIRCLE, SUBTYPES.GEOM2D);
785
            circle.setPoints(center, tol);
786
            return queryByGeometry(circle, featureType);
787
        } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
788
            throw new CreateGeometryException(TYPES.CIRCLE, SUBTYPES.GEOM2D, e);
789
        }
790
    }
791
792 35485 jjdelcerro
    public FeatureSet queryByPoint(org.gvsig.fmap.geom.primitive.Point point,
793
        double tol,
794
        FeatureType featureType) throws DataException {
795
        GeometryManager manager = GeometryLocator.getGeometryManager();
796
        try {
797
            Circle circle =
798
                (Circle) manager.create(TYPES.CIRCLE, SUBTYPES.GEOM2D);
799
            circle.setPoints(point, tol);
800
            return queryByGeometry(circle, featureType);
801
        } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
802
            throw new CreateGeometryException(TYPES.CIRCLE, SUBTYPES.GEOM2D, e);
803
        }
804
    }
805
806 33739 fdiaz
    public FeatureSet queryByGeometry(Geometry geom, FeatureType featureType) throws DataException {
807
        FeatureQuery featureQuery = featureStore.createFeatureQuery();
808
        String geomName =
809
            featureStore.getDefaultFeatureType()
810
                .getDefaultGeometryAttributeName();
811
        featureQuery.setFeatureType(featureType);
812
        IntersectsGeometryEvaluator iee =
813
            new IntersectsGeometryEvaluator(geom,
814
                getMapContext().getViewPort().getProjection(),
815
                featureStore.getDefaultFeatureType(),
816
                geomName);
817
        featureQuery.setFilter(iee);
818
        return getFeatureStore().getFeatureSet(featureQuery);
819
820
    }
821
822 35753 jpiera
    /**
823
     * It return the {@link FeatureSet} that intersects with the envelope.
824
     * @param envelope
825
     *          envelope that defines the area for the query.
826
     * @param featureType
827
     *          only the features with this feature type are used in
828
     *          the query.
829
     * @return
830
     *          the set of features that intersect with the envelope.
831
     * @throws DataException
832
     */
833 33739 fdiaz
    public FeatureSet queryByEnvelope(Envelope envelope, FeatureType featureType) throws DataException {
834
        return queryByEnvelope(envelope, featureType, null);
835
    }
836
837 35753 jpiera
    /**
838
     * It return the {@link FeatureSet} that intersects with the envelope.
839
     * @param envelope
840
     *          envelope that defines the area for the query.
841
     * @param featureType
842
     *          only the features with this feature type are used in
843
     *          the query.
844
     * @param names
845
     *          the feature attributes that have to be checked.
846
     * @return
847
     *          the set of features that intersect with the envelope.
848
     * @throws DataException
849
     */
850 33739 fdiaz
    public FeatureSet queryByEnvelope(Envelope envelope,
851
        FeatureType featureType,
852
        String[] names) throws DataException {
853
        FeatureQuery featureQuery = featureStore.createFeatureQuery();
854
        if (names == null) {
855
            featureQuery.setFeatureType(featureType);
856
        } else {
857
            featureQuery.setAttributeNames(names);
858
            featureQuery.setFeatureTypeId(featureType.getId());
859
        }
860
        String geomName =
861 37298 jpiera
            featureStore.getDefaultFeatureType()
862 33739 fdiaz
                .getDefaultGeometryAttributeName();
863 35753 jpiera
        IntersectsGeometryEvaluator iee =
864
            new IntersectsGeometryEvaluator(envelope.getGeometry(),
865 33739 fdiaz
                getMapContext().getViewPort().getProjection(),
866
                featureStore.getDefaultFeatureType(),
867
                geomName);
868
        featureQuery.setFilter(iee);
869
        return getFeatureStore().getFeatureSet(featureQuery);
870
871
    }
872
873
    public DynObjectSet getInfo(Point p, double tolerance, Cancellable cancel) throws LoadLayerException,
874
        DataException {
875
876 33657 cordinyana
        return getInfo(p, tolerance, cancel, true);
877
    }
878
879 33739 fdiaz
    public DynObjectSet getInfo(Point p,
880
        double tolerance,
881
        Cancellable cancel,
882 33657 cordinyana
        boolean fast) throws LoadLayerException, DataException {
883
        Point2D infop = new Point2D.Double(p.x, p.y);
884
        Point2D pReal = this.getMapContext().getViewPort().toMapPoint(infop);
885 33739 fdiaz
        return queryByPoint(pReal,
886
            tolerance,
887
            getFeatureStore().getDefaultFeatureType()).getDynObjectSet(fast);
888 33657 cordinyana
    }
889 25038 jmvivo
890 35485 jjdelcerro
    public DynObjectSet getInfo(org.gvsig.fmap.geom.primitive.Point p,
891
        double tolerance) throws LoadLayerException, DataException {
892 35627 fdiaz
        return queryByPoint(p,tolerance, getFeatureStore().getDefaultFeatureType()).getDynObjectSet(false);
893 35485 jjdelcerro
    }
894
895 33739 fdiaz
    public void legendCleared(LegendClearEvent event) {
896 38210 cordinyana
        this.updateDrawVersion();
897 33739 fdiaz
        LegendChangedEvent e =
898
            LegendChangedEvent.createLegendChangedEvent(legend, legend);
899
        this.callLegendChanged(e);
900
    }
901 25038 jmvivo
902 33739 fdiaz
    public boolean symbolChanged(SymbolLegendEvent e) {
903 38210 cordinyana
        this.updateDrawVersion();
904 33739 fdiaz
        LegendChangedEvent ev =
905
            LegendChangedEvent.createLegendChangedEvent(legend, legend);
906
        this.callLegendChanged(ev);
907
        return true;
908
    }
909 25242 jmvivo
910 33739 fdiaz
    public void update(Observable observable, Object notification) {
911
        if (observable.equals(this.featureStore)) {
912
            if (notification instanceof FeatureStoreNotification) {
913
                FeatureStoreNotification event =
914
                    (FeatureStoreNotification) notification;
915
                if (event.getType() == FeatureStoreNotification.AFTER_CANCELEDITING
916
                    || event.getType() == FeatureStoreNotification.AFTER_DELETE
917
                    || event.getType() == FeatureStoreNotification.AFTER_UNDO
918
                    || event.getType() == FeatureStoreNotification.AFTER_REDO
919
                    || event.getType() == FeatureStoreNotification.AFTER_REFRESH
920
                    || event.getType() == FeatureStoreNotification.AFTER_UPDATE
921
                    || event.getType() == FeatureStoreNotification.AFTER_UPDATE_TYPE
922
                    || event.getType() == FeatureStoreNotification.SELECTION_CHANGE
923
                    || event.getType() == FeatureStoreNotification.AFTER_INSERT) {
924
                    this.updateDrawVersion();
925 25242 jmvivo
926 35184 jpiera
                } else if (event.getType() == FeatureStoreNotification.TRANSFORM_CHANGE){
927
                    //If a transform has to be applied, try to reload the layer.
928
                    try {
929
                        reload();
930
                    } catch (ReloadLayerException e) {
931 33739 fdiaz
                        this.setAvailable(false);
932 35184 jpiera
                    }
933
                } else if (event.getType() == FeatureStoreNotification.RESOURCE_CHANGED) {
934
                    this.setAvailable(false);
935
                } else         if (event.getType() == FeatureStoreNotification.AFTER_FINISHEDITING) {
936
                    this.setAvailable(true);
937
                }
938 33739 fdiaz
            }
939
        }
940
        // Only if its an event from our own legend
941
        else
942
            // I comment this line because a legend doesn't implements the
943
            // Observable interface.
944
            // This code is necessary on edition.
945
            // if (observable == getLegend()) {
946
            if (notification instanceof FeatureDrawnNotification) {
947
                Geometry geometry =
948
                    ((FeatureDrawnNotification) notification).getDrawnGeometry();
949
                spatialCache.insert(geometry.getEnvelope(), geometry);
950
                // }
951
            }
952 25920 jmvivo
953 33739 fdiaz
    }
954 25920 jmvivo
955 33739 fdiaz
    /*
956
     * (non-Javadoc)
957
     *
958
     * @see org.gvsig.metadata.Metadata#getMetadataChildren()
959
     */
960
    public Set getMetadataChildren() {
961
        Set ret = new TreeSet();
962
        ret.add(this.featureStore);
963
        return ret;
964
    }
965 27988 jmvivo
966 33739 fdiaz
    /*
967
     * (non-Javadoc)
968
     *
969
     * @see org.gvsig.metadata.Metadata#getMetadataID()
970
     */
971
    public Object getMetadataID() throws MetadataException {
972
        return "Layer(" + this.getName() + "):"
973
            + this.featureStore.getMetadataID();
974
    }
975 26313 vcaballero
976 34488 cmartin
977 30173 jldominguez
978 33739 fdiaz
    public GeometryType getTypeVectorLayer() throws DataException,
979
        LocatorException,
980
        GeometryTypeNotSupportedException,
981
        GeometryTypeNotValidException {
982
        // FIXME Esto deberia de pedirse a FType!!!!
983
        FeatureStore fs = this.getFeatureStore();
984
        FeatureType fType = fs.getDefaultFeatureType();
985
        FeatureAttributeDescriptor attr =
986
            fType.getAttributeDescriptor(fType.getDefaultGeometryAttributeIndex());
987
        GeometryType geomType =
988
            GeometryLocator.getGeometryManager()
989
                .getGeometryType(attr.getGeometryType(),
990
                    attr.getGeometrySubType());
991
        return geomType;
992
    }
993 30173 jldominguez
994 33739 fdiaz
    public static void registerPersistent() {
995
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
996
        if (manager.getDefinition(FLyrDefault.class) == null) {
997
            FLyrDefault.registerPersistent();
998
        }
999
        DynStruct definition =
1000
            manager.addDefinition(FLyrVect.class,
1001
                "FLyrVect",
1002
                "FLyrVect Persistence definition",
1003
                null,
1004
                null);
1005
        definition.extend(PersistenceManager.PERSISTENCE_NAMESPACE,
1006
            "FLyrDefault");
1007
1008
        definition.addDynFieldObject("legend")
1009
            .setClassOfValue(IVectorLegend.class)
1010
            .setMandatory(true);
1011
        definition.addDynFieldObject("featureStore")
1012
            .setClassOfValue(FeatureStore.class)
1013
            .setMandatory(true);
1014
        definition.addDynFieldBoolean("isLabeled").setMandatory(true);
1015
        definition.addDynFieldInt("typeShape").setMandatory(true);
1016
        definition.addDynFieldObject("labelingStrategy")
1017
            .setClassOfValue(ILabelingStrategy.class)
1018
            .setMandatory(false);
1019
1020
    }
1021
1022
    protected void doDispose() throws BaseException {
1023
        dispose(featureStore);
1024
        spatialCache.clearAll();
1025
    }
1026
}