Ticket #2031 (new enhancement)
Draw labels at angles relative to true geographic north regardless of projection.
| Reported by: | sroberts@… | Owned by: | sdlime |
|---|---|---|---|
| Priority: | high | Milestone: | |
| Component: | MapServer C Library | Version: | unspecified |
| Severity: | minor | Keywords: | |
| Cc: | dmorissette |
Description (last modified by dmorissette) (diff)
As far as I can tell Mapserver lacks the ability to draw symbols or labels at
angles relative to true geographic north regardless of the map projection being
used. All angles are only relative to the top of the image in the image
coordinate system, not the map coordinate system. Having the ability to draw
symbols/labels relative to true north is essential for some applications. For
example, drawing the symbol of a ship pointed in the actual direction the ship
is going on a polar stereographic map.
The following is a proposed enhancement to the Mapfile LABEL object to support
this capability. (I assume it should be fairly straightforward to make the same
enhancements to the Mapfile STYLE object.)
A) Create a new boolean directive for "LABEL" called something like
"ANGLETRUENORTH". When set to false or absent LABEL angles should be treated as
before. However if "ANGLETRUENORTH TRUE" is present in LABEL then an angle
specified via "ANGLE" or "LABELANGLEITEM" should be drawn at the angle relative
to geographic north where angle is given in degrees clockwise from 0 at the top
where 0 = North, 90 = East, 180 = South, 270 = West. (I found it necessary to
reverse the direction of the drawing angle from counter-clockwise to clockwise
since the standard for these types of applications is clockwise.)
B) Create a subroutine to offset the angle correctly. The following code will
do this. Probably the logical place to put this would be in mapproject.c?:
------------------------------begin code----------------------------------
/************************************************************************/
/* msProjectAngle() */
/* */
/* Shifts "angle" by the correct amount to keep it relative to the */
/* geographic north pole regardless of map projection and location */
/* on map. */
/* */
/* "angle" is relative to geographic north where angle is given in */
/* degrees clockwise from 0 at the top (0 = North, 90 = East, */
/* 180 = South, 270 = West). */
/* */
/* "mappoint" has been projected to the map projection and is the */
/* location of "angle" on map. */
/************************************************************************/
int msProjectAngle(mapObj *map, pointObj *mappoint, double *angle)
{
#ifdef USE_PROJ
double angle_offset;
pointObj mappoint2;
/* Only transform angle if out proj is not latlong */
if(!pj_is_latlong(map->projection.proj)) {
/* Make a copy of the first point */
mappoint2.x = mappoint->x;
mappoint2.y = mappoint->y;
/* convert to latlong */
if( msProjectPoint(&map->projection, &map->latlon, &mappoint2) ==
MS_FAILURE )
return MS_FAILURE;
/* apply a slight offset(~100 meters) south of the original point */
mappoint2.y -= 3.0/(60.0*60.0);
/* convert the offset point back to map projection */
if( msProjectPoint( &map->latlon, &map->projection, &mappoint2) ==
MS_FAILURE )
return MS_FAILURE;
/* Calculate angle between these two points. This will be the angle offset
relative to true north for the map projection. */
angle_offset = MS_RAD_TO_DEG*asin((mappoint->x -
mappoint2.x)/sqrt(pow((mappoint->x - mappoint2.x),2.0) + pow((mappoint->y -
mappoint2.y),2.0)));
if((mappoint->y - mappoint2.y) < 0) angle_offset = 180 - angle_offset;
*angle += angle_offset;
}
/* Change from counterclockwise to clockwise */
*angle = - *angle;
return(MS_SUCCESS);
#else
msSetError(MS_PROJERR, "Projection support is not available.",
"msProjectAngle()");
return(MS_FAILURE);
#endif
}
-------------------------------end code-----------------------------------
C) Modifiy mapdraw.c to include a call to the above subroutine where it draws
the point labels if it detects the "ANGLETRUENORTH" directive. Attached is a
proposed patch for mapdraw.c.
Does the above seem like a reasonable approach? Would it be possible to include
some variation of this in the next release?
-Steve
Attachments
Change History
Note: See
TracTickets for help on using
tickets.

