Revision 40673

View differences:

trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.labeling.app/org.gvsig.labeling.app.mainplugin/src/main/java/org/gvsig/labeling/placements/PlacementManager.java
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
package org.gvsig.labeling.placements;
42

  
43
import java.util.ArrayList;
44
import java.util.Iterator;
45

  
46
import org.apache.log4j.Logger;
47
import org.gvsig.symbology.fmap.labeling.placements.CannotPlaceLabel;
48
import org.gvsig.symbology.fmap.labeling.placements.CompoundLabelPlacement;
49
import org.gvsig.symbology.fmap.labeling.placements.ILabelPlacement;
50
import org.gvsig.symbology.fmap.labeling.placements.LinePlacementConstraints;
51
import org.gvsig.symbology.fmap.labeling.placements.MultiShapePlacement;
52
import org.gvsig.symbology.fmap.labeling.placements.MultiShapePlacementConstraints;
53
import org.gvsig.symbology.fmap.labeling.placements.PointPlacementConstraints;
54
import org.gvsig.symbology.fmap.labeling.placements.PolygonPlacementConstraints;
55

  
56
import com.hardcode.gdbms.engine.data.driver.DriverException;
57
import com.iver.cit.gvsig.fmap.core.FShape;
58
import com.iver.cit.gvsig.fmap.rendering.styling.labeling.IPlacementConstraints;
59
import com.iver.utiles.IPersistence;
60
import com.iver.utiles.NotExistInXMLEntity;
61
import com.iver.utiles.XMLEntity;
62

  
63
/**
64
 *
65
 * PlacementManager.java
66
 *
67
 *
68
 * @author jaume dominguez faus - jaume.dominguez@iver.es Jan 3, 2008
69
 *
70
 */
71
public class PlacementManager {
72
	private static Logger logger = Logger.getLogger(PlacementManager.class.getName());
73
	private static ArrayList<Class<?>> installedLabelPlacements = new ArrayList<Class<?>>();
74
	private static ArrayList<ILabelPlacement> availableLabelPlacements;
75
	private static final CannotPlaceLabel cantPlaceLabel = new CannotPlaceLabel();
76
	private PlacementManager() {}
77

  
78
	public static ILabelPlacement getPlacement(IPlacementConstraints placementConstraints, int shapeType) {
79

  
80
		ArrayList<ILabelPlacement> suitablePlacements = new ArrayList<ILabelPlacement>();
81
		if (placementConstraints.getClass().equals(MultiShapePlacementConstraints.class)) {
82
			MultiShapePlacementConstraints msp = (MultiShapePlacementConstraints) placementConstraints;
83

  
84
			return new MultiShapePlacement(
85
					getPlacement(msp.getPointConstraints(),   FShape.POINT),
86
					getPlacement(msp.getLineConstraints(),    FShape.LINE),
87
					getPlacement(msp.getPolygonConstraints(), FShape.POLYGON)
88
					);
89
		} else {
90
			for (Iterator<ILabelPlacement> iterator = getAvailablePlacements().iterator(); iterator.hasNext();) {
91
				ILabelPlacement placement = iterator.next();
92
				if (placement.isSuitableFor(placementConstraints, shapeType)) {
93
					suitablePlacements.add(placement);
94
				}
95
			}
96

  
97
			if (suitablePlacements.size() == 0)
98
				return cantPlaceLabel;
99
			else if (suitablePlacements.size() == 1)
100
				return suitablePlacements.get(0);
101
			else
102
				return new CompoundLabelPlacement(
103
						(ILabelPlacement[]) suitablePlacements.
104
						toArray(new ILabelPlacement[suitablePlacements.size()]));
105

  
106
		}
107

  
108
	}
109

  
110
	public static void addLabelPlacement(Class<?> labelPlacementClass) {
111
//		if (!labelPlacementClass.isInstance(ILabelPlacement.class))
112
//		throw new IllegalArgumentException(
113
//			labelPlacementClass.getName()+" is not an valid label placement algorithm.");
114
		installedLabelPlacements.add(labelPlacementClass);
115

  
116
		// invalidate current list of available placements
117
		if (availableLabelPlacements != null)
118
			availableLabelPlacements.clear();
119
		availableLabelPlacements = null;
120
	}
121

  
122
	private static ArrayList<ILabelPlacement> getAvailablePlacements() {
123
		if (availableLabelPlacements == null) {
124
			availableLabelPlacements = new ArrayList<ILabelPlacement>(installedLabelPlacements.size());
125
			for (Iterator<Class<?>> iterator = installedLabelPlacements.iterator(); iterator.hasNext();) {
126
				Class<?> clazz = null;
127
				try {
128
					clazz = iterator.next();
129
					availableLabelPlacements.add((ILabelPlacement) clazz.newInstance());
130
				} catch (Exception e) {
131
					Logger.getLogger(PlacementManager.class).error("couldn't install label placement '"+clazz.getName(), e);
132
				}
133
			}
134
		}
135

  
136
		return availableLabelPlacements;
137
	}
138

  
139

  
140
	/**
141
	 * Creates a new instance of placement constraints from a vector layer. The
142
	 * placement constraints are created according the layer shape type.
143
	 * @param layerDest
144
	 * @return
145
	 * @throws DriverException
146
	 */
147
	public static IPlacementConstraints createPlacementConstraints(int shapeType) {
148
		switch (shapeType % FShape.Z) {
149
		case FShape.LINE:
150
			return new LinePlacementConstraints();
151
		case FShape.POLYGON:
152
			return new PolygonPlacementConstraints();
153
		case FShape.POINT:
154
		case FShape.MULTIPOINT: // TODO (09/01/08) is this correct??? if not fix it also in PlacementProperties (twice), , MarkerPlacementAroundPoint
155
			return new PointPlacementConstraints();
156
		case FShape.MULTI:
157
			return new MultiShapePlacementConstraints(
158
					createPlacementConstraints(FShape.POINT),
159
					createPlacementConstraints(FShape.LINE),
160
					createPlacementConstraints(FShape.POLYGON));
161
		}
162
		throw new Error("Shape type not yet supported");
163
//		return null;
164
	}
165

  
166
	public static IPlacementConstraints createPlacementConstraints(XMLEntity entity) {
167
		String className = null;
168
		try {
169
			className = entity.getStringProperty("className");
170
		} catch (NotExistInXMLEntity e) {
171
			logger.error("Symbol class name not set.\n" +
172
					" Maybe you forgot to add the" +
173
					" putProperty(\"className\", yourClassName)" +
174
					" call in the getXMLEntity method of your symbol", e);
175
		}
176

  
177

  
178
		Class clazz = null;
179
		Object obj = null;
180
		try {
181
			clazz = Class.forName(className);
182
			obj = clazz.newInstance();
183
			((IPersistence) obj).setXMLEntity(entity);
184

  
185
		} catch (InstantiationException e) {
186
			logger.error("Trying to instantiate an interface" +
187
					" or abstract class + "+className+"\n"+e.getMessage(), e);
188
		} catch (IllegalAccessException e) {
189
			logger.error(null, e);
190
		} catch (ClassNotFoundException e) {
191
			logger.error("No class called " + className +
192
					" was found.\nCheck the following.\n<br>" +
193
					"\t- The fullname of the class you're looking " +
194
					"for matches the value in the className " +
195
					"property of the XMLEntity ("+className+").\n<br>" +
196
					"\t- The jar file containing your symbol class is in" +
197
					"the application classpath<br>", e);
198
		}
199
		return (IPlacementConstraints) obj;
200
	}
201

  
202
}
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.labeling.app/org.gvsig.labeling.app.mainplugin/src/main/java/org/gvsig/labeling/placements/LinePlacementConstraints.java
80 80
*/
81 81
package org.gvsig.labeling.placements;
82 82

  
83
import com.iver.cit.gvsig.fmap.rendering.styling.labeling.IPlacementConstraints;
84
import com.iver.utiles.XMLEntity;
83
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IPlacementConstraints;
84

  
85 85
/**
86 86
 *
87 87
 * @author jaume dominguez faus - jaume.dominguez@iver.es
......
98 98
		setPageOriented(false);
99 99
	}
100 100

  
101
	public String getClassName() {
102
		return getClass().getName();
103
	}
104 101

  
105
	public XMLEntity getXMLEntity() {
106
		XMLEntity xml = super.getXMLEntity();
107
		xml.putProperty("className", getClassName());
108
		return xml;
109
	}
110

  
111

  
112
//	private TextPath getTreePath(Integer index, Graphics2D g, FShape shp, char[] text) {
113
//		TextPath tp = (TextPath) textPaths.get(index);
114
//		if (tp == null) {
115
//			tp = new TextPath(g, shp, text);
116
//			textPaths.put(index, tp);
117
//		}
118
//		return tp;
119
//	}
120 102
}
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.labeling.app/org.gvsig.labeling.app.mainplugin/src/main/java/org/gvsig/labeling/placements/PolygonPlacementConstraints.java
80 80
*/
81 81
package org.gvsig.labeling.placements;
82 82

  
83
import com.iver.utiles.XMLEntity;
84 83
/**
85 84
 *
86 85
 * @author jaume dominguez faus - jaume.dominguez@iver.es
......
91 90
		setPlacementMode(HORIZONTAL);
92 91
	}
93 92

  
94
	public String getClassName() {
95
		return getClass().getName();
96
	}
97 93

  
98
	public XMLEntity getXMLEntity() {
99
		XMLEntity xml = super.getXMLEntity();
100
		xml.putProperty("className", getClassName());
101
		return xml;
102
	}
103 94

  
104 95
}
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.labeling.app/org.gvsig.labeling.app.mainplugin/src/main/java/org/gvsig/labeling/symbol/SmartTextSymbol.java
1
package org.gvsig.labeling.symbol;
2

  
3
import java.awt.BasicStroke;
4
import java.awt.BorderLayout;
5
import java.awt.Color;
6
import java.awt.Dimension;
7
import java.awt.Font;
8
import java.awt.Graphics;
9
import java.awt.Graphics2D;
10
import java.awt.Rectangle;
11
import java.awt.Shape;
12
import java.awt.Stroke;
13
import java.awt.event.ActionEvent;
14
import java.awt.event.ActionListener;
15
import java.awt.font.FontRenderContext;
16
import java.awt.font.GlyphVector;
17
import java.awt.font.LineMetrics;
18
import java.awt.geom.AffineTransform;
19
import java.util.ArrayList;
20

  
21
import javax.print.attribute.PrintRequestAttributeSet;
22
import javax.swing.JCheckBox;
23
import javax.swing.JFrame;
24
import javax.swing.JPanel;
25
import javax.swing.JTextField;
26

  
27
import org.gvsig.compat.print.PrintAttributes;
28
import org.gvsig.fmap.dal.feature.Feature;
29
import org.gvsig.fmap.geom.Geometry;
30
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
31
import org.gvsig.fmap.geom.GeometryLocator;
32
import org.gvsig.fmap.geom.GeometryManager;
33
import org.gvsig.fmap.geom.Geometry.TYPES;
34
import org.gvsig.fmap.geom.exception.CreateGeometryException;
35
import org.gvsig.fmap.geom.primitive.Curve;
36
import org.gvsig.fmap.geom.primitive.Point;
37
import org.gvsig.fmap.geom.primitive.Surface;
38
import org.gvsig.fmap.mapcontext.ViewPort;
39
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IPlacementConstraints;
40
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
41
import org.gvsig.fmap.mapcontext.rendering.symbols.ITextSymbol;
42
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
43
import org.gvsig.gui.beans.swing.GridBagLayoutPanel;
44
import org.gvsig.gui.beans.swing.JComboBoxFonts;
45
import org.gvsig.gui.beans.swing.JIncrementalNumberField;
46
import org.gvsig.labeling.placements.PointPlacementConstraints;
47
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.TextPath;
48
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
49
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.CartographicSupportToolkit;
50
import org.gvsig.tools.persistence.PersistentState;
51
import org.gvsig.tools.persistence.exception.PersistenceException;
52
import org.gvsig.tools.task.Cancellable;
53
import org.slf4j.Logger;
54
import org.slf4j.LoggerFactory;
55

  
56

  
57
/**
58
 * Class used to create symbols composed using a text defined by
59
 * the user.This text can be edited (changing the color, the font of the characters, and
60
 * the rotation of the text)and has the property that can follow a path.If this path
61
 * does not exist, the text is treated as a simpletextsymbol (when is drawn).
62
 * @author   jaume dominguez faus - jaume.dominguez@iver.es
63
 */
64
public class SmartTextSymbol implements ITextSymbol {
65
	
66
	private static final Logger logger = LoggerFactory.getLogger(
67
			SmartTextSymbol.class);
68
	
69
	public static final int SYMBOL_STYLE_TEXTALIGNMENT_LEFT = 0;
70
	public static final int SYMBOL_STYLE_TEXTALIGNMENT_RIGHT = 1;
71
	public static final int SYMBOL_STYLE_TEXTALIGNMENT_CENTERED = 2;
72

  
73
	// ===========================
74
	private static GeometryManager geoman = GeometryLocator.getGeometryManager();
75
	
76
	private char[] charText;
77
//	Background: ITextBackground
78
//	Case
79
	private double characterSpacing;
80
	private double characterWidth;
81
//	Direction
82
	private IFillSymbol fillSymbol;
83
	private double flipAngle;
84
//	boolean kerning;
85
	private double leading;
86
//	Position: textPosition
87
	private Color ShadowColor;
88
	private double ShadowXOffset;
89
	private double ShadowYOffset;
90
//	TypeSetting: Boolean
91
	private double wordSpacing;
92
//	ISimpleTextSymbol : ITextSymbol
93
//	BreakCharacter: Long
94
//	Clip: Boolean
95
	private TextPath textPath;
96
	private double xOffset;
97
	private double yOffset;
98
	private double angle;
99
//	Color: IColor
100

  
101
//	HorizontalAlignment:
102
//	esriTextHorizontalAlignment
103
	private boolean rightToLeft;
104
	//	VerticalAlignment
105
	private double maskSize;
106
//	MaskStyle
107
	private  IFillSymbol maskSymbol;
108
	private double margin;
109
	private int alignment;
110
	private boolean kerning = false;
111
	private TextPath tp;
112
	private IPlacementConstraints constraints;
113
	
114
	private boolean shapeVisible = true;
115
	private int unit = CartographicSupportToolkit.DefaultMeasureUnit;
116
	private int referenceSystem = CartographicSupportToolkit.DefaultReferenceSystem;
117
	private double rotation = 0;
118
	
119
	// =======================
120
	private Surface auxSurface = null;
121
	
122

  
123
	public SmartTextSymbol(ITextSymbol sym, IPlacementConstraints constraints) {
124

  
125
//		if(sym instanceof SimpleTextSymbol){
126
//			SimpleTextSymbol mySym = (SimpleTextSymbol)sym;
127

  
128
			this.setAutoresizeEnabled(sym.isAutoresizeEnabled());
129
			this.setDescription(sym.getDescription());
130
			this.setFont(sym.getFont());
131
			this.setFontSize(sym.getFont().getSize());
132
			this.setIsShapeVisible(sym.isShapeVisible());
133
			this.setText(sym.getText());
134
			this.setTextColor(sym.getTextColor());
135
			this.constraints = constraints;
136

  
137
			setCharacterSpacing(2); //???
138
			setWordSpacing(TextPath.DEFAULT_WORD_SPACING);
139
			boolean rtl = false; // right to left text
140
			if (constraints.isAtTheBeginingOfLine()) {
141
				if (rtl) {
142
					setAlignment(SYMBOL_STYLE_TEXTALIGNMENT_RIGHT);
143
				}
144
				else {
145
					setAlignment(SYMBOL_STYLE_TEXTALIGNMENT_LEFT);
146
				}
147
			}
148
			else if (constraints.isAtTheEndOfLine()) {
149
				if (rtl) {
150
					setAlignment(SYMBOL_STYLE_TEXTALIGNMENT_LEFT);
151
				}
152
				else {
153
					setAlignment(SYMBOL_STYLE_TEXTALIGNMENT_RIGHT);
154
				}
155
			}
156
			else { //constraints.isInTheMiddleOfLine() or constraints.isAtBestOfLine()
157
				setAlignment(SYMBOL_STYLE_TEXTALIGNMENT_CENTERED);
158
			}
159
			setKerning(false);
160
			setRightToLeft(rtl);
161
		// }
162
	}
163
	
164
	
165
	public void setIsShapeVisible(boolean v) {
166
		this.shapeVisible = v;
167
	}
168
	
169
	public boolean isShapeVisible() {
170
		return shapeVisible;
171
	}
172
	
173

  
174

  
175
	public SmartTextSymbol() {
176
		PointPlacementConstraints pc = new PointPlacementConstraints();
177
		this.constraints = pc;
178
		
179
	}
180

  
181
	/**
182
	 * Draws the text according. If this symbol has the text path set, then
183
	 * it is used as the text line, otherwise shp <b>must be an FPoint2D</b>
184
	 * indicating the starting point of the text and then the text will
185
	 * be rendered from there and following the rotation previously set.
186
	 */
187
	
188
	public void draw(Graphics2D g, AffineTransform affineTransform,
189
			Geometry geom, Feature f, Cancellable cancel) {
190
	
191
		if (!isShapeVisible()) return;
192

  
193
		setMargin(0);
194

  
195

  
196
		tp = new TextPath(g, geom, charText, getFont(),
197
				(float) characterSpacing, (float) characterWidth, kerning,
198
				(float) leading, alignment, (float) wordSpacing, (float) margin, rightToLeft);
199
		Font font = getFont();
200
		g.setFont(font);
201
		FontRenderContext frc = g.getFontRenderContext();
202
		LineMetrics lineMetrics = font.getLineMetrics(getText(), frc);
203
		
204
//		GlyphVector glyph =  font.layoutGlyphVector(frc, charText, 0, charText.length, Font.LAYOUT_NO_START_CONTEXT);
205
		double cons = 0;
206

  
207
		/* Repartimos el leading (espacio de separaci?n entre lineas)
208
		 * arriba y abajo para que exista la misma separaci?n entre la
209
		 * caja de la letra y la linea tanto si se dibuja por abajo como
210
		 * si se dibuja por arriba. 
211
		 */
212
		if(this.constraints.isAboveTheLine()) {
213
			cons = lineMetrics.getDescent()+lineMetrics.getLeading()/2;
214
		}
215
		else if (this.constraints.isBelowTheLine()) {
216
			cons = -(lineMetrics.getAscent()+lineMetrics.getLeading()/2);
217
		}
218
		/* Dibujamos la letra de tal manera que el centro de la caja de letra
219
		 * coincida con la linea
220
		 */
221
		else if(this.constraints.isOnTheLine()) {
222
//			cons = lineMetrics.getDescent()+(lineMetrics.getLeading()/2)-(lineMetrics.getHeight()/2);
223
			cons = lineMetrics.getDescent()+lineMetrics.getLeading()-(lineMetrics.getHeight()/2);
224
		}
225
		
226
		double[] coords = tp.nextPosForGlyph(0);
227
		Stroke haloStroke = new BasicStroke(getHaloWidth(), BasicStroke.CAP_ROUND,
228
                BasicStroke.JOIN_ROUND);
229

  
230
		for (int i = 0; i < tp.getGlyphCount(); i++) {
231
			coords = tp.nextPosForGlyph(i);
232
			if (coords[0] == TextPath.NO_POS || coords[1] == TextPath.NO_POS)
233
				continue;
234

  
235
			// move the label 'cons" units above/below the line
236
			double xOffset = cons * Math.sin(coords[2]);
237
			double yOffset = cons * Math.cos(coords[2]);
238

  
239
			g.translate(coords[0]+xOffset, coords[1]-yOffset);
240
			g.rotate(coords[2]);
241

  
242
			char[] aux = new char[1];
243
			aux[0] = charText[i];
244
			if (isDrawWithHalo()) {
245
				GlyphVector glyph = font.createGlyphVector(frc, aux);
246
				Shape outlineChar = glyph.getOutline();
247
				g.setStroke(haloStroke);
248
				g.setColor(getHaloColor());
249
				g.draw(outlineChar);
250
			}
251
			
252
			g.setColor(this.getTextColor());
253
			g.drawString(String.valueOf(charText[i]), 0, 0);
254
			g.rotate(-coords[2]);
255
			g.translate(-coords[0]-xOffset, -coords[1]+yOffset);
256
		}
257
	}
258

  
259
	public void getPixExtentPlus(
260
			Geometry shp, float[] distances, ViewPort viewPort, int dpi) {
261
		// TODO Implement it
262
		throw new RuntimeException("Not yet implemented!");
263
	}
264

  
265
	public int getOnePointRgb() {
266
		return getTextColor().getRGB();
267
	}
268

  
269
	/*
270
	public XMLEntity getXMLEntity() {
271
		XMLEntity xml = new XMLEntity();
272
		xml.putProperty("className", getClassName());
273
		xml.putProperty("desc", getDescription());
274
		xml.putProperty("isShapeVisible", isShapeVisible());
275
		return xml;
276
	}
277
	*/
278

  
279
	public int getSymbolType() {
280
		return Geometry.TYPES.GEOMETRY;
281
	}
282

  
283
	public boolean isSuitableFor(Geometry geom) {
284
		return geom.getGeometryType().isTypeOf(TYPES.CURVE);
285
	}
286
	
287
	public void drawInsideRectangle(
288
			Graphics2D g,
289
			AffineTransform scaleInstance,
290
			Rectangle r,
291
			PrintAttributes properties) throws SymbolDrawingException {
292
		// let's take the bottom segment of the rectangle as the line
293
		
294
		Surface surf = null;
295
		try {
296
			surf = geoman.createSurface(SUBTYPES.GEOM2D);
297
		} catch (CreateGeometryException e) {
298
			logger.info("Error while creating surface.", e);
299
			throw new SymbolDrawingException(
300
					SymbolDrawingException.UNSUPPORTED_SET_OF_SETTINGS);
301
		}
302
		surf.addVertex(r.getX(), r.getY());
303
		surf.addVertex(r.getX() + r.getWidth(), r.getY());
304
		
305
		if (properties == null) {
306
			draw(g, scaleInstance, surf, null, null);
307
		} else {
308
			print(g, scaleInstance, surf, properties);
309
		}
310
	}
311

  
312

  
313
	/*
314
	public void setXMLEntity(XMLEntity xml) {
315
		setFont(new Font("Arial", Font.PLAIN, 18));
316
		setText("this is my TEST text that follows a line");
317
		setDescription(xml.getStringProperty("desc"));
318
		setIsShapeVisible(xml.getBooleanProperty("isShapeVisible"));
319

  
320
	}
321
	*/
322

  
323
	public void setText(String text) {
324
		this.charText = text.toCharArray();
325
	}
326

  
327
	public String getText() {
328
		return new String(charText);
329
	}
330

  
331
	public void setCharacterSpacing(double charSpacing) {
332
		this.characterSpacing = charSpacing;
333
	}
334

  
335
	public void setWordSpacing(double wordSpacing) {
336
		this.wordSpacing = wordSpacing;
337
	}
338

  
339
	public void setAlignment(int alignment) {
340
		this.alignment = alignment;
341
	}
342

  
343
	public void setKerning(boolean kerning) {
344
		this.kerning = kerning;
345
	}
346

  
347
	public void setMargin(double margin) {
348
		this.margin = margin;
349
	}
350

  
351
	public void setRightToLeft(boolean rightToLeft) {
352
		this.rightToLeft = rightToLeft;
353
	}
354
	
355
	// ==============================================
356
	// ==============================================
357
	// ==============================================
358

  
359
	
360
	public ISymbol getSymbolForSelection() {
361
		// TODO Auto-generated method stub
362
		return null;
363
	}
364

  
365

  
366

  
367
	public boolean isOneDotOrPixel(Geometry geom,
368
			double[] positionOfDotOrPixel, ViewPort viewPort, int dpi) {
369
		// TODO Auto-generated method stub
370
		return false;
371
	}
372

  
373

  
374
	public String getDescription() {
375
		// TODO Auto-generated method stub
376
		return null;
377
	}
378

  
379

  
380
	public void setDescription(String desc) {
381
		// TODO Auto-generated method stub
382
		
383
	}
384

  
385

  
386
	public Color getColor() {
387
		// TODO Auto-generated method stub
388
		return null;
389
	}
390

  
391

  
392
	public void setColor(Color color) {
393
		// TODO Auto-generated method stub
394
		
395
	}
396

  
397

  
398
	public void loadFromState(PersistentState arg0) throws PersistenceException {
399
		// TODO Auto-generated method stub
400
		
401
	}
402

  
403

  
404
	public void saveToState(PersistentState arg0) throws PersistenceException {
405
		// TODO Auto-generated method stub
406
		
407
	}
408

  
409

  
410
	public void print(Graphics2D g, AffineTransform at, Geometry shape,
411
			PrintAttributes properties) {
412
		// TODO Auto-generated method stub
413
		
414
	}
415

  
416

  
417
	public void setFont(Font font) {
418
		// TODO Auto-generated method stub
419
		
420
	}
421

  
422

  
423
	public Font getFont() {
424
		// TODO Auto-generated method stub
425
		return null;
426
	}
427

  
428

  
429
	public Color getTextColor() {
430
		// TODO Auto-generated method stub
431
		return null;
432
	}
433

  
434

  
435
	public void setTextColor(Color color) {
436
		// TODO Auto-generated method stub
437
		
438
	}
439

  
440

  
441
	public void setFontSize(double d) {
442
		// TODO Auto-generated method stub
443
		
444
	}
445

  
446

  
447
	public Geometry getTextWrappingShape(Point p) {
448
		// TODO Auto-generated method stub
449
		return null;
450
	}
451

  
452

  
453
	public Rectangle getBounds() {
454
		// TODO Auto-generated method stub
455
		return null;
456
	}
457

  
458

  
459
	public void setAutoresizeEnabled(boolean autoresizeFlag) {
460
		// TODO Auto-generated method stub
461
		
462
	}
463

  
464

  
465
	public boolean isAutoresizeEnabled() {
466
		// TODO Auto-generated method stub
467
		return false;
468
	}
469

  
470

  
471
	public Color getHaloColor() {
472
		// TODO Auto-generated method stub
473
		return null;
474
	}
475

  
476

  
477
	public void setHaloColor(Color haloColor) {
478
		// TODO Auto-generated method stub
479
		
480
	}
481

  
482

  
483
	public float getHaloWidth() {
484
		// TODO Auto-generated method stub
485
		return 0;
486
	}
487

  
488

  
489
	public void setHaloWidth(float haloWidth) {
490
		// TODO Auto-generated method stub
491
		
492
	}
493

  
494

  
495
	public boolean isDrawWithHalo() {
496
		// TODO Auto-generated method stub
497
		return false;
498
	}
499

  
500

  
501
	public void setDrawWithHalo(boolean drawWithHalo) {
502
		// TODO Auto-generated method stub
503
		
504
	}
505
	
506
	// ========================
507
	
508
	public Object clone() throws CloneNotSupportedException {
509
		return this;
510
	}
511

  
512
}
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.labeling.app/org.gvsig.labeling.app.mainplugin/src/main/java/org/gvsig/labeling/symbol/SmartTextSymbolLabelClass.java
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
package org.gvsig.labeling.symbol;
42

  
43
import java.awt.Color;
44
import java.awt.Dimension;
45
import java.awt.Graphics2D;
46
import java.awt.Rectangle;
47
import java.awt.Shape;
48
import java.awt.geom.PathIterator;
49

  
50
import org.gvsig.symbology.fmap.symbols.SmartTextSymbol;
51

  
52
import com.iver.cit.gvsig.fmap.core.FPoint2D;
53
import com.iver.cit.gvsig.fmap.core.FShape;
54
import com.iver.cit.gvsig.fmap.core.styles.ILabelStyle;
55
import com.iver.cit.gvsig.fmap.core.symbols.ITextSymbol;
56
import com.iver.cit.gvsig.fmap.core.symbols.SymbolDrawingException;
57
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
58
import com.iver.cit.gvsig.fmap.rendering.styling.labeling.LabelClass;
59
import com.iver.cit.gvsig.fmap.rendering.styling.labeling.LabelLocationMetrics;
60
import com.iver.utiles.XMLEntity;
61

  
62
/**
63
 * <p>
64
 * SmartTextSymbolLabelClass.java<br>
65
 * </p>
66
 *
67
 * <p>
68
 *
69
 *   This is a <b>wrapper</b> to be able to use a SmartTextSymbol as a
70
 * LabelClass. A SmartTextSymbol uses a line instead of a point.
71
 * Being in fact a Line and not a Marker, it does not make any sense
72
 * to have label styles since the label styles are well-defined rectangle
73
 * areas where texts are placed in fields backgrounded by an image. In this
74
 * contexts, the area is defined dinamically for each line, and there is no
75
 * sense to have texts fields. They will be rendered as a single string
76
 * along a line.<br>
77
 * </p>
78
 * <p> The label itself is the SmartTextSymbol,
79
 * the geometry (the line), the label expression,
80
 * and the text applied to the symbol.<br>
81
 * </p>
82
 * <p>
83
 *   Most of the operations performed by this LabelClass are in fact
84
 * delegated to the symbol.<br>
85
 * </p>
86
 *
87
 *
88
 * @author jaume dominguez faus - jaume.dominguez@iver.es Mar 6, 2008
89
 *
90
 */
91
public class SmartTextSymbolLabelClass extends LabelClass {
92
	private SmartTextSymbol smartTextSymbol;
93

  
94
	@Override
95
	public void draw(Graphics2D graphics, LabelLocationMetrics llm, FShape shp) {
96

  
97
		getTextSymbol().draw(graphics, null, shp, null);
98

  
99

  
100
	}
101

  
102
	@Override
103
	public void drawInsideRectangle(Graphics2D graphics, Rectangle bounds)
104
			throws SymbolDrawingException {
105
		getTextSymbol().drawInsideRectangle(graphics, null, bounds, null);
106
	}
107

  
108

  
109
	@Override
110
	public String getClassName() {
111
		return getClass().getName();
112
	}
113

  
114
	@Override
115
	public ILabelStyle getLabelStyle() {
116
		// label style not allowed in this context
117
		return null;
118
	}
119

  
120

  
121
//	@Override
122
//	public FShape getShape(LabelLocationMetrics llm) {
123
//		// TODO Auto-generated method stub
124
//		throw new Error("Not yet implemented!");
125
//	}
126

  
127

  
128
	@Override
129
	public ITextSymbol getTextSymbol() {
130
		if (smartTextSymbol == null) {
131
			smartTextSymbol = new SmartTextSymbol();
132
		}
133
		return smartTextSymbol;
134
	}
135

  
136

  
137
	@Override
138
	public XMLEntity getXMLEntity() {
139
		XMLEntity xml = super.getXMLEntity();
140
		xml.putProperty("className", getClassName());
141
		return xml;
142
	}
143

  
144
	@Override
145
	public void setLabelStyle(ILabelStyle labelStyle) {
146
		// operation don't supported in this context
147
	}
148

  
149

  
150
	@Override
151
	public void setTextSymbol(ITextSymbol textSymbol) {
152
////		if (! (textSymbol instanceof SmartTextSymbol)) throw new IllegalArgumentException("Only SmartTextSymbol allowed in this context");
153
//		if (! (textSymbol instanceof SmartTextSymbol)) {
154
//			// transform it into a SmartTextSymbol
155
//			SmartTextSymbol aux = new SmartTextSymbol();
156
//			if (textSymbol != null) {
157
//				aux.setDescription(textSymbol.getDescription());
158
//				aux.setText(textSymbol.getText());
159
//				aux.setFont(textSymbol.getFont());
160
//				aux.setTextColor(textSymbol.getTextColor());
161
//				aux.setFontSize(textSymbol.getFont().getSize());
162
//
163
//			}
164
//			textSymbol = aux;
165
//		}
166
		this.smartTextSymbol = (SmartTextSymbol) textSymbol;
167
		super.setTextSymbol(textSymbol);
168
	}
169

  
170

  
171
}
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.labeling.app/org.gvsig.labeling.app.mainplugin/src/main/java/org/gvsig/labeling/parse/ITextParser.java
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: ITextParser.java 10671 2007-03-09 08:33:43Z jaume $
45
 * $Log$
46
 * Revision 1.2  2007-03-09 08:33:43  jaume
47
 * *** empty log message ***
48
 *
49
 * Revision 1.1.2.1  2007/02/09 07:47:05  jaume
50
 * Isymbol moved
51
 *
52
 *
53
 */
54
package org.gvsig.labeling.parse;
55

  
56
public interface ITextParser {
57
	public final String REGEX_FIELD = "[.+]";
58
	public final String REGEX_TAG_SEPARATOR = "[^\\],";
59

  
60
	/**
61
	 * Returns true if the label has at least one tag.
62
	 * 
63
	 * @return boolean
64
	 */
65
	public boolean hasTags();
66

  
67
	/**
68
	 * Returns the next text for the tag
69
	 */
70
	public String next();
71

  
72
}
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.labeling.app/org.gvsig.labeling.app.mainplugin/src/main/java/org/gvsig/labeling/ExtendedLabelingExtension.java
23 23
import org.gvsig.labeling.placements.LinePlacementInTheMiddle;
24 24
import org.gvsig.labeling.placements.MarkerPlacementAroundPoint;
25 25
import org.gvsig.labeling.placements.MarkerPlacementOnPoint;
26
import org.gvsig.labeling.placements.PlacementManager;
26 27
import org.gvsig.labeling.placements.PolygonPlacementInside;
27 28
import org.gvsig.labeling.placements.PolygonPlacementOnCentroid;
28 29
import org.gvsig.labeling.placements.PolygonPlacementParallel;
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.labeling.app/org.gvsig.labeling.app.mainplugin/src/main/java/org/gvsig/labeling/label/GeneralLabelingStrategy.java
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: GeneralLabelingStrategy.java 13749 2007-09-17 14:16:11Z jaume $
45
 * $Log$
46
 * Revision 1.2  2007-09-17 14:16:11  jaume
47
 * multilayer symbols sizing bug fixed
48
 *
49
 * Revision 1.1  2007/05/22 12:17:41  jaume
50
 * *** empty log message ***
51
 *
52
 * Revision 1.1  2007/05/22 10:05:31  jaume
53
 * *** empty log message ***
54
 *
55
 * Revision 1.10  2007/05/17 09:32:06  jaume
56
 * *** empty log message ***
57
 *
58
 * Revision 1.9  2007/05/09 11:04:58  jaume
59
 * refactored legend hierarchy
60
 *
61
 * Revision 1.8  2007/04/13 11:59:30  jaume
62
 * *** empty log message ***
63
 *
64
 * Revision 1.7  2007/04/12 14:28:43  jaume
65
 * basic labeling support for lines
66
 *
67
 * Revision 1.6  2007/04/11 16:01:08  jaume
68
 * maybe a label placer refactor
69
 *
70
 * Revision 1.5  2007/04/10 16:34:01  jaume
71
 * towards a styled labeling
72
 *
73
 * Revision 1.4  2007/04/02 16:34:56  jaume
74
 * Styled labeling (start commiting)
75
 *
76
 * Revision 1.3  2007/03/28 16:48:01  jaume
77
 * *** empty log message ***
78
 *
79
 * Revision 1.2  2007/03/26 14:40:38  jaume
80
 * added print method (BUT UNIMPLEMENTED)
81
 *
82
 * Revision 1.1  2007/03/20 16:16:20  jaume
83
 * refactored to use ISymbol instead of FSymbol
84
 *
85
 * Revision 1.2  2007/03/09 11:20:57  jaume
86
 * Advanced symbology (start committing)
87
 *
88
 * Revision 1.1  2007/03/09 08:33:43  jaume
89
 * *** empty log message ***
90
 *
91
 * Revision 1.1.2.5  2007/02/21 07:34:08  jaume
92
 * labeling starts working
93
 *
94
 * Revision 1.1.2.4  2007/02/15 16:23:44  jaume
95
 * *** empty log message ***
96
 *
97
 * Revision 1.1.2.3  2007/02/09 07:47:05  jaume
98
 * Isymbol moved
99
 *
100
 * Revision 1.1.2.2  2007/02/02 16:21:24  jaume
101
 * start commiting labeling stuff
102
 *
103
 * Revision 1.1.2.1  2007/02/01 17:46:49  jaume
104
 * *** empty log message ***
105
 *
106
 *
107
 */
108
package org.gvsig.labeling.label;
109

  
110
import java.awt.Graphics2D;
111
import java.awt.Shape;
112
import java.awt.geom.Point2D;
113
import java.awt.geom.Rectangle2D;
114
import java.awt.image.BufferedImage;
115
import java.io.StringReader;
116
import java.text.NumberFormat;
117
import java.util.ArrayList;
118
import java.util.Hashtable;
119
import java.util.Iterator;
120
import java.util.TreeMap;
121
import java.util.TreeSet;
122

  
123
import javax.print.attribute.PrintRequestAttributeSet;
124
import javax.print.attribute.standard.PrintQuality;
125

  
126
import org.gvsig.fmap.dal.exception.ReadException;
127
import org.gvsig.fmap.dal.feature.Feature;
128
import org.gvsig.fmap.dal.feature.FeatureSet;
129
import org.gvsig.fmap.geom.Geometry;
130
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
131
import org.gvsig.fmap.geom.GeometryLocator;
132
import org.gvsig.fmap.geom.Geometry.TYPES;
133
import org.gvsig.fmap.geom.GeometryManager;
134
import org.gvsig.fmap.geom.primitive.Envelope;
135
import org.gvsig.fmap.geom.primitive.Point;
136
import org.gvsig.fmap.geom.type.GeometryType;
137
import org.gvsig.fmap.mapcontext.ViewPort;
138
import org.gvsig.fmap.mapcontext.layers.FLayer;
139
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
140
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelClass;
141
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingMethod;
142
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
143
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IPlacementConstraints;
144
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IZoomConstraints;
145
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
146
import org.gvsig.i18n.Messages;
147
import org.gvsig.labeling.operations.Expression;
148
import org.gvsig.labeling.operations.ExpressionException;
149
import org.gvsig.labeling.parse.LabelExpressionParser;
150
import org.gvsig.labeling.placements.ILabelPlacement;
151
import org.gvsig.labeling.placements.LinePlacementConstraints;
152
import org.gvsig.labeling.placements.MultiShapePlacementConstraints;
153
import org.gvsig.labeling.placements.PlacementManager;
154
import org.gvsig.labeling.placements.PointPlacementConstraints;
155
import org.gvsig.labeling.placements.PolygonPlacementConstraints;
156
import org.gvsig.labeling.placements.RemoveDuplicatesComparator;
157
import org.gvsig.labeling.symbol.SmartTextSymbolLabelClass;
158
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.LabelLocationMetrics;
159
import org.gvsig.tools.dispose.DisposableIterator;
160
import org.gvsig.tools.task.Cancellable;
161
import org.slf4j.Logger;
162
import org.slf4j.LoggerFactory;
163

  
164
import com.vividsolutions.jts.geom.CoordinateSequence;
165
import com.vividsolutions.jts.geom.CoordinateSequences;
166
import com.vividsolutions.jts.geom.GeometryFactory;
167
import com.vividsolutions.jts.geom.LineString;
168
import com.vividsolutions.jts.geom.Lineal;
169

  
170
/**
171
 *
172
 * GeneralLabelingStrategy.java
173
 *
174
 *
175
 * @author jaume dominguez faus - jaume.dominguez@iver.es Jan 4, 2008
176
 *
177
 */
178
public class GeneralLabelingStrategy implements
179
ILabelingStrategy, Cloneable, CartographicSupport {
180
	
181
	private static final Logger logger = LoggerFactory.getLogger(
182
			GeneralLabelingStrategy.class);
183
	
184
	public static IPlacementConstraints DefaultPointPlacementConstraints =
185
			new PointPlacementConstraints();
186
	public static IPlacementConstraints DefaultLinePlacementConstraints =
187
			new LinePlacementConstraints();
188
	public static IPlacementConstraints DefaultPolygonPlacementConstraints =
189
			new PolygonPlacementConstraints();
190
	
191
	private static String[] NO_TEXT = { Messages.getText("text_field") };
192
	
193
	private static MultiShapePlacementConstraints DefaultMultiShapePlacementConstratints =
194
			new MultiShapePlacementConstraints();
195
	
196
	private ILabelingMethod method;
197
	private IPlacementConstraints placementConstraints;
198
	protected FLyrVect layer;
199
	private IZoomConstraints zoomConstraints;
200
	private boolean allowOverlapping;
201
	private long parseTime;
202
	private int unit;
203
	private int referenceSystem;
204
	private double sizeAfter;
205
	private boolean printMode = false; /* indicate whether output is for a print product (PDF, PS, ...) */
206

  
207
	public void setLayer(FLayer layer) {
208
		FLyrVect l = (FLyrVect) layer;
209
		this.layer = l;
210
	}
211

  
212
	public ILabelingMethod getLabelingMethod() {
213
		return method;
214
	}
215

  
216
	public void setLabelingMethod(ILabelingMethod method) {
217
		this.method = method;
218
	}
219

  
220
	private class GeometryItem{
221
		public Geometry geom = null;
222
		public int weigh = 0;
223
		public double savedPerimeter;
224

  
225
		public GeometryItem(Geometry geom, int weigh){
226
			this.geom = geom;
227
			this.weigh = weigh;
228
			this.savedPerimeter = 0;
229
		}
230
	}
231
	public void draw(BufferedImage mapImage, Graphics2D mapGraphics,
232
			ViewPort viewPort,
233
			Cancellable cancel,
234
			double dpi) throws ReadException {
235
		
236
		int x = (int)viewPort.getOffset().getX();
237
		int y = (int)viewPort.getOffset().getY();
238
//		boolean bVisualFXEnabled = false; // if true, the user can see how the labeling is drawing up
239

  
240
		//offsets for page generation (PDF, PS, direct printing)
241
		int print_offset_x = x;
242
		int print_offset_y = y;
243
		if (printMode) {
244
			//for printing, we never offset the labels themselves
245
			x = 0;
246
			y = 0;
247
			printMode = false;
248
		}		
249

  
250
		TreeMap<String[], GeometryItem> labelsToPlace = null;
251
		parseTime =0;
252
//		long t1 = System.currentTimeMillis();
253
		String[] usedFields = getUsedFields();
254

  
255
		int notPlacedCount = 0;
256
		int placedCount = 0;
257

  
258
		/*
259
		 * Get the label placement solvers according the user's settings
260
		 */
261
		ILabelPlacement placement = PlacementManager.getPlacement(
262
				getPlacementConstraints(), layer.getShapeType());
263

  
264

  
265
		BufferedImage targetBI;
266
		Graphics2D targetGr;
267

  
268

  
269
		/*
270
		 * get an ordered set of the LabelClasses up on the
271
		 * label priority
272
		 */
273
		ILabelClass[] lcs = method.getLabelClasses();
274
		TreeSet<ILabelClass> ts = new TreeSet<ILabelClass>(
275
				new LabelClassComparatorByPriority());
276

  
277
		for (int i = 0; i < lcs.length; i++) ts.add(lcs[i]);
278

  
279
		if (ts.size()==0) return;
280

  
281
		/*
282
		 * now we have an ordered set, it is only need to give a pass
283
		 * for each label class to render by priorities.
284
		 *
285
		 * If no priorities were defined, the following loop only executes
286
		 * once
287
		 */
288
		for (ILabelClass lc : ts) {
289
			
290
			FeatureSet fset =  method.getFeatureIteratorByLabelClass(layer, lc, viewPort, usedFields);
291

  
292
			// duplicates treatment stuff
293
			/* handle the duplicates mode */
294
			int duplicateMode = getDuplicateLabelsMode();
295
			if (duplicateMode == IPlacementConstraints.REMOVE_DUPLICATE_LABELS) {
296
				// we need to register the labels already placed
297

  
298
				labelsToPlace = new TreeMap<String[], GeometryItem>(
299
						new RemoveDuplicatesComparator());
300
			}
301

  
302
			boolean bLabelsReallocatable = !isAllowingOverlap();
303

  
304
			BufferedImage overlapDetectImage = null;
305
			Graphics2D overlapDetectGraphics = null;
306
			if (bLabelsReallocatable) {
307
				int width = viewPort.getImageWidth() + print_offset_x;
308

  
309
				if(width<0){
310
					width = 1;
311
				}
312
				int height = viewPort.getImageHeight() + print_offset_y;
313
				if(height<0){
314
					height = 1;
315
				}
316
				if (mapImage!=null)
317
					overlapDetectImage = new BufferedImage(
318
							mapImage.getWidth()  + print_offset_x,
319
							mapImage.getHeight()  + print_offset_y,
320
							BufferedImage.TYPE_INT_ARGB
321
				);
322
				else
323
					overlapDetectImage = new BufferedImage(
324
							viewPort.getImageWidth() + print_offset_x,
325
							viewPort.getImageHeight() + print_offset_y,
326
							BufferedImage.TYPE_INT_ARGB
327
					);
328

  
329
				overlapDetectGraphics = overlapDetectImage.createGraphics();
330
				overlapDetectGraphics.setRenderingHints(mapGraphics.getRenderingHints());
331
			}
332
			if (bLabelsReallocatable) {
333
				targetBI = overlapDetectImage;
334
				targetGr = overlapDetectGraphics;
335
				targetGr.translate(-x, -y);
336
			} else {
337
				targetBI = mapImage;
338
				targetGr = mapGraphics;
339
			}
340

  
341
			DisposableIterator diter = fset.fastIterator();
342
			Feature featu = null;
343
			Geometry geome = null;
344
			while ( !cancel.isCanceled() && diter.hasNext()) {
345
				
346
				featu = (Feature) diter.next();
347
				geome = featu.getDefaultGeometry();
348
				if (geome == null || geome.getType() == Geometry.TYPES.NULL) {
349
					continue;
350
				}
351
					
352

  
353
				if (!setupLabel(featu, lc, cancel,
354
						usedFields, viewPort, dpi, duplicateMode)) {
355
					continue;
356
				}
357

  
358
				String[] texts = lc.getTexts();
359
//				System.out.println(texts[0]);
360
				if (duplicateMode == IPlacementConstraints.REMOVE_DUPLICATE_LABELS) {
361
					// check if this text (so label) is already present in the map
362

  
363
					GeometryItem item = labelsToPlace.get(texts);
364
					if (item == null){
365
						item = new GeometryItem(geome, 0);
366
						labelsToPlace.put(texts, item);
367
					}
368
					if (item.geom != null) {
369
						
370
						notPlacedCount++;
371
						if (geome.getType() != Geometry.TYPES.POINT) {
372
							// FJP: Cambiamos la uni?n por una comprobaci?n de longitud, por ejemplo.
373
							// La geometr?a con mayor longitud del bounding box ser? la que etiquetamos.
374
							// Ser? inexacto, pero m?s r?pido. Solo lo queremos para saber qu? entidad etiquetamos
375
							// El problema con la uni?n es que para l?neas va muy mal (no sabes lo que te va
376
							// a etiquetar, y para pol?gonos ser? muy lenta. De todas formas, habr?a que evitar
377
							// la conversi?n al JTS.
378
//							Geometry jtsGeom = item.geom.toJTSGeometry().union(geom.toJTSGeometry());
379
//							if (jtsGeom instanceof LineString) {
380
//								CoordinateSequence cs = ((LineString) (jtsGeom)).getCoordinateSequence();
381
//								CoordinateSequences.reverse(cs);
382
//								jtsGeom = new LineString(cs, null);
383
//							}
384
//							item.geom = FConverter.jts_to_igeometry(jtsGeom);
385

  
386
							Envelope auxBox = geome.getEnvelope();
387
							double perimeterAux = 2 * (auxBox.getLength(0)+auxBox.getLength(1)); 
388
							if (perimeterAux > item.savedPerimeter) {
389
								item.geom = geome; //FConverter.jts_to_igeometry(jtsGeom);
390
								item.savedPerimeter = perimeterAux;
391
							}
392
						} else {
393
							int weigh = item.weigh;
394
							Point pointFromLabel = item.geom.centroid();
395
							Point pointGeome = geome.centroid();
396
							item.geom = GeometryLocator.getGeometryManager().createPoint(
397
									(pointFromLabel.getX()*weigh + pointGeome.getX())/(weigh+1),
398
									(pointFromLabel.getY()*weigh + pointGeome.getY())/(weigh+1),
399
									Geometry.SUBTYPES.GEOM2D);
400
						}
401
					} else {
402
						item.geom = geome;
403
					}
404
					item.weigh++;
405
				} else {
406
					// Check if size is a pixel
407
					if (isOnePoint(viewPort, geom)) {
408
						continue;
409
					}
410
//					lc.toCartographicSize(viewPort, dpi, null);
411

  
412
					drawLabelInGeom(targetBI, targetGr, lc, placement, viewPort, geom, cancel, dpi, bLabelsReallocatable);
413
					placedCount++;
414
				}
415
			}
416
			
417
			// ======= End iteration in feature set ====================
418
			
419
			if (duplicateMode == IPlacementConstraints.REMOVE_DUPLICATE_LABELS) {
420
				Iterator<String[]> textsIt = labelsToPlace.keySet().iterator();
421
				while ( !cancel.isCanceled() && textsIt.hasNext()) {
422
					notPlacedCount++;
423
					String[] texts = textsIt.next();
424

  
425
					GeometryItem item = labelsToPlace.get(texts);
426
					if(item != null){
427
						lc.setTexts(texts);
428
						// Check if size is a pixel
429
						if (isOnePoint(viewPort, item.geom)) {
430
							continue;
431
						}
432

  
433
//						lc.toCartographicSize(viewPort, dpi, null);
434
						drawLabelInGeom(targetBI, targetGr, lc, placement, viewPort, item.geom, cancel, dpi, bLabelsReallocatable);
435
					}
436
				}
437
			}
438

  
439
			if (bLabelsReallocatable) {
440
				targetGr.translate(x, y);
441
				if (mapImage!=null)
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff