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

History | View | Annotate | Download (12.6 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.Color;
27
import java.awt.Graphics2D;
28
import java.awt.Rectangle;
29
import java.awt.geom.AffineTransform;
30
import java.awt.geom.Point2D;
31
import java.io.IOException;
32
import java.net.URL;
33

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

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

    
67
    private final Logger LOG = LoggerFactory.getLogger(PictureMarkerSymbol.class);
68

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

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

    
80
    private BackgroundFileStyle bgImage;
81
    private BackgroundFileStyle bgSelImage;
82

    
83
    public PictureMarkerSymbol() {
84
        super();
85
        setSize(18);
86
    }
87

    
88
    /**
89
     * Constructor method
90
     *
91
     * @param imageURL , URL of the normal image
92
     * @param selImageURL , 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
    /**
106
     * Sets the file for the image to be used as a marker symbol
107
     *
108
     * @param imageUrl
109
     * @throws IOException
110
     */
111
    @Override
112
    public void setImage(URL imageUrl) throws IOException {
113
        bgImage = BackgroundFileStyle.createStyleByURL(imageUrl);
114
        bgImage.setSymbolTable(this.getSymbolTable(this.getFeature()));
115
    }
116

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

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

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

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

    
198
    }
199

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

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

    
210
        super.drawInsideRectangle(g, scaleInstance, r, properties);
211

    
212
        this.setSize(saved_size);
213
    }
214

    
215
    public String getClassName() {
216
        return getClass().getName();
217
    }
218

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

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

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

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

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

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

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

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

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

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

    
289
    public static class RegisterPersistence implements Callable {
290

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

    
303
                // Extend the Style base definition
304
                definition.extend(manager.getDefinition(MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME));
305

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

    
318
    public static class RegisterSymbol implements Callable {
319

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

    
324
            manager.registerSymbol(PictureMarkerSymbol.PICTURE_MARKER_SYMBOL_PERSISTENCE_DEFINITION_NAME,
325
                    PictureMarkerSymbol.class);
326

    
327
            return true;
328
        }
329

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

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

    
357

    
358
}