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

History | View | Annotate | Download (21.9 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.Shape;
131
import java.awt.TexturePaint;
132
import java.awt.geom.AffineTransform;
133
import java.awt.image.BufferedImage;
134
import java.util.Random;
135

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

    
172
/**
173
 * Allows to define a marker symbol of any type as a path image to be used for a filled of a
174
 * polygon's padding
175
 *
176
 * @author   jaume dominguez faus - jaume.dominguez@iver.es
177
 */
178
public class MarkerFillSymbol extends AbstractFillSymbol implements IMarkerFillSymbol {
179
        private static final Logger logger = LoggerFactory.getLogger(MarkerFillSymbol.class);
180

    
181
    public static final String MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME =
182
        "MarkerFillSymbol";
183
    private static final String MARKER_SYMBOL = "markerSymbol";
184
    private static final String SELECTION_SYMBOL = "selectionSymbol";
185
    private static final String MARKER_FILL_PROPERTIES = "markerFillProperties";
186
    private static final String PREVIOUS_MARKERSIZE = "previousMarkerSize";
187

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

    
199
        public ISymbol getSymbolForSelection() {
200
                if (selectionSymbol == null) {
201
                        selectionSymbol = (MarkerFillSymbol) cloneForSelection();
202
                        selectionSymbol.setFillColor(MapContext.getSelectionColor());
203
                }else {
204
            selectionSymbol.setColor(MapContext.getSelectionColor());
205
        }
206

    
207
                return selectionSymbol;
208
        }
209

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

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

    
268
                                int size = (int) markerSymbol.getSize();
269
                                Rectangle rProv = new Rectangle();
270
                                rProv.setFrame(0, 0, size, size);
271
                                Paint resulPatternFill = null;
272

    
273
                                double xSeparation = markerFillProperties.getXSeparation(); // TODO apply CartographicSupport
274
                                double ySeparation = markerFillProperties.getYSeparation(); // TODO apply CartographicSupport
275
                                double xOffset = markerFillProperties.getXOffset();
276
                                double yOffset = markerFillProperties.getYOffset();
277

    
278
                                BufferedImage sample = null;
279
                                sample = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
280
                                Graphics2D gAux = sample.createGraphics();
281

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

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

    
310
                                resulPatternFill = new TexturePaint(bi,rProv);
311
                                sample = null;
312
                                gAux.dispose();
313

    
314
                                g.setColor(null);
315
                                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
316
                                                RenderingHints.VALUE_ANTIALIAS_ON);
317

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

    
329
                                double s = markerSymbol.getSize();
330
                                Geometry auxgeo = geom.cloneGeometry();
331
                                auxgeo.transform(affineTransform);
332
                                Shape shp = auxgeo.getShape();
333
                                Rectangle r = shp.getBounds();
334
                                int drawCount = (int) (Math.min(r.getWidth(), r.getHeight())/s);
335
                                Random random = new Random();
336

    
337
                                int minx = r.x;
338
                                int miny = r.y;
339
                                int width = r.width;
340
                                int height = r.height;
341

    
342
                                r = new Rectangle();
343
                                g.setClip(shp);
344

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

    
370
        public int getSymbolType() {
371
                return Geometry.TYPES.SURFACE;
372
        }
373

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

    
392
                                BufferedImage sample = null;
393
                                sample = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
394
                                Graphics2D gAux = sample.createGraphics();
395

    
396
                                double xSeparation = markerFillProperties.getXSeparation(); // TODO apply CartographicSupport
397
                                double ySeparation = markerFillProperties.getYSeparation(); // TODO apply CartographicSupport
398
                                double xOffset = markerFillProperties.getXOffset();
399
                                double yOffset = markerFillProperties.getYOffset();
400

    
401
                                markerSymbol.drawInsideRectangle(gAux, new AffineTransform(), rProv, properties);
402

    
403
                                rProv.setRect(0, 0,
404
                                                rProv.getWidth() + xSeparation,
405
                                                rProv.getHeight() + ySeparation);
406

    
407
                                BufferedImage bi = new BufferedImage(rProv.width, rProv.height, BufferedImage.TYPE_INT_ARGB);
408
                                gAux = bi.createGraphics();
409
                                gAux.drawImage(sample, null, (int) (xSeparation*0.5), (int) (ySeparation*0.5));
410

    
411

    
412
                                resulPatternFill = new TexturePaint(bi,rProv);
413
                                g.setColor(null);
414
                                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
415
                                                RenderingHints.VALUE_ANTIALIAS_ON);
416

    
417
                                g.translate(xOffset, -yOffset);
418
                                g.setPaint(resulPatternFill);
419
                                g.fill(r);
420
                                g.translate(-xOffset, yOffset);
421
                                g.setClip(null);
422
                        }
423
                        break;
424
                        case RANDOM_FILL:
425
                                g.setClip(r);
426
                                int x = r.x;
427
                                int y = r.y;
428
                                int width = r.width;
429
                                int height= r.height;
430
                                g.setBackground(null);
431

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

    
455

    
456
        public String getClassName() {
457
                return getClass().getName();
458
        }
459

    
460
        public void setMarker(IMarkerSymbol marker) {
461
                this.markerSymbol = marker;
462
        }
463

    
464
        public IMarkerSymbol getMarker() {
465
                return markerSymbol;
466
        }
467

    
468
        public Color getFillColor(){
469
                return markerSymbol.getColor();
470
        }
471

    
472
        public void setFillColor (Color color) {
473
                markerSymbol.setColor(color);
474
        }
475

    
476
        public void print(Graphics2D g, AffineTransform at, Geometry geom, PrintAttributes properties) {
477
                this.properties=properties;
478
        draw(g, at, geom, null, null);
479
        this.properties=null;
480

    
481
        }
482
        /**
483
         * Sets the markerfillproperties to be used by the class
484
         *
485
         * @param markerFillStyle,IMarkerFillPropertiesStyle
486
         */
487
        public void setMarkerFillProperties(IMarkerFillPropertiesStyle markerFillStyle) {
488
                this.markerFillProperties = markerFillStyle;
489
        }
490

    
491
        /**
492
         * Returns the markerfillproperties that are used by the class
493
         *
494
         * @return markerFillProperties,IMarkerFillPropertiesStyle
495
         */
496
        public IMarkerFillPropertiesStyle getMarkerFillProperties() {
497
                return markerFillProperties;
498
        }
499

    
500
        @Override
501
        public void setUnit(int unitIndex) {
502
                super.setUnit(unitIndex);
503
                if (getMarker()!=null) {
504
                        getMarker().setUnit(unitIndex);
505
                }
506
        }
507

    
508
        @Override
509
        public void setReferenceSystem(int system) {
510
                super.setReferenceSystem(system);
511
                if (getMarker()!=null) {
512
                        getMarker().setReferenceSystem(system);
513
                }
514
        }
515

    
516
        public void setCartographicSize(double cartographicSize, Geometry geom) {
517

    
518
                super.setCartographicSize(cartographicSize, geom);
519
                IMarkerSymbol marker = getMarker();
520
                if (marker!=null) {
521
                                marker.setCartographicSize(previousMarkerSize, geom);
522
                        }
523

    
524
                super.setCartographicSize(cartographicSize, geom);
525

    
526
        }
527

    
528
        public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
529
                IMarkerSymbol marker = getMarker();
530
                if (marker!=null) {
531
                        previousMarkerSize = marker.getSize();
532
                        double size = CartographicSupportToolkit.getCartographicLength(this, previousMarkerSize, viewPort, dpi);
533
                        marker.setSize(size);
534
                }
535
                double s = super.toCartographicSize(viewPort, dpi, geom);
536
                return s;
537

    
538
        }
539

    
540

    
541
    public Object clone() throws CloneNotSupportedException {
542
            MarkerFillSymbol copy = (MarkerFillSymbol) super.clone();
543

    
544
        // clone marker
545
        if (markerSymbol != null) {
546
            copy.markerSymbol = (IMarkerSymbol) markerSymbol.clone();
547
        }
548

    
549
        // clone selection
550
        if (selectionSymbol != null) {
551
            copy.selectionSymbol = (MarkerFillSymbol) selectionSymbol.clone();
552
        }
553

    
554
        // clone markerFillProperties
555
        if (markerFillProperties != null) {
556
            copy.markerFillProperties = (IMarkerFillPropertiesStyle) markerFillProperties.clone();
557
        }
558

    
559
        // FIXME: clone properties
560

    
561
        return copy;
562
    }
563

    
564
    public void loadFromState(PersistentState state) throws PersistenceException {
565
        // Set parent style properties
566
        super.loadFromState(state);
567

    
568
        this.markerSymbol =  (IMarkerSymbol) state.get(MARKER_SYMBOL);
569
        this.selectionSymbol = (MarkerFillSymbol) state.get(SELECTION_SYMBOL);
570
        this.markerFillProperties = (IMarkerFillPropertiesStyle) state.get(MARKER_FILL_PROPERTIES);
571
        this.previousMarkerSize = (Double) state.get(PREVIOUS_MARKERSIZE);
572
    }
573

    
574
    public void saveToState(PersistentState state) throws PersistenceException {
575
        // Save parent fill symbol properties
576
        super.saveToState(state);
577

    
578
        // Save own properties
579
        state.set(MARKER_SYMBOL, this.markerSymbol);
580
        state.set(SELECTION_SYMBOL, this.selectionSymbol);
581
        state.set(MARKER_FILL_PROPERTIES, this.markerFillProperties);
582
        state.set(PREVIOUS_MARKERSIZE, this.previousMarkerSize);
583
    }
584

    
585
    public static class RegisterPersistence implements Callable {
586

    
587
        public Object call() throws Exception {
588
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
589
            if (manager.getDefinition(MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
590
                DynStruct definition =
591
                    manager.addDefinition(MarkerFillSymbol.class,
592
                                    MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME,
593
                                    MARK_FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME
594
                            + " Persistence definition",
595
                        null,
596
                        null);
597

    
598
                // Extend the Style base definition
599
                definition.extend(manager.getDefinition(FILL_SYMBOL_PERSISTENCE_DEFINITION_NAME));
600

    
601
                definition.addDynFieldObject(MARKER_SYMBOL)
602
                .setClassOfValue(IMarkerSymbol.class).setMandatory(true);
603
                definition.addDynFieldObject(SELECTION_SYMBOL)
604
                    .setClassOfValue(IMarkerFillSymbol.class).setMandatory(false);
605
                definition.addDynFieldObject(MARKER_FILL_PROPERTIES)
606
                .setClassOfValue(IMarkerFillPropertiesStyle.class).setMandatory(true);
607
                definition.addDynFieldDouble(PREVIOUS_MARKERSIZE);
608
            }
609
            return Boolean.TRUE;
610
        }
611
    }
612

    
613
        public static class RegisterSymbol implements Callable {
614

    
615
                public Object call() throws Exception {
616
                int[] shapeTypes;
617
                SymbolManager manager = MapContextLocator.getSymbolManager();
618

    
619
                shapeTypes =
620
                    new int[] { Geometry.TYPES.SURFACE, Geometry.TYPES.CIRCLE,
621
                        Geometry.TYPES.ELLIPSE, Geometry.TYPES.MULTISURFACE };
622
                manager.registerMultiLayerSymbol(IFillSymbol.SYMBOL_NAME,
623
                    shapeTypes,
624
                    MarkerFillSymbol.class);
625

    
626
                        return Boolean.TRUE;
627
                }
628

    
629
        }
630

    
631

    
632
}