Opened 16 years ago

Closed 16 years ago

#2455 closed defect (fixed)

ANGLE FOLLOW sometimes not centered on straight lines

Reported by: richf Owned by: sdlime
Priority: low Milestone: 5.2 release
Component: MapServer C Library Version: 5.0
Severity: minor Keywords:
Cc:

Description

This seems similar to the misplaced labels noted here in bug #1620: https://trac.osgeo.org/mapserver/attachment/ticket/1620/labels.png

Sometimes, esp. it seems when the road really is curvy, things look fine. But other times, which I think is in general when the road segment is perfectly straight, what appears to be happening is that the text is on the line, either it appears:

  • Somewhat above center. This is the common error. I'm not sure if the center of the text is aligned with the top of the line, or if the bottom of the text is aligned with the center of the line. They're close here because the size of the text is close to the width of the line.
  • Somewhat below center. This is a less common error. Similar to above, I'm not sure if the center of the text is aligned with the bottom of the line, or if the top of the text is aligned with the center of the line. Again, they're close here because the size of the text is close to the width of the line.

It doesn't appear to be affected by the renderer. I will attach two map files (one using AGG and one using GD) and the corresponding outputs to illustrate. I'm not sure if I can attach the data or not -- I'll have to first check if the license I have for the data will let me do that, if it's needed.

This doesn't appear to me to be covered by any of bugs #2020, #2221, #2223, or #2329, which is why I'm filing a new bug.

I'm running mapserver-5.0.0, compiled on debian 3.1 (sarge), with locally compiled copies of gd 2.0.35 and agg 2.5, with the following configuration:

[rich@peyote mapserver-5.0.0 17:52:02]$ ./mapserv -v
MapServer version 5.0.0 OUTPUT=GIF OUTPUT=PNG OUTPUT=WBMP OUTPUT=SVG SUPPORTS=PROJ SUPPORTS=AGG SUPPORTS=FREETYPE SUPPORTS=THREADS INPUT=POSTGIS INPUT=SHAPEFILE

I'm not sure if this is related (or even if it's a problem), but since it might be, I'll report it here. In msDrawShape() in mapdraw.c, at line 1352, there's:

      /* Bug #1620 implementation */
      if ( layer->class[c]->label.autofollow == MS_TRUE ) {

        annopath = msPolylineLabelPath(shape, layer->class[c]->label.minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &status);

a little below this, at line 1557, there's:

      /* Use regular label algorithm if angle is AUTO or a number, or if ANGLE FOLLOW failed */
      if ( layer->class[c]->label.autofollow == MS_FALSE || (!annopath && status != MS_FAILURE) ) {

if the ANGLE FOLLOW failed, won't status be set to MS_FAILURE ? So shouldn't the second bit read either:

      /* Use regular label algorithm if angle is AUTO or a number, or if ANGLE FOLLOW failed */
      if ( layer->class[c]->label.autofollow == MS_FALSE || (!annopath && status == MS_FAILURE) ) {

or:

      /* Use regular label algorithm if angle is AUTO or a number, or if ANGLE FOLLOW failed */
      if ( layer->class[c]->label.autofollow == MS_FALSE || (!annopath && status != MS_SUCCESS) ) {

?

Attachments (8)

labelbug.agg.map (2.0 KB ) - added by richf 16 years ago.
.map file with AGG renderer
labelbug.agg.png (21.2 KB ) - added by richf 16 years ago.
.png output with AGG renderer
labelbug.gd.map (1.7 KB ) - added by richf 16 years ago.
.map file with GD renderer
labelbug.gd.png (21.3 KB ) - added by richf 16 years ago.
.png output with GD renderer
labelbug.59th.png (12.3 KB ) - added by richf 16 years ago.
map that goes along with the comment from 12/20/07 22:16:45
labelbug.59th.points.png (11.4 KB ) - added by richf 16 years ago.
map that goes along with the comment from 12/21/07 15:33:41
labelbug.59th.points.2.png (11.4 KB ) - added by richf 16 years ago.
map that goes along with comment:4 (12/21/07 17:08:04)
labelbug.59th.noposition.png (12.2 KB ) - added by richf 16 years ago.
never mind the previous attachment, it was a mistaken duplicate, this is the one i meant to attach

Download all attachments as: .zip

Change History (18)

by richf, 16 years ago

Attachment: labelbug.agg.map added

.map file with AGG renderer

by richf, 16 years ago

Attachment: labelbug.agg.png added

.png output with AGG renderer

by richf, 16 years ago

Attachment: labelbug.gd.map added

.map file with GD renderer

by richf, 16 years ago

Attachment: labelbug.gd.png added

.png output with GD renderer

comment:1 by richf, 16 years ago

fonts.list only has a single line, so i'll just include it here, rather than attaching:

verdana                 verdana.ttf

ASIDE: Is there any way to put that info inline into the map file rather than having a level of indirection pointing to a file for it?

comment:2 by richf, 16 years ago

I narrowed down the FILTER in my previous example (labelbug.agg.map) for the LAYER with TYPE ANNOTATION to have only the following streets:

        FILTER      "the_geom && 'LINESTRING(-122.29387782911999 37.83784162816001, -122.28812217088 37.84215837184)' AND (st_name='59TH ST' OR st_name='HORTON ST')"

In the png that I will attach next, HORTON ST looks okay in 2 cases and bad in 1 case, and 59TH ST looks bad in all 3 cases.

I ran mapserv with gdb and set breakpoints in msDrawShape() in mapdraw.c at line 1350 (case(MS_SHAPE_LINE)) and line 1533 (case MS_LAYER_LINE). Line 1350 was reached once for each label output. Line 1533 was never reached.

In both of the 2 good cases, line 1352:

        annopath = msPolylineLabelPath(shape, layer->class[c]->label.minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &status);

returned a valid annopath, and the label was actually added to the map with line 1362.

In all of the 4 bad cases, line 1352 returned a NULL annopath.

Regarding my previous observation about the clause (!annopath && status != MS_FAILURE), which is at both line 1380 and line 1557. (I had only noticed one when I originally filed the bug.)

It's possible that it might be an issue, but if so it's not relevant here. In all of the bad cases, status was still set to 0 (MS_SUCCESS) after the call to msPolylineLabelPath() on line 1352. What caused the /* Regular labels */ section to become applicable was the fact that annopath was NULL.

Anyway, in all 4 of the bad cases, the label was actually added to the map with line 1393:

            if(msAddLabel(map, layer->index, c, shape->index, shape->tileindex, &annopnt, NULL, shape->text, length, &label) != MS_SUCCESS) return(MS_FAILURE);

I haven't yet tracked it down any further, and I have to take a break now, but I wanted to post the findings that I have so far, which I think seem to confirm that the problem coincides with labels for which the ANGLE FOLLOW does not end up applying. My guess is that it's not a bug that it doesn't apply in these cases, because the road segment is straight. (And that the bug is the consequence of it not applying.) But I'm not familiar enough with the code to know whether or not that's really true.

by richf, 16 years ago

Attachment: labelbug.59th.png added

map that goes along with the comment from 12/20/07 22:16:45

comment:3 by richf, 16 years ago

I have done some more debugging. See the map that I will attach next for details.

I followed all 6 calls into msAddLabel() at maplabel.c:52. The 2 "good" cases came from mapdraw.c:1362 and have a valid labelPathObj *labelpath and a NULL pointObj *point. The 4 "bad" cases came from mapdraw.c:1393 and have a valid pointObj *point and a NULL labelPathObj *labelpath.

Each of the point cases is just a single point. Each of the path cases contains 9 points, one for each character in the char *string, counting the space.

I plotted all of these points on the map. In the path cases, the text is placed so that each point is at the lower left corner of each character. In other words, the text is above and to the right of the points. This works out okay, because the path is tracing near the edge of the street, not in the middle.

In the point cases, the entire text is placed so that the point is approximately at the lower right corner of the entire string. In other words, all of the text is above and approximately to the left of the single point. I say approximately, because if you look closely, the point is closer to the middle of the "T" in "59TH ST" than to the edge. But that's a minor issue. This is a problem here because the point is in the middle of the street, not near the edge.

I can think of two possible ways to address this.

  1. Assume that the point is correct, but the placement of text relative to the point is wrong. Rather than having the text above and to the left of the point, center it (both horizontally and vertically) relative to the point. Only the vertical placement is necessary to address my primary concern, but I think horizontal is probably the correct thing to do as well, and might address some other labeling artifacts I'm having.
  1. Assume that the placement is correct, but that the point is wrong. Rather than have the point end up in the middle of the street verically, place it by the edge (offset downward by half of the height of the font). This will address the vertical placement, which is the primary concern of the bug. It will do nothing to address the horizontal placement, although that could be accounted for as well by offsetting the point to the right half of the width of the string given the font.

My assumption is that (1) is the more logical approach, but it might depend on other assumptions made within the code. If possible, I'd like to get some feedback from someone more familiar with the code before proceeding too much further with debugging.

by richf, 16 years ago

Attachment: labelbug.59th.points.png added

map that goes along with the comment from 12/21/07 15:33:41

comment:4 by richf, 16 years ago

This might just be a case of user error on my part. If I comment out the POSITION AUTO within the LABEL declaration, things look fine. Will attach a map to illustrate.

Fwiw, I noticed that cachePtr.label.position was getting set to 110 (MS_AUTO), and that, along with the following description from here:

http://mapserver.gis.umn.edu/docs/reference/mapfile/label

POSITION [ul|uc|ur|cl|cc|cr|ll|lc|lr|auto]
    Position of the label relative to the labeling point (layers only). First letter is "Y" position, second letter is "X" position. "Auto" tells MapServer to calculate a label position that will not interfere with other labels.... With lines, it only uses lc or uc, until it finds a position that doesn't collide with labels that have already been drawn.

caused me to think that this might be an issue.

by richf, 16 years ago

Attachment: labelbug.59th.points.2.png added

map that goes along with comment:4 (12/21/07 17:08:04)

by richf, 16 years ago

never mind the previous attachment, it was a mistaken duplicate, this is the one i meant to attach

comment:5 by richf, 16 years ago

Priority: normallow
Severity: normalminor

Ok, I got rid of all of my POSITION AUTO from any LABEL that had a ANGLE FOLLOW declaration, and now things look much better.

I don't know if having these together giving the result that I saw is a bug or not. I'd consider changing the summary of this bug to "POSITION AUTO with ANGLE FOLLOW leads to badness", but I don't know whether changing the summary of a bug is considered not desirable here.

Will still keep open, in case this is a bug, but lowering in priority and severity. If this isn't a bug, then just resolve as INVALID. And if that's the case, sorry if I've wasted anyone's time, although mostly it's probably just my time that I wasted. (Should I have posted this as a question to the mailing list before filing a bug?)

comment:6 by sdlime, 16 years ago

Milestone: 5.0.1 release
Status: newassigned

Hi Rich: Wow, thanks for the detailed report. You didn't waste anyone's time and I thank you for doing all the legwork, saved me tons of time. I would definitely consider this a bug on a couple of fronts.

1) We need to make the label cache drawing routine aware that there are no alternative placements for curved labels, and...

2) The docs need to reflect this.

Steve

comment:7 by sdlime, 16 years ago

Milestone: 5.0.1 release5.2 release

I'm going to defer this until 5.2. There was work done to merge the label cache rendering between GD and AGG so fixing this will be easier. Figure that's no big deal since the workaround is easy.

Steve

comment:8 by sdlime, 16 years ago

Resolution: fixed
Status: assignedclosed

Fixed in svn main trunk (r7231). Closing...

Steve

comment:9 by tbonfort, 16 years ago

Resolution: fixed
Status: closedreopened

reopening as the fix causes #2600

comment:10 by sdlime, 16 years ago

Resolution: fixed
Status: reopenedclosed
Note: See TracTickets for help on using tickets.