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 / fill / impl / MarkerFillSymbol.java @ 40560

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

    
125
import java.awt.Color;
126
import java.awt.Graphics2D;
127
import java.awt.Paint;
128
import java.awt.Rectangle;
129
import java.awt.RenderingHints;
130
import java.awt.TexturePaint;
131
import java.awt.geom.AffineTransform;
132
import java.awt.image.BufferedImage;
133
import java.util.Random;
134

    
135
import org.gvsig.compat.print.PrintAttributes;
136
import org.gvsig.fmap.dal.feature.Feature;
137
import org.gvsig.fmap.geom.Geometry;
138
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
139
import org.gvsig.fmap.geom.Geometry.TYPES;
140
import org.gvsig.fmap.geom.GeometryLocator;
141
import org.gvsig.fmap.geom.GeometryManager;
142
import org.gvsig.fmap.geom.exception.CreateGeometryException;
143
import org.gvsig.fmap.geom.operation.GeometryOperationException;
144
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
145
import org.gvsig.fmap.geom.primitive.Point;
146
import org.gvsig.fmap.mapcontext.MapContext;
147
import org.gvsig.fmap.mapcontext.MapContextLocator;
148
import org.gvsig.fmap.mapcontext.ViewPort;
149
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
150
import org.gvsig.fmap.mapcontext.rendering.symbols.IWarningSymbol;
151
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
152
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
153
import org.gvsig.i18n.Messages;
154
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
155
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IMarkerFillSymbol;
156
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.CartographicSupportToolkit;
157
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
158
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.impl.PictureMarkerSymbol;
159
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.IMarkerFillPropertiesStyle;
160
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.SimpleMarkerFillPropertiesStyle;
161
import org.gvsig.tools.ToolsLocator;
162
import org.gvsig.tools.dynobject.DynStruct;
163
import org.gvsig.tools.persistence.PersistenceManager;
164
import org.gvsig.tools.persistence.PersistentState;
165
import org.gvsig.tools.persistence.exception.PersistenceException;
166
import org.gvsig.tools.task.Cancellable;
167
import org.gvsig.tools.util.Callable;
168
import org.slf4j.Logger;
169
import org.slf4j.LoggerFactory;
170

    
171
/**
172
 * Allows to define a marker symbol of any type as a path image to be used for a filled of a
173
 * polygon's padding
174
 *
175
 * @author   jaume dominguez faus - jaume.dominguez@iver.es
176
 */
177
public class MarkerFillSymbol extends AbstractFillSymbol implements IMarkerFillSymbol {
178
        private static final Logger logger = LoggerFactory.getLogger(MarkerFillSymbol.class);
179
        
180
    public static final String MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME =
181
        "MarkerFillSymbol";
182
    private static final String MARKER_SYMBOL = "markerSymbol";
183
    private static final String SELECTION_SYMBOL = "selectionSymbol";
184
    private static final String MARKER_FILL_PROPERTIES = "markerFillProperties";
185
    private static final String PREVIOUS_MARKERSIZE = "previousMarkerSize";
186

    
187
        public static final int RANDOM_FILL = 3;
188
        public static final int GRID_FILL = 1;
189
        public static final int SINGLE_CENTERED_SYMBOL = 2;
190
        public static int DefaultFillStyle = GRID_FILL;
191
        private MarkerFillSymbol selectionSymbol;
192
        private IMarkerFillPropertiesStyle markerFillProperties = new SimpleMarkerFillPropertiesStyle();
193
        private IMarkerSymbol markerSymbol = (IMarkerSymbol) MapContextLocator.getSymbolManager().createSymbol(IMarkerSymbol.SYMBOL_NAME);
194
        private double previousMarkerSize = markerSymbol.getSize();
195
        private PrintAttributes properties;
196
        private GeometryManager geometryManager = GeometryLocator.getGeometryManager();
197

    
198
        public ISymbol getSymbolForSelection() {
199
                if (selectionSymbol == null) {
200
                        selectionSymbol = (MarkerFillSymbol) cloneForSelection();
201
                        selectionSymbol.setFillColor(MapContext.getSelectionColor());
202
                }
203

    
204
                return selectionSymbol;
205
        }
206

    
207
        public void draw(Graphics2D g, AffineTransform affineTransform, Geometry geom, Feature feat, Cancellable cancel) {
208
                Point centroid = null;
209
                Point p = null;
210
                        switch (markerFillProperties.getFillStyle()) {
211
                        case SINGLE_CENTERED_SYMBOL:
212
                                // case a single marker is used into a polygon shapetype
213
                                //                        Geometry geom = FConverter.java2d_to_jts(geom);
214
                                //                        com.vividsolutions.jts.geom.Point centroid = geom.getCentroid();
215
                                try {
216
                                        centroid = geom.centroid();
217
                                } catch (GeometryOperationNotSupportedException e2) {
218
                                        logger.warn("Can't get centroid", e2);
219
                                } catch (GeometryOperationException e2) {
220
                                        logger.warn("Can't get centroid", e2);
221
                                }
222

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

    
265
                                int size = (int) markerSymbol.getSize();
266
                                Rectangle rProv = new Rectangle();
267
                                rProv.setFrame(0, 0, size, size);
268
                                Paint resulPatternFill = null;
269

    
270
                                double xSeparation = markerFillProperties.getXSeparation(); // TODO apply CartographicSupport
271
                                double ySeparation = markerFillProperties.getYSeparation(); // TODO apply CartographicSupport
272
                                double xOffset = markerFillProperties.getXOffset();
273
                                double yOffset = markerFillProperties.getYOffset();
274

    
275
                                BufferedImage sample = null;
276
                                sample = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
277
                                Graphics2D gAux = sample.createGraphics();
278

    
279
                                try {
280
                                        markerSymbol.drawInsideRectangle(gAux, gAux.getTransform(), rProv, null);
281
                                } catch (SymbolDrawingException e) {
282
                                        if (e.getType() == SymbolDrawingException.UNSUPPORTED_SET_OF_SETTINGS) {
283
                                                try {
284
                                                        IWarningSymbol warning =
285
                                                                (IWarningSymbol) MapContextLocator.getSymbolManager()
286
                                                                .getWarningSymbol(
287
                                                                                SymbolDrawingException.STR_UNSUPPORTED_SET_OF_SETTINGS,
288
                                                                                "",
289
                                                                                SymbolDrawingException.UNSUPPORTED_SET_OF_SETTINGS);
290
                                                        warning.drawInsideRectangle(gAux, gAux.getTransform(), rProv, null);
291
                                                } catch (SymbolDrawingException e1) {
292
                                                        // IMPOSSIBLE TO REACH THIS
293
                                                }
294
                                        } else {
295
                                                // should be unreachable code
296
                                                throw new Error(Messages.getText("symbol_shapetype_mismatch"));
297
                                        }
298
                                }
299
                                rProv.setRect(0, 0,
300
                                                rProv.getWidth() + xSeparation,
301
                                                rProv.getHeight() + ySeparation);
302

    
303
                                BufferedImage bi = new BufferedImage(rProv.width, rProv.height, BufferedImage.TYPE_INT_ARGB);
304
                                gAux = bi.createGraphics();
305
                                gAux.drawImage(sample, null, (int) (xSeparation*0.5), (int) (ySeparation*0.5));
306

    
307
                                resulPatternFill = new TexturePaint(bi,rProv);
308
                                sample = null;
309
                                gAux.dispose();
310

    
311
                                g.setColor(null);
312
                                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
313
                                                RenderingHints.VALUE_ANTIALIAS_ON);
314

    
315
                                g.translate(xOffset, -yOffset);
316
                                g.setPaint(resulPatternFill);
317
                                g.fill(geom.getShape());
318
                                g.translate(-xOffset, +yOffset);
319
                                g.setClip(rClip);
320
                                bi = null;
321
                        }
322
                        break;
323
                        case RANDOM_FILL:
324
                        {
325

    
326
                                double s = markerSymbol.getSize();
327
                                Rectangle r = geom.getShape().getBounds();
328
                                int drawCount = (int) (Math.min(r.getWidth(), r.getHeight())/s);
329
                                Random random = new Random();
330

    
331
                                int minx = r.x;
332
                                int miny = r.y;
333
                                int width = r.width;
334
                                int height = r.height;
335

    
336
                                r = new Rectangle();
337
                                g.setClip(geom.getShape());
338

    
339
                                for (int i = 0; (cancel==null || !cancel.isCanceled()) && i < drawCount; i++) {
340
                                        int x = (int) Math.abs(random.nextDouble() * width);
341
                                        int y = (int) Math.abs(random.nextDouble() * height);
342
                                        x = x + minx;
343
                                        y = y + miny;
344
                                        //                                markerSymbol.draw(g, new AffineTransform(), new FPoint2D(x, y), cancel);
345
                                        p = null;
346
                                        try {
347
                                                p = geometryManager.createPoint(x, y, SUBTYPES.GEOM2D);
348
                                        } catch (CreateGeometryException e) {
349
                                                logger.error("Can't create the point ("+x+","+y+")", e);
350
                                        }
351
                                        if (p!=null){
352
                                                markerSymbol.draw(g, new AffineTransform(), p, feat, cancel);
353
                                        }
354
                                }
355
                                g.setClip(null);
356
                        }
357
                        break;
358
                        }
359
                        if(getOutline()!= null){
360
                                getOutline().draw(g, affineTransform, geom, feat, cancel);
361
                        }
362
        }
363

    
364
        public int getSymbolType() {
365
                return Geometry.TYPES.SURFACE;
366
        }
367

    
368
        public void drawInsideRectangle(Graphics2D g, AffineTransform scaleInstance, Rectangle r, PrintAttributes properties) throws SymbolDrawingException {
369
                markerFillProperties.setSampleSymbol(markerSymbol);
370
                Point p;
371
                try {
372
                        switch (markerFillProperties.getFillStyle()) {
373
                        case SINGLE_CENTERED_SYMBOL:
374
                                p = geometryManager.createPoint(r.getCenterX(), r.getCenterY(), SUBTYPES.GEOM2D);
375
                                markerSymbol.draw(g, null, p, null, null);
376
                                break;
377
                        case GRID_FILL:
378
                        {
379
                                g.setClip(r);
380
                                int size = (int) markerSymbol.getSize();
381
                                if (size <= 0 ) size = 1;
382
                                Rectangle rProv = new Rectangle();
383
                                rProv.setFrame(0, 0, size, size);
384
                                Paint resulPatternFill = null;
385

    
386
                                BufferedImage sample = null;
387
                                sample = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
388
                                Graphics2D gAux = sample.createGraphics();
389

    
390
                                double xSeparation = markerFillProperties.getXSeparation(); // TODO apply CartographicSupport
391
                                double ySeparation = markerFillProperties.getYSeparation(); // TODO apply CartographicSupport
392
                                double xOffset = markerFillProperties.getXOffset();
393
                                double yOffset = markerFillProperties.getYOffset();
394

    
395
                                markerSymbol.drawInsideRectangle(gAux, new AffineTransform(), rProv, properties);
396

    
397
                                rProv.setRect(0, 0,
398
                                                rProv.getWidth() + xSeparation,
399
                                                rProv.getHeight() + ySeparation);
400

    
401
                                BufferedImage bi = new BufferedImage(rProv.width, rProv.height, BufferedImage.TYPE_INT_ARGB);
402
                                gAux = bi.createGraphics();
403
                                gAux.drawImage(sample, null, (int) (xSeparation*0.5), (int) (ySeparation*0.5));
404

    
405

    
406
                                resulPatternFill = new TexturePaint(bi,rProv);
407
                                g.setColor(null);
408
                                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
409
                                                RenderingHints.VALUE_ANTIALIAS_ON);
410

    
411
                                g.translate(xOffset, -yOffset);
412
                                g.setPaint(resulPatternFill);
413
                                g.fill(r);
414
                                g.translate(-xOffset, yOffset);
415
                                g.setClip(null);
416
                        }
417
                        break;
418
                        case RANDOM_FILL:
419
                                g.setClip(r);
420
                                int x = r.x;
421
                                int y = r.y;
422
                                int width = r.width;
423
                                int height= r.height;
424
                                g.setBackground(null);
425

    
426
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*0.2), (y+height*0.8), SUBTYPES.GEOM2D), null, null);
427
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*0.634), (y+height*0.3), SUBTYPES.GEOM2D), null, null);
428
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*0.26), (y+height*0.35), SUBTYPES.GEOM2D), null, null);
429
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*0.45), (y+height*0.98), SUBTYPES.GEOM2D), null, null);
430
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*0.9), (y+height*0.54), SUBTYPES.GEOM2D), null, null);
431
                                markerSymbol.draw(g, null, geometryManager.createPoint((x+width*1.1), (y+height*0.7), SUBTYPES.GEOM2D), null, null);
432
                                g.setClip(null);
433
                                break;
434
                        }
435
                        if(getOutline()!= null && hasOutline()){
436
                                if (properties==null) {
437
                                        //                                getOutline().draw(g, scaleInstance, new FPolyline2D(new GeneralPathX(r)), null);
438
                                        getOutline().draw(g, scaleInstance, geometryManager.createPoint(r.getCenterX(), r.getCenterY(), SUBTYPES.GEOM2D), null,  null);
439
                                } else {
440
                                        //                                getOutline().print(g, scaleInstance, new FPolyline2D(new GeneralPathX(r)), properties);
441
                                        getOutline().print(g, scaleInstance, geometryManager.createPoint(r.getCenterX(), r.getCenterY(), SUBTYPES.GEOM2D), properties);
442
                                }
443
                        }
444
                } catch (CreateGeometryException e) {
445
                        throw new SymbolDrawingException(TYPES.POINT);
446
                }
447
        }
448

    
449

    
450
        public String getClassName() {
451
                return getClass().getName();
452
        }
453

    
454
        public void setMarker(IMarkerSymbol marker) {
455
                this.markerSymbol = marker;
456
        }
457

    
458
        public IMarkerSymbol getMarker() {
459
                return markerSymbol;
460
        }
461

    
462
        public Color getFillColor(){
463
                return markerSymbol.getColor();
464
        }
465

    
466
        public void setFillColor (Color color) {
467
                markerSymbol.setColor(color);
468
        }
469

    
470
        public void print(Graphics2D g, AffineTransform at, Geometry geom, PrintAttributes properties) {
471
                this.properties=properties;
472
        draw(g, at, geom, null, null);
473
        this.properties=null;
474

    
475
        }
476
        /**
477
         * Sets the markerfillproperties to be used by the class
478
         *
479
         * @param markerFillStyle,IMarkerFillPropertiesStyle
480
         */
481
        public void setMarkerFillProperties(IMarkerFillPropertiesStyle markerFillStyle) {
482
                this.markerFillProperties = markerFillStyle;
483
        }
484

    
485
        /**
486
         * Returns the markerfillproperties that are used by the class
487
         *
488
         * @return markerFillProperties,IMarkerFillPropertiesStyle
489
         */
490
        public IMarkerFillPropertiesStyle getMarkerFillProperties() {
491
                return markerFillProperties;
492
        }
493

    
494
        @Override
495
        public void setUnit(int unitIndex) {
496
                super.setUnit(unitIndex);
497
                if (getMarker()!=null) {
498
                        getMarker().setUnit(unitIndex);
499
                }
500
        }
501

    
502
        @Override
503
        public void setReferenceSystem(int system) {
504
                super.setReferenceSystem(system);
505
                if (getMarker()!=null) {
506
                        getMarker().setReferenceSystem(system);
507
                }
508
        }
509

    
510
        public void setCartographicSize(double cartographicSize, Geometry geom) {
511
                
512
                super.setCartographicSize(cartographicSize, geom);
513
                IMarkerSymbol marker = getMarker();
514
                if (marker!=null) {
515
                                marker.setCartographicSize(previousMarkerSize, geom);
516
                        }
517
                
518
                super.setCartographicSize(cartographicSize, geom);
519

    
520
        }
521

    
522
        public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
523
                IMarkerSymbol marker = getMarker();
524
                if (marker!=null) {
525
                        previousMarkerSize = marker.getSize();
526
                        double size = CartographicSupportToolkit.getCartographicLength(this, previousMarkerSize, viewPort, dpi);
527
                        marker.setSize(size);
528
                }
529
                double s = super.toCartographicSize(viewPort, dpi, geom);
530
                return s;
531
                
532
        }
533
        
534
        
535
    public Object clone() throws CloneNotSupportedException {
536
            MarkerFillSymbol copy = (MarkerFillSymbol) super.clone();
537

    
538
        // clone marker
539
        if (markerSymbol != null) {
540
            copy.markerSymbol = (IMarkerSymbol) markerSymbol.clone();
541
        }
542

    
543
        // clone selection
544
        if (selectionSymbol != null) {
545
            copy.selectionSymbol = (MarkerFillSymbol) selectionSymbol.clone();
546
        }
547

    
548
        // clone markerFillProperties
549
        if (markerFillProperties != null) {
550
            copy.markerFillProperties = (IMarkerFillPropertiesStyle) markerFillProperties.clone();
551
        }
552

    
553
        // FIXME: clone properties
554
        
555
        return copy;
556
    }
557

    
558
    public void loadFromState(PersistentState state) throws PersistenceException {
559
        // Set parent style properties
560
        super.loadFromState(state);
561

    
562
        this.markerSymbol =  (IMarkerSymbol) state.get(MARKER_SYMBOL);
563
        this.selectionSymbol = (MarkerFillSymbol) state.get(SELECTION_SYMBOL);
564
        this.markerFillProperties = (IMarkerFillPropertiesStyle) state.get(MARKER_FILL_PROPERTIES);
565
        this.previousMarkerSize = (Double) state.get(PREVIOUS_MARKERSIZE);
566
    }
567

    
568
    public void saveToState(PersistentState state) throws PersistenceException {
569
        // Save parent fill symbol properties
570
        super.saveToState(state);
571

    
572
        // Save own properties
573
        state.set(MARKER_SYMBOL, this.markerSymbol);
574
        state.set(SELECTION_SYMBOL, this.selectionSymbol);
575
        state.set(MARKER_FILL_PROPERTIES, this.markerFillProperties);
576
        state.set(PREVIOUS_MARKERSIZE, this.previousMarkerSize);
577
    }
578

    
579
    public static class RegisterPersistence implements Callable {
580

    
581
        public Object call() throws Exception {
582
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
583
            if (manager.getDefinition(MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
584
                DynStruct definition =
585
                    manager.addDefinition(MarkerFillSymbol.class,
586
                                    MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME,
587
                                    MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME
588
                            + " Persistence definition",
589
                        null,
590
                        null);
591

    
592
                // Extend the Style base definition
593
                definition.extend(manager.getDefinition(FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME));
594

    
595
                definition.addDynFieldObject(MARKER_SYMBOL)
596
                .setClassOfValue(IMarkerSymbol.class).setMandatory(true);
597
                definition.addDynFieldObject(SELECTION_SYMBOL)
598
                    .setClassOfValue(IMarkerFillSymbol.class).setMandatory(false);
599
                definition.addDynFieldObject(MARKER_FILL_PROPERTIES)
600
                .setClassOfValue(IMarkerFillPropertiesStyle.class).setMandatory(true);
601
                definition.addDynFieldDouble(PREVIOUS_MARKERSIZE);
602
            }
603
            return Boolean.TRUE;
604
        }
605
    }
606

    
607
        public static class RegisterSymbol implements Callable {
608

    
609
                public Object call() throws Exception {
610
                int[] shapeTypes;
611
                SymbolManager manager = MapContextLocator.getSymbolManager();
612
                
613
                shapeTypes =
614
                    new int[] { Geometry.TYPES.SURFACE, Geometry.TYPES.CIRCLE,
615
                        Geometry.TYPES.ELLIPSE, Geometry.TYPES.MULTISURFACE };
616
                manager.registerMultiLayerSymbol(IFillSymbol.SYMBOL_NAME,
617
                    shapeTypes,
618
                    MarkerFillSymbol.class);
619
                
620
                        return Boolean.TRUE;
621
                }
622
                
623
        }
624

    
625

    
626
}