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 |
} |