root / trunk / extensions / extSymbology / src / org / gvsig / symbology / fmap / labeling / GeneralLabelingStrategy.java @ 20905
History | View | Annotate | Download (16.5 KB)
1 | 20768 | jdominguez | /* 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.symbology.fmap.labeling; |
||
109 | |||
110 | import java.awt.Graphics2D; |
||
111 | import java.awt.RenderingHints; |
||
112 | import java.awt.geom.Rectangle2D; |
||
113 | import java.awt.image.BufferedImage; |
||
114 | import java.io.CharArrayReader; |
||
115 | import java.text.NumberFormat; |
||
116 | import java.util.ArrayList; |
||
117 | import java.util.TreeSet; |
||
118 | |||
119 | import javax.print.attribute.PrintRequestAttributeSet; |
||
120 | |||
121 | import org.apache.log4j.Logger; |
||
122 | import org.cresques.cts.ICoordTrans; |
||
123 | import org.gvsig.symbology.fmap.labeling.lang.Symbol; |
||
124 | import org.gvsig.symbology.fmap.labeling.parse.LabelExpressionParser; |
||
125 | import org.gvsig.symbology.fmap.labeling.parse.ParseException; |
||
126 | import org.gvsig.symbology.fmap.labeling.placements.ILabelPlacement; |
||
127 | import org.gvsig.symbology.fmap.labeling.placements.RemoveDuplicatesComparator; |
||
128 | |||
129 | import com.hardcode.gdbms.driver.exceptions.ReadDriverException; |
||
130 | import com.hardcode.gdbms.engine.values.Value; |
||
131 | import com.iver.cit.gvsig.fmap.ViewPort; |
||
132 | import com.iver.cit.gvsig.fmap.core.FShape; |
||
133 | import com.iver.cit.gvsig.fmap.core.IFeature; |
||
134 | import com.iver.cit.gvsig.fmap.core.IGeometry; |
||
135 | import com.iver.cit.gvsig.fmap.core.v02.FConverter; |
||
136 | import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator; |
||
137 | import com.iver.cit.gvsig.fmap.layers.FLayer; |
||
138 | import com.iver.cit.gvsig.fmap.layers.FLyrVect; |
||
139 | import com.iver.cit.gvsig.fmap.rendering.styling.labeling.ILabelingMethod; |
||
140 | import com.iver.cit.gvsig.fmap.rendering.styling.labeling.ILabelingStrategy; |
||
141 | import com.iver.cit.gvsig.fmap.rendering.styling.labeling.IPlacementConstraints; |
||
142 | import com.iver.cit.gvsig.fmap.rendering.styling.labeling.IZoomConstraints; |
||
143 | import com.iver.cit.gvsig.fmap.rendering.styling.labeling.LabelClass; |
||
144 | import com.iver.cit.gvsig.fmap.rendering.styling.labeling.LabelLocationMetrics; |
||
145 | import com.iver.cit.gvsig.fmap.rendering.styling.labeling.LabelingFactory; |
||
146 | import com.iver.utiles.XMLEntity; |
||
147 | import com.iver.utiles.swing.threads.Cancellable; |
||
148 | |||
149 | /**
|
||
150 | *
|
||
151 | * GeneralLabelingStrategy.java
|
||
152 | *
|
||
153 | *
|
||
154 | * @author jaume dominguez faus - jaume.dominguez@iver.es Jan 4, 2008
|
||
155 | *
|
||
156 | */
|
||
157 | 20905 | jdominguez | public class GeneralLabelingStrategy implements ILabelingStrategy, Cloneable { |
158 | 20768 | jdominguez | private ILabelingMethod method;
|
159 | private IPlacementConstraints placementConstraints;
|
||
160 | protected FLyrVect layer;
|
||
161 | private IZoomConstraints zoomConstraints;
|
||
162 | private boolean allowOverlapping; |
||
163 | private long minScaleView = -1; |
||
164 | private long maxScaleView = -1; |
||
165 | |||
166 | public void setLayer(FLayer layer) throws ReadDriverException { |
||
167 | FLyrVect l = (FLyrVect) layer; |
||
168 | this.layer = l;
|
||
169 | } |
||
170 | |||
171 | public ILabelingMethod getLabelingMethod() {
|
||
172 | return method;
|
||
173 | } |
||
174 | |||
175 | public void setLabelingMethod(ILabelingMethod method) { |
||
176 | this.method = method;
|
||
177 | } |
||
178 | |||
179 | public void draw(BufferedImage mapImage, Graphics2D mapGraphics, ViewPort viewPort, |
||
180 | Cancellable cancel, double dpi)
|
||
181 | throws ReadDriverException {
|
||
182 | mapGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
||
183 | TreeSet<?> placedLabels = null; |
||
184 | |||
185 | long t1 = System.currentTimeMillis(); |
||
186 | String[] usedFields = getUsedFields(); |
||
187 | |||
188 | int notPlacedCount = 0; |
||
189 | int placedCount = 0; |
||
190 | ILabelPlacement placement = PlacementManager.getPlacement(getPlacementConstraints(), layer.getShapeType()); |
||
191 | |||
192 | /* handle the duplicates mode */
|
||
193 | int duplicateMode = getDuplicateLabelsMode();
|
||
194 | |||
195 | /*
|
||
196 | * get an ordered set of the LabelClasses up on the
|
||
197 | * label priority
|
||
198 | */
|
||
199 | LabelClass[] lcs = method.getLabelClasses();
|
||
200 | TreeSet<LabelClass> ts = new TreeSet<LabelClass>(new LabelClassComparatorByPriority()); |
||
201 | |||
202 | for (int i = 0; i < lcs.length; i++) ts.add(lcs[i]); |
||
203 | |||
204 | /*
|
||
205 | * now we have an ordered set, it is only need to give a pass
|
||
206 | * for each label class to render by priorities.
|
||
207 | *
|
||
208 | * If no priorities were defined, the following loop only executes
|
||
209 | * once
|
||
210 | */
|
||
211 | for (LabelClass lc : ts) {
|
||
212 | IFeatureIterator it = method.getFeatureIteratorByLabelClass(layer, lc, viewPort, usedFields); |
||
213 | |||
214 | // duplicates treatment stuff
|
||
215 | if (duplicateMode == IPlacementConstraints.REMOVE_DUPLICATE_LABELS) {
|
||
216 | // we need to register the labels already placed
|
||
217 | if (placedLabels == null) |
||
218 | placedLabels = new TreeSet<String[]>( |
||
219 | new RemoveDuplicatesComparator());
|
||
220 | else placedLabels.clear();
|
||
221 | } |
||
222 | |||
223 | // TODO Pending of the refactoring on geometries model
|
||
224 | //
|
||
225 | // else if (duplicateMode == IPlacementConstraints.ONE_LABEL_PER_FEATURE) {
|
||
226 | // // we need to register the labels already placed
|
||
227 | // if (placedLabels == null) placedLabels = new TreeSet();
|
||
228 | // else placedLabels.clear();
|
||
229 | // }
|
||
230 | //duplicates stuff
|
||
231 | |||
232 | 20905 | jdominguez | boolean bLabelsReallocatable = !isAllowingOverlap();
|
233 | 20768 | jdominguez | BufferedImage levelImg = null, |
234 | bi = new BufferedImage( |
||
235 | mapImage.getWidth(), |
||
236 | mapImage.getHeight(), |
||
237 | BufferedImage.TYPE_INT_ARGB
|
||
238 | ); |
||
239 | Graphics2D levelGraphics = null, |
||
240 | gBi = bi.createGraphics(); |
||
241 | gBi.setRenderingHints(mapGraphics.getRenderingHints()); |
||
242 | |||
243 | if (bLabelsReallocatable) {
|
||
244 | levelImg = new BufferedImage(mapImage.getWidth(),mapImage.getHeight(),BufferedImage.TYPE_INT_ARGB); |
||
245 | levelGraphics = bi.createGraphics(); |
||
246 | levelGraphics.setRenderingHints(mapGraphics.getRenderingHints()); |
||
247 | } |
||
248 | |||
249 | while ( !cancel.isCanceled() && it.hasNext()) {
|
||
250 | |||
251 | IFeature feat = it.next(); |
||
252 | IGeometry geom = feat.getGeometry(); |
||
253 | |||
254 | if (!setupLabel(feat, lc, cancel, usedFields, viewPort, dpi, duplicateMode, placedLabels))
|
||
255 | continue;
|
||
256 | |||
257 | // Check if size is a pixel
|
||
258 | if (isOnePoint(viewPort, geom)) {
|
||
259 | continue;
|
||
260 | } |
||
261 | |||
262 | BufferedImage[] targetBis; |
||
263 | Graphics2D targetG;
|
||
264 | |||
265 | if (method.definesPriorities()) {
|
||
266 | if (bLabelsReallocatable) {
|
||
267 | targetBis = new BufferedImage[] { bi, levelImg } ; |
||
268 | targetG = levelGraphics; |
||
269 | } else {
|
||
270 | targetBis = new BufferedImage[] { bi } ; |
||
271 | targetG = gBi; |
||
272 | } |
||
273 | } else {
|
||
274 | if (bLabelsReallocatable) {
|
||
275 | targetBis = new BufferedImage[] { bi }; |
||
276 | targetG = gBi; |
||
277 | } else {
|
||
278 | targetBis = new BufferedImage[] { mapImage }; |
||
279 | targetG = mapGraphics; |
||
280 | } |
||
281 | } |
||
282 | |||
283 | // Calculate the label possible places
|
||
284 | ArrayList<LabelLocationMetrics> llm = placement.guess(
|
||
285 | lc, |
||
286 | FConverter.transformToInts(geom, viewPort.getAffineTransform()), |
||
287 | getPlacementConstraints(), |
||
288 | 0,
|
||
289 | cancel); |
||
290 | |||
291 | /*
|
||
292 | * search if there is room left by the previous and
|
||
293 | * with more priority labels, then check the current
|
||
294 | * level
|
||
295 | */
|
||
296 | if (lookupAndPlaceLabel(targetBis, targetG,
|
||
297 | llm, placement, lc, geom, viewPort, cancel, |
||
298 | bLabelsReallocatable)) { |
||
299 | placedCount++; |
||
300 | } else {
|
||
301 | notPlacedCount++; |
||
302 | } |
||
303 | |||
304 | if (bLabelsReallocatable) {
|
||
305 | mapGraphics.drawImage(bi, null, null); |
||
306 | } |
||
307 | } |
||
308 | } |
||
309 | int total = placedCount+notPlacedCount;
|
||
310 | |||
311 | 20905 | jdominguez | if (total>0) |
312 | Logger.getLogger(getClass()).info("Labeled layer '"+layer.getName()+"' "+(System.currentTimeMillis()-t1)/1000D+" seconds. "+placedCount+"/"+total+" labels placed ("+NumberFormat.getInstance().format(100*placedCount/(double) total)+"%)"); |
||
313 | 20768 | jdominguez | |
314 | } |
||
315 | |||
316 | |||
317 | private int getDuplicateLabelsMode() { |
||
318 | if (getPlacementConstraints() == null) { |
||
319 | return IPlacementConstraints.DefaultDuplicateLabelsMode;
|
||
320 | } |
||
321 | return getPlacementConstraints().getDuplicateLabelsMode();
|
||
322 | } |
||
323 | |||
324 | private boolean lookupAndPlaceLabel(BufferedImage[] bis, Graphics2D g, ArrayList<LabelLocationMetrics> llm, ILabelPlacement placement, LabelClass lc, IGeometry geom, ViewPort viewPort, Cancellable cancel, boolean bLabelsReallocatable) { |
||
325 | int i;
|
||
326 | for (i = 0; !cancel.isCanceled() && i < llm.size(); i++) { |
||
327 | LabelLocationMetrics labelMetrics = llm.get(i); |
||
328 | |||
329 | if (bLabelsReallocatable) {
|
||
330 | for (int j = 0; j < bis.length; j++) { |
||
331 | BufferedImage bi = bis[j];
|
||
332 | if (!isOverlapping(bi, lc.getShape(labelMetrics))) {
|
||
333 | lc.draw(g, labelMetrics, null);
|
||
334 | // SimpleMarkerSymbol sms = new SimpleMarkerSymbol();
|
||
335 | // sms.setSize(5);
|
||
336 | // sms.setColor(Color.YELLOW);
|
||
337 | // sms.draw(g, null, new FPoint2D(labelMetrics.getAnchor()), null);
|
||
338 | return true; |
||
339 | } |
||
340 | } |
||
341 | } else {
|
||
342 | lc.draw(g, labelMetrics, null);
|
||
343 | return true; |
||
344 | } |
||
345 | } |
||
346 | return false; |
||
347 | } |
||
348 | |||
349 | @SuppressWarnings("unchecked") |
||
350 | private boolean setupLabel(IFeature feat, LabelClass lc, |
||
351 | Cancellable cancel, String[] usedFields, ViewPort viewPort, |
||
352 | double dpi, int duplicateMode, TreeSet<?> placedLabels) { |
||
353 | |||
354 | Value[] vv = feat.getAttributes();
|
||
355 | String expr = lc.getLabelExpression();
|
||
356 | LabelExpressionParser parser = new LabelExpressionParser(
|
||
357 | new CharArrayReader(expr.toCharArray())); |
||
358 | for (int i = 0; !cancel.isCanceled() && i < usedFields.length; i++) { |
||
359 | parser.putSymbol( |
||
360 | Symbol.createVariableSymbolFromValue(usedFields[i], vv[i])); |
||
361 | } |
||
362 | String[] texts; |
||
363 | try {
|
||
364 | texts = parser.LabelExpression(); |
||
365 | |||
366 | if (duplicateMode == IPlacementConstraints.REMOVE_DUPLICATE_LABELS) {
|
||
367 | // check if this text (so label) is already present in the map
|
||
368 | if (placedLabels.contains(texts))
|
||
369 | // the label has already placed before
|
||
370 | return false; |
||
371 | |||
372 | /*
|
||
373 | * the text is not present, it will be registered for next to
|
||
374 | * be avoided
|
||
375 | */
|
||
376 | ((TreeSet<String[]>) placedLabels).add(texts); |
||
377 | } |
||
378 | lc.setTexts(texts); |
||
379 | } catch (ParseException e) { |
||
380 | e.printStackTrace(); |
||
381 | return false; |
||
382 | } |
||
383 | |||
384 | lc.toCartographicSize(viewPort, dpi, null);
|
||
385 | return true; |
||
386 | } |
||
387 | |||
388 | private boolean isOverlapping(BufferedImage bi, FShape labelShape) { |
||
389 | |||
390 | Rectangle2D rPixels = labelShape.getBounds2D();
|
||
391 | for (int i= (int) rPixels.getX(); i<rPixels.getMaxX(); i++){ |
||
392 | for (int j= (int) rPixels.getY(); j<rPixels.getMaxY(); j++){ |
||
393 | if (!labelShape.contains(i, j)) {
|
||
394 | continue;
|
||
395 | } |
||
396 | |||
397 | if (i<0 || j<0) { |
||
398 | continue;
|
||
399 | } |
||
400 | |||
401 | if (bi.getWidth()<i+1 || bi.getHeight()<j+1) { |
||
402 | continue;
|
||
403 | } |
||
404 | |||
405 | if (bi.getRGB(i,j)!=0){ |
||
406 | return true; |
||
407 | } |
||
408 | } |
||
409 | } |
||
410 | return false; |
||
411 | } |
||
412 | |||
413 | private boolean isOnePoint(ViewPort viewPort, IGeometry geom) { |
||
414 | boolean onePoint = false; |
||
415 | int shapeType = geom.getGeometryType();
|
||
416 | if (shapeType!=FShape.POINT && shapeType!=FShape.MULTIPOINT) {
|
||
417 | |||
418 | Rectangle2D geomBounds = geom.getBounds2D();
|
||
419 | ICoordTrans ct = layer.getCoordTrans(); |
||
420 | |||
421 | if (ct!=null) { |
||
422 | geomBounds = ct.convert(geomBounds); |
||
423 | } |
||
424 | |||
425 | double dist1Pixel = viewPort.getDist1pixel();
|
||
426 | onePoint = (geomBounds.getWidth() <= dist1Pixel |
||
427 | && geomBounds.getHeight() <= dist1Pixel); |
||
428 | } |
||
429 | return onePoint;
|
||
430 | } |
||
431 | |||
432 | public String getClassName() { |
||
433 | return getClass().getName();
|
||
434 | } |
||
435 | |||
436 | public XMLEntity getXMLEntity() {
|
||
437 | XMLEntity xml = new XMLEntity();
|
||
438 | xml.putProperty("className", getClassName());
|
||
439 | xml.putProperty("allowOverlapping", allowOverlapping);
|
||
440 | xml.putProperty("minScaleView", minScaleView);
|
||
441 | xml.putProperty("maxScaleView", maxScaleView);
|
||
442 | |||
443 | if (method!=null) { |
||
444 | XMLEntity methodEntity = method.getXMLEntity(); |
||
445 | methodEntity.putProperty("id", "LabelingMethod"); |
||
446 | xml.addChild(methodEntity); |
||
447 | } |
||
448 | |||
449 | if (placementConstraints != null) { |
||
450 | XMLEntity pcEntity = placementConstraints.getXMLEntity(); |
||
451 | pcEntity.putProperty("id", "PlacementConstraints"); |
||
452 | xml.addChild(pcEntity); |
||
453 | } |
||
454 | |||
455 | if (zoomConstraints != null) { |
||
456 | XMLEntity zcEntity = zoomConstraints.getXMLEntity(); |
||
457 | zcEntity.putProperty("id", "ZoomConstraints"); |
||
458 | xml.addChild(zcEntity); |
||
459 | } |
||
460 | return xml;
|
||
461 | } |
||
462 | |||
463 | public void setXMLEntity(XMLEntity xml) { |
||
464 | XMLEntity aux = xml.firstChild("id", "LabelingMethod"); |
||
465 | |||
466 | // overlapping mode
|
||
467 | if (xml.contains("allowsOverlapping")) { |
||
468 | allowOverlapping = xml.getBooleanProperty("allowsOverlapping");
|
||
469 | } |
||
470 | |||
471 | // scale visualization
|
||
472 | if (xml.contains("minScaleView")) { |
||
473 | minScaleView = xml.getLongProperty("minScaleView");
|
||
474 | } |
||
475 | |||
476 | if (xml.contains("maxScaleView")) { |
||
477 | maxScaleView = xml.getLongProperty("maxScaleView");
|
||
478 | } |
||
479 | |||
480 | |||
481 | if (aux != null) { |
||
482 | method = LabelingFactory.createMethodFromXML(aux); |
||
483 | } |
||
484 | |||
485 | aux = xml.firstChild("id", "PlacementConstraints"); |
||
486 | if (aux != null) { |
||
487 | placementConstraints = LabelingFactory.createPlacementConstraintsFromXML(aux); |
||
488 | } |
||
489 | |||
490 | aux = xml.firstChild("id", "ZoomConstraints"); |
||
491 | if (aux != null) { |
||
492 | zoomConstraints = LabelingFactory.createZoomConstraintsFromXML(aux); |
||
493 | } |
||
494 | } |
||
495 | |||
496 | 20905 | jdominguez | public boolean isAllowingOverlap() { |
497 | 20768 | jdominguez | return allowOverlapping;
|
498 | } |
||
499 | |||
500 | public void setAllowOverlapping(boolean allowOverlapping) { |
||
501 | this.allowOverlapping = allowOverlapping;
|
||
502 | } |
||
503 | |||
504 | public IPlacementConstraints getPlacementConstraints() {
|
||
505 | return placementConstraints;
|
||
506 | } |
||
507 | |||
508 | public void setPlacementConstraints(IPlacementConstraints constraints) { |
||
509 | this.placementConstraints = constraints;
|
||
510 | } |
||
511 | |||
512 | public IZoomConstraints getZoomConstraints() {
|
||
513 | return zoomConstraints;
|
||
514 | } |
||
515 | |||
516 | public void setZoomConstraints(IZoomConstraints constraints) { |
||
517 | this.zoomConstraints = constraints;
|
||
518 | } |
||
519 | |||
520 | public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintRequestAttributeSet properties) throws ReadDriverException { |
||
521 | |||
522 | } |
||
523 | |||
524 | public String[] getUsedFields() { |
||
525 | LabelClass[] lcs = method.getLabelClasses();
|
||
526 | ArrayList<String> fieldNames = new ArrayList<String>(); |
||
527 | for (int i = 0; i < lcs.length; i++) { |
||
528 | String expr = lcs[i].getLabelExpression();
|
||
529 | int start;
|
||
530 | while ((start = expr.indexOf("[")) != -1) { |
||
531 | int end = expr.indexOf("]"); |
||
532 | String field = expr.substring(start+1, end).trim(); |
||
533 | if (!fieldNames.contains(field))
|
||
534 | fieldNames.add(field); |
||
535 | expr = expr.substring(end+1, expr.length());
|
||
536 | } |
||
537 | |||
538 | } |
||
539 | return fieldNames.toArray(new String[fieldNames.size()]); |
||
540 | } |
||
541 | |||
542 | public boolean shouldDrawLabels(double scale) { |
||
543 | if (minScaleView == -1 && maxScaleView == -1) { |
||
544 | // parameters not set, so the layer decides.
|
||
545 | return layer.isWithinScale(scale);
|
||
546 | } |
||
547 | |||
548 | if (minScaleView <= scale) {
|
||
549 | return (maxScaleView != -1) ? maxScaleView >= scale : true; |
||
550 | } |
||
551 | |||
552 | return false; |
||
553 | } |
||
554 | |||
555 | public long getMaxScaleView() { |
||
556 | return maxScaleView;
|
||
557 | } |
||
558 | |||
559 | public long getMinScaleView() { |
||
560 | return minScaleView;
|
||
561 | } |
||
562 | |||
563 | public void setMaxScaleView(long maxScaleView) { |
||
564 | this.maxScaleView = maxScaleView;
|
||
565 | } |
||
566 | |||
567 | public void setMinScaleView(long minScaleView) { |
||
568 | this.minScaleView = minScaleView;
|
||
569 | } |
||
570 | } |