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

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
public class PictureMarkerSymbol extends AbstractMarkerSymbol implements IPictureMarkerSymbol {
59

    
60
    private final Logger LOG =
61
        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

    
72
    private boolean selected;
73
    private PictureMarkerSymbol selectionSym;
74

    
75
    private BackgroundFileStyle bgImage;
76
    private BackgroundFileStyle bgSelImage;
77

    
78
    /**
79
     * Constructor method
80
     */
81
    public PictureMarkerSymbol() {
82
        super();
83
        setSize(18);
84
    }
85

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

    
102
    }
103

    
104
    /**
105
     * Sets the file for the image to be used as a marker symbol
106
     *
107
     * @param imageFile
108
     *            , File
109
     * @throws IOException
110
     */
111
    public void setImage(URL imageUrl) throws IOException {
112

    
113
        bgImage = BackgroundFileStyle.createStyleByURL(imageUrl);
114
    }
115

    
116
    /**
117
     * Sets the file for the image to be used as a marker symbol (when it is
118
     * selected in the map)
119
     *
120
     * @param imageFile
121
     *            , File
122
     * @throws IOException
123
     */
124
    public void setSelImage(URL imageFileUrl) throws IOException {
125

    
126
        bgSelImage = BackgroundFileStyle.createStyleByURL(imageFileUrl);
127
    }
128

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

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

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

    
189
        }
190

    
191
    }
192

    
193

    
194
    public void drawInsideRectangle(Graphics2D g, AffineTransform scaleInstance, Rectangle r, PrintAttributes properties) throws SymbolDrawingException {
195

    
196
        /*
197
         * Marker symbols which are not simple (images, etc)
198
         * are resized when drawn inside a rectangle
199
         */
200
        double saved_size = this.getSize();
201
        this.setSize(r.getHeight());
202

    
203
        super.drawInsideRectangle(g, scaleInstance, r, properties);
204

    
205
        // =================== Restoring size
206
        this.setSize(saved_size);
207
    }
208

    
209

    
210
    public String getClassName() {
211
        return getClass().getName();
212
    }
213

    
214
    // public void print(Graphics2D g, AffineTransform at, FShape shape)
215
    // throws ReadDriverException {
216
    // // TODO Implement it
217
    // throw new Error("Not yet implemented!");
218
    //
219
    // }
220
     /**
221
      * Returns the URL of the image that is used as a marker symbol
222
      * @return imagePath,URL
223
      */
224
    public URL getSource() {
225
            return bgImage.getSource();
226
    }
227
    /**
228
     * Returns the URL of the image that is used as a marker symbol (when it
229
     is selected in the map)
230
     * @return selimagePath,URL
231
     */
232
    public URL getSelectedSource(){
233
            return bgSelImage.getSource();
234
    }
235

    
236
    public Object clone() throws CloneNotSupportedException {
237
        PictureMarkerSymbol copy = (PictureMarkerSymbol) super.clone();
238

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

    
249
        // clone brackground image
250
        if (bgImage != null) {
251
            copy.bgImage = (BackgroundFileStyle) bgImage.clone();
252
        }
253

    
254
        // clone selection brackground image
255
        if (bgSelImage != null) {
256
            copy.bgSelImage = (BackgroundFileStyle) bgSelImage.clone();
257
        }
258
        return copy;
259
    }
260

    
261
    public void loadFromState(PersistentState state) throws PersistenceException {
262
        // Set parent style properties
263
        super.loadFromState(state);
264

    
265
        this.selected = (Boolean) state.get(SELECTED);
266
        this.selectionSym = (PictureMarkerSymbol) state.get(SELECTION_SYMBOL);
267
        this.bgImage = (BackgroundFileStyle) state.get(BACKGROUND_IMAGE);
268
        this.bgSelImage =
269
            (BackgroundFileStyle) state.get(BACKGROUND_SELECTION_IMAGE);
270
    }
271

    
272
    public void saveToState(PersistentState state) throws PersistenceException {
273
        // Save parent fill symbol properties
274
        super.saveToState(state);
275

    
276
        // Save own properties
277
        state.set(SELECTED, this.selected);
278
        state.set(SELECTION_SYMBOL, this.getSymbolForSelection());
279
        state.set(BACKGROUND_IMAGE, this.bgImage);
280
        state.set(BACKGROUND_SELECTION_IMAGE, this.bgSelImage);
281
    }
282

    
283
    public static class RegisterPersistence implements Callable {
284

    
285
        public Object call() throws Exception {
286
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
287
            if (manager.getDefinition(PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
288
                DynStruct definition =
289
                    manager.addDefinition(PictureMarkerSymbol.class,
290
                        PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME,
291
                        PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME
292
                            + " Persistence definition",
293
                        null,
294
                        null);
295

    
296
                // Extend the Style base definition
297
                definition.extend(manager.getDefinition(MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME));
298

    
299
                definition.addDynFieldBoolean(SELECTED).setMandatory(false);
300
                definition.addDynFieldObject(SELECTION_SYMBOL).setMandatory(false)
301
                    .setClassOfValue(PictureMarkerSymbol.class).setMandatory(false);
302
                definition.addDynFieldObject(BACKGROUND_IMAGE)
303
                    .setClassOfValue(BackgroundFileStyle.class).setMandatory(false);
304
                definition.addDynFieldObject(BACKGROUND_SELECTION_IMAGE)
305
                    .setClassOfValue(BackgroundFileStyle.class).setMandatory(false);
306
            }
307
            return Boolean.TRUE;
308
        }
309
    }
310

    
311
        public static class RegisterSymbol implements Callable {
312

    
313
                public Object call() throws Exception {
314
                        SymbolManager manager = MapContextLocator.getSymbolManager();
315

    
316
                manager.registerSymbol(PictureMarkerSymbol.PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME,
317
                    PictureMarkerSymbol.class);
318

    
319
                        return Boolean.TRUE;
320
                }
321

    
322
        }
323

    
324
}