final public class LabelCacheDefault implements LabelCache(Code)
Default LabelCache Implementation
DJB (major changes on May 11th, 2005): 1.The old version of the labeler, if
given a *set* of points, lines, or polygons justed labels the first item in
the set. The sets are formed when you want to only put a single "Main St" on
the map even if you have a bunch of small "Main St" segments.
I changed this to be much much wiser.
Basically, the new way looks at the set of geometries that its going to put a
label on and find the "best" one that represents it. That geometry is then
labeled (see below for details on where that label is placed).
2. I changed the actual drawing routines;
1. get the "representative geometry" 2. for points, label as before 3. for
lines, find the middle point on the line (old version just averaged start and
end points) and centre label on that point (rotated) 4. for polygon, put the
label in the middle
3.
ie. for lines, try the label at the 1/3, 1/2, and 2/3 location. Metric is how
close the label bounding box is to the line.
ie. for polygons, bisect the polygon (about the centroid) in to North, South,
East and West polygons. Use the location that has the label best inside the
polygon.
After this is done, you can start doing constraint relaxation...
4. TODO: deal with labels going off the edge of the screen (much reduced
now). 5. TODO: add a "minimum quality" parameter (ie. if you're labeling a
tiny polygon with a tiny label, dont bother). Metrics are descibed in #3. 6.
TODO: add ability for SLD to tweak parameters (ie. "always label").
------------------------------------------------------------------------------------------
I've added extra functionality; a) priority -- if you set the in a
TextSymbolizer, then you can control the order of labelling ** see mailing
list for more details b) no ---
turns off grouping for this symbolizer c) 5 --
do not put labels within 5 pixels of this label.
author: jeichar author: dblasby
clipLineString(LineString line, Polygon bbox, Envelope displayGeomEnv) try to be more robust dont bother returning points
This will try to solve robustness problems, but read code as to what it
does.
public MultiPolygon
clipPolygon(Polygon poly, Polygon bbox, Envelope displayGeomEnv) try to do a more robust way of clipping a polygon to a bounding box.
When true, the text is rendered as its GlyphVector outline (as a geometry) instead of using
drawGlypVector. Pro: labels and halos are perfectly centered, some people prefer the
extra antialiasing obtained. Cons: possibly slower, some people do not like the
extra antialiasing :)
public MultiLineString clipLineString(LineString line, Polygon bbox, Envelope displayGeomEnv)(Code)
try to be more robust dont bother returning points
This will try to solve robustness problems, but read code as to what it
does. It might return the unclipped line if there's a problem!
Parameters: line - Parameters: bbox - MUST BE A BOUNDING BOX
clipPolygon
public MultiPolygon clipPolygon(Polygon poly, Polygon bbox, Envelope displayGeomEnv)(Code)
try to do a more robust way of clipping a polygon to a bounding box. This
might return the orginal polygon if it cannot clip TODO: this is a bit
simplistic, there's lots more to do.
Parameters: poly - Parameters: bbox - Parameters: displayGeomEnv - a MutliPolygon
1. make a list of all the geoms (not clipped) NOTE: reject points,
convert polygons to their exterior ring (you shouldnt be calling this
function with points and polys) 2. join the lines together 3. clip
resulting lines to display geometry 4. return longest line
NOTE: the joining has multiple solution. For example, consider a Y (3
lines): * * 1 2 * * * 3 * solutions are: 1->2 and 3 1->3 and 2 2->3 and 1
(see mergeLines() below for detail of the algorithm; its basically a
greedy algorithm that should form the 'longest' possible route through
the linework)
NOTE: we clip after joining because there could be connections "going on"
outside the display bbox
Parameters: geoms - Parameters: displayGeometry - must be poly
Point getPointSetRepresentativeLocation(List geoms, Geometry displayGeometry)(Code)
1. get a list of points from the input geometries that are inside the
displayGeom NOTE: lines and polygons are reduced to their centroids (you
shouldnt really calling this with lines and polys) 2. choose the most
"central" of the points METRIC - choose anyone TODO: change metric to be
"closest to the centoid of the possible points"
Parameters: geoms - list of Point or MultiPoint (any other geometry types arerejected Parameters: displayGeometry - a point or null (if there's nothing to draw)
1. make a list of all the polygons clipped to the displayGeometry NOTE:
reject any points or lines 2. choose the largest of the clipped
geometries
Parameters: geoms - Parameters: displayGeometry -
get the priority from the symbolizer its an expression, so it will try to
evaluate it: 1. if its missing --> DEFAULT_PRIORITY 2. if its a number,
return that number 3. if its not a number, convert to string and try to
parse the number; return the number 4. otherwise, return DEFAULT_PRIORITY
Parameters: symbolizer - Parameters: feature -
merges a set of lines together into a (usually) smaller set. This one's
pretty dumb, we use the JTS method (which doesnt merge on degree 3 nodes)
and try to construct less lines.
There's multiple solutions, but we do this the easy way. Usually you will
not be given more than 3 lines (especially after jts is finished with).
Find a line, find a lines that it "connects" to and add it. Keep going.
DONE: be smarter - use length so the algorithm becomes greedy.
This isnt 100% correct, but usually it does the right thing.
NOTE: this is O(N^2), but N tends to be <10
Parameters: lines -
middleLine
Point middleLine(LineString l, double percent)(Code)
calculate the middle of a line. The returning point will be x% (0.5 =
50%) along the line and on the line.
Parameters: l - Parameters: percent - 0=start, 0.5=middle, 1.0=end
pull a line from the list, and: 1. if nothing connects to it (its
issolated), add it to "result" 2. otherwise, merge it at the start/end
with the LONGEST line there. 3. remove the original line, and the lines
it merged with from the hashtables 4. go again, with the merged line
Parameters: edges - Parameters: nodes - Parameters: result -
public void setOutlineRenderingEnabled(boolean outlineRenderingEnabled)(Code)
Sets the text rendering mode.
When true, the text is rendered as its GlyphVector outline (as a geometry) instead of using
drawGlypVector. Pro: labels and halos are perfectly centered, some people prefer the
extra antialiasing obtained. Cons: possibly slower, some people do not like the
extra antialiasing :)