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 @ 45517

History | View | Annotate | Download (11 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.io.IOException;
30
import java.net.URL;
31

    
32
import org.gvsig.compat.print.PrintAttributes;
33
import org.gvsig.fmap.dal.feature.Feature;
34
import org.gvsig.fmap.geom.Geometry;
35
import org.gvsig.fmap.geom.primitive.Point;
36
import org.gvsig.fmap.mapcontext.MapContext;
37
import org.gvsig.fmap.mapcontext.MapContextLocator;
38
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
39
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
40
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
41
import org.gvsig.i18n.Messages;
42
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IPictureMarkerSymbol;
43
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.BackgroundFileStyle;
44
import org.gvsig.tools.ToolsLocator;
45
import org.gvsig.tools.dynobject.DynStruct;
46
import org.gvsig.tools.persistence.PersistenceManager;
47
import org.gvsig.tools.persistence.PersistentState;
48
import org.gvsig.tools.persistence.exception.PersistenceException;
49
import org.gvsig.tools.task.Cancellable;
50
import org.gvsig.tools.util.Callable;
51
import org.slf4j.Logger;
52
import org.slf4j.LoggerFactory;
53

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

    
61
    private final Logger LOG = LoggerFactory.getLogger(PictureMarkerSymbol.class);
62

    
63
    public static final String PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME
64
            = "PictureMarkerSymbol";
65
    private static final String SELECTED = "selected";
66
    private static final String SELECTION_SYMBOL = "selectionSym";
67
    private static final String BACKGROUND_IMAGE = "bgImage";
68
    private static final String BACKGROUND_SELECTION_IMAGE = "bgSelImage";
69

    
70
//    private static final float SELECTION_OPACITY_FACTOR = .3F;
71
    private boolean selected;
72
    private PictureMarkerSymbol selectionSym;
73

    
74
    private BackgroundFileStyle bgImage;
75
    private BackgroundFileStyle bgSelImage;
76

    
77
    public PictureMarkerSymbol() {
78
        super();
79
        setSize(18);
80
    }
81

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

    
97
    }
98

    
99
    /**
100
     * Sets the file for the image to be used as a marker symbol
101
     *
102
     * @param imageUrl
103
     * @throws IOException
104
     */
105
    @Override
106
    public void setImage(URL imageUrl) throws IOException {
107
        bgImage = BackgroundFileStyle.createStyleByURL(imageUrl);
108
    }
109

    
110
    /**
111
     * Sets the file for the image to be used as a marker symbol (when it is
112
     * selected in the map)
113
     *
114
     * @param imageFileUrl
115
     * @throws IOException
116
     */
117
    @Override
118
    public void setSelImage(URL imageFileUrl) throws IOException {
119
        bgSelImage = BackgroundFileStyle.createStyleByURL(imageFileUrl);
120
    }
121

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

    
138
    @Override
139
    public void draw(Graphics2D g,
140
            AffineTransform affineTransform,
141
            Geometry geom,
142
            Feature f,
143
            Cancellable cancel) {
144
        Point p;
145
        try {
146
            p = geom.centroid();
147
        } catch (Exception ex) {
148
            return;
149
        }
150
        if (affineTransform != null) {
151
            p.transform(affineTransform);
152
        }
153
        double x, y;
154
        int size = (int) Math.round(getSize());
155
        double halfSize = getSize() / 2;
156
        x = p.getX() - halfSize;
157
        y = p.getY() - halfSize;
158
        int xOffset = (int) getOffset().getX();
159
        int yOffset = (int) getOffset().getY();
160

    
161
        if (size > 0) {
162
            BackgroundFileStyle bg = (!selected) ? bgImage : bgSelImage;
163
            Rectangle rect = new Rectangle(size, size);
164
            g.translate(x + xOffset, y + yOffset);
165
            double auxRotation = getRotation();
166
            g.rotate(auxRotation, halfSize, halfSize);
167
            if (bg != null) {
168
                try {
169
                    bg.drawInsideRectangle(g, rect);
170
                } catch (SymbolDrawingException e) {
171
                    LOG.warn(Messages.getText("label_style_could_not_be_painted")
172
                            + ": " + bg.getSource().toString(),
173
                            e);
174
                }
175
            } else {
176
                LOG.warn(Messages.getText("label_style_could_not_be_painted")
177
                        + ": bg is Null");
178
            }
179
            g.rotate(-auxRotation, halfSize, halfSize);
180
            g.translate(-(x + xOffset), -(y + yOffset));
181

    
182
        }
183

    
184
    }
185

    
186
    @Override
187
    public void drawInsideRectangle(Graphics2D g, AffineTransform scaleInstance, Rectangle r, PrintAttributes properties) throws SymbolDrawingException {
188

    
189
        /*
190
         * Marker symbols which are not simple (images, etc)
191
         * are resized when drawn inside a rectangle
192
         */
193
        double saved_size = this.getSize();
194
        this.setSize(r.getHeight());
195

    
196
        super.drawInsideRectangle(g, scaleInstance, r, properties);
197

    
198
        this.setSize(saved_size);
199
    }
200

    
201
    public String getClassName() {
202
        return getClass().getName();
203
    }
204

    
205
    /**
206
     * Returns the URL of the image that is used as a marker symbol
207
     *
208
     * @return imagePath,URL
209
     */
210
    @Override
211
    public URL getSource() {
212
        return bgImage.getSource();
213
    }
214

    
215
    /**
216
     * Returns the URL of the image that is used as a marker symbol (when it is
217
     * selected in the map)
218
     *
219
     * @return selimagePath,URL
220
     */
221
    @Override
222
    public URL getSelectedSource() {
223
        return bgSelImage.getSource();
224
    }
225

    
226
    @Override
227
    public PictureMarkerSymbol clone() throws CloneNotSupportedException {
228
        PictureMarkerSymbol copy = (PictureMarkerSymbol) super.clone();
229

    
230
        // clone selection
231
        if (selectionSym != null) {
232
            //to avoid an infinite loop
233
            if (this == selectionSym) {
234
                copy.selectionSym = copy;
235
            } else {
236
                copy.selectionSym = (PictureMarkerSymbol) selectionSym.clone();
237
            }
238
        }
239

    
240
        // clone brackground image
241
        if (bgImage != null) {
242
            copy.bgImage = (BackgroundFileStyle) bgImage.clone();
243
        }
244

    
245
        // clone selection brackground image
246
        if (bgSelImage != null) {
247
            copy.bgSelImage = (BackgroundFileStyle) bgSelImage.clone();
248
        }
249
        return copy;
250
    }
251

    
252
    @Override
253
    public void loadFromState(PersistentState state) throws PersistenceException {
254
        // Set parent style properties
255
        super.loadFromState(state);
256

    
257
        this.selected = (Boolean) state.get(SELECTED);
258
        this.selectionSym = (PictureMarkerSymbol) state.get(SELECTION_SYMBOL);
259
        this.bgImage = (BackgroundFileStyle) state.get(BACKGROUND_IMAGE);
260
        this.bgSelImage = (BackgroundFileStyle) state.get(BACKGROUND_SELECTION_IMAGE);
261
    }
262

    
263
    @Override
264
    public void saveToState(PersistentState state) throws PersistenceException {
265
        // Save parent fill symbol properties
266
        super.saveToState(state);
267

    
268
        // Save own properties
269
        state.set(SELECTED, this.selected);
270
        state.set(SELECTION_SYMBOL, this.getSymbolForSelection());
271
        state.set(BACKGROUND_IMAGE, this.bgImage);
272
        state.set(BACKGROUND_SELECTION_IMAGE, this.bgSelImage);
273
    }
274

    
275
    public static class RegisterPersistence implements Callable {
276

    
277
        @Override
278
        public Object call() throws Exception {
279
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
280
            if (manager.getDefinition(PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
281
                DynStruct definition
282
                        = manager.addDefinition(PictureMarkerSymbol.class,
283
                                PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME,
284
                                PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME
285
                                + " Persistence definition",
286
                                null,
287
                                null);
288

    
289
                // Extend the Style base definition
290
                definition.extend(manager.getDefinition(MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME));
291

    
292
                definition.addDynFieldBoolean(SELECTED).setMandatory(false);
293
                definition.addDynFieldObject(SELECTION_SYMBOL).setMandatory(false)
294
                        .setClassOfValue(PictureMarkerSymbol.class).setMandatory(false);
295
                definition.addDynFieldObject(BACKGROUND_IMAGE)
296
                        .setClassOfValue(BackgroundFileStyle.class).setMandatory(false);
297
                definition.addDynFieldObject(BACKGROUND_SELECTION_IMAGE)
298
                        .setClassOfValue(BackgroundFileStyle.class).setMandatory(false);
299
            }
300
            return true;
301
        }
302
    }
303

    
304
    public static class RegisterSymbol implements Callable {
305

    
306
        @Override
307
        public Object call() throws Exception {
308
            SymbolManager manager = MapContextLocator.getSymbolManager();
309

    
310
            manager.registerSymbol(PictureMarkerSymbol.PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME,
311
                    PictureMarkerSymbol.class);
312

    
313
            return true;
314
        }
315

    
316
    }
317

    
318
}