Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.labeling.app / org.gvsig.labeling.app.mainplugin / src / main / java / org / gvsig / labeling / placements / AbstractLinePlacement.java @ 43510

History | View | Annotate | Download (4.64 KB)

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

    
26
import java.awt.geom.Point2D;
27
import java.awt.geom.Rectangle2D;
28
import java.util.ArrayList;
29

    
30
import org.apache.batik.ext.awt.geom.PathLength;
31
import org.gvsig.fmap.geom.Geometry;
32
import org.gvsig.fmap.mapcontext.ViewPort;
33
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelClass;
34
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IPlacementConstraints;
35
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.LabelLocationMetrics;
36
import org.gvsig.tools.task.Cancellable;
37

    
38
public abstract class AbstractLinePlacement implements ILabelPlacement {
39
        public static final double PI = Math.PI;
40
        public static final double HALF_PI = PI * 0.5;
41
        private final ArrayList<LabelLocationMetrics> guessed =
42
                        new ArrayList<>();
43
        private static final double TOLERANCE = 1E-2;
44

    
45

    
46
    @Override
47
        public ArrayList<LabelLocationMetrics> guess(ILabelClass lc, Geometry geom,
48
                        IPlacementConstraints pc, double cartographicSymbolSize,
49
                        Cancellable cancel, ViewPort vp) {
50
                
51
                guessed.clear();
52

    
53
                Geometry shp = geom.cloneGeometry();
54
                shp.transform(vp.getAffineTransform());
55

    
56
                PathLength pathLen = new PathLength(shp);
57

    
58
                LabelLocationMetrics initial = initialLocation(lc, pc, pathLen, cancel);
59

    
60
                if (cancel.isCanceled()) {
61
            return CannotPlaceLabel.NO_PLACES;
62
        }
63

    
64
                double theta = initial.getRotation();
65

    
66

    
67
                double xOffset = 0;
68
                double yOffset = 0;
69
                Rectangle2D bounds = lc.getBounds();
70

    
71
                if (pc.isPageOriented()) {
72
                        if(theta >  HALF_PI) { // from origin to left-down
73
                                theta = (theta - Math.PI);
74

    
75
                                Point2D anchor = initial.getAnchor();
76

    
77
                                double cosTheta = Math.cos(theta);
78
                                double sinTheta = Math.sin(theta);
79
                                double width = bounds.getWidth();
80
                                double height = bounds.getHeight()*1.1;
81
                initial.getAnchor().setLocation(
82
                    anchor.getX() - cosTheta*width + sinTheta*height,
83
                    anchor.getY() - sinTheta*width - cosTheta*height);
84
                        } else if (theta < -HALF_PI ) { // from origin to left-up
85
                            /*
86
                                if (Math.abs(Math.abs(theta) - HALF_PI) -TOLERANCE > 0)
87
                                        // the condition avoids errors when segment is almost up-down vertical
88
                                {
89
                                */
90
                                        theta = (theta + Math.PI);
91
                                        Point2D anchor = initial.getAnchor();
92
                                        double cosTheta = Math.cos(theta);
93
                                        double sinTheta = Math.sin(theta);
94
                                        double width = bounds.getWidth();
95
                                        double height = bounds.getHeight()*1.1;
96
                                        initial.getAnchor().setLocation(
97
                                                        anchor.getX() - cosTheta*width + sinTheta*height,
98
                                                        anchor.getY() - sinTheta*width - cosTheta*height);
99
                                                        
100
                                // }
101
                        }
102

    
103

    
104
                }
105

    
106
                if (pc.isBelowTheLine() ||
107
                                pc.isOnTheLine() ||
108
                                pc.isAboveTheLine()) {
109

    
110
                        double h = bounds.getHeight()*0.5;
111

    
112
                        xOffset += h * Math.sin(theta);
113
                        yOffset += h * Math.cos(theta);
114

    
115

    
116
                        Point2D initialAnchor = initial.getAnchor();
117
                        // calculate the possibles in the inverse
118
                        // order to the preferred order and add it
119
                        // always in the first position
120
                        if (pc.isBelowTheLine()) {
121
                                Point2D anchor = new Point2D.Double(
122
                                                initialAnchor.getX() +        -xOffset,
123
                                                initialAnchor.getY() +        +yOffset);
124
                                guessed.add(0, new LabelLocationMetrics(anchor, theta, false));
125
                        }
126

    
127
                        if (pc.isOnTheLine()) {
128
                                guessed.add(0, new LabelLocationMetrics(initial.getAnchor(), theta, false));
129
                        }
130

    
131
                        if (pc.isAboveTheLine()) {
132
                                Point2D anchor = new Point2D.Double(
133
                                                initialAnchor.getX() +        +xOffset,
134
                                                initialAnchor.getY() +  -yOffset);
135
                                guessed.add(0, new LabelLocationMetrics(anchor, theta, false));
136
                        }
137
                } else {
138
                        // will say that on the line is legal
139
                        guessed.add(0, initial);
140
                }
141
                return guessed;
142
        }
143

    
144
        abstract LabelLocationMetrics initialLocation(
145
                        ILabelClass lc, IPlacementConstraints pc,
146
                        PathLength pathLen, Cancellable cancel);
147

    
148
}