Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / org.gvsig.symbology / org.gvsig.symbology.lib / org.gvsig.symbology.lib.impl / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / symbol / fill / impl / MarkerFillSymbol.java @ 34294

History | View | Annotate | Download (21.9 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41

    
42
/* CVS MESSAGES:
43
*
44
* $Id: MarkerFillSymbol.java 16176 2007-11-08 16:07:26Z jdominguez $
45
* $Log$
46
* Revision 1.19  2007-09-21 12:25:32  jaume
47
* cancellation support extended down to the IGeometry and ISymbol level
48
*
49
* Revision 1.18  2007/09/20 11:53:11  jvidal
50
* bug solved
51
*
52
* Revision 1.16  2007/08/09 10:39:41  jaume
53
* first round of found bugs fixed
54
*
55
* Revision 1.15  2007/08/08 12:04:05  jvidal
56
* javadoc
57
*
58
* Revision 1.14  2007/08/03 09:22:09  jaume
59
* refactored class names
60
*
61
* Revision 1.13  2007/08/02 11:13:50  jaume
62
* char encoding fix
63
*
64
* Revision 1.12  2007/08/01 11:45:59  jaume
65
* passing general tests (drawing test yet missing)
66
*
67
* Revision 1.11  2007/07/23 06:52:25  jaume
68
* default selection color refactored, moved to MapContext
69
*
70
* Revision 1.10  2007/05/28 15:36:42  jaume
71
* *** empty log message ***
72
*
73
* Revision 1.9  2007/05/08 08:47:40  jaume
74
* *** empty log message ***
75
*
76
* Revision 1.8  2007/03/28 16:48:14  jaume
77
* *** empty log message ***
78
*
79
* Revision 1.7  2007/03/26 14:25:17  jaume
80
* implements IPrintable
81
*
82
* Revision 1.6  2007/03/21 17:36:22  jaume
83
* *** empty log message ***
84
*
85
* Revision 1.5  2007/03/13 16:58:36  jaume
86
* Added QuantityByCategory (Multivariable legend) and some bugfixes in symbols
87
*
88
* Revision 1.4  2007/03/09 11:20:57  jaume
89
* Advanced symbology (start committing)
90
*
91
* Revision 1.2.2.4  2007/02/16 10:54:12  jaume
92
* multilayer splitted to multilayerline, multilayermarker,and  multilayerfill
93
*
94
* Revision 1.2.2.3  2007/02/15 16:23:44  jaume
95
* *** empty log message ***
96
*
97
* Revision 1.2.2.2  2007/02/12 15:15:20  jaume
98
* refactored interval legend and added graduated symbol legend
99
*
100
* Revision 1.2.2.1  2007/02/09 07:47:05  jaume
101
* Isymbol moved
102
*
103
* Revision 1.2  2007/01/10 16:39:41  jaume
104
* ISymbol now belongs to com.iver.cit.gvsig.fmap.core.symbols package
105
*
106
* Revision 1.1  2007/01/10 16:31:36  jaume
107
* *** empty log message ***
108
*
109
* Revision 1.10  2006/11/09 18:39:05  jaume
110
* *** empty log message ***
111
*
112
* Revision 1.9  2006/11/09 10:22:50  jaume
113
* *** empty log message ***
114
*
115
* Revision 1.8  2006/11/08 13:05:51  jaume
116
* *** empty log message ***
117
*
118
* Revision 1.7  2006/11/08 10:56:47  jaume
119
* *** empty log message ***
120
*
121
* Revision 1.6  2006/11/07 08:52:30  jaume
122
* *** empty log message ***
123
*
124
* Revision 1.5  2006/11/06 17:08:45  jaume
125
* *** empty log message ***
126
*
127
* Revision 1.4  2006/11/06 16:06:52  jaume
128
* *** empty log message ***
129
*
130
* Revision 1.3  2006/11/06 07:33:54  jaume
131
* javadoc, source style
132
*
133
* Revision 1.2  2006/10/31 16:16:34  jaume
134
* *** empty log message ***
135
*
136
* Revision 1.1  2006/10/30 19:30:35  jaume
137
* *** empty log message ***
138
*
139
*
140
*/
141
package org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.impl;
142

    
143
import java.awt.Color;
144
import java.awt.Graphics2D;
145
import java.awt.Paint;
146
import java.awt.Rectangle;
147
import java.awt.RenderingHints;
148
import java.awt.TexturePaint;
149
import java.awt.geom.AffineTransform;
150
import java.awt.image.BufferedImage;
151
import java.util.Random;
152

    
153
import org.gvsig.compat.print.PrintAttributes;
154
import org.gvsig.fmap.dal.feature.Feature;
155
import org.gvsig.fmap.geom.Geometry;
156
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
157
import org.gvsig.fmap.geom.Geometry.TYPES;
158
import org.gvsig.fmap.geom.GeometryLocator;
159
import org.gvsig.fmap.geom.GeometryManager;
160
import org.gvsig.fmap.geom.exception.CreateGeometryException;
161
import org.gvsig.fmap.geom.operation.GeometryOperationException;
162
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
163
import org.gvsig.fmap.geom.primitive.Point;
164
import org.gvsig.fmap.mapcontext.MapContext;
165
import org.gvsig.fmap.mapcontext.MapContextLocator;
166
import org.gvsig.fmap.mapcontext.ViewPort;
167
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
168
import org.gvsig.fmap.mapcontext.rendering.symbols.IWarningSymbol;
169
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
170
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
171
import org.gvsig.i18n.Messages;
172
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
173
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IMarkerFillSymbol;
174
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.CartographicSupportToolkit;
175
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
176
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.impl.PictureMarkerSymbol;
177
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.IMarkerFillPropertiesStyle;
178
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.SimpleMarkerFillPropertiesStyle;
179
import org.gvsig.tools.ToolsLocator;
180
import org.gvsig.tools.dynobject.DynStruct;
181
import org.gvsig.tools.persistence.PersistenceManager;
182
import org.gvsig.tools.persistence.PersistentState;
183
import org.gvsig.tools.persistence.exception.PersistenceException;
184
import org.gvsig.tools.task.Cancellable;
185
import org.gvsig.tools.util.Callable;
186
import org.slf4j.Logger;
187
import org.slf4j.LoggerFactory;
188

    
189
/**
190
 * Allows to define a marker symbol of any type as a path image to be used for a filled of a
191
 * polygon's padding
192
 *
193
 * @author   jaume dominguez faus - jaume.dominguez@iver.es
194
 */
195
public class MarkerFillSymbol extends AbstractFillSymbol implements IMarkerFillSymbol {
196
        private static final Logger logger = LoggerFactory.getLogger(MarkerFillSymbol.class);
197
        
198
    public static final String MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME =
199
        "MarkerFillSymbol";
200
    private static final String MARKER_SYMBOL = "markerSymbol";
201
    private static final String SELECTION_SYMBOL = "selectionSymbol";
202
    private static final String MARKER_FILL_PROPERTIES = "markerFillProperties";
203
    private static final String PREVIOUS_MARKERSIZE = "previousMarkerSize";
204

    
205
        public static final int RANDOM_FILL = 3;
206
        public static final int GRID_FILL = 1;
207
        public static final int SINGLE_CENTERED_SYMBOL = 2;
208
        public static int DefaultFillStyle = GRID_FILL;
209
        private MarkerFillSymbol selectionSymbol;
210
        private IMarkerFillPropertiesStyle markerFillProperties = new SimpleMarkerFillPropertiesStyle();
211
        private IMarkerSymbol markerSymbol = (IMarkerSymbol) MapContextLocator.getSymbolManager().createSymbol(IMarkerSymbol.SYMBOL_NAME);
212
        private double previousMarkerSize = markerSymbol.getSize();
213
        private PrintAttributes properties;
214
        private GeometryManager geometryManager = GeometryLocator.getGeometryManager();
215

    
216
        public ISymbol getSymbolForSelection() {
217
                if (selectionSymbol == null) {
218
                        selectionSymbol = (MarkerFillSymbol) cloneForSelection();
219
                        selectionSymbol.setFillColor(MapContext.getSelectionColor());
220
                }
221

    
222
                return selectionSymbol;
223
        }
224

    
225
        public void draw(Graphics2D g, AffineTransform affineTransform, Geometry geom, Feature feat, Cancellable cancel) {
226
                Point centroid = null;
227
                Point p = null;
228
                        switch (markerFillProperties.getFillStyle()) {
229
                        case SINGLE_CENTERED_SYMBOL:
230
                                // case a single marker is used into a polygon shapetype
231
                                //                        Geometry geom = FConverter.java2d_to_jts(geom);
232
                                //                        com.vividsolutions.jts.geom.Point centroid = geom.getCentroid();
233
                                try {
234
                                        centroid = geom.centroid();
235
                                } catch (GeometryOperationNotSupportedException e2) {
236
                                        logger.warn("Can't get centroid", e2);
237
                                } catch (GeometryOperationException e2) {
238
                                        logger.warn("Can't get centroid", e2);
239
                                }
240

    
241
                                /*
242
                                 * Hay ocasiones en que jts no puede calcular un centroide y devuelve NaN
243
                                 * (por ejemplo con geometr?as poligonales cuyos puntos tienen todos la misma
244
                                 * abscisa y distinta ordenada con tan solo una diferencia de 1 ? 2 unidades)
245
                                 * entonces, en lugar de utilizar este centroide tomamos el centro del
246
                                 * bounds del shp (la geometr?a es tan peque?a que consideramos que deben coincidir).
247
                                 */
248
                                p = null;
249
                                if(centroid!=null && !(Double.isNaN(centroid.getX()) || Double.isNaN(centroid.getY()))){
250
                                        double pX = centroid.getX()+markerFillProperties.getXOffset();
251
                                        double pY = centroid.getY()+markerFillProperties.getYOffset();
252
                                        try {
253
                                                p = geometryManager.createPoint(pX, pY, SUBTYPES.GEOM2D);
254
                                        } catch (CreateGeometryException e) {
255
                                                logger.error("Can't create the point ("+pX+","+pY+")", e);
256
                                        }
257
                                        if (p != null) {
258
                                                markerSymbol.draw(g, affineTransform, p, feat, null);
259
                                        }
260
                                } else {
261
                                        double pX = geom.getBounds().getCenterX();
262
                                        double pY = geom.getBounds().getCenterY();
263
                                        try {
264
                                        p = geometryManager.createPoint(pX, pY, SUBTYPES.GEOM2D);
265
                                        } catch (CreateGeometryException e) {
266
                                                logger.error("Can't create the point ("+pX+","+pY+")", e);
267
                                        }
268
                                        if (p != null) {
269
                                                markerSymbol.draw(g, affineTransform, p, feat, null);
270
                                        }
271
                                }
272
                                break;
273
                        case GRID_FILL:
274
                                // case a grid fill is used
275
                        {
276
                                Rectangle rClip = null;
277
                                if (g.getClipBounds()!=null){
278
                                        rClip=(Rectangle)g.getClipBounds().clone();
279
                                        g.setClip(rClip.x, rClip.y, rClip.width, rClip.height);
280
                                }
281
                                g.clip(geom);
282

    
283
                                int size = (int) markerSymbol.getSize();
284
                                Rectangle rProv = new Rectangle();
285
                                rProv.setFrame(0, 0, size, size);
286
                                Paint resulPatternFill = null;
287

    
288
                                double xSeparation = markerFillProperties.getXSeparation(); // TODO apply CartographicSupport
289
                                double ySeparation = markerFillProperties.getYSeparation(); // TODO apply CartographicSupport
290
                                double xOffset = markerFillProperties.getXOffset();
291
                                double yOffset = markerFillProperties.getYOffset();
292

    
293
                                BufferedImage sample = null;
294
                                sample = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
295
                                Graphics2D gAux = sample.createGraphics();
296

    
297
                                try {
298
                                        markerSymbol.drawInsideRectangle(gAux, gAux.getTransform(), rProv, null);
299
                                } catch (SymbolDrawingException e) {
300
                                        if (e.getType() == SymbolDrawingException.UNSUPPORTED_SET_OF_SETTINGS) {
301
                                                try {
302
                                                        IWarningSymbol warning =
303
                                                                (IWarningSymbol) MapContextLocator.getSymbolManager()
304
                                                                .getWarningSymbol(
305
                                                                                SymbolDrawingException.STR_UNSUPPORTED_SET_OF_SETTINGS,
306
                                                                                "",
307
                                                                                SymbolDrawingException.UNSUPPORTED_SET_OF_SETTINGS);
308
                                                        warning.drawInsideRectangle(gAux, gAux.getTransform(), rProv, null);
309
                                                } catch (SymbolDrawingException e1) {
310
                                                        // IMPOSSIBLE TO REACH THIS
311
                                                }
312
                                        } else {
313
                                                // should be unreachable code
314
                                                throw new Error(Messages.getText("symbol_shapetype_mismatch"));
315
                                        }
316
                                }
317
                                rProv.setRect(0, 0,
318
                                                rProv.getWidth() + xSeparation,
319
                                                rProv.getHeight() + ySeparation);
320

    
321
                                BufferedImage bi = new BufferedImage(rProv.width, rProv.height, BufferedImage.TYPE_INT_ARGB);
322
                                gAux = bi.createGraphics();
323
                                gAux.drawImage(sample, null, (int) (xSeparation*0.5), (int) (ySeparation*0.5));
324

    
325
                                resulPatternFill = new TexturePaint(bi,rProv);
326
                                sample = null;
327
                                gAux.dispose();
328

    
329
                                g.setColor(null);
330
                                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
331
                                                RenderingHints.VALUE_ANTIALIAS_ON);
332

    
333
                                g.translate(xOffset, -yOffset);
334
                                g.setPaint(resulPatternFill);
335
                                g.fill(geom);
336
                                g.translate(-xOffset, +yOffset);
337
                                g.setClip(rClip);
338
                                bi = null;
339
                        }
340
                        break;
341
                        case RANDOM_FILL:
342
                        {
343

    
344
                                double s = markerSymbol.getSize();
345
                                Rectangle r = geom.getBounds();
346
                                int drawCount = (int) (Math.min(r.getWidth(), r.getHeight())/s);
347
                                Random random = new Random();
348

    
349
                                int minx = r.x;
350
                                int miny = r.y;
351
                                int width = r.width;
352
                                int height = r.height;
353

    
354
                                r = new Rectangle();
355
                                g.setClip(geom);
356

    
357
                                for (int i = 0; (cancel==null || !cancel.isCanceled()) && i < drawCount; i++) {
358
                                        int x = (int) Math.abs(random.nextDouble() * width);
359
                                        int y = (int) Math.abs(random.nextDouble() * height);
360
                                        x = x + minx;
361
                                        y = y + miny;
362
                                        //                                markerSymbol.draw(g, new AffineTransform(), new FPoint2D(x, y), cancel);
363
                                        p = null;
364
                                        try {
365
                                                p = geometryManager.createPoint(x, y, SUBTYPES.GEOM2D);
366
                                        } catch (CreateGeometryException e) {
367
                                                logger.error("Can't create the point ("+x+","+y+")", e);
368
                                        }
369
                                        if (p!=null){
370
                                                markerSymbol.draw(g, new AffineTransform(), p, feat, cancel);
371
                                        }
372
                                }
373
                                g.setClip(null);
374
                        }
375
                        break;
376
                        }
377
                        if(getOutline()!= null){
378
                                getOutline().draw(g, affineTransform, geom, feat, cancel);
379
                        }
380
        }
381

    
382
        public int getSymbolType() {
383
                return Geometry.TYPES.SURFACE;
384
        }
385

    
386
        public void drawInsideRectangle(Graphics2D g, AffineTransform scaleInstance, Rectangle r, PrintAttributes properties) throws SymbolDrawingException {
387
                markerFillProperties.setSampleSymbol(markerSymbol);
388
                Point p;
389
                try {
390
                        switch (markerFillProperties.getFillStyle()) {
391
                        case SINGLE_CENTERED_SYMBOL:
392
                                p = geometryManager.createPoint(r.getCenterX(), r.getCenterY(), SUBTYPES.GEOM2D);
393
                                markerSymbol.draw(g, null, p, null, null);
394
                                break;
395
                        case GRID_FILL:
396
                        {
397
                                g.setClip(r);
398
                                int size = (int) markerSymbol.getSize();
399
                                if (size <= 0 ) size = 1;
400
                                Rectangle rProv = new Rectangle();
401
                                rProv.setFrame(0, 0, size, size);
402
                                Paint resulPatternFill = null;
403

    
404
                                BufferedImage sample = null;
405
                                sample = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
406
                                Graphics2D gAux = sample.createGraphics();
407

    
408
                                double xSeparation = markerFillProperties.getXSeparation(); // TODO apply CartographicSupport
409
                                double ySeparation = markerFillProperties.getYSeparation(); // TODO apply CartographicSupport
410
                                double xOffset = markerFillProperties.getXOffset();
411
                                double yOffset = markerFillProperties.getYOffset();
412

    
413
                                markerSymbol.drawInsideRectangle(gAux, new AffineTransform(), rProv, properties);
414

    
415
                                rProv.setRect(0, 0,
416
                                                rProv.getWidth() + xSeparation,
417
                                                rProv.getHeight() + ySeparation);
418

    
419
                                BufferedImage bi = new BufferedImage(rProv.width, rProv.height, BufferedImage.TYPE_INT_ARGB);
420
                                gAux = bi.createGraphics();
421
                                gAux.drawImage(sample, null, (int) (xSeparation*0.5), (int) (ySeparation*0.5));
422

    
423

    
424
                                resulPatternFill = new TexturePaint(bi,rProv);
425
                                g.setColor(null);
426
                                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
427
                                                RenderingHints.VALUE_ANTIALIAS_ON);
428

    
429
                                g.translate(xOffset, -yOffset);
430
                                g.setPaint(resulPatternFill);
431
                                g.fill(r);
432
                                g.translate(-xOffset, yOffset);
433
                                g.setClip(null);
434
                        }
435
                        break;
436
                        case RANDOM_FILL:
437
                                g.setClip(r);
438
                                int x = r.x;
439
                                int y = r.y;
440
                                int width = r.width;
441
                                int height= r.height;
442
                                g.setBackground(null);
443

    
444
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*0.2), (y+height*0.8), SUBTYPES.GEOM2D), null, null);
445
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*0.634), (y+height*0.3), SUBTYPES.GEOM2D), null, null);
446
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*0.26), (y+height*0.35), SUBTYPES.GEOM2D), null, null);
447
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*0.45), (y+height*0.98), SUBTYPES.GEOM2D), null, null);
448
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*0.9), (y+height*0.54), SUBTYPES.GEOM2D), null, null);
449
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*1.1), (y+height*0.7), SUBTYPES.GEOM2D), null, null);
450
                                g.setClip(null);
451
                                break;
452
                        }
453
                        if(getOutline()!= null && hasOutline()){
454
                                if (properties==null) {
455
                                        //                                getOutline().draw(g, scaleInstance, new FPolyline2D(new GeneralPathX(r)), null);
456
                                        getOutline().draw(g, scaleInstance, geometryManager.createPoint(r.getCenterX(), r.getCenterY(), SUBTYPES.GEOM2D), null,  null);
457
                                } else {
458
                                        //                                getOutline().print(g, scaleInstance, new FPolyline2D(new GeneralPathX(r)), properties);
459
                                        getOutline().print(g, scaleInstance, geometryManager.createPoint(r.getCenterX(), r.getCenterY(), SUBTYPES.GEOM2D), properties);
460
                                }
461
                        }
462
                } catch (CreateGeometryException e) {
463
                        throw new SymbolDrawingException(TYPES.POINT);
464
                }
465
        }
466

    
467

    
468
        public String getClassName() {
469
                return getClass().getName();
470
        }
471

    
472
        public void setMarker(IMarkerSymbol marker) {
473
                this.markerSymbol = marker;
474
        }
475

    
476
        public IMarkerSymbol getMarker() {
477
                return markerSymbol;
478
        }
479

    
480
        public Color getFillColor(){
481
                return markerSymbol.getColor();
482
        }
483

    
484
        public void setFillColor (Color color) {
485
                markerSymbol.setColor(color);
486
        }
487

    
488
        public void print(Graphics2D g, AffineTransform at, Geometry geom, PrintAttributes properties) {
489
                this.properties=properties;
490
        draw(g, at, geom, null, null);
491
        this.properties=null;
492

    
493
        }
494
        /**
495
         * Sets the markerfillproperties to be used by the class
496
         *
497
         * @param markerFillStyle,IMarkerFillPropertiesStyle
498
         */
499
        public void setMarkerFillProperties(IMarkerFillPropertiesStyle markerFillStyle) {
500
                this.markerFillProperties = markerFillStyle;
501
        }
502

    
503
        /**
504
         * Returns the markerfillproperties that are used by the class
505
         *
506
         * @return markerFillProperties,IMarkerFillPropertiesStyle
507
         */
508
        public IMarkerFillPropertiesStyle getMarkerFillProperties() {
509
                return markerFillProperties;
510
        }
511

    
512
        @Override
513
        public void setUnit(int unitIndex) {
514
                super.setUnit(unitIndex);
515
                if (getMarker()!=null) {
516
                        getMarker().setUnit(unitIndex);
517
                }
518
        }
519

    
520
        @Override
521
        public void setReferenceSystem(int system) {
522
                super.setReferenceSystem(system);
523
                if (getMarker()!=null) {
524
                        getMarker().setReferenceSystem(system);
525
                }
526
        }
527

    
528
        public void setCartographicSize(double cartographicSize, Geometry geom) {
529
                
530
                super.setCartographicSize(cartographicSize, geom);
531
                IMarkerSymbol marker = getMarker();
532
                if (marker!=null) {
533
                                marker.setCartographicSize(previousMarkerSize, geom);
534
                        }
535
                
536
                super.setCartographicSize(cartographicSize, geom);
537

    
538
        }
539

    
540
        public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
541
                IMarkerSymbol marker = getMarker();
542
                if (marker!=null) {
543
                        previousMarkerSize = marker.getSize();
544
                        double size = CartographicSupportToolkit.getCartographicLength(this, previousMarkerSize, viewPort, dpi);
545
                        marker.setSize(size);
546
                }
547
                double s = super.toCartographicSize(viewPort, dpi, geom);
548
                return s;
549
                
550
        }
551
        
552
        
553
    public Object clone() throws CloneNotSupportedException {
554
            MarkerFillSymbol copy = (MarkerFillSymbol) super.clone();
555

    
556
        // clone marker
557
        if (markerSymbol != null) {
558
            copy.markerSymbol = (IMarkerSymbol) markerSymbol.clone();
559
        }
560

    
561
        // clone selection
562
        if (selectionSymbol != null) {
563
            copy.selectionSymbol = (MarkerFillSymbol) selectionSymbol.clone();
564
        }
565

    
566
        // clone markerFillProperties
567
        if (markerFillProperties != null) {
568
            copy.markerFillProperties = (IMarkerFillPropertiesStyle) markerFillProperties.clone();
569
        }
570

    
571
        // FIXME: clone properties
572
        
573
        return copy;
574
    }
575

    
576
    public void loadFromState(PersistentState state) throws PersistenceException {
577
        // Set parent style properties
578
        super.loadFromState(state);
579

    
580
        this.markerSymbol =  (IMarkerSymbol) state.get(MARKER_SYMBOL);
581
        this.selectionSymbol = (MarkerFillSymbol) state.get(SELECTION_SYMBOL);
582
        this.markerFillProperties = (IMarkerFillPropertiesStyle) state.get(MARKER_FILL_PROPERTIES);
583
        this.previousMarkerSize = (Double) state.get(PREVIOUS_MARKERSIZE);
584
    }
585

    
586
    public void saveToState(PersistentState state) throws PersistenceException {
587
        // Save parent fill symbol properties
588
        super.saveToState(state);
589

    
590
        // Save own properties
591
        state.set(MARKER_SYMBOL, this.markerSymbol);
592
        state.set(SELECTION_SYMBOL, this.selectionSymbol);
593
        state.set(MARKER_FILL_PROPERTIES, this.markerFillProperties);
594
        state.set(PREVIOUS_MARKERSIZE, this.previousMarkerSize);
595
    }
596

    
597
    public static class RegisterPersistence implements Callable {
598

    
599
        public Object call() throws Exception {
600
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
601
            if (manager.getDefinition(MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
602
                DynStruct definition =
603
                    manager.addDefinition(MarkerFillSymbol.class,
604
                                    MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME,
605
                                    MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME
606
                            + " Persistence definition",
607
                        null,
608
                        null);
609

    
610
                // Extend the Style base definition
611
                definition.extend(manager.getDefinition(FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME));
612

    
613
                definition.addDynFieldObject(MARKER_SYMBOL)
614
                .setClassOfValue(IMarkerSymbol.class).setMandatory(true);
615
                definition.addDynFieldObject(SELECTION_SYMBOL)
616
                    .setClassOfValue(IMarkerFillSymbol.class).setMandatory(false);
617
                definition.addDynFieldObject(MARKER_FILL_PROPERTIES)
618
                .setClassOfValue(IMarkerFillPropertiesStyle.class).setMandatory(true);
619
                definition.addDynFieldDouble(PREVIOUS_MARKERSIZE);
620
            }
621
            return Boolean.TRUE;
622
        }
623
    }
624

    
625
        public static class RegisterSymbol implements Callable {
626

    
627
                public Object call() throws Exception {
628
                int[] shapeTypes;
629
                SymbolManager manager = MapContextLocator.getSymbolManager();
630
                
631
                shapeTypes =
632
                    new int[] { Geometry.TYPES.SURFACE, Geometry.TYPES.CIRCLE,
633
                        Geometry.TYPES.ELLIPSE, Geometry.TYPES.MULTISURFACE };
634
                manager.registerMultiLayerSymbol(IFillSymbol.SYMBOL_NAME,
635
                    shapeTypes,
636
                    MarkerFillSymbol.class);
637
                
638
                        return Boolean.TRUE;
639
                }
640
                
641
        }
642

    
643

    
644
}