Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / rendering / styling / PolygonPlacementConstraints.java @ 13606

History | View | Annotate | Download (7.18 KB)

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

    
42
/* CVS MESSAGES:
43
*
44
* $Id: PolygonPlacementConstraints.java 13606 2007-09-10 15:47:11Z jaume $
45
* $Log$
46
* Revision 1.11  2007-09-10 15:47:11  jaume
47
* *** empty log message ***
48
*
49
* Revision 1.10  2007/07/18 06:54:34  jaume
50
* continuing with cartographic support
51
*
52
* Revision 1.9  2007/04/26 11:41:00  jaume
53
* attempting to let defining size in world units
54
*
55
* Revision 1.8  2007/04/19 14:21:30  jaume
56
* *** empty log message ***
57
*
58
* Revision 1.7  2007/04/18 15:35:11  jaume
59
* *** empty log message ***
60
*
61
* Revision 1.6  2007/04/13 11:59:30  jaume
62
* *** empty log message ***
63
*
64
* Revision 1.5  2007/04/12 14:28:43  jaume
65
* basic labeling support for lines
66
*
67
* Revision 1.4  2007/04/11 16:01:08  jaume
68
* maybe a label placer refactor
69
*
70
* Revision 1.3  2007/04/02 16:34:56  jaume
71
* Styled labeling (start commiting)
72
*
73
* Revision 1.2  2007/03/09 08:33:43  jaume
74
* *** empty log message ***
75
*
76
* Revision 1.1.2.1  2007/02/21 07:34:08  jaume
77
* labeling starts working
78
*
79
*
80
*/
81
package com.iver.cit.gvsig.fmap.rendering.styling;
82

    
83
import java.awt.Graphics2D;
84
import java.awt.Rectangle;
85
import java.awt.geom.AffineTransform;
86
import java.awt.geom.PathIterator;
87
import java.awt.geom.Point2D;
88
import java.util.Vector;
89
import java.util.logging.Level;
90
import java.util.logging.Logger;
91

    
92
import org.cresques.px.gml.MultiPolygon;
93

    
94
import com.iver.cit.gvsig.fmap.core.FPoint2D;
95
import com.iver.cit.gvsig.fmap.core.FShape;
96
import com.iver.cit.gvsig.fmap.core.IGeometry;
97
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
98
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
99
import com.iver.utiles.XMLEntity;
100
import com.vividsolutions.jts.geom.Geometry;
101
import com.vividsolutions.jts.geom.Point;
102
/**
103
 *
104
 * @author jaume dominguez faus - jaume.dominguez@iver.es
105
 *
106
 */
107
public class PolygonPlacementConstraints extends AbstractPlacementConstraints {
108
        private static final double HALF_PI = Math.PI * 0.5;
109
        public PolygonPlacementConstraints() {
110
                setPlacementMode(HORIZONTAL);
111
        }
112

    
113
        public FShape[] getLocationsFor(IGeometry geom, FShape labelShape, MultiPolygon exclusionZone) {
114
                // TODO Implement it
115
                throw new Error("Not yet implemented!");
116

    
117
        }
118

    
119
        public void placeLabel(Graphics2D g, IGeometry geom, LabelClass lc, MultiPolygon exclusionZone, AffineTransform transform) {
120
                Rectangle labelBounds = lc.getShape(g, transform, geom).getBounds();
121
                double theta = 0;
122
                Geometry geo = FConverter.java2d_to_jts((FShape) geom.getInternalShape());
123

    
124
                if (geo == null) {
125
                        return;
126
                }
127

    
128
                Point pJTS = geo.getCentroid();
129

    
130
                if (pJTS == null) {
131
                        Logger.getAnonymousLogger().log(Level.SEVERE, "no centroid could be found");
132
                        return;
133
                }
134

    
135
                FPoint2D startingPoint = new FPoint2D(pJTS.getX(), pJTS.getY());
136
                if (isHorizontal()) {
137

    
138
                } else if (isParallel()) {
139
                        // calculated with the Linear Regression technique
140
                        PathIterator pi = geom.getPathIterator(transform);
141
                        geom.transform(transform);
142
                        Rectangle geomBounds =geom.getBounds();
143
                        double sumx = 0, sumy = 0, sumxx = 0, sumyy = 0, sumxy = 0;
144
                        double Sxx, Sxy, b, a;
145
                        double[] coords = new double[6];
146
                        int count = 0;
147

    
148
                        // add points to the regression process
149
                        Vector v = new Vector();
150
                        while (!pi.isDone()) {
151
                                pi.currentSegment(coords);
152
                                Point2D p;
153
                                if (geomBounds.width > geomBounds.height)
154
                                        p = new Point2D.Double(coords[0], coords[1]);
155
                                else
156
                                        p = new Point2D.Double(coords[1], coords[0]);
157
                                v.addElement(p);
158
                                count++;
159
                                sumx += p.getX();
160
                                sumy += p.getY();
161
                                sumxx += p.getX()*p.getX();
162
                                sumyy += p.getY()*p.getY();
163
                                sumxy += p.getX()*p.getY();
164
                                pi.next();
165
                        }
166

    
167
                        // start regression
168
                        double n = (double) count;
169
                        Sxx = sumxx-sumx*sumx/n;
170
                        Sxy = sumxy-sumx*sumy/n;
171
                        b = Sxy/Sxx;
172
                        a = (sumy-b*sumx)/n;
173

    
174
                        boolean isVertical = false;
175
                        if (geomBounds.width < geomBounds.height) {
176
                                if (b == 0) {
177
                                        // force vertical (to avoid divide by zero)
178
                                        isVertical = true;
179

    
180
                                } else {
181
                                        // swap axes
182
                                        double bAux = 1/b;
183
                                        a = - a / b;
184
                                        b = bAux;
185
                                }
186
                        }
187

    
188
                        if (isVertical){
189
                                theta = HALF_PI;
190
                        } else {
191
                                double p1x = 0;
192
                                double  p1y =geomBounds.height-a;
193
                                double  p2x = geomBounds.width;
194
                                double  p2y = geomBounds.height-
195
                                (a+geomBounds.width*b);
196

    
197
                                theta = -Math.atan(((p2y - p1y) / (p2x - p1x)) );
198
                        }
199

    
200

    
201
//                        } else {
202
//                        int minx = 0, miny = 0, maxx = 0, maxy = 0;
203
//                        while (!pi.isDone()) {
204
//                        pi.currentSegment(coords);
205
//                        FPoint2D p = new FPoint2D(coords[0], coords[1]);
206
//                        if (coords[0] < geomBounds.width /2) {
207
//                        minx += coords[0] % geomBounds.width;
208
//                        } else {
209
//                        maxx += coords[0] %geomBounds.width;
210
//                        }
211
//
212
//                        if (coords[1] < geomBounds.height/2) {
213
//                        miny += coords[1] %geomBounds.height;
214
//                        } else {
215
//                        maxy += coords[1] %geomBounds.height;
216
//                        }
217
//
218
//                        g.drawRect((int) coords[0], (int) coords[1], 1, 1);
219
//                        pi.next();
220
//                        count++;
221
//                        }
222
//
223
//                        if (count >0) {
224
//                        minx /= count;
225
//                        miny /= count;
226
//                        maxx /= count;
227
//                        maxy /= count;
228
//
229
//                        theta = -Math.atan(((maxy - miny) / (maxx - minx)) );
230
//                        System.err.println("("+minx+","+miny+","+maxx+","+maxy+")");
231
//                        g.setColor(Color.RED);
232
//                        g.drawRect((int) (maxx + geomBounds.x), (int) (maxy + geomBounds.y), 1,1);
233
//                        g.setColor(Color.BLUE);
234
//                        g.drawRect((int) minx + geomBounds.x, (int) miny + geomBounds.y, 1,1);
235
//                        }
236
//                        }
237
                }
238
                startingPoint.transform(transform);
239
                // center the label TODO change this
240
                labelBounds.setLocation(0-(int) (labelBounds.width*.5), 0 - (int) (labelBounds.height*.5));
241
                g.translate((int) startingPoint.getX(), (int) startingPoint.getY());
242
                if (theta != 0) {
243
                        g.rotate(theta);
244
                }
245
                lc.drawInsideRectangle(g, labelBounds);
246
                if (theta != 0) {
247
                        g.rotate(-theta);
248
                }
249
                g.translate(-(int) startingPoint.getX(), -(int) startingPoint.getY());
250

    
251
        }
252

    
253

    
254
        public String getClassName() {
255
                return getClass().getName();
256
        }
257

    
258
        public XMLEntity getXMLEntity() {
259
                XMLEntity xml = super.getXMLEntity();
260
                xml.putProperty("className", getClassName());
261
                return xml;
262
        }
263

    
264
        public void postprocess() {
265
                // TODO Auto-generated method stub
266
                throw new Error("Not yet implemented!");
267
        }
268

    
269
        public void preprocess(IFeatureIterator featIterator) {
270
                // TODO Auto-generated method stub
271
                throw new Error("Not yet implemented!");
272
        }
273

    
274
}