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

History | View | Annotate | Download (12 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
/* CVS MESSAGES:
25
 *
26
 * $Id: PictureMarkerSymbol.java 15593 2007-10-29 13:01:13Z jdominguez $
27
 * $Log$
28
 * Revision 1.17  2007-09-21 12:25:32  jaume
29
 * cancellation support extended down to the IGeometry and ISymbol level
30
 *
31
 * Revision 1.16  2007/09/19 16:22:04  jaume
32
 * removed unnecessary imports
33
 *
34
 * Revision 1.15  2007/09/11 07:46:55  jaume
35
 * *** empty log message ***
36
 *
37
 * Revision 1.14  2007/08/16 06:55:19  jvidal
38
 * javadoc updated
39
 *
40
 * Revision 1.13  2007/08/09 06:42:24  jvidal
41
 * javadoc
42
 *
43
 * Revision 1.12  2007/08/08 12:05:17  jvidal
44
 * javadoc
45
 *
46
 * Revision 1.11  2007/07/18 06:54:35  jaume
47
 * continuing with cartographic support
48
 *
49
 * Revision 1.10  2007/07/03 10:58:29  jaume
50
 * first refactor on CartographicSupport
51
 *
52
 * Revision 1.9  2007/06/29 13:07:01  jaume
53
 * +PictureLineSymbol
54
 *
55
 * Revision 1.8  2007/06/11 12:25:48  jaume
56
 * ISymbol drawing integration tests (markers and lines)
57
 *
58
 * Revision 1.7  2007/06/07 06:50:40  jaume
59
 * *** empty log message ***
60
 *
61
 * Revision 1.6  2007/05/29 15:46:37  jaume
62
 * *** empty log message ***
63
 *
64
 * Revision 1.5  2007/05/08 08:47:40  jaume
65
 * *** empty log message ***
66
 *
67
 * Revision 1.4  2007/03/21 17:36:22  jaume
68
 * *** empty log message ***
69
 *
70
 * Revision 1.3  2007/03/09 11:20:57  jaume
71
 * Advanced symbology (start committing)
72
 *
73
 * Revision 1.1.2.4  2007/02/21 07:34:09  jaume
74
 * labeling starts working
75
 *
76
 * Revision 1.1.2.3  2007/02/16 10:54:12  jaume
77
 * multilayer splitted to multilayerline, multilayermarker,and  multilayerfill
78
 *
79
 * Revision 1.1.2.2  2007/02/15 16:23:44  jaume
80
 * *** empty log message ***
81
 *
82
 * Revision 1.1.2.1  2007/02/09 07:47:05  jaume
83
 * Isymbol moved
84
 *
85
 * Revision 1.1  2007/01/24 17:58:22  jaume
86
 * new features and architecture error fixes
87
 *
88
 *
89
 */
90
package org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.impl;
91

    
92
import java.awt.Graphics2D;
93
import java.awt.Rectangle;
94
import java.awt.geom.AffineTransform;
95
import java.io.IOException;
96
import java.net.URL;
97

    
98
import org.gvsig.fmap.dal.feature.Feature;
99
import org.gvsig.fmap.geom.Geometry;
100
import org.gvsig.fmap.mapcontext.MapContextLocator;
101
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
102
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
103
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
104
import org.gvsig.i18n.Messages;
105
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IPictureMarkerSymbol;
106
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.BackgroundFileStyle;
107
import org.gvsig.tools.ToolsLocator;
108
import org.gvsig.tools.dynobject.DynStruct;
109
import org.gvsig.tools.persistence.PersistenceManager;
110
import org.gvsig.tools.persistence.PersistentState;
111
import org.gvsig.tools.persistence.exception.PersistenceException;
112
import org.gvsig.tools.task.Cancellable;
113
import org.gvsig.tools.util.Callable;
114
import org.slf4j.Logger;
115
import org.slf4j.LoggerFactory;
116

    
117
/**
118
 * PictureMarkerSymbol allows to use an image file as a definition to be painted
119
 * instead of a marker symbol.
120
 */
121
public class PictureMarkerSymbol extends AbstractMarkerSymbol implements IPictureMarkerSymbol {
122

    
123
    private final Logger LOG =
124
        LoggerFactory.getLogger(PictureMarkerSymbol.class);
125

    
126
    public static final String PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME =
127
        "PictureMarkerSymbol";
128
    private static final String SELECTED = "selected";
129
    private static final String SELECTION_SYMBOL = "selectionSym";
130
    private static final String BACKGROUND_IMAGE = "bgImage";
131
    private static final String BACKGROUND_SELECTION_IMAGE = "bgSelImage";
132

    
133
//    private static final float SELECTION_OPACITY_FACTOR = .3F;
134
    
135
    private boolean selected;
136
    private PictureMarkerSymbol selectionSym;
137

    
138
    private BackgroundFileStyle bgImage;
139
    private BackgroundFileStyle bgSelImage;
140

    
141
    /**
142
     * Constructor method
143
     */
144
    public PictureMarkerSymbol() {
145
        super();
146
        setSize(18);
147
    }
148

    
149
    /**
150
     * Constructor method
151
     * 
152
     * @param imageURL
153
     *            , URL of the normal image
154
     * @param selImageURL
155
     *            , URL of the image when it is selected in the map
156
     * @throws IOException
157
     */
158
    public PictureMarkerSymbol(URL imageURL, URL selImageURL) throws IOException {
159
        setImage(imageURL);
160
        if (selImageURL != null)
161
            setSelImage(selImageURL);
162
        else
163
            setSelImage(imageURL);
164

    
165
    }
166

    
167
    /**
168
     * Sets the file for the image to be used as a marker symbol
169
     * 
170
     * @param imageFile
171
     *            , File
172
     * @throws IOException
173
     */
174
    public void setImage(URL imageUrl) throws IOException {
175

    
176
        bgImage = BackgroundFileStyle.createStyleByURL(imageUrl);
177
    }
178

    
179
    /**
180
     * Sets the file for the image to be used as a marker symbol (when it is
181
     * selected in the map)
182
     * 
183
     * @param imageFile
184
     *            , File
185
     * @throws IOException
186
     */
187
    public void setSelImage(URL imageFileUrl) throws IOException {
188

    
189
        bgSelImage = BackgroundFileStyle.createStyleByURL(imageFileUrl);
190
    }
191

    
192
    public ISymbol getSymbolForSelection() {
193
        if (selectionSym == null) {
194
            try {
195
                selectionSym = (PictureMarkerSymbol) this.clone();
196
            } catch (CloneNotSupportedException e) {
197
                LOG.error("Error creating the selection symbol for the symbol "
198
                    + this, e);
199
            }
200
            selectionSym.selected = true;
201
            selectionSym.selectionSym = selectionSym; // avoid too much lazy
202
                                                      // creations
203
        }
204
        return selectionSym;
205
    }
206

    
207
    public void draw(Graphics2D g,
208
        AffineTransform affineTransform,
209
        Geometry geom,
210
        Feature f,
211
        Cancellable cancel) {
212
                org.gvsig.fmap.geom.primitive.Point p = (org.gvsig.fmap.geom.primitive.Point)geom.cloneGeometry();
213
                if (affineTransform!=null) {
214
                        p.transform(affineTransform);
215
                }
216
        double x, y;
217
        int size = (int) Math.round(getSize());
218
        double halfSize = getSize() / 2;
219
        x = p.getX() - halfSize;
220
        y = p.getY() - halfSize;
221
        int xOffset = (int) getOffset().getX();
222
        int yOffset = (int) getOffset().getY();
223

    
224
        if (size > 0) {
225
            BackgroundFileStyle bg = (!selected) ? bgImage : bgSelImage;
226
            Rectangle rect = new Rectangle(size, size);
227
            g.translate(x + xOffset, y + yOffset);
228
            double auxRotation = getRotation();
229
            g.rotate(auxRotation, halfSize, halfSize);
230
            if (bg != null) {
231
                try {
232
                    bg.drawInsideRectangle(g, rect);
233
                } catch (SymbolDrawingException e) {
234
                    LOG.warn(Messages.getText("label_style_could_not_be_painted")
235
                        + ": " + bg.getSource().toString(),
236
                        e);
237
                }
238
            } else {
239
                LOG.warn(Messages.getText("label_style_could_not_be_painted")
240
                    + ": bg is Null");
241
            }
242
            g.rotate(-auxRotation, halfSize, halfSize);
243
            g.translate(-(x + xOffset), -(y + yOffset));
244

    
245
        }
246

    
247
    }
248

    
249
    public String getClassName() {
250
        return getClass().getName();
251
    }
252

    
253
    // public void print(Graphics2D g, AffineTransform at, FShape shape)
254
    // throws ReadDriverException {
255
    // // TODO Implement it
256
    // throw new Error("Not yet implemented!");
257
    //
258
    // }
259
     /**
260
      * Returns the URL of the image that is used as a marker symbol
261
      * @return imagePath,URL
262
      */
263
    public URL getSource() {
264
            return bgImage.getSource();
265
    }
266
    /**
267
     * Returns the URL of the image that is used as a marker symbol (when it
268
     is selected in the map)
269
     * @return selimagePath,URL
270
     */
271
    public URL getSelectedSource(){
272
            return bgSelImage.getSource();
273
    }
274

    
275
    public Object clone() throws CloneNotSupportedException {
276
        PictureMarkerSymbol copy = (PictureMarkerSymbol) super.clone();
277

    
278
        // clone selection
279
        if (selectionSym != null) {
280
                //to avoid an infinite loop
281
                if (this == selectionSym){
282
                        copy.selectionSym = copy;
283
                } else {
284
                        copy.selectionSym = (PictureMarkerSymbol) selectionSym.clone();
285
                }
286
        }
287

    
288
        // clone brackground image
289
        if (bgImage != null) {
290
            copy.bgImage = (BackgroundFileStyle) bgImage.clone();
291
        }
292

    
293
        // clone selection brackground image
294
        if (bgSelImage != null) {
295
            copy.bgSelImage = (BackgroundFileStyle) bgSelImage.clone();
296
        }
297
        return copy;
298
    }
299

    
300
    public void loadFromState(PersistentState state) throws PersistenceException {
301
        // Set parent style properties
302
        super.loadFromState(state);
303

    
304
        this.selected = (Boolean) state.get(SELECTED);
305
        this.selectionSym = (PictureMarkerSymbol) state.get(SELECTION_SYMBOL);
306
        this.bgImage = (BackgroundFileStyle) state.get(BACKGROUND_IMAGE);
307
        this.bgSelImage =
308
            (BackgroundFileStyle) state.get(BACKGROUND_SELECTION_IMAGE);
309
    }
310

    
311
    public void saveToState(PersistentState state) throws PersistenceException {
312
        // Save parent fill symbol properties
313
        super.saveToState(state);
314

    
315
        // Save own properties
316
        state.set(SELECTED, this.selected);
317
        state.set(SELECTION_SYMBOL, this.getSymbolForSelection());
318
        state.set(BACKGROUND_IMAGE, this.bgImage);
319
        state.set(BACKGROUND_SELECTION_IMAGE, this.bgSelImage);
320
    }
321

    
322
    public static class RegisterPersistence implements Callable {
323

    
324
        public Object call() throws Exception {
325
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
326
            if (manager.getDefinition(PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
327
                DynStruct definition =
328
                    manager.addDefinition(PictureMarkerSymbol.class,
329
                        PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME,
330
                        PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME
331
                            + " Persistence definition",
332
                        null,
333
                        null);
334

    
335
                // Extend the Style base definition
336
                definition.extend(manager.getDefinition(MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME));
337

    
338
                definition.addDynFieldBoolean(SELECTED).setMandatory(false);
339
                definition.addDynFieldObject(SELECTION_SYMBOL).setMandatory(false)
340
                    .setClassOfValue(PictureMarkerSymbol.class).setMandatory(false);
341
                definition.addDynFieldObject(BACKGROUND_IMAGE)
342
                    .setClassOfValue(BackgroundFileStyle.class).setMandatory(false);
343
                definition.addDynFieldObject(BACKGROUND_SELECTION_IMAGE)
344
                    .setClassOfValue(BackgroundFileStyle.class).setMandatory(false);
345
            }
346
            return Boolean.TRUE;
347
        }
348
    }
349
    
350
        public static class RegisterSymbol implements Callable {
351

    
352
                public Object call() throws Exception {
353
                        SymbolManager manager = MapContextLocator.getSymbolManager();
354

    
355
                manager.registerSymbol(PictureMarkerSymbol.PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME,
356
                    PictureMarkerSymbol.class);
357

    
358
                        return Boolean.TRUE;
359
                }
360
                
361
        }
362

    
363
}