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 / label / GeneralLabelingStrategy.java @ 42980
History | View | Annotate | Download (32.2 KB)
1 | 40911 | jldominguez | /* 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.geom.Point2D; |
||
112 | import java.awt.image.BufferedImage; |
||
113 | import java.util.ArrayList; |
||
114 | import java.util.Iterator; |
||
115 | 41227 | jldominguez | import java.util.List; |
116 | 40911 | jldominguez | import java.util.TreeMap; |
117 | import java.util.TreeSet; |
||
118 | |||
119 | 42980 | fdiaz | import org.slf4j.Logger; |
120 | import org.slf4j.LoggerFactory; |
||
121 | |||
122 | 40911 | jldominguez | import org.gvsig.compat.print.PrintAttributes; |
123 | import org.gvsig.fmap.dal.exception.DataException; |
||
124 | import org.gvsig.fmap.dal.exception.ReadException; |
||
125 | import org.gvsig.fmap.dal.feature.Feature; |
||
126 | import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
||
127 | import org.gvsig.fmap.dal.feature.FeatureSet; |
||
128 | import org.gvsig.fmap.geom.Geometry; |
||
129 | import org.gvsig.fmap.geom.Geometry.SUBTYPES; |
||
130 | import org.gvsig.fmap.geom.Geometry.TYPES; |
||
131 | import org.gvsig.fmap.geom.GeometryException; |
||
132 | import org.gvsig.fmap.geom.GeometryLocator; |
||
133 | import org.gvsig.fmap.geom.GeometryManager; |
||
134 | 41227 | jldominguez | import org.gvsig.fmap.geom.aggregate.MultiPrimitive; |
135 | 42555 | fdiaz | import org.gvsig.fmap.geom.operation.GeometryOperationException; |
136 | import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException; |
||
137 | 40911 | jldominguez | import org.gvsig.fmap.geom.primitive.Envelope; |
138 | import org.gvsig.fmap.geom.primitive.Point; |
||
139 | import org.gvsig.fmap.geom.type.GeometryType; |
||
140 | import org.gvsig.fmap.mapcontext.ViewPort; |
||
141 | import org.gvsig.fmap.mapcontext.layers.FLayer; |
||
142 | import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect; |
||
143 | import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelClass; |
||
144 | import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingMethod; |
||
145 | import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy; |
||
146 | import org.gvsig.fmap.mapcontext.rendering.legend.styling.IPlacementConstraints; |
||
147 | import org.gvsig.fmap.mapcontext.rendering.legend.styling.IZoomConstraints; |
||
148 | import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport; |
||
149 | import org.gvsig.i18n.Messages; |
||
150 | import org.gvsig.labeling.lang.LabelClassUtils; |
||
151 | import org.gvsig.labeling.placements.ILabelPlacement; |
||
152 | import org.gvsig.labeling.placements.LinePlacementConstraints; |
||
153 | import org.gvsig.labeling.placements.MultiShapePlacementConstraints; |
||
154 | import org.gvsig.labeling.placements.PlacementManager; |
||
155 | import org.gvsig.labeling.placements.PointPlacementConstraints; |
||
156 | import org.gvsig.labeling.placements.PolygonPlacementConstraints; |
||
157 | import org.gvsig.labeling.placements.RemoveDuplicatesComparator; |
||
158 | import org.gvsig.labeling.symbol.SmartTextSymbol; |
||
159 | import org.gvsig.labeling.symbol.SymbolUtils; |
||
160 | import org.gvsig.symbology.SymbologyLocator; |
||
161 | import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.LabelLocationMetrics; |
||
162 | import org.gvsig.tools.ToolsLocator; |
||
163 | import org.gvsig.tools.dispose.DisposableIterator; |
||
164 | import org.gvsig.tools.dynobject.DynStruct; |
||
165 | import org.gvsig.tools.persistence.PersistenceManager; |
||
166 | import org.gvsig.tools.persistence.PersistentState; |
||
167 | import org.gvsig.tools.persistence.exception.PersistenceException; |
||
168 | import org.gvsig.tools.task.Cancellable; |
||
169 | 42555 | fdiaz | |
170 | 40911 | jldominguez | /**
|
171 | *
|
||
172 | * GeneralLabelingStrategy.java
|
||
173 | *
|
||
174 | *
|
||
175 | * @author jaume dominguez faus - jaume.dominguez@iver.es Jan 4, 2008
|
||
176 | *
|
||
177 | */
|
||
178 | 41789 | fdiaz | public class GeneralLabelingStrategy implements ILabelingStrategy, Cloneable, |
179 | CartographicSupport { |
||
180 | |||
181 | private static final Logger logger = LoggerFactory |
||
182 | .getLogger(GeneralLabelingStrategy.class); |
||
183 | |||
184 | public static final String GENERAL_LABEL_STRATEGY_PERSISTENCE_NAME = "GENERAL_LABEL_STRATEGY_PERSISTENCE_NAME"; |
||
185 | |||
186 | public static PointPlacementConstraints DefaultPointPlacementConstraints = new PointPlacementConstraints(); |
||
187 | public static LinePlacementConstraints DefaultLinePlacementConstraints = new LinePlacementConstraints(); |
||
188 | public static PolygonPlacementConstraints DefaultPolygonPlacementConstraints = new PolygonPlacementConstraints(); |
||
189 | |||
190 | 40911 | jldominguez | private static String[] NO_TEXT = { Messages.getText("text_field") }; |
191 | 41789 | fdiaz | |
192 | private static MultiShapePlacementConstraints DefaultMultiShapePlacementConstratints = new MultiShapePlacementConstraints(); |
||
193 | |||
194 | 40911 | jldominguez | private ILabelingMethod method;
|
195 | private IPlacementConstraints placementConstraints;
|
||
196 | private IZoomConstraints zoomConstraints;
|
||
197 | 41789 | fdiaz | |
198 | 40911 | jldominguez | private boolean allowOverlapping; |
199 | 41789 | fdiaz | |
200 | 40911 | jldominguez | protected FLyrVect layer;
|
201 | |||
202 | 41789 | fdiaz | // private long parseTime;
|
203 | 40911 | jldominguez | private int unit; |
204 | private int referenceSystem; |
||
205 | // private double sizeAfter;
|
||
206 | 41789 | fdiaz | private boolean printMode = false; /* |
207 | * indicate whether output is for a
|
||
208 | * print product (PDF, PS, ...)
|
||
209 | */
|
||
210 | |||
211 | 42980 | fdiaz | private List<Geometry> drawnGeometryLabels; |
212 | |||
213 | 40911 | jldominguez | public GeneralLabelingStrategy() {
|
214 | 41789 | fdiaz | method = SymbologyLocator.getSymbologyManager() |
215 | .createDefaultLabelingMethod(); |
||
216 | 40911 | jldominguez | } |
217 | |||
218 | public void setLayer(FLayer layer) { |
||
219 | FLyrVect l = (FLyrVect) layer; |
||
220 | this.layer = l;
|
||
221 | } |
||
222 | |||
223 | public ILabelingMethod getLabelingMethod() {
|
||
224 | return method;
|
||
225 | } |
||
226 | |||
227 | public void setLabelingMethod(ILabelingMethod method) { |
||
228 | this.method = method;
|
||
229 | } |
||
230 | |||
231 | 41789 | fdiaz | private class GeometryItem { |
232 | 40911 | jldominguez | public Geometry geom = null; |
233 | public int weigh = 0; |
||
234 | public double savedPerimeter; |
||
235 | |||
236 | 41789 | fdiaz | public GeometryItem(Geometry geom, int weigh) { |
237 | 40911 | jldominguez | this.geom = geom;
|
238 | this.weigh = weigh;
|
||
239 | this.savedPerimeter = 0; |
||
240 | } |
||
241 | } |
||
242 | 41789 | fdiaz | |
243 | 42980 | fdiaz | public void draw(BufferedImage mapImage, Graphics2D mapGraphics, double scale, ViewPort viewPort, |
244 | Cancellable cancel, double dpi) throws ReadException { |
||
245 | 40911 | jldominguez | |
246 | 42980 | fdiaz | drawnGeometryLabels = new ArrayList<Geometry>(1000); |
247 | 41789 | fdiaz | |
248 | 42980 | fdiaz | int x = (int) viewPort.getOffset().getX(); |
249 | int y = (int) viewPort.getOffset().getY(); |
||
250 | 40911 | jldominguez | |
251 | 42980 | fdiaz | // offsets for page generation (PDF, PS, direct printing)
|
252 | int print_offset_x = x;
|
||
253 | int print_offset_y = y;
|
||
254 | if (printMode) {
|
||
255 | // for printing, we never offset the labels themselves
|
||
256 | x = 0;
|
||
257 | y = 0;
|
||
258 | printMode = false;
|
||
259 | } |
||
260 | 41789 | fdiaz | |
261 | 42980 | fdiaz | TreeMap<String[], GeometryItem> labelsToPlace = null; |
262 | 40911 | jldominguez | |
263 | 42980 | fdiaz | String[] usedFields = getUsedFields(); |
264 | 40911 | jldominguez | |
265 | 42980 | fdiaz | int notPlacedCount = 0; |
266 | int placedCount = 0; |
||
267 | 40911 | jldominguez | |
268 | 42980 | fdiaz | /*
|
269 | * Get the label placement solvers according the user's settings
|
||
270 | */
|
||
271 | ILabelPlacement placement = PlacementManager.getPlacement(getPlacementConstraints(), layer.getShapeType()); |
||
272 | 40911 | jldominguez | |
273 | 42980 | fdiaz | BufferedImage targetBI;
|
274 | Graphics2D targetGr;
|
||
275 | 40911 | jldominguez | |
276 | 42980 | fdiaz | /*
|
277 | * get an ordered set of the LabelClasses up on the label priority
|
||
278 | */
|
||
279 | ILabelClass[] lcs = method.getLabelClasses();
|
||
280 | TreeSet<ILabelClass> ts = new TreeSet<ILabelClass>(new LabelClassComparatorByPriority()); |
||
281 | 40911 | jldominguez | |
282 | 42980 | fdiaz | for (int i = 0; i < lcs.length; i++) |
283 | ts.add(lcs[i]); |
||
284 | 40911 | jldominguez | |
285 | 42980 | fdiaz | if (ts.size() == 0) |
286 | return;
|
||
287 | 41789 | fdiaz | |
288 | 42980 | fdiaz | /*
|
289 | * now we have an ordered set, it is only need to give a pass for each
|
||
290 | * label class to render by priorities.
|
||
291 | *
|
||
292 | * If no priorities were defined, the following loop only executes once
|
||
293 | */
|
||
294 | for (ILabelClass lc : ts) {
|
||
295 | 41789 | fdiaz | |
296 | 42980 | fdiaz | if (!lc.isVisible(scale)) {
|
297 | /*
|
||
298 | * Avoid non-visible labels
|
||
299 | */
|
||
300 | continue;
|
||
301 | } |
||
302 | 40911 | jldominguez | |
303 | 42980 | fdiaz | FeatureSet fset = null;
|
304 | DisposableIterator diter = null;
|
||
305 | try {
|
||
306 | 40911 | jldominguez | |
307 | 42980 | fdiaz | try {
|
308 | fset = method.getFeatureIteratorByLabelClass(layer, lc, viewPort, usedFields); |
||
309 | } catch (DataException e) {
|
||
310 | throw new ReadException(layer.getFeatureStore().getProviderName(), e); |
||
311 | } |
||
312 | 40911 | jldominguez | |
313 | 42980 | fdiaz | // duplicates treatment stuff
|
314 | /* handle the duplicates mode */
|
||
315 | int duplicateMode = getDuplicateLabelsMode();
|
||
316 | if (duplicateMode == IPlacementConstraints.REMOVE_DUPLICATE_LABELS) {
|
||
317 | // we need to register the labels already placed
|
||
318 | 40911 | jldominguez | |
319 | 42980 | fdiaz | labelsToPlace = new TreeMap<String[], GeometryItem>(new RemoveDuplicatesComparator()); |
320 | } |
||
321 | 40911 | jldominguez | |
322 | 42980 | fdiaz | boolean bLabelsReallocatable = !isAllowingOverlap();
|
323 | 41790 | fdiaz | |
324 | 42980 | fdiaz | BufferedImage overlapDetectImage = null; |
325 | Graphics2D overlapDetectGraphics = null; |
||
326 | if (bLabelsReallocatable) {
|
||
327 | int width = viewPort.getImageWidth() + print_offset_x;
|
||
328 | 41790 | fdiaz | |
329 | 42980 | fdiaz | if (width < 0) { |
330 | width = 1;
|
||
331 | } |
||
332 | int height = viewPort.getImageHeight() + print_offset_y;
|
||
333 | if (height < 0) { |
||
334 | height = 1;
|
||
335 | } |
||
336 | if (mapImage != null) |
||
337 | overlapDetectImage = |
||
338 | new BufferedImage(mapImage.getWidth() + print_offset_x, mapImage.getHeight() |
||
339 | + print_offset_y, BufferedImage.TYPE_INT_ARGB);
|
||
340 | else
|
||
341 | overlapDetectImage = |
||
342 | new BufferedImage(viewPort.getImageWidth() + print_offset_x, viewPort.getImageHeight() |
||
343 | + print_offset_y, BufferedImage.TYPE_INT_ARGB);
|
||
344 | 40911 | jldominguez | |
345 | 42980 | fdiaz | overlapDetectGraphics = overlapDetectImage.createGraphics(); |
346 | overlapDetectGraphics.setRenderingHints(mapGraphics.getRenderingHints()); |
||
347 | } |
||
348 | if (bLabelsReallocatable) {
|
||
349 | targetBI = overlapDetectImage; |
||
350 | targetGr = overlapDetectGraphics; |
||
351 | targetGr.translate(-x, -y); |
||
352 | } else {
|
||
353 | targetBI = mapImage; |
||
354 | targetGr = mapGraphics; |
||
355 | } |
||
356 | 40911 | jldominguez | |
357 | 42980 | fdiaz | try {
|
358 | diter = fset.fastIterator(); |
||
359 | } catch (DataException e) {
|
||
360 | throw new ReadException(layer.getFeatureStore().getProviderName(), e); |
||
361 | } |
||
362 | Feature featu = null;
|
||
363 | Geometry geome = null;
|
||
364 | 40911 | jldominguez | |
365 | 42980 | fdiaz | while (!cancel.isCanceled() && diter.hasNext()) {
|
366 | 40911 | jldominguez | |
367 | 42980 | fdiaz | featu = (Feature) diter.next(); |
368 | geome = featu.getDefaultGeometry(); |
||
369 | if (geome == null || geome.getType() == Geometry.TYPES.NULL) { |
||
370 | continue;
|
||
371 | } |
||
372 | 40911 | jldominguez | |
373 | 42980 | fdiaz | if (!setupLabel(featu, lc, cancel, usedFields, viewPort, dpi, duplicateMode)) {
|
374 | continue;
|
||
375 | } |
||
376 | 41789 | fdiaz | |
377 | 42980 | fdiaz | String[] texts = lc.getTexts(); |
378 | 41789 | fdiaz | |
379 | 42980 | fdiaz | if (duplicateMode == IPlacementConstraints.REMOVE_DUPLICATE_LABELS) {
|
380 | // check if this text (so label) is already present in
|
||
381 | // the map
|
||
382 | 41789 | fdiaz | |
383 | 42980 | fdiaz | GeometryItem item = labelsToPlace.get(texts); |
384 | if (item == null) { |
||
385 | item = new GeometryItem(geome, 0); |
||
386 | labelsToPlace.put(texts, item); |
||
387 | } |
||
388 | if (item.geom != null) { |
||
389 | 41789 | fdiaz | |
390 | 42980 | fdiaz | notPlacedCount++; |
391 | if (geome.getType() != Geometry.TYPES.POINT) {
|
||
392 | 41789 | fdiaz | |
393 | 42980 | fdiaz | Envelope auxBox = geome.getEnvelope(); |
394 | double perimeterAux = 2 * (auxBox.getLength(0) + auxBox.getLength(1)); |
||
395 | if (perimeterAux > item.savedPerimeter) {
|
||
396 | item.geom = geome; // FConverter.jts_to_igeometry(jtsGeom);
|
||
397 | item.savedPerimeter = perimeterAux; |
||
398 | } |
||
399 | } else {
|
||
400 | int weigh = item.weigh;
|
||
401 | 41789 | fdiaz | |
402 | 42980 | fdiaz | try {
|
403 | Point pointFromLabel = item.geom.centroid();
|
||
404 | Point pointGeome = geome.centroid();
|
||
405 | item.geom = |
||
406 | GeometryLocator.getGeometryManager().createPoint( |
||
407 | (pointFromLabel.getX() * weigh + pointGeome.getX()) / (weigh + 1),
|
||
408 | (pointFromLabel.getY() * weigh + pointGeome.getY()) / (weigh + 1),
|
||
409 | Geometry.SUBTYPES.GEOM2D); |
||
410 | } catch (Exception ex) { |
||
411 | throw new ReadException(layer.getFeatureStore().getProviderName(), ex); |
||
412 | } |
||
413 | 40911 | jldominguez | |
414 | 42980 | fdiaz | } |
415 | } else {
|
||
416 | item.geom = geome; |
||
417 | } |
||
418 | item.weigh++; |
||
419 | } else {
|
||
420 | // Check if size is a pixel
|
||
421 | if (isOnePoint(viewPort, geome)) {
|
||
422 | continue;
|
||
423 | } |
||
424 | 41789 | fdiaz | |
425 | 42980 | fdiaz | List<Geometry> geome_parts = new ArrayList<Geometry>(); |
426 | if (duplicateMode == IPlacementConstraints.ONE_LABEL_PER_FEATURE_PART) {
|
||
427 | geome_parts = getGeometryParts(geome); |
||
428 | } else {
|
||
429 | geome_parts.add(geome); |
||
430 | } |
||
431 | 41789 | fdiaz | |
432 | 42980 | fdiaz | try {
|
433 | int n = geome_parts.size();
|
||
434 | for (int k = 0; k < n; k++) { |
||
435 | drawLabelInGeom(targetBI, targetGr, lc, placement, viewPort, geome_parts.get(k), |
||
436 | cancel, dpi, bLabelsReallocatable); |
||
437 | } |
||
438 | } catch (GeometryException e) {
|
||
439 | throw new ReadException(layer.getFeatureStore().getProviderName(), e); |
||
440 | } |
||
441 | 41789 | fdiaz | |
442 | 42980 | fdiaz | placedCount++; |
443 | } |
||
444 | } |
||
445 | 41789 | fdiaz | |
446 | 42980 | fdiaz | // ======= End iteration in feature set ====================
|
447 | 40911 | jldominguez | |
448 | 42980 | fdiaz | if (duplicateMode == IPlacementConstraints.REMOVE_DUPLICATE_LABELS) {
|
449 | Iterator<String[]> textsIt = labelsToPlace.keySet().iterator(); |
||
450 | while (!cancel.isCanceled() && textsIt.hasNext()) {
|
||
451 | notPlacedCount++; |
||
452 | String[] texts = textsIt.next(); |
||
453 | 40911 | jldominguez | |
454 | 42980 | fdiaz | GeometryItem item = labelsToPlace.get(texts); |
455 | if (item != null) { |
||
456 | lc.setTexts(texts); |
||
457 | // Check if size is a pixel
|
||
458 | if (isOnePoint(viewPort, item.geom)) {
|
||
459 | continue;
|
||
460 | } |
||
461 | 40911 | jldominguez | |
462 | 42980 | fdiaz | try {
|
463 | drawLabelInGeom(targetBI, targetGr, lc, placement, viewPort, item.geom, cancel, dpi, |
||
464 | bLabelsReallocatable); |
||
465 | } catch (GeometryException e) {
|
||
466 | throw new ReadException(layer.getFeatureStore().getProviderName(), e); |
||
467 | } |
||
468 | } |
||
469 | } |
||
470 | } |
||
471 | 41790 | fdiaz | |
472 | 42980 | fdiaz | if (bLabelsReallocatable) {
|
473 | targetGr.translate(x, y); |
||
474 | if (mapImage != null) { |
||
475 | mapGraphics.drawImage(overlapDetectImage, null, null); |
||
476 | } else {
|
||
477 | mapGraphics.drawImage(overlapDetectImage, null, null); |
||
478 | } |
||
479 | } |
||
480 | 40911 | jldominguez | |
481 | 42980 | fdiaz | } finally {
|
482 | if (diter != null) { |
||
483 | diter.dispose(); |
||
484 | } |
||
485 | if (fset != null) { |
||
486 | fset.dispose(); |
||
487 | } |
||
488 | } |
||
489 | } // big iteration
|
||
490 | 41789 | fdiaz | |
491 | 42980 | fdiaz | } |
492 | |||
493 | 41227 | jldominguez | private List<Geometry> getGeometryParts(Geometry ge) { |
494 | |||
495 | 41789 | fdiaz | List<Geometry> resp = new ArrayList<Geometry>(); |
496 | if (ge != null) { |
||
497 | if (ge instanceof MultiPrimitive) { |
||
498 | MultiPrimitive mp = (MultiPrimitive) ge; |
||
499 | int n = mp.getPrimitivesNumber();
|
||
500 | for (int i = 0; i < n; i++) { |
||
501 | resp.add(mp.getPrimitiveAt(i)); |
||
502 | } |
||
503 | } else {
|
||
504 | resp.add(ge); |
||
505 | } |
||
506 | } |
||
507 | return resp;
|
||
508 | } |
||
509 | 40911 | jldominguez | |
510 | 41789 | fdiaz | private void drawLabelInGeom(BufferedImage targetBI, Graphics2D targetGr, |
511 | ILabelClass lc, ILabelPlacement placement, ViewPort viewPort, |
||
512 | Geometry geom, Cancellable cancel, double dpi,
|
||
513 | boolean bLabelsReallocatable) throws GeometryException { |
||
514 | |||
515 | 40911 | jldominguez | lc.toCartographicSize(viewPort, dpi, null);
|
516 | ArrayList<LabelLocationMetrics> llm = null; |
||
517 | 41789 | fdiaz | llm = placement.guess(lc, geom, getPlacementConstraints(), 0, cancel,
|
518 | viewPort); |
||
519 | 40911 | jldominguez | |
520 | setReferenceSystem(lc.getReferenceSystem()); |
||
521 | setUnit(lc.getUnit()); |
||
522 | |||
523 | /*
|
||
524 | 41789 | fdiaz | * search if there is room left by the previous and with more priority
|
525 | * labels, then check the current level
|
||
526 | 40911 | jldominguez | */
|
527 | 41789 | fdiaz | lookupAndPlaceLabel(targetBI, targetGr, llm, placement, lc, geom, |
528 | viewPort, cancel, bLabelsReallocatable); |
||
529 | 40911 | jldominguez | |
530 | } |
||
531 | |||
532 | private int getDuplicateLabelsMode() { |
||
533 | if (getPlacementConstraints() == null) { |
||
534 | return IPlacementConstraints.DefaultDuplicateLabelsMode;
|
||
535 | } |
||
536 | return getPlacementConstraints().getDuplicateLabelsMode();
|
||
537 | } |
||
538 | |||
539 | private boolean lookupAndPlaceLabel(BufferedImage bi, Graphics2D g, |
||
540 | ArrayList<LabelLocationMetrics> llm, ILabelPlacement placement,
|
||
541 | 41789 | fdiaz | ILabelClass lc, Geometry geom, ViewPort viewPort, |
542 | 40911 | jldominguez | Cancellable cancel, boolean bLabelsReallocatable)
|
543 | 41789 | fdiaz | throws GeometryException {
|
544 | |||
545 | 42980 | fdiaz | GeometryManager gm = GeometryLocator.getGeometryManager(); |
546 | 40911 | jldominguez | int i;
|
547 | for (i = 0; !cancel.isCanceled() && i < llm.size(); i++) { |
||
548 | LabelLocationMetrics labelMetrics = llm.get(i); |
||
549 | |||
550 | IPlacementConstraints pc = getPlacementConstraints(); |
||
551 | 41789 | fdiaz | if (pc instanceof MultiShapePlacementConstraints) { |
552 | MultiShapePlacementConstraints mpc = (MultiShapePlacementConstraints) pc; |
||
553 | |||
554 | 40911 | jldominguez | GeometryType geom_gt = null;
|
555 | 41789 | fdiaz | |
556 | 40911 | jldominguez | geom_gt = gm.getGeometryType(geom.getType(), SUBTYPES.GEOM2D); |
557 | |||
558 | 41789 | fdiaz | if (geom_gt.getType() == TYPES.POINT
|
559 | || geom_gt.getType() == TYPES.MULTIPOINT) { |
||
560 | 40911 | jldominguez | pc = mpc.getPointConstraints(); |
561 | } else {
|
||
562 | 41789 | fdiaz | if (geom_gt.isTypeOf(TYPES.CURVE)
|
563 | || geom_gt.getType() == TYPES.MULTICURVE) { |
||
564 | 40911 | jldominguez | pc = mpc.getLineConstraints(); |
565 | } else {
|
||
566 | 41789 | fdiaz | if (geom_gt.isTypeOf(TYPES.SURFACE)
|
567 | || geom_gt.getType() == TYPES.MULTISURFACE) { |
||
568 | 40911 | jldominguez | pc = mpc.getPolygonConstraints(); |
569 | } |
||
570 | } |
||
571 | } |
||
572 | } |
||
573 | |||
574 | /*
|
||
575 | * Ver comentario en el metodo drawLabelInGeom
|
||
576 | */
|
||
577 | if (bLabelsReallocatable) {
|
||
578 | 41789 | fdiaz | |
579 | 40911 | jldominguez | Geometry aux_geom = null;
|
580 | aux_geom = lc.getShape(labelMetrics); |
||
581 | 41789 | fdiaz | |
582 | 40911 | jldominguez | if (!isOverlapping(bi, aux_geom)) {
|
583 | |||
584 | 41789 | fdiaz | if (!pc.isFollowingLine()) {
|
585 | 40911 | jldominguez | lc.draw(g, labelMetrics, geom); |
586 | } else {
|
||
587 | 41789 | fdiaz | |
588 | 41131 | jldominguez | ILabelClass smsLc = new SmartTextSymbolLabelClass();
|
589 | 41789 | fdiaz | SmartTextSymbol sms = new SmartTextSymbol(
|
590 | lc.getTextSymbol(), pc); |
||
591 | 40911 | jldominguez | |
592 | 41789 | fdiaz | double sizeBefore = lc.getTextSymbol().getFont()
|
593 | .getSize(); |
||
594 | double sizeAfter = SymbolUtils.getCartographicLength(
|
||
595 | this, sizeBefore, viewPort, viewPort.getDPI());
|
||
596 | 40911 | jldominguez | sms.setFontSize(sizeAfter); |
597 | |||
598 | smsLc.setTextSymbol(sms); |
||
599 | geom.transform(viewPort.getAffineTransform()); |
||
600 | smsLc.draw(g, null, geom);
|
||
601 | sms.setFontSize(sizeBefore); |
||
602 | |||
603 | } |
||
604 | return true; |
||
605 | } |
||
606 | } else {
|
||
607 | 41789 | fdiaz | if (!pc.isFollowingLine()) {
|
608 | 40911 | jldominguez | lc.draw(g, labelMetrics, null);
|
609 | 41789 | fdiaz | } else {
|
610 | ILabelClass smsLc = new SmartTextSymbolLabelClass();
|
||
611 | SmartTextSymbol sms = new SmartTextSymbol(
|
||
612 | lc.getTextSymbol(), pc); |
||
613 | 40911 | jldominguez | |
614 | double sizeBefore = lc.getTextSymbol().getFont().getSize();
|
||
615 | double sizeAfter = SymbolUtils.getCartographicLength(this, |
||
616 | 41789 | fdiaz | sizeBefore, viewPort, viewPort.getDPI()); |
617 | 40911 | jldominguez | sms.setFontSize(sizeAfter); |
618 | |||
619 | smsLc.setTextSymbol(sms); |
||
620 | geom.transform(viewPort.getAffineTransform()); |
||
621 | smsLc.draw(g, null, geom);
|
||
622 | |||
623 | sms.setFontSize(sizeBefore); |
||
624 | } |
||
625 | return true; |
||
626 | } |
||
627 | } |
||
628 | return false; |
||
629 | } |
||
630 | |||
631 | /**
|
||
632 | 41789 | fdiaz | * Divide una cadena de caracteres por el caracter dos puntos siempre que no
|
633 | * est? entre comillas.
|
||
634 | 40911 | jldominguez | *
|
635 | * @param str
|
||
636 | * Cadena de caracteres
|
||
637 | *
|
||
638 | * @return String[]
|
||
639 | *
|
||
640 | */
|
||
641 | 41789 | fdiaz | private String[] divideExpression(String str) { |
642 | 40911 | jldominguez | ArrayList<String> r = new ArrayList<String>(); |
643 | boolean inQuotationMarks = false; |
||
644 | int lastIndex = 0; |
||
645 | 41789 | fdiaz | for (int i = 0; i < str.length(); i++) { |
646 | 42171 | jbadia | String currentChar = str.substring(i, i + 1); |
647 | if (currentChar.compareTo("\"") == 0 ) { |
||
648 | 40911 | jldominguez | inQuotationMarks = !inQuotationMarks; |
649 | 42171 | jbadia | // Si es el cierre de las comillas
|
650 | if(!inQuotationMarks){
|
||
651 | r.add(str.substring(lastIndex, i + 1).replace("\"", "'")); |
||
652 | lastIndex = i + 1;
|
||
653 | } |
||
654 | 40911 | jldominguez | } |
655 | 42171 | jbadia | if (currentChar.compareTo(":") == 0 |
656 | 41789 | fdiaz | && !inQuotationMarks) { |
657 | if (lastIndex < i) {
|
||
658 | 40911 | jldominguez | r.add(str.substring(lastIndex, i)); |
659 | } |
||
660 | 41789 | fdiaz | lastIndex = i + 1;
|
661 | 40911 | jldominguez | } |
662 | } |
||
663 | 41789 | fdiaz | if (lastIndex < str.length() - 1) { |
664 | 40911 | jldominguez | r.add(str.substring(lastIndex)); |
665 | } |
||
666 | String[] result = new String[r.size()]; |
||
667 | r.toArray(result); |
||
668 | return result;
|
||
669 | } |
||
670 | |||
671 | /**
|
||
672 | * Compute the texts to show in the label and store them in LabelClass.
|
||
673 | */
|
||
674 | @SuppressWarnings("unchecked") |
||
675 | private boolean setupLabel(Feature featu, ILabelClass lc, |
||
676 | Cancellable cancel, String[] usedFields, ViewPort viewPort, |
||
677 | 41789 | fdiaz | double dpi, int duplicateMode) { |
678 | 40911 | jldominguez | |
679 | String expr = lc.getStringLabelExpression();
|
||
680 | |||
681 | long pt1 = System.currentTimeMillis(); |
||
682 | String[] texts = NO_TEXT; |
||
683 | 41421 | jjdelcerro | List<String> preTexts = new ArrayList<String>(); |
684 | 40911 | jldominguez | try {
|
685 | if (expr != null) { |
||
686 | |||
687 | if (expr.equals("")) { |
||
688 | expr = texts[0];
|
||
689 | } |
||
690 | |||
691 | String[] multiexpr = divideExpression(expr); |
||
692 | 41789 | fdiaz | for (int i = 0; i < multiexpr.length; i++) { |
693 | |||
694 | 40911 | jldominguez | expr = multiexpr[i]; |
695 | 41789 | fdiaz | Object res = LabelClassUtils.evaluate(expr,
|
696 | featu.getEvaluatorData()); |
||
697 | 40911 | jldominguez | if (res != null) { |
698 | preTexts.add(res.toString()); |
||
699 | } else {
|
||
700 | 41421 | jjdelcerro | preTexts.add("");
|
701 | 40911 | jldominguez | } |
702 | } |
||
703 | texts = new String[preTexts.size()]; |
||
704 | preTexts.toArray(texts); |
||
705 | 41789 | fdiaz | // parseTime += System.currentTimeMillis()-pt1;
|
706 | 40911 | jldominguez | } |
707 | lc.setTexts(texts); |
||
708 | |||
709 | } catch (Exception e) { |
||
710 | 41421 | jjdelcerro | logger.warn("While setting up label", e);
|
711 | 40911 | jldominguez | return false; |
712 | } |
||
713 | return true; |
||
714 | } |
||
715 | 41789 | fdiaz | |
716 | 42980 | fdiaz | private boolean isOverlapping(BufferedImage bi, Geometry lblgeom) { |
717 | 41789 | fdiaz | |
718 | 42980 | fdiaz | for (Iterator iterator = drawnGeometryLabels.iterator(); iterator.hasNext();) { |
719 | Geometry drawnGeometry = (Geometry) iterator.next(); |
||
720 | try {
|
||
721 | if (drawnGeometry.intersects(lblgeom)) {
|
||
722 | 42555 | fdiaz | return true; |
723 | } |
||
724 | 42980 | fdiaz | } catch (GeometryOperationNotSupportedException | GeometryOperationException e) {
|
725 | logger.warn("Can't check overlapping geometry");
|
||
726 | 42555 | fdiaz | } |
727 | } |
||
728 | 42980 | fdiaz | drawnGeometryLabels.add(lblgeom); |
729 | return false; |
||
730 | 40911 | jldominguez | |
731 | 42980 | fdiaz | } |
732 | |||
733 | 40911 | jldominguez | private boolean isOnePoint(ViewPort viewPort, Geometry geom) { |
734 | 41789 | fdiaz | |
735 | 40911 | jldominguez | boolean onePoint = false; |
736 | int shapeType = geom.getType();
|
||
737 | 41789 | fdiaz | |
738 | 40911 | jldominguez | if (shapeType != TYPES.POINT && shapeType != TYPES.MULTIPOINT) {
|
739 | |||
740 | Envelope env = geom.getEnvelope(); |
||
741 | double dist1Pixel = viewPort.getDist1pixel();
|
||
742 | 41789 | fdiaz | onePoint = (env.getLength(0) <= dist1Pixel && env.getLength(1) <= dist1Pixel); |
743 | 40911 | jldominguez | } |
744 | return onePoint;
|
||
745 | } |
||
746 | |||
747 | public boolean isAllowingOverlap() { |
||
748 | return allowOverlapping;
|
||
749 | } |
||
750 | |||
751 | public void setAllowOverlapping(boolean allowOverlapping) { |
||
752 | this.allowOverlapping = allowOverlapping;
|
||
753 | } |
||
754 | |||
755 | public IPlacementConstraints getPlacementConstraints() {
|
||
756 | if (placementConstraints != null) |
||
757 | return placementConstraints;
|
||
758 | |||
759 | GeometryType gt = null;
|
||
760 | 41789 | fdiaz | |
761 | 40911 | jldominguez | try {
|
762 | gt = layer.getGeometryType(); |
||
763 | // force 2d for comparison
|
||
764 | gt = GeometryLocator.getGeometryManager().getGeometryType( |
||
765 | gt.getType(), SUBTYPES.GEOM2D); |
||
766 | } catch (Exception e) { |
||
767 | logger.error("While getting placements constraints.", e);
|
||
768 | return null; |
||
769 | } |
||
770 | 41789 | fdiaz | |
771 | if (gt.isTypeOf(TYPES.POINT) || gt.isTypeOf(TYPES.MULTIPOINT)) {
|
||
772 | 40911 | jldominguez | return DefaultPointPlacementConstraints;
|
773 | } else {
|
||
774 | 41789 | fdiaz | if (gt.isTypeOf(TYPES.CURVE) || gt.isTypeOf(TYPES.MULTICURVE)) {
|
775 | 40911 | jldominguez | return DefaultLinePlacementConstraints;
|
776 | } else {
|
||
777 | if (gt.isTypeOf(TYPES.SURFACE)
|
||
778 | || gt.isTypeOf(TYPES.MULTISURFACE)) { |
||
779 | return DefaultPolygonPlacementConstraints;
|
||
780 | } else {
|
||
781 | 41789 | fdiaz | if (gt.isTypeOf(TYPES.AGGREGATE)
|
782 | || gt.isTypeOf(TYPES.GEOMETRY)) { |
||
783 | DefaultMultiShapePlacementConstratints |
||
784 | .setPointConstraints(DefaultPointPlacementConstraints); |
||
785 | DefaultMultiShapePlacementConstratints |
||
786 | .setLineConstraints(DefaultLinePlacementConstraints); |
||
787 | DefaultMultiShapePlacementConstratints |
||
788 | .setPolygonConstraints(DefaultPolygonPlacementConstraints); |
||
789 | 40911 | jldominguez | return DefaultMultiShapePlacementConstratints;
|
790 | } |
||
791 | } |
||
792 | } |
||
793 | } |
||
794 | return null; |
||
795 | } |
||
796 | |||
797 | public void setPlacementConstraints(IPlacementConstraints constraints) { |
||
798 | this.placementConstraints = constraints;
|
||
799 | } |
||
800 | |||
801 | public IZoomConstraints getZoomConstraints() {
|
||
802 | return zoomConstraints;
|
||
803 | } |
||
804 | |||
805 | public void setZoomConstraints(IZoomConstraints constraints) { |
||
806 | this.zoomConstraints = constraints;
|
||
807 | } |
||
808 | |||
809 | 41789 | fdiaz | public void print(Graphics2D g, double scale, ViewPort viewPort, |
810 | 40911 | jldominguez | Cancellable cancel, PrintAttributes properties) |
811 | throws ReadException {
|
||
812 | 41789 | fdiaz | |
813 | 40911 | jldominguez | double dpi = 100; |
814 | int pq = properties.getPrintQuality();
|
||
815 | 41789 | fdiaz | if (pq == PrintAttributes.PRINT_QUALITY_NORMAL) {
|
816 | 40911 | jldominguez | dpi = 300;
|
817 | 41789 | fdiaz | } else if (pq == PrintAttributes.PRINT_QUALITY_HIGH) { |
818 | 40911 | jldominguez | dpi = 600;
|
819 | 41789 | fdiaz | } else if (pq == PrintAttributes.PRINT_QUALITY_DRAFT) { |
820 | 40911 | jldominguez | dpi = 72;
|
821 | } |
||
822 | |||
823 | 41789 | fdiaz | viewPort.setOffset(new Point2D.Double(0, 0)); |
824 | |||
825 | 40911 | jldominguez | /* signal printing output */
|
826 | printMode = true;
|
||
827 | |||
828 | 41789 | fdiaz | draw(null, g, scale, viewPort, cancel, dpi);
|
829 | 40911 | jldominguez | } |
830 | |||
831 | public String[] getUsedFields() { |
||
832 | |||
833 | /*
|
||
834 | 41789 | fdiaz | * TODO Solve the problem with the [ and ]. Currently SQLJEP evaluator
|
835 | * cannot tell which fields are being used. Options: allow [] and remove
|
||
836 | * them or maybe while parsing the SQLJEP evaluator can inform with
|
||
837 | * events like "I have found a field"
|
||
838 | 40911 | jldominguez | */
|
839 | 41789 | fdiaz | |
840 | 40911 | jldominguez | FeatureAttributeDescriptor[] atts = null; |
841 | try {
|
||
842 | 41789 | fdiaz | atts = layer.getFeatureStore().getDefaultFeatureType() |
843 | .getAttributeDescriptors(); |
||
844 | 40911 | jldominguez | } catch (DataException e) {
|
845 | logger.error("While getting atributes.", e);
|
||
846 | } |
||
847 | 41789 | fdiaz | |
848 | 40911 | jldominguez | int n = atts.length;
|
849 | String[] resp = new String[n]; |
||
850 | 41789 | fdiaz | for (int i = 0; i < n; i++) { |
851 | 40911 | jldominguez | resp[i] = atts[i].getName(); |
852 | } |
||
853 | return resp;
|
||
854 | |||
855 | } |
||
856 | |||
857 | public boolean shouldDrawLabels(double scale) { |
||
858 | double minScaleView = -1; |
||
859 | double maxScaleView = -1; |
||
860 | |||
861 | if (zoomConstraints != null) { |
||
862 | minScaleView = zoomConstraints.getMinScale(); |
||
863 | maxScaleView = zoomConstraints.getMaxScale(); |
||
864 | } |
||
865 | |||
866 | if (minScaleView == -1 && maxScaleView == -1) { |
||
867 | // parameters not set, so the layer decides.
|
||
868 | return layer.isWithinScale(scale);
|
||
869 | } |
||
870 | |||
871 | if (minScaleView >= scale) {
|
||
872 | return (maxScaleView != -1) ? maxScaleView <= scale : true; |
||
873 | } |
||
874 | |||
875 | return false; |
||
876 | } |
||
877 | |||
878 | public void setUnit(int unitIndex) { |
||
879 | unit = unitIndex; |
||
880 | |||
881 | } |
||
882 | |||
883 | public int getUnit() { |
||
884 | return unit;
|
||
885 | } |
||
886 | |||
887 | public int getReferenceSystem() { |
||
888 | return referenceSystem;
|
||
889 | } |
||
890 | |||
891 | public void setReferenceSystem(int referenceSystem) { |
||
892 | this.referenceSystem = referenceSystem;
|
||
893 | } |
||
894 | 41789 | fdiaz | |
895 | 40911 | jldominguez | public static void registerPersistent() { |
896 | 41789 | fdiaz | |
897 | PersistenceManager manager = ToolsLocator.getPersistenceManager(); |
||
898 | if (manager.getDefinition(GENERAL_LABEL_STRATEGY_PERSISTENCE_NAME) == null) { |
||
899 | DynStruct definition = manager.addDefinition( |
||
900 | GeneralLabelingStrategy.class, |
||
901 | GENERAL_LABEL_STRATEGY_PERSISTENCE_NAME, |
||
902 | GENERAL_LABEL_STRATEGY_PERSISTENCE_NAME |
||
903 | + " Persistence definition", null, null); |
||
904 | definition.addDynFieldObject("labelingMethod")
|
||
905 | .setClassOfValue(ILabelingMethod.class).setMandatory(true);
|
||
906 | definition.addDynFieldObject("placementConstraints")
|
||
907 | .setClassOfValue(IPlacementConstraints.class) |
||
908 | .setMandatory(false);
|
||
909 | definition.addDynFieldObject("zoomConstraints")
|
||
910 | .setClassOfValue(IZoomConstraints.class) |
||
911 | .setMandatory(false);
|
||
912 | |||
913 | definition.addDynFieldBoolean("allowOverlapping")
|
||
914 | .setMandatory(true);
|
||
915 | definition.addDynFieldInt("unit").setMandatory(true); |
||
916 | definition.addDynFieldInt("referenceSystem").setMandatory(true); |
||
917 | } |
||
918 | 40911 | jldominguez | } |
919 | 41789 | fdiaz | |
920 | public void loadFromState(PersistentState state) |
||
921 | throws PersistenceException {
|
||
922 | |||
923 | 40911 | jldominguez | method = (ILabelingMethod) state.get("labelingMethod");
|
924 | 41789 | fdiaz | |
925 | 40911 | jldominguez | if (state.hasValue("placementConstraints")) { |
926 | 41789 | fdiaz | placementConstraints = (IPlacementConstraints) state |
927 | .get("placementConstraints");
|
||
928 | 40911 | jldominguez | } |
929 | 41789 | fdiaz | |
930 | 40911 | jldominguez | if (state.hasValue("zoomConstraints")) { |
931 | zoomConstraints = (IZoomConstraints) state.get("zoomConstraints");
|
||
932 | } |
||
933 | |||
934 | this.allowOverlapping = state.getBoolean("allowOverlapping"); |
||
935 | this.unit = state.getInt("unit"); |
||
936 | this.referenceSystem = state.getInt("referenceSystem"); |
||
937 | } |
||
938 | |||
939 | public void saveToState(PersistentState state) throws PersistenceException { |
||
940 | 41789 | fdiaz | |
941 | 40911 | jldominguez | state.set("labelingMethod", method);
|
942 | 41789 | fdiaz | |
943 | 40911 | jldominguez | if (placementConstraints != null) { |
944 | state.set("placementConstraints", placementConstraints);
|
||
945 | } |
||
946 | |||
947 | if (zoomConstraints != null) { |
||
948 | state.set("zoomConstraints", zoomConstraints);
|
||
949 | } |
||
950 | |||
951 | state.set("allowOverlapping", allowOverlapping);
|
||
952 | state.set("unit", unit);
|
||
953 | state.set("referenceSystem", referenceSystem);
|
||
954 | |||
955 | } |
||
956 | |||
957 | public double toCartographicSize(ViewPort vp, double dpi, Geometry geom) { |
||
958 | /*
|
||
959 | * This method is not used but we must implement CartographicSupport
|
||
960 | */
|
||
961 | return 0; |
||
962 | } |
||
963 | |||
964 | public void setCartographicSize(double cartographicSize, Geometry geom) { |
||
965 | /*
|
||
966 | * This method is not used but we must implement CartographicSupport
|
||
967 | */
|
||
968 | } |
||
969 | |||
970 | public double getCartographicSize(ViewPort vp, double dpi, Geometry geom) { |
||
971 | /*
|
||
972 | * This method is not used but we must implement CartographicSupport
|
||
973 | */
|
||
974 | return 0; |
||
975 | } |
||
976 | 41789 | fdiaz | |
977 | 40911 | jldominguez | public Object clone() throws CloneNotSupportedException { |
978 | return LabelClassUtils.clone(this); |
||
979 | } |
||
980 | |||
981 | } |