Revision 43156

View differences:

trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.symbology/org.gvsig.symbology.lib/org.gvsig.symbology.lib.impl/pom.xml
128 128
    
129 129
    <!-- Test dependencies -->
130 130

  
131
<!--
132
    <dependency>
133
      <groupId>org.gvsig</groupId>
134
      <artifactId>org.gvsig.symbology.lib.api</artifactId>
135
      <version>2.0.1-SNAPSHOT</version>
136
      <type>test-jar</type>
137
      <scope>test</scope>
138
    </dependency>
139
-->
131

  
140 132
  </dependencies>
141 133

  
142 134

  
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/svgsupport/DefaultSVGRenderer.java
1
package org.gvsig.svgsupport;
2

  
3
import java.awt.Graphics2D;
4
import java.awt.RenderingHints;
5
import java.awt.geom.AffineTransform;
6
import java.awt.geom.Rectangle2D;
7
import java.io.File;
8
import java.io.IOException;
9
import java.net.URISyntaxException;
10
import java.net.URL;
11
import org.apache.batik.bridge.BridgeContext;
12
import org.apache.batik.bridge.DocumentLoader;
13
import org.apache.batik.bridge.GVTBuilder;
14
import org.apache.batik.bridge.UserAgentAdapter;
15
import org.apache.batik.bridge.ViewBox;
16
import org.apache.batik.dom.svg.SVGOMDocument;
17
import org.apache.batik.gvt.GraphicsNode;
18
import org.apache.batik.gvt.renderer.StaticRenderer;
19
import org.w3c.dom.Document;
20
import org.w3c.dom.Element;
21

  
22
public class DefaultSVGRenderer implements SVGRenderer {
23

  
24
    private final GVTBuilder gvtBuilder = new GVTBuilder();
25
    private final UserAgentAdapter userAgent;
26
    private final DocumentLoader loader;
27
    private final StaticRenderer renderer = new StaticRenderer();
28
    private GraphicsNode gvtRoot;
29
    private final BridgeContext ctx;
30
    private Element elt;
31
    private URL source;
32

  
33
    private static RenderingHints defaultRenderingHints = null;
34

  
35
    public DefaultSVGRenderer() {
36
        userAgent = new UserAgentAdapter();
37
        loader = new DocumentLoader(userAgent);
38
        ctx = new BridgeContext(userAgent, loader);
39
        renderer.setDoubleBuffered(true);
40
    }
41

  
42
    @Override
43
    public Rectangle2D getBounds() {
44
        Rectangle2D bounds = gvtRoot.getBounds();
45
        return bounds;
46
    }
47

  
48
    @Override
49
    public void drawInsideRectangle(Graphics2D g,
50
            Rectangle2D rect,
51
            boolean keepAspectRatio) {
52
        if (keepAspectRatio) {
53
            AffineTransform ataux = null;
54
            if (elt.hasAttribute("viewBox")) {
55

  
56
                try {
57
                    ataux
58
                            = ViewBox.getViewTransform(null,
59
                                    elt,
60
                                    (float) rect.getWidth(),
61
                                    (float) rect.getHeight(),
62
                                    ctx);
63
                } catch (NullPointerException e) {
64
                    
65
                }
66
            }
67
            if( ataux == null ) {
68
                Rectangle2D bounds = gvtRoot.getBounds();
69

  
70
                ataux = getNoRotationTransform(
71
                    bounds,
72
                    new Rectangle2D.Double(
73
                        rect.getX(),
74
                        rect.getY(),
75
                        rect.getWidth(),
76
                        rect.getHeight()),
77
                    true
78
                );
79
            }
80
            RenderingHints renderingHints = new RenderingHints(null);
81
            renderingHints.putAll(getDefaultRenderingHints());
82
            g.setRenderingHints(renderingHints);
83
            gvtRoot.setTransform(ataux);
84
            gvtRoot.paint(g);
85

  
86
        } else {
87

  
88
            Rectangle2D bounds = gvtRoot.getBounds();
89
            AffineTransform ataux = getNoRotationTransform(
90
                bounds,
91
                new Rectangle2D.Double(
92
                    rect.getX(),
93
                    rect.getY(),
94
                    rect.getWidth(),
95
                    rect.getHeight()
96
                ),
97
                false
98
            );
99

  
100
            RenderingHints renderingHints = new RenderingHints(null);
101
            renderingHints.putAll(getDefaultRenderingHints());
102
            g.setRenderingHints(renderingHints);
103
            gvtRoot.setTransform(ataux);
104
            gvtRoot.paint(g);
105
        }
106
    }
107
    
108
    @Override
109
    public void setSource(URL url) throws IOException {
110

  
111
        source = url;
112
        Document svgDoc;
113
        try {
114
            svgDoc = loader.loadDocument(url.toURI().toString());
115
        } catch (URISyntaxException e) {
116
            throw new IOException(e);
117
        }
118
        gvtRoot = gvtBuilder.build(ctx, svgDoc);
119
        renderer.setTree(gvtRoot);
120
        elt = ((SVGOMDocument) svgDoc).getRootElement();
121
    }
122

  
123
    
124
    @Override
125
    public URL getSource() {
126
        return this.source;
127
    }
128

  
129
    private AffineTransform getNoRotationTransform(
130
            Rectangle2D from_rect,
131
            Rectangle2D to_rect,
132
            boolean keep_aspect) {
133

  
134
        double scalex = to_rect.getWidth() / from_rect.getWidth();
135
        double scaley = to_rect.getHeight() / from_rect.getHeight();
136

  
137
        if (keep_aspect) {
138
            // force min value for both
139
            scalex = Math.min(scalex, scaley);
140
            scaley = scalex;
141
        }
142

  
143
        double from_new_center_x = scalex * from_rect.getCenterX();
144
        double from_new_center_y = scaley * from_rect.getCenterY();
145

  
146
        double offx = to_rect.getCenterX() - from_new_center_x;
147
        double offy = to_rect.getCenterY() - from_new_center_y;
148

  
149
        AffineTransform resp
150
                = AffineTransform.getTranslateInstance(offx, offy);
151

  
152
        // this composition is equivalent to:
153
        // first scale, then move
154
        resp.concatenate(
155
                AffineTransform.getScaleInstance(scalex, scaley));
156
        return resp;
157
    }
158

  
159
    private RenderingHints getDefaultRenderingHints() {
160
        if (defaultRenderingHints == null) {
161
            defaultRenderingHints = new RenderingHints(null);
162
            defaultRenderingHints.put(RenderingHints.KEY_ANTIALIASING,
163
                    RenderingHints.VALUE_ANTIALIAS_ON);
164

  
165
            defaultRenderingHints.put(RenderingHints.KEY_INTERPOLATION,
166
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
167
        }
168
        return defaultRenderingHints;
169
    }
170

  
171
    @Override
172
    public void setSource(File f) throws IOException {
173
        setSource(f.toURI().toURL());
174
    }
175
}
176

  
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/impl/DefaultSymbologyManager.java
49 49
*/
50 50
package org.gvsig.symbology.impl;
51 51

  
52
import java.awt.Shape;
52 53
import java.io.IOException;
53 54
import java.net.URL;
54 55
import java.util.Collection;
55 56
import java.util.Collections;
56 57
import java.util.HashMap;
57 58
import java.util.Map;
59
import org.apache.batik.ext.awt.geom.DefaultPathLength;
58 60

  
59 61
import org.gvsig.fmap.mapcontext.rendering.legend.IInterval;
60 62
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelClass;
......
64 66
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IZoomConstraints;
65 67
import org.gvsig.fmap.mapcontext.rendering.symbols.styles.IBackgroundFileStyle;
66 68
import org.gvsig.fmap.mapcontext.rendering.symbols.styles.ILabelStyle;
69
import org.gvsig.svgsupport.DefaultSVGRenderer;
70
import org.gvsig.svgsupport.SVGRenderer;
71
import org.gvsig.symbology.PathLength;
67 72
import org.gvsig.symbology.SymbologyLocator;
68 73
import org.gvsig.symbology.SymbologyManager;
69 74
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl.FInterval;
70 75
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.AttrInTableLabelingStrategy;
71 76
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.DefaultLabelingMethod;
72 77
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.IAttrInTableLabelingStrategy;
73
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.LabelClass;
74 78
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.ZoomConstraintsImpl;
75 79
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.IMultiShapeSymbol;
76 80
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IMarkerFillSymbol;
......
116 120
		return new FInterval(min, max);
117 121
	}
118 122

  
123
    @Override
124
    public SVGRenderer createSVGRenderer() {
125
        return new DefaultSVGRenderer();
126
    }
127

  
119 128
	public static class RegisterSymbologyManager implements Callable {
120 129

  
121 130
		public Object call() throws Exception {
......
256 265
            }
257 266
            this.defaultLabelClassFactory = factory;
258 267
        }
268

  
269
    @Override
270
    public PathLength createPathLength(Shape path) {
271
        return new DefaultPathLength(path);
272
    }
259 273
        
274
 
260 275
        
261 276
}
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/style/ArrowDecoratorStyle.java
28 28
import java.awt.geom.AffineTransform;
29 29
import java.awt.geom.Point2D;
30 30

  
31
import org.apache.batik.ext.awt.geom.PathLength;
31
import org.apache.batik.ext.awt.geom.DefaultPathLength;
32 32
import org.gvsig.fmap.dal.feature.Feature;
33 33
import org.gvsig.fmap.geom.Geometry;
34 34
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
......
37 37
import org.gvsig.fmap.geom.exception.CreateGeometryException;
38 38
import org.gvsig.fmap.geom.primitive.Point;
39 39
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
40
import org.gvsig.symbology.PathLength;
40 41
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
41 42
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IArrowMarkerSymbol;
42 43
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
......
53 54
 * different options to draw an arrow in a line (and draw it too). This
54 55
 * information is taken from the panel.
55 56
 *
56
 * @author 2005-2008 jaume dominguez faus - jaume.dominguez@iver.es
57
 * @author 2009- <a href="cordinyana@gvsig.org">C?sar Ordi?ana</a> - gvSIG team
58 57
 */
59 58
public class ArrowDecoratorStyle extends AbstractStyle implements IArrowDecoratorStyle  {
60 59
	public static final String ARROR_DECORATOR_STYLE_PERSISTENCE_DEFINITION_NAME = "ArrowDecoratorStyle";
......
169 168

  
170 169
		Geometry geomToDraw = geom.cloneGeometry();
171 170
		geomToDraw.transform(affineTransform);
172
		PathLength pl = new PathLength(geomToDraw.getShape());
171
		PathLength pl = new DefaultPathLength(geomToDraw.getShape());
173 172
		float size = (float) marker.getSize();
174 173
		marker.setRotation(0.0);
175 174
		float myLineLength = pl.lengthOfPath();
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/style/SVGStyle.java
25 25

  
26 26
import java.awt.Graphics2D;
27 27
import java.awt.Rectangle;
28
import java.awt.RenderingHints;
29
import java.awt.geom.AffineTransform;
30 28
import java.awt.geom.Rectangle2D;
31 29
import java.io.IOException;
32
import java.net.URISyntaxException;
33 30
import java.net.URL;
34 31

  
35
import org.apache.batik.bridge.BridgeContext;
36
import org.apache.batik.bridge.DocumentLoader;
37
import org.apache.batik.bridge.GVTBuilder;
38
import org.apache.batik.bridge.UserAgentAdapter;
39
import org.apache.batik.bridge.ViewBox;
40
import org.apache.batik.dom.svg.SVGOMDocument;
41
import org.apache.batik.gvt.GraphicsNode;
42
import org.apache.batik.gvt.renderer.StaticRenderer;
43
import org.w3c.dom.Document;
44
import org.w3c.dom.Element;
45 32

  
46 33
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
47 34
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
35
import org.gvsig.svgsupport.DefaultSVGRenderer;
48 36
import org.gvsig.tools.ToolsLocator;
49 37
import org.gvsig.tools.dynobject.DynStruct;
50 38
import org.gvsig.tools.persistence.PersistenceManager;
......
59 47
 * hyperlinks using outbound simple XLinks.It is an open standard created
60 48
 * by the World Wide Web Consortium..
61 49
 * 
62
 * @author jaume dominguez faus - jaume.dominguez@iver.es
63
 * 
64 50
 */
65 51
public class SVGStyle extends BackgroundFileStyle {
66 52

  
67
    public static final String SVG_STYLE_PERSISTENCE_DEFINITION_NAME =
68
        "SVGStyle";
53
    public static final String SVG_STYLE_PERSISTENCE_DEFINITION_NAME = "SVGStyle";
69 54
    private static final String SOURCE = "source";
70
    private final GVTBuilder gvtBuilder = new GVTBuilder();
71
    private final UserAgentAdapter userAgent;
72
    private final DocumentLoader loader;
73
    private final StaticRenderer renderer = new StaticRenderer();
74
    private GraphicsNode gvtRoot;
75
    private final BridgeContext ctx;
76
    private Element elt;
55
    private DefaultSVGRenderer renderer;
77 56

  
78
    protected static final RenderingHints defaultRenderingHints;
79
    static {
80
        defaultRenderingHints = new RenderingHints(null);
81
        defaultRenderingHints.put(RenderingHints.KEY_ANTIALIASING,
82
            RenderingHints.VALUE_ANTIALIAS_ON);
83

  
84
        defaultRenderingHints.put(RenderingHints.KEY_INTERPOLATION,
85
            RenderingHints.VALUE_INTERPOLATION_BILINEAR);
86
    }
87

  
88 57
    /**
89 58
     * Constructor method
90 59
     * 
91 60
     */
92 61
    public SVGStyle() {
93
        userAgent = new UserAgentAdapter();
94
        loader = new DocumentLoader(userAgent);
95
        ctx = new BridgeContext(userAgent, loader);
96
        renderer.setDoubleBuffered(true);
62
        this.renderer = new DefaultSVGRenderer();
97 63
    }
98 64

  
99 65
    @Override
100 66
    public void drawInsideRectangle(Graphics2D g,
101 67
        Rectangle rect,
102 68
        boolean keepAspectRatio) throws SymbolDrawingException {
103
        if (keepAspectRatio) {
104
            AffineTransform ataux;
105
            if (elt.hasAttribute("viewBox")) {
106

  
107
                try {
108
                    ataux =
109
                        ViewBox.getViewTransform(null,
110
                            elt,
111
                            (float) rect.getWidth(),
112
                            (float) rect.getHeight(),
113
                            ctx);
114
                } catch (NullPointerException e) {
115
                    throw new SymbolDrawingException(SymbolDrawingException.UNSUPPORTED_SET_OF_SETTINGS);
116
                }
117
            } else {
118
                Rectangle2D bounds = gvtRoot.getBounds();
119
                
120
                ataux = getNoRotationTransform(
121
                    bounds,
122
                    new Rectangle2D.Double(
123
                        rect.x,
124
                        rect.y,
125
                        rect.width,
126
                        rect.height),
127
                    true);
128
            }
129
            RenderingHints renderingHints = new RenderingHints(null);
130
            renderingHints.putAll(defaultRenderingHints);
131
            g.setRenderingHints(renderingHints);
132
            gvtRoot.setTransform(ataux);
133
            gvtRoot.paint(g);
134

  
135
        } else {
136

  
137
            Rectangle2D bounds = gvtRoot.getBounds();
138
            AffineTransform ataux = getNoRotationTransform(
139
                bounds,
140
                new Rectangle2D.Double(rect.x, rect.y, rect.width, rect.height),
141
                false);
142
            
143
            RenderingHints renderingHints = new RenderingHints(null);
144
            renderingHints.putAll(defaultRenderingHints);
145
            g.setRenderingHints(renderingHints);
146
            gvtRoot.setTransform(ataux);
147
            gvtRoot.paint(g);
148
        }
69
        this.renderer.drawInsideRectangle(g, rect, keepAspectRatio);
149 70
    }
150 71

  
151 72
    @Override
......
157 78
    public void setSource(URL url) throws IOException {
158 79

  
159 80
    	source = url;
160
    	Document svgDoc;
161
    	try {
162
    		svgDoc = loader.loadDocument(url.toURI().toString());
163
    	} catch (URISyntaxException e) {
164
            throw new IOException(e);
165
    	}
166
    	gvtRoot = gvtBuilder.build(ctx, svgDoc);
167
    	renderer.setTree(gvtRoot);
168
    	elt = ((SVGOMDocument) svgDoc).getRootElement();
81
        this.renderer.setSource(url);
169 82
    }
170 83

  
171 84
    @Override
172 85
    public Rectangle getBounds() {
173 86
        try {
174
            Rectangle2D r = gvtRoot.getBounds();
87
            Rectangle2D r = this.renderer.getBounds();
175 88
            return new Rectangle((int) r.getX(),
176 89
                (int) r.getY(),
177 90
                (int) r.getWidth(),
......
234 147
            return Boolean.TRUE;
235 148
        }
236 149

  
237
    }
238
    
239
    
240
    private AffineTransform getNoRotationTransform(
241
        Rectangle2D from_rect,
242
        Rectangle2D to_rect,
243
        boolean keep_aspect) {
244
        
245
        double scalex = to_rect.getWidth() / from_rect.getWidth();
246
        double scaley = to_rect.getHeight() / from_rect.getHeight();
247
        
248
        if (keep_aspect) {
249
            // force min value for both
250
            scalex = Math.min(scalex,  scaley);
251
            scaley = scalex;
252
        }
253
        
254
        double from_new_center_x = scalex * from_rect.getCenterX(); 
255
        double from_new_center_y = scaley * from_rect.getCenterY(); 
256
        
257
        double offx = to_rect.getCenterX() - from_new_center_x;
258
        double offy = to_rect.getCenterY() - from_new_center_y;
259
        
260
        AffineTransform resp =
261
            AffineTransform.getTranslateInstance(offx, offy);
262
        
263
        // this composition is equivalent to:
264
        // first scale, then move
265
        resp.concatenate(
266
            AffineTransform.getScaleInstance(scalex, scaley));
267
        return resp;
268
    }
150
    }    
269 151
}
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/impl/FLabel.java
21 21
 * For any additional information, do not hesitate to contact us
22 22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 23
 */
24
/*
25
 * Created on 13-jul-2004
26
 *
27
 * TODO To change the template for this generated file go to
28
 * Window - Preferences - Java - Code Generation - Code and Comments
29
 */
30
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
31
 *
32
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
33
 *
34
 * This program is free software; you can redistribute it and/or
35
 * modify it under the terms of the GNU General Public License
36
 * as published by the Free Software Foundation; either version 2
37
 * of the License, or (at your option) any later version.
38
 *
39
 * This program is distributed in the hope that it will be useful,
40
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
41
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
 * GNU General Public License for more details.
43
 *
44
 * You should have received a copy of the GNU General Public License
45
 * along with this program; if not, write to the Free Software
46
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
47
 *
48
 * For more information, contact:
49
 *
50
 *  Generalitat Valenciana
51
 *   Conselleria d'Infraestructures i Transport
52
 *   Av. Blasco Ib??ez, 50
53
 *   46010 VALENCIA
54
 *   SPAIN
55
 *
56
 *      +34 963862235
57
 *   gvsig@gva.es
58
 *      www.gvsig.gva.es
59
 *
60
 *    or
61
 *
62
 *   IVER T.I. S.A
63
 *   Salamanca 50
64
 *   46005 Valencia
65
 *   Spain
66
 *
67
 *   +34 963163400
68
 *   dac@iver.es
69
 */
70 24
package org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl;
71 25

  
72 26
import java.awt.Color;
......
77 31
import java.awt.geom.Point2D;
78 32
import java.awt.geom.Rectangle2D;
79 33

  
80
import org.apache.batik.ext.awt.geom.PathLength;
34
import org.apache.batik.ext.awt.geom.DefaultPathLength;
81 35
import org.slf4j.Logger;
82 36
import org.slf4j.LoggerFactory;
83 37

  
......
86 40
import org.gvsig.fmap.geom.primitive.Point;
87 41
import org.gvsig.fmap.mapcontext.ViewPort;
88 42
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
43
import org.gvsig.symbology.PathLength;
89 44
import org.gvsig.utils.XMLEntity;
90 45

  
91 46
/**
92 47
 * Se utiliza para etiquetar. Las capas vectoriales tienen un arrayList
93 48
 * (m_labels) de FLabel, un FLabel por cada registro.
94
 *
95
 * @author FJP
96 49
 * @deprecated
97 50
 */
98 51
public class FLabel implements Cloneable {
......
334 287
		label.setOrig(pAux);
335 288
		switch (geom.getType()) {
336 289
			case org.gvsig.fmap.geom.Geometry.TYPES.CURVE:
337
           		PathLength pathLen = new PathLength(geom.getShape());
290
                                PathLength pathLen = new DefaultPathLength(geom.getShape());
338 291
				float midDistance = pathLen.lengthOfPath() / 2;
339 292
				angle = pathLen.angleAtLength(midDistance);
340 293

  
......
359 312
				return pAux;
360 313

  
361 314
			case org.gvsig.fmap.geom.Geometry.TYPES.CURVE:
362
            	PathLength pathLen = new PathLength(geom.getShape());
315
            	DefaultPathLength pathLen = new DefaultPathLength(geom.getShape());
363 316

  
364 317
				// if (pathLen.lengthOfPath() < width / mT.getScaleX()) return;
365 318
				float midDistance = pathLen.lengthOfPath() / 2;
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/impl/FGraphicUtilities.java
21 21
 * For any additional information, do not hesitate to contact us
22 22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 23
 */
24
/*
25
 * Created on 28-abr-2004
26
 *
27
 * To change the template for this generated file go to
28
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
29
 */
30
/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
31
 *
32
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
33
 *
34
 * This program is free software; you can redistribute it and/or
35
 * modify it under the terms of the GNU General Public License
36
 * as published by the Free Software Foundation; either version 2
37
 * of the License, or (at your option) any later version.
38
 *
39
 * This program is distributed in the hope that it will be useful,
40
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
41
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
 * GNU General Public License for more details.
43
 *
44
 * You should have received a copy of the GNU General Public License
45
 * along with this program; if not, write to the Free Software
46
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
47
 *
48
 * For more information, contact:
49
 *
50
 *  Generalitat Valenciana
51
 *   Conselleria d'Infraestructures i Transport
52
 *   Av. Blasco Ib��ez, 50
53
 *   46010 VALENCIA
54
 *   SPAIN
55
 *
56
 *      +34 963862235
57
 *   gvsig@gva.es
58
 *      www.gvsig.gva.es
59
 *
60
 *    or
61
 *
62
 *   IVER T.I. S.A
63
 *   Salamanca 50
64
 *   46005 Valencia
65
 *   Spain
66
 *
67
 *   +34 963163400
68
 *   dac@iver.es
69
 */
70 24
package org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl;
71 25

  
72 26
import java.awt.Color;
......
77 31
import java.awt.geom.AffineTransform;
78 32
import java.awt.geom.Point2D;
79 33

  
80
import org.apache.batik.ext.awt.geom.PathLength;
34
import org.apache.batik.ext.awt.geom.DefaultPathLength;
81 35
import org.gvsig.fmap.geom.Geometry;
82 36
import org.gvsig.fmap.geom.GeometryLocator;
83 37
import org.gvsig.fmap.geom.GeometryManager;
......
88 42
import org.gvsig.fmap.geom.primitive.Point;
89 43
import org.gvsig.fmap.mapcontext.MapContext;
90 44
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
45
import org.gvsig.symbology.PathLength;
91 46
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
92 47
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
93 48
import org.slf4j.Logger;
......
104 59
 * Recordar: Que sea ISymbol el que renderiza.
105 60
 * extensible el s�mbolo a usar. NOTA: Ver tambi�n comentario en ISymbol
106 61
 *
107
 * @author fjp
108 62
 * @deprecated
109 63
 */
110 64
public class FGraphicUtilities {
......
429 383
				//
430 384
				if (theLabel.getOrig() == null) // Calculamos el punto y la orientaci�n solo la primera vez
431 385
				 {
432
					PathLength pathLen = new PathLength(geom.getShape());
386
					PathLength pathLen = new DefaultPathLength(geom.getShape());
433 387

  
434 388
					// if (pathLen.lengthOfPath() < width / mT.getScaleX()) return;
435 389
					float midDistance = pathLen.lengthOfPath() / 2;
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/line/impl/PictureLineSymbol.java
24 24
package org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.impl;
25 25

  
26 26
import java.awt.BasicStroke;
27
import java.awt.Color;
28 27
import java.awt.Graphics2D;
29 28
import java.awt.Rectangle;
30 29
import java.awt.Shape;
......
34 33
import java.io.IOException;
35 34
import java.net.URL;
36 35

  
37
import org.apache.batik.ext.awt.geom.PathLength;
36
import org.apache.batik.ext.awt.geom.DefaultPathLength;
38 37
import org.gvsig.compat.print.PrintAttributes;
39 38
import org.gvsig.fmap.dal.feature.Feature;
40 39
import org.gvsig.fmap.geom.Geometry;
......
45 44
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
46 45
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
47 46
import org.gvsig.i18n.Messages;
47
import org.gvsig.symbology.PathLength;
48 48
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.CartographicSupportToolkit;
49 49
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.IPictureLineSymbol;
50 50
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.BackgroundFileStyle;
......
63 63
 * PictureLineSymbol allows to use any symbol defined as an image (by an image file)
64 64
 * supported  by gvSIG.This symbol will be used as an initial object.The line will be
65 65
 * painted as a succession of puntual symbols through the path defined by it(the line).
66
 *
67
 * @author jaume dominguez faus - jaume.dominguez@iver.es
68 66
 */
69 67
public class PictureLineSymbol extends AbstractLineSymbol implements IPictureLineSymbol  {
70 68

  
......
178 176
		if (imageWidth==0 || imageHeight==0) return;
179 177
		int height = (int) csWidth;
180 178

  
181
		PathLength pl = new PathLength(geom_transf_clip);
179
		PathLength pl = new DefaultPathLength(geom_transf_clip);
182 180
		PathIterator iterator = geom_transf_clip.getPathIterator(null, 0.8);
183 181
		double[] theData = new double[6];
184 182
		Point2D firstPoint = null, startPoint = null, endPoint = null;
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/legend/styling/AttrInTableLabelingStrategy.java
31 31
import java.util.ArrayList;
32 32
import java.util.List;
33 33

  
34
import org.apache.batik.ext.awt.geom.PathLength;
34
import org.apache.batik.ext.awt.geom.DefaultPathLength;
35 35
import org.cresques.cts.ICoordTrans;
36 36
import org.cresques.cts.IProjection;
37 37
import org.slf4j.LoggerFactory;
......
59 59
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingMethod;
60 60
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IPlacementConstraints;
61 61
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IZoomConstraints;
62
import org.gvsig.symbology.PathLength;
62 63
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.CartographicSupportToolkit;
63 64
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.impl.SimpleTextSymbol;
64 65
import org.gvsig.tools.ToolsLocator;
......
77 78
 * LabelingStrategy used when the user wants to use label sizes, rotations, etc.
78 79
 * from the values included in fields of the datasource's table
79 80
 *
80
 * @author jaume dominguez faus - jaume.dominguez@iver.es
81
 *
82 81
 */
83 82
public class AttrInTableLabelingStrategy implements IAttrInTableLabelingStrategy {
84 83

  
......
371 370
                                Geometry aux_geom = geom.cloneGeometry();
372 371
                                aux_geom.transform(viewPort.getAffineTransform());
373 372

  
374
                                PathLength pathLen = new PathLength(aux_geom);
373
                                PathLength pathLen = new DefaultPathLength(aux_geom);
375 374
                                float length = pathLen.lengthOfPath();
376 375
                                float distance = (float) (length * 0.4);
377 376
                                rotation = pathLen.angleAtLength(distance);
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/legend/styling/TextPath.java
21 21
 * For any additional information, do not hesitate to contact us
22 22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 23
 */
24
/* CVS MESSAGES:
25
 *
26
 * $Id: TextPath.java 25636 2008-12-01 08:42:11Z vcaballero $
27
 * $Log$
28
 * Revision 1.2  2007-03-09 11:20:57  jaume
29
 * Advanced symbology (start committing)
30
 *
31
 * Revision 1.1.2.3  2007/02/21 07:34:09  jaume
32
 * labeling starts working
33
 *
34
 * Revision 1.1.2.2  2007/02/09 07:47:05  jaume
35
 * Isymbol moved
36
 *
37
 * Revision 1.1.2.1  2007/02/06 17:01:04  jaume
38
 * first version (only lines)
39
 *
40
 *
41
 */
42 24
package org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling;
43 25

  
44 26
import java.awt.Font;
......
47 29
import java.awt.font.GlyphVector;
48 30
import java.awt.geom.Point2D;
49 31

  
50
import org.apache.batik.ext.awt.geom.PathLength;
32
import org.apache.batik.ext.awt.geom.DefaultPathLength;
51 33
import org.gvsig.fmap.geom.Geometry;
52 34
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
53 35
import org.gvsig.fmap.geom.GeometryLocator;
......
60 42
import org.slf4j.LoggerFactory;
61 43

  
62 44
import com.vividsolutions.jts.algorithm.Angle;
45
import org.gvsig.symbology.PathLength;
63 46
/**
64 47
 * <p>Class that represents baseline of a string and allows the baseline to
65 48
 * be composed as contiguous segments with distinct slope each.<br></p>
......
68 51
 * the character at a determined position in the string is placed and
69 52
 * rotated.<br></p>
70 53
 *
71
 * @author jaume dominguez faus - jaume.dominguez@iver.es
72
 *
73 54
 */
74 55
public class TextPath {
75 56
	private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
......
145 126

  
146 127
		PathLength pl;
147 128
		try {
148
			pl = new PathLength(softenShape(path, gv).getShape());
129
			pl = new DefaultPathLength(softenShape(path, gv).getShape());
149 130
			if (alignment==ITextSymbol.SYMBOL_STYLE_ALIGNMENT_RIGHT) {
150 131
				posList = computeAtRight(gv, pl, text);
151 132
			}
......
164 145

  
165 146
		float interval = (float) gv.getVisualBounds().getWidth()/(gv.getNumGlyphs()*3);
166 147

  
167
		PathLength pl = new PathLength(shape.getShape());
148
		PathLength pl = new DefaultPathLength(shape.getShape());
168 149
		if (pl.lengthOfPath()==0.0f) {
169 150
			return shape; 
170 151
		}
trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.symbology/org.gvsig.symbology.lib/org.gvsig.symbology.lib.impl/src/main/java/org/apache/batik/ext/awt/geom/DefaultPathLength.java
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

  
25
package org.apache.batik.ext.awt.geom;
26
/*
27
 * Based on portions of code from org.apache.batik.ext.awt.geom of the
28
 * batik-awt-util project, The Apache XML Graphics Project.
29
 * https://xmlgraphics.apache.org/
30
 */
31

  
32
import java.awt.Shape;
33
import java.awt.geom.AffineTransform;
34
import java.awt.geom.FlatteningPathIterator;
35
import java.awt.geom.PathIterator;
36
import java.awt.geom.Point2D;
37
import java.util.List;
38
import java.util.ArrayList;
39

  
40
import org.gvsig.symbology.PathLength;
41
/**
42
 * Utilitiy class for length calculations of paths.
43
 * <p>
44
 *   PathLength is a utility class for calculating the length
45
 *   of a path, the location of a point at a particular length
46
 *   along the path, and the angle of the tangent to the path
47
 *   at a given length.
48
 * </p>
49
 * <p>
50
 *   It uses a FlatteningPathIterator to create a flattened version
51
 *   of the Path. This means the values returned are not always
52
 *   exact (in fact, they rarely are), but in most cases they
53
 *   are reasonably accurate.
54
 * </p>
55
 *
56
 * @author <a href="mailto:dean.jackson@cmis.csiro.au">Dean Jackson</a>
57
 * @version $Id$
58
 */
59
public class DefaultPathLength implements PathLength {
60

  
61
    /**
62
     * The path to use for calculations.
63
     */
64
    protected Shape path;
65

  
66
    /**
67
     * The list of flattened path segments.
68
     */
69
    protected List segments;
70

  
71
    /**
72
     * Array where the index is the index of the original path segment
73
     * and the value is the index of the first of the flattened segments
74
     * in {@link #segments} that corresponds to that original path segment.
75
     */
76
    protected int[] segmentIndexes;
77

  
78
    /**
79
     * Cached copy of the path length.
80
     */
81
    protected float pathLength;
82

  
83
    /**
84
     * Whether this path been flattened yet.
85
     */
86
    protected boolean initialised;
87

  
88
    /**
89
     * Creates a new PathLength object for the specified {@link Shape}.
90
     * @param path The Path (or Shape) to use.
91
     */
92
    public DefaultPathLength(Shape path) {
93
        setPath(path);
94
    }
95

  
96
    /**
97
     * Returns the path to use for calculations.
98
     * @return Path used in calculations.
99
     */
100
    public Shape getPath() {
101
        return path;
102
    }
103

  
104
    /**
105
     * Sets the path to use for calculations.
106
     * @param v Path to be used in calculations.
107
     */
108
    public void setPath(Shape v) {
109
        this.path = v;
110
        initialised = false;
111
    }
112

  
113
    /**
114
     * Returns the length of the path used by this PathLength object.
115
     * @return The length of the path.
116
     */
117
    @Override
118
    public float lengthOfPath() {
119
        if (!initialised) {
120
            initialise();
121
        }
122
        return pathLength;
123
    }
124

  
125
    /**
126
     * Flattens the path and determines the path length.
127
     */
128
    protected void initialise() {
129
        pathLength = 0f;
130

  
131
        PathIterator pi = path.getPathIterator(new AffineTransform());
132
        SingleSegmentPathIterator sspi = new SingleSegmentPathIterator();
133
        segments = new ArrayList(20);
134
        List indexes = new ArrayList(20);
135
        int index = 0;
136
        int origIndex = -1;
137
        float lastMoveX = 0f;
138
        float lastMoveY = 0f;
139
        float currentX = 0f;
140
        float currentY = 0f;
141
        float[] seg = new float[6];
142
        int segType;
143

  
144
        segments.add(new PathSegment(PathIterator.SEG_MOVETO, 0f, 0f, 0f,
145
                                     origIndex));
146

  
147
        while (!pi.isDone()) {
148
            origIndex++;
149
            indexes.add(new Integer(index));
150
            segType = pi.currentSegment(seg);
151
            switch (segType) {
152
                case PathIterator.SEG_MOVETO:
153
                    segments.add(new PathSegment(segType, seg[0], seg[1],
154
                                                 pathLength, origIndex));
155
                    currentX = seg[0];
156
                    currentY = seg[1];
157
                    lastMoveX = currentX;
158
                    lastMoveY = currentY;
159
                    index++;
160
                    pi.next();
161
                    break;
162
                case PathIterator.SEG_LINETO:
163
                    pathLength += Point2D.distance(currentX, currentY, seg[0],
164
                                                   seg[1]);
165
                    segments.add(new PathSegment(segType, seg[0], seg[1],
166
                                                 pathLength, origIndex));
167
                    currentX = seg[0];
168
                    currentY = seg[1];
169
                    index++;
170
                    pi.next();
171
                    break;
172
                case PathIterator.SEG_CLOSE:
173
                    pathLength += Point2D.distance(currentX, currentY,
174
                                                   lastMoveX, lastMoveY);
175
                    segments.add(new PathSegment(PathIterator.SEG_LINETO,
176
                                                 lastMoveX, lastMoveY,
177
                                                 pathLength, origIndex));
178
                    currentX = lastMoveX;
179
                    currentY = lastMoveY;
180
                    index++;
181
                    pi.next();
182
                    break;
183
                default:
184
                    sspi.setPathIterator(pi, currentX, currentY);
185
                    FlatteningPathIterator fpi =
186
                        new FlatteningPathIterator(sspi, 0.01f);
187
                    while (!fpi.isDone()) {
188
                        segType = fpi.currentSegment(seg);
189
                        if (segType == PathIterator.SEG_LINETO) {
190
                            pathLength += Point2D.distance(currentX, currentY,
191
                                                           seg[0], seg[1]);
192
                            segments.add(new PathSegment(segType, seg[0],
193
                                                         seg[1], pathLength,
194
                                                         origIndex));
195
                            currentX = seg[0];
196
                            currentY = seg[1];
197
                            index++;
198
                        }
199
                        fpi.next();
200
                    }
201
            }
202
        }
203
        segmentIndexes = new int[indexes.size()];
204
        for (int i = 0; i < segmentIndexes.length; i++) {
205
            segmentIndexes[i] = ((Integer) indexes.get(i)).intValue();
206
        }
207
        initialised = true;
208
    }
209

  
210
    /**
211
     * Returns the number of segments in the path.
212
     */
213
    public int getNumberOfSegments() {
214
        if (!initialised) {
215
            initialise();
216
        }
217
        return segmentIndexes.length;
218
    }
219

  
220
    /**
221
     * Returns the length at the start of the segment given by the specified
222
     * index.
223
     */
224
    public float getLengthAtSegment(int index) {
225
        if (!initialised) {
226
            initialise();
227
        }
228
        if (index <= 0) {
229
            return 0;
230
        }
231
        if (index >= segmentIndexes.length) {
232
            return pathLength;
233
        }
234
        PathSegment seg = (PathSegment) segments.get(segmentIndexes[index]);
235
        return seg.getLength();
236
    }
237

  
238
    /**
239
     * Returns the index of the segment at the given distance along the path.
240
     */
241
    public int segmentAtLength(float length) {
242
        int upperIndex = findUpperIndex(length);
243
        if (upperIndex == -1) {
244
            // Length is off the end of the path.
245
            return -1;
246
        }
247

  
248
        if (upperIndex == 0) {
249
            // Length was probably zero, so return the upper segment.
250
            PathSegment upper = (PathSegment) segments.get(upperIndex);
251
            return upper.getIndex();
252
        }
253

  
254
        PathSegment lower = (PathSegment) segments.get(upperIndex - 1);
255
        return lower.getIndex();
256
    }
257

  
258
    /**
259
     * Returns the point that is the given proportion along the path segment
260
     * given by the specified index.
261
     */
262
    public Point2D pointAtLength(int index, float proportion) {
263
        if (!initialised) {
264
            initialise();
265
        }
266
        if (index < 0 || index >= segmentIndexes.length) {
267
            return null;
268
        }
269
        PathSegment seg = (PathSegment) segments.get(segmentIndexes[index]);
270
        float start = seg.getLength();
271
        float end;
272
        if (index == segmentIndexes.length - 1) {
273
            end = pathLength;
274
        } else {
275
            seg = (PathSegment) segments.get(segmentIndexes[index + 1]);
276
            end = seg.getLength();
277
        }
278
        return pointAtLength(start + (end - start) * proportion);
279
    }
280

  
281
    /**
282
     * Returns the point that is at the given length along the path.
283
     * @param length The length along the path
284
     * @return The point at the given length
285
     */
286
    @Override
287
    public Point2D pointAtLength(float length) {
288
        int upperIndex = findUpperIndex(length);
289
        if (upperIndex == -1) {
290
            // Length is off the end of the path.
291
            return null;
292
        }
293

  
294
        PathSegment upper = (PathSegment) segments.get(upperIndex);
295

  
296
        if (upperIndex == 0) {
297
            // Length was probably zero, so return the upper point.
298
            return new Point2D.Float(upper.getX(), upper.getY());
299
        }
300

  
301
        PathSegment lower = (PathSegment) segments.get(upperIndex - 1);
302

  
303
        // Now work out where along the line would be the length.
304
        float offset = length - lower.getLength();
305

  
306
        // Compute the slope.
307
        double theta = Math.atan2(upper.getY() - lower.getY(),
308
                                  upper.getX() - lower.getX());
309

  
310
        float xPoint = (float) (lower.getX() + offset * Math.cos(theta));
311
        float yPoint = (float) (lower.getY() + offset * Math.sin(theta));
312

  
313
        return new Point2D.Float(xPoint, yPoint);
314
    }
315

  
316
    /**
317
     * Returns the slope of the path at the specified length.
318
     * @param index The segment number
319
     * @param proportion The proportion along the given segment
320
     * @return the angle in radians, in the range [-{@link Math#PI},
321
     *         {@link Math#PI}].
322
     */
323
    public float angleAtLength(int index, float proportion) {
324
        if (!initialised) {
325
            initialise();
326
        }
327
        if (index < 0 || index >= segmentIndexes.length) {
328
            return 0f;
329
        }
330
        PathSegment seg = (PathSegment) segments.get(segmentIndexes[index]);
331
        float start = seg.getLength();
332
        float end;
333
        if (index == segmentIndexes.length - 1) {
334
            end = pathLength;
335
        } else {
336
            seg = (PathSegment) segments.get(segmentIndexes[index + 1]);
337
            end = seg.getLength();
338
        }
339
        return angleAtLength(start + (end - start) * proportion);
340
    }
341

  
342
    /**
343
     * Returns the slope of the path at the specified length.
344
     * @param length The length along the path
345
     * @return the angle in radians, in the range [-{@link Math#PI},
346
     *         {@link Math#PI}].
347
     */
348
    @Override
349
    public float angleAtLength(float length) {
350
        int upperIndex = findUpperIndex(length);
351
        if (upperIndex == -1) {
352
            // Length is off the end of the path.
353
            return 0f;
354
        }
355

  
356
        PathSegment upper = (PathSegment) segments.get(upperIndex);
357

  
358
        if (upperIndex == 0) {
359
            // Length was probably zero, so return the angle between the first
360
            // and second segments.
361
            upperIndex = 1;
362
        }
363

  
364
        PathSegment lower = (PathSegment) segments.get(upperIndex - 1);
365

  
366
        // Compute the slope.
367
        return (float) Math.atan2(upper.getY() - lower.getY(),
368
                                  upper.getX() - lower.getX());
369
    }
370

  
371
    /**
372
     * Returns the index of the path segment that bounds the specified
373
     * length along the path.
374
     * @param length The length along the path
375
     * @return The path segment index, or -1 if there is not such segment
376
     */
377
    public int findUpperIndex(float length) {
378
        if (!initialised) {
379
            initialise();
380
        }
381

  
382
        if (length < 0 || length > pathLength) {
383
            // Length is outside the path, so return -1.
384
            return -1;
385
        }
386

  
387
        // Find the two segments that are each side of the length.
388
        int lb = 0;
389
        int ub = segments.size() - 1;
390
        while (lb != ub) {
391
            int curr = (lb + ub) >> 1;
392
            PathSegment ps = (PathSegment) segments.get(curr);
393
            if (ps.getLength() >= length) {
394
                ub = curr;
395
            } else {
396
                lb = curr + 1;
397
            }
398
        }
399
        for (;;) {
400
            PathSegment ps = (PathSegment) segments.get(ub);
401
            if (ps.getSegType() != PathIterator.SEG_MOVETO
402
                    || ub == segments.size() - 1) {
403
                break;
404
            }
405
            ub++;
406
        }
407

  
408
        int upperIndex = -1;
409
        int currentIndex = 0;
410
        int numSegments = segments.size();
411
        while (upperIndex <= 0 && currentIndex < numSegments) {
412
            PathSegment ps = (PathSegment) segments.get(currentIndex);
413
            if (ps.getLength() >= length
414
                    && ps.getSegType() != PathIterator.SEG_MOVETO) {
415
                upperIndex = currentIndex;
416
            }
417
            currentIndex++;
418
        }
419
        return upperIndex;
420
    }
421

  
422
    /**
423
     * A {@link PathIterator} that returns only the next path segment from
424
     * another {@link PathIterator}.
425
     */
426
    protected static class SingleSegmentPathIterator implements PathIterator {
427

  
428
        /**
429
         * The path iterator being wrapped.
430
         */
431
        protected PathIterator it;
432

  
433
        /**
434
         * Whether the single segment has been passed.
435
         */
436
        protected boolean done;
437

  
438
        /**
439
         * Whether the generated move command has been returned.
440
         */
441
        protected boolean moveDone;
442

  
443
        /**
444
         * The x coordinate of the next move command.
445
         */
446
        protected double x;
447

  
448
        /**
449
         * The y coordinate of the next move command.
450
         */
451
        protected double y;
452

  
453
        /**
454
         * Sets the path iterator to use and the initial SEG_MOVETO command
455
         * to return before it.
456
         */
457
        public void setPathIterator(PathIterator it, double x, double y) {
458
            this.it = it;
459
            this.x = x;
460
            this.y = y;
461
            done = false;
462
            moveDone = false;
463
        }
464

  
465
        public int currentSegment(double[] coords) {
466
            int type = it.currentSegment(coords);
467
            if (!moveDone) {
468
                coords[0] = x;
469
                coords[1] = y;
470
                return SEG_MOVETO;
471
            }
472
            return type;
473
        }
474

  
475
        public int currentSegment(float[] coords) {
476
            int type = it.currentSegment(coords);
477
            if (!moveDone) {
478
                coords[0] = (float) x;
479
                coords[1] = (float) y;
480
                return SEG_MOVETO;
481
            }
482
            return type;
483
        }
484

  
485
        public int getWindingRule() {
486
            return it.getWindingRule();
487
        }
488

  
489
        public boolean isDone() {
490
            return done || it.isDone();
491
        }
492

  
493
        public void next() {
494
            if (!done) {
495
                if (!moveDone) {
496
                    moveDone = true;
497
                } else {
498
                    it.next();
499
                    done = true;
500
                }
501
            }
502
        }
503
    }
504

  
505
    /**
506
     * A single path segment in the flattened version of the path.
507
     * This is a local helper class. PathSegment-objects are stored in
508
     * the {@link PathLength#segments} - list.
509
     * This is used as an immutable value-object.
510
     */
511
    protected static class PathSegment {
512

  
513
        /**
514
         * The path segment type.
515
         */
516
        protected final int segType;
517

  
518
        /**
519
         * The x coordinate of the path segment.
520
         */
521
        protected float x;
522

  
523
        /**
524
         * The y coordinate of the path segment.
525
         */
526
        protected float y;
527

  
528
        /**
529
         * The length of the path segment, accumulated from the start.
530
         */
531
        protected float length;
532

  
533
        /**
534
         * The index of the original path segment this flattened segment is a
535
         * part of.
536
         */
537
        protected int index;
538

  
539
        /**
540
         * Creates a new PathSegment with the specified parameters.
541
         * @param segType The segment type
542
         * @param x The x coordinate
543
         * @param y The y coordinate
544
         * @param len The segment length
545
         * @param idx The index of the original path segment this flattened
546
         *            segment is a part of
547
         */
548
        PathSegment(int segType, float x, float y, float len, int idx) {
549
            this.segType = segType;
550
            this.x = x;
551
            this.y = y;
552
            this.length = len;
553
            this.index = idx;
554
        }
555

  
556
        /**
557
         * Returns the segment type.
558
         */
559
        public int getSegType() {
560
            return segType;
561
        }
562

  
563
        /**
564
         * Returns the x coordinate of the path segment.
565
         */
566
        public float getX() {
567
            return x;
568
        }
569

  
570
        /**
571
         * Sets the x coordinate of the path segment.
572
         */
573
        public void setX(float v) {
574
            x = v;
575
        }
576

  
577
        /**
578
         * Returns the y coordinate of the path segment.
579
         */
580
        public float getY() {
581
            return y;
582
        }
583

  
584
        /**
585
         * Sets the y coordinate of the path segment.
586
         */
587
        public void setY(float v) {
588
            y = v;
589
        }
590

  
591
        /**
592
         * Returns the length of the path segment.
593
         */
594
        public float getLength() {
595
            return length;
596
        }
597

  
598
        /**
599
         * Sets the length of the path segment.
600
         */
601
        public void setLength(float v) {
602
            length = v;
603
        }
604

  
605
        /**
606
         * Returns the segment index.
607
         */
608
        public int getIndex() {
609
            return index;
610
        }
611

  
612
        /**
613
         * Sets the segment index.
614
         */
615
        public void setIndex(int v) {
616
            index = v;
617
        }
618
    }
619
}
trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.symbology/org.gvsig.symbology.lib/org.gvsig.symbology.lib.api/src/main/java/org/gvsig/symbology/PathLength.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.symbology;
25

  
26
import java.awt.geom.Point2D;
27

  
28

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff