Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.symbology / org.gvsig.symbology.lib / org.gvsig.symbology.lib.impl / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / symbol / marker / impl / PictureMarkerSymbol.java @ 45529

History | View | Annotate | Download (12.5 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.impl;
25

    
26
import java.awt.Graphics2D;
27
import java.awt.Rectangle;
28
import java.awt.geom.AffineTransform;
29
import java.awt.geom.Point2D;
30
import java.io.IOException;
31
import java.net.URL;
32
import org.gvsig.compat.print.PrintAttributes;
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.feature.Feature;
35
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
36
import org.gvsig.fmap.dal.feature.FeatureStore;
37
import org.gvsig.fmap.dal.feature.FeatureType;
38
import org.gvsig.fmap.geom.Geometry;
39
import org.gvsig.fmap.geom.primitive.Point;
40
import org.gvsig.fmap.mapcontext.MapContext;
41
import org.gvsig.fmap.mapcontext.MapContextLocator;
42
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
43
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
44
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
45
import org.gvsig.i18n.Messages;
46
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IPictureMarkerSymbol;
47
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.BackgroundFileStyle;
48
import org.gvsig.tools.ToolsLocator;
49
import org.gvsig.tools.dynobject.DynStruct;
50
import org.gvsig.tools.persistence.PersistenceManager;
51
import org.gvsig.tools.persistence.PersistentState;
52
import org.gvsig.tools.persistence.exception.PersistenceException;
53
import org.gvsig.tools.task.Cancellable;
54
import org.gvsig.tools.util.Callable;
55
import org.slf4j.Logger;
56
import org.slf4j.LoggerFactory;
57

    
58
/**
59
 * PictureMarkerSymbol allows to use an image file as a definition to be painted
60
 * instead of a marker symbol.
61
 */
62
@SuppressWarnings("UseSpecificCatch")
63
public class PictureMarkerSymbol extends AbstractMarkerSymbol implements IPictureMarkerSymbol {
64

    
65
    private final Logger LOG = LoggerFactory.getLogger(PictureMarkerSymbol.class);
66

    
67
    public static final String PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME
68
            = "PictureMarkerSymbol";
69
    private static final String SELECTED = "selected";
70
    private static final String SELECTION_SYMBOL = "selectionSym";
71
    private static final String BACKGROUND_IMAGE = "bgImage";
72
    private static final String BACKGROUND_SELECTION_IMAGE = "bgSelImage";
73

    
74
//    private static final float SELECTION_OPACITY_FACTOR = .3F;
75
    private boolean selected;
76
    private PictureMarkerSymbol selectionSym;
77

    
78
    private BackgroundFileStyle bgImage;
79
    private BackgroundFileStyle bgSelImage;
80

    
81
    public PictureMarkerSymbol() {
82
        super();
83
        setSize(18);
84
    }
85

    
86
    /**
87
     * Constructor method
88
     *
89
     * @param imageURL , URL of the normal image
90
     * @param selImageURL , URL of the image when it is selected in the map
91
     * @throws IOException
92
     */
93
    public PictureMarkerSymbol(URL imageURL, URL selImageURL) throws IOException {
94
        setImage(imageURL);
95
        if (selImageURL != null) {
96
            setSelImage(selImageURL);
97
        } else {
98
            setSelImage(imageURL);
99
        }
100

    
101
    }
102

    
103
    /**
104
     * Sets the file for the image to be used as a marker symbol
105
     *
106
     * @param imageUrl
107
     * @throws IOException
108
     */
109
    @Override
110
    public void setImage(URL imageUrl) throws IOException {
111
        bgImage = BackgroundFileStyle.createStyleByURL(imageUrl);
112
        bgImage.setSymbolTable(this.getSymbolTable(this.getFeature()));
113
    }
114

    
115
    /**
116
     * Sets the file for the image to be used as a marker symbol (when it is
117
     * selected in the map)
118
     *
119
     * @param imageFileUrl
120
     * @throws IOException
121
     */
122
    @Override
123
    public void setSelImage(URL imageFileUrl) throws IOException {
124
        bgSelImage = BackgroundFileStyle.createStyleByURL(imageFileUrl);
125
        bgSelImage.setSymbolTable(this.getSymbolTable(this.getFeature()));
126
    }
127

    
128
    @Override
129
    public ISymbol getSymbolForSelection() {
130
        if (selectionSym == null) {
131
            try {
132
                selectionSym = (PictureMarkerSymbol) this.clone();
133
            } catch (CloneNotSupportedException e) {
134
                LOG.warn("Error creating the selection symbol for the symbol "+ this, e);
135
            }
136
            selectionSym.selected = true;
137
            selectionSym.selectionSym = selectionSym; // avoid too much lazy creations
138
        } else {
139
            selectionSym.setColor(MapContext.getSelectionColor());
140
        }
141
        return selectionSym;
142
    }
143

    
144
    @Override
145
    public void draw(Graphics2D g,
146
            AffineTransform affineTransform,
147
            Geometry geom,
148
            Feature f,
149
            Cancellable cancel) {
150
        Point p;
151
        try {
152
            p = geom.centroid();
153
        } catch (Exception ex) {
154
            return;
155
        }
156
        if (affineTransform != null) {
157
            p.transform(affineTransform);
158
        }
159
        double x, y;
160
        int size = (int) Math.round(getEfectiveSize(f));
161
        double halfSize = getEfectiveSize(f) / 2;
162
        x = p.getX() - halfSize;
163
        y = p.getY() - halfSize;
164
        Point2D theOffset = this.getEfectiveOffset(f);
165
        int xOffset = (int) theOffset.getX();
166
        int yOffset = (int) theOffset.getY();
167

    
168
        if (size > 0) {
169
            if( isDrawLineToOffset() ) {
170
                g.setColor(this.getEfectiveLineToOffsetColor(f));
171
                g.drawLine((int)p.getX(), (int)p.getY(), (int)p.getX() + xOffset, (int)p.getY() + yOffset);
172
            }
173
            BackgroundFileStyle bg = (!selected) ? bgImage : bgSelImage;
174
            Rectangle rect = new Rectangle(size, size);
175
            g.translate(x + xOffset, y + yOffset);
176
            double auxRotation = getEfectiveRotationInRadians(f);
177
            g.rotate(auxRotation, halfSize, halfSize);
178
            if (bg != null) {
179
                try {
180
                    bg.setSymbolTable(this.getSymbolTable(f));
181
                    bg.drawInsideRectangle(g, rect);
182
                } catch (SymbolDrawingException e) {
183
                    LOG.warn(Messages.getText("label_style_could_not_be_painted")
184
                            + ": " + bg.getSource().toString(),
185
                            e);
186
                }
187
            } else {
188
                LOG.warn(Messages.getText("label_style_could_not_be_painted")
189
                        + ": bg is Null");
190
            }
191
            g.rotate(-auxRotation, halfSize, halfSize);
192
            g.translate(-(x + xOffset), -(y + yOffset));
193
            
194
        }
195

    
196
    }
197

    
198
    @Override
199
    public void drawInsideRectangle(Graphics2D g, AffineTransform scaleInstance, Rectangle r, PrintAttributes properties) throws SymbolDrawingException {
200

    
201
        /*
202
         * Marker symbols which are not simple (images, etc)
203
         * are resized when drawn inside a rectangle
204
         */
205
        double saved_size = this.getSize();
206
        this.setSize(r.getHeight());
207

    
208
        super.drawInsideRectangle(g, scaleInstance, r, properties);
209

    
210
        this.setSize(saved_size);
211
    }
212

    
213
    public String getClassName() {
214
        return getClass().getName();
215
    }
216

    
217
    /**
218
     * Returns the URL of the image that is used as a marker symbol
219
     *
220
     * @return imagePath,URL
221
     */
222
    @Override
223
    public URL getSource() {
224
        return bgImage.getSource();
225
    }
226

    
227
    /**
228
     * Returns the URL of the image that is used as a marker symbol (when it is
229
     * selected in the map)
230
     *
231
     * @return selimagePath,URL
232
     */
233
    @Override
234
    public URL getSelectedSource() {
235
        return bgSelImage.getSource();
236
    }
237

    
238
    @Override
239
    public PictureMarkerSymbol clone() throws CloneNotSupportedException {
240
        PictureMarkerSymbol copy = (PictureMarkerSymbol) super.clone();
241

    
242
        // clone selection
243
        if (selectionSym != null) {
244
            //to avoid an infinite loop
245
            if (this == selectionSym) {
246
                copy.selectionSym = copy;
247
            } else {
248
                copy.selectionSym = (PictureMarkerSymbol) selectionSym.clone();
249
            }
250
        }
251

    
252
        // clone brackground image
253
        if (bgImage != null) {
254
            copy.bgImage = (BackgroundFileStyle) bgImage.clone();
255
        }
256

    
257
        // clone selection brackground image
258
        if (bgSelImage != null) {
259
            copy.bgSelImage = (BackgroundFileStyle) bgSelImage.clone();
260
        }
261
        return copy;
262
    }
263

    
264
    @Override
265
    public void loadFromState(PersistentState state) throws PersistenceException {
266
        // Set parent style properties
267
        super.loadFromState(state);
268

    
269
        this.selected = (Boolean) state.get(SELECTED);
270
        this.selectionSym = (PictureMarkerSymbol) state.get(SELECTION_SYMBOL);
271
        this.bgImage = (BackgroundFileStyle) state.get(BACKGROUND_IMAGE);
272
        this.bgSelImage = (BackgroundFileStyle) state.get(BACKGROUND_SELECTION_IMAGE);
273
    }
274

    
275
    @Override
276
    public void saveToState(PersistentState state) throws PersistenceException {
277
        // Save parent fill symbol properties
278
        super.saveToState(state);
279

    
280
        // Save own properties
281
        state.set(SELECTED, this.selected);
282
        state.set(SELECTION_SYMBOL, this.getSymbolForSelection());
283
        state.set(BACKGROUND_IMAGE, this.bgImage);
284
        state.set(BACKGROUND_SELECTION_IMAGE, this.bgSelImage);
285
    }
286

    
287
    public static class RegisterPersistence implements Callable {
288

    
289
        @Override
290
        public Object call() throws Exception {
291
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
292
            if (manager.getDefinition(PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
293
                DynStruct definition
294
                        = manager.addDefinition(PictureMarkerSymbol.class,
295
                                PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME,
296
                                PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME
297
                                + " Persistence definition",
298
                                null,
299
                                null);
300

    
301
                // Extend the Style base definition
302
                definition.extend(manager.getDefinition(MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME));
303

    
304
                definition.addDynFieldBoolean(SELECTED).setMandatory(false);
305
                definition.addDynFieldObject(SELECTION_SYMBOL).setMandatory(false)
306
                        .setClassOfValue(PictureMarkerSymbol.class).setMandatory(false);
307
                definition.addDynFieldObject(BACKGROUND_IMAGE)
308
                        .setClassOfValue(BackgroundFileStyle.class).setMandatory(false);
309
                definition.addDynFieldObject(BACKGROUND_SELECTION_IMAGE)
310
                        .setClassOfValue(BackgroundFileStyle.class).setMandatory(false);
311
            }
312
            return true;
313
        }
314
    }
315

    
316
    public static class RegisterSymbol implements Callable {
317

    
318
        @Override
319
        public Object call() throws Exception {
320
            SymbolManager manager = MapContextLocator.getSymbolManager();
321

    
322
            manager.registerSymbol(PictureMarkerSymbol.PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME,
323
                    PictureMarkerSymbol.class);
324

    
325
            return true;
326
        }
327

    
328
    }
329
 
330
    @Override
331
    public String[] getRequiredFeatureAttributeNames(FeatureStore featureStore) throws DataException {
332
        // By default only need the default Geometry
333
        FeatureType ftype = featureStore.getDefaultFeatureTypeQuietly();
334
        String[] res = new String[ftype.size()];
335
        int cont = 0;
336
        for (FeatureAttributeDescriptor attr : ftype) {
337
            res[cont++]=attr.getName();
338
        }
339
        return res;
340
    }
341

    
342
    @Override
343
    public void setFeature(Feature feature) {
344
        super.setFeature(feature);
345
        if( this.bgImage!=null ) {
346
            this.bgImage.setSymbolTable(this.getSymbolTable(this.getFeature()));
347
        }
348
        if( this.bgSelImage!=null ) {
349
            this.bgSelImage.setSymbolTable(this.getSymbolTable(this.getFeature()));
350
        }
351
    }
352
}