Skip to content
Permalink
Browse files

GRID layer: fix label positionning when requesting WGS84 graticule in…

… EPSG:3857

This clamps labels in the validity area of EPSG:3857, even if the eastings of the
BBOX exceed 20037508.
  • Loading branch information
rouault committed Feb 20, 2017
1 parent 094c6f5 commit fc36c0aa8b0277ae10770a6c959ad25927c5306b
@@ -187,6 +187,19 @@ int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery)
* These lines will be used when generating labels to get correct placement at arc/rect edge intersections.
*/
rectMapCoordinates = layer->map->extent;
#ifdef USE_PROJ
layer->project = msProjectionsDiffer(&(layer->projection), &(layer->map->projection));
if( layer->project &&
strstr(layer->map->projection.args[0], "epsg:3857") &&
pj_is_latlong(layer->projection.proj) )
{
if( rectMapCoordinates.minx < -20037508)
rectMapCoordinates.minx = -20037508;
if( rectMapCoordinates.maxx > 20037508 )
rectMapCoordinates.maxx = 20037508;
}
#endif

msFree(pInfo->pboundinglines);
pInfo->pboundinglines = (lineObj *) msSmallMalloc( sizeof( lineObj ) * 4 );
msFree(pInfo->pboundingpoints);
@@ -205,7 +218,6 @@ int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery)
pInfo->pboundinglines[0].point[1].y = rectMapCoordinates.maxy;

#ifdef USE_PROJ
layer->project = msProjectionsDiffer(&(layer->projection), &(layer->map->projection));
if(layer->project)
msProjectLine(&layer->map->projection, &layer->projection, &pInfo->pboundinglines[0]);
#endif
@@ -287,7 +299,7 @@ int msGraticuleLayerNextShape(layerObj *layer, shapeObj *shape)
case 0:
if(!pInfo->blabelaxes) { /* Bottom */
pInfo->ilabelstate++;
shape->numlines = 0;
msFreeShape(shape);
return MS_SUCCESS;
}

@@ -306,15 +318,19 @@ int msGraticuleLayerNextShape(layerObj *layer, shapeObj *shape)

_FormatLabel( layer, shape, shape->line->point[0].x );
if(_AdjustLabelPosition( layer, shape, posBottom ) != MS_SUCCESS)
return MS_FAILURE;
{
msFreeShape(shape);
pInfo->ilabelstate++;
return MS_SUCCESS;
}

pInfo->ilabelstate++;
return MS_SUCCESS;

case 1:
if(!pInfo->blabelaxes) { /* Top */
pInfo->ilabelstate++;
shape->numlines = 0;
msFreeShape(shape);
return MS_SUCCESS;
}

@@ -333,7 +349,11 @@ int msGraticuleLayerNextShape(layerObj *layer, shapeObj *shape)

_FormatLabel( layer, shape, shape->line->point[0].x );
if(_AdjustLabelPosition( layer, shape, posTop ) != MS_SUCCESS)
return MS_FAILURE;
{
msFreeShape(shape);
pInfo->ilabelstate++;
return MS_SUCCESS;
}

pInfo->ilabelstate++;
return MS_SUCCESS;
@@ -372,7 +392,7 @@ int msGraticuleLayerNextShape(layerObj *layer, shapeObj *shape)
case 0:
if(!pInfo->blabelaxes) { /* Left side */
pInfo->ilabelstate++;
shape->numlines = 0;
msFreeShape(shape);
return MS_SUCCESS;
}

@@ -391,15 +411,19 @@ int msGraticuleLayerNextShape(layerObj *layer, shapeObj *shape)

_FormatLabel( layer, shape, shape->line->point[0].y );
if(_AdjustLabelPosition( layer, shape, posLeft ) != MS_SUCCESS)
return MS_FAILURE;
{
msFreeShape(shape);
pInfo->ilabelstate++;
return MS_SUCCESS;
}

pInfo->ilabelstate++;
return MS_SUCCESS;

case 1:
if(!pInfo->blabelaxes) { /* Right side */
pInfo->ilabelstate++;
shape->numlines = 0;
msFreeShape(shape);
return MS_SUCCESS;
}

@@ -418,7 +442,11 @@ int msGraticuleLayerNextShape(layerObj *layer, shapeObj *shape)

_FormatLabel( layer, shape, shape->line->point[0].y );
if(_AdjustLabelPosition( layer, shape, posRight ) != MS_SUCCESS)
return MS_FAILURE;
{
msFreeShape(shape);
pInfo->ilabelstate++;
return MS_SUCCESS;
}

pInfo->ilabelstate++;
return MS_SUCCESS;
@@ -1039,7 +1067,20 @@ static int _AdjustLabelPosition( layerObj *pLayer, shapeObj *pShape, msGraticule

#ifdef USE_PROJ
if(pLayer->project)
{
msProjectShape( &pLayer->projection, &pLayer->map->projection, pShape );

/* Poor man detection of reprojection failure */
if( pj_is_latlong(pLayer->projection.proj) !=
pj_is_latlong(pLayer->map->projection.proj) )
{
if( ptPoint.x == pShape->line->point[0].x &&
ptPoint.y == pShape->line->point[0].y )
{
return MS_FAILURE;
}
}
}
#endif

if(pLayer->transform) {
@@ -1067,8 +1108,8 @@ static int _AdjustLabelPosition( layerObj *pLayer, shapeObj *pShape, msGraticule
pShape->line->point[0].y = fabs(rectLabel.maxy - rectLabel.miny) * 2 + 5;
break;
case posLeft:
pShape->line->point[1].x = 0;
pShape->line->point[0].x = fabs(rectLabel.maxx - rectLabel.minx) * 2 + 5;
pShape->line->point[0].x = 0;
pShape->line->point[1].x = fabs(rectLabel.maxx - rectLabel.minx) * 2 + 5;
break;
case posRight:
pShape->line->point[1].x = pLayer->map->width;
@@ -1081,7 +1122,75 @@ static int _AdjustLabelPosition( layerObj *pLayer, shapeObj *pShape, msGraticule

#ifdef USE_PROJ
if(pLayer->project)
{
/* Clamp coordinates into the validity area of the projection, in the */
/* particular case of EPSG:3857 (WebMercator) to longlat reprojection */
if( strstr(pLayer->map->projection.args[0], "epsg:3857") &&
pj_is_latlong(pLayer->projection.proj) )
{
if( !pLayer->map->projection.gt.need_geotransform &&
ePosition == posLeft && pShape->line->point[0].x < -20037508)
{
pShape->line->point[1].x = -20037508 + (pShape->line->point[1].x -
pShape->line->point[0].x);
pShape->line->point[0].x = -20037508;
}
else if( pLayer->map->projection.gt.need_geotransform &&
ePosition == posLeft &&
pLayer->map->projection.gt.geotransform[0] +
pShape->line->point[0].x *
pLayer->map->projection.gt.geotransform[1] +
pShape->line->point[0].y *
pLayer->map->projection.gt.geotransform[2] < -20037508)
{
double y_tmp;
double width = pShape->line->point[1].x - pShape->line->point[0].x;

y_tmp = pLayer->map->projection.gt.geotransform[3] +
pShape->line->point[0].x *
pLayer->map->projection.gt.geotransform[4] +
pShape->line->point[0].y *
pLayer->map->projection.gt.geotransform[5];
pShape->line->point[0].x =
pLayer->map->projection.gt.invgeotransform[0] +
-20037508 * pLayer->map->projection.gt.invgeotransform[1] +
y_tmp * pLayer->map->projection.gt.invgeotransform[2];
pShape->line->point[1].x = pShape->line->point[0].x + width;
}

if( !pLayer->map->projection.gt.need_geotransform &&
ePosition == posRight && pShape->line->point[1].x > 20037508)
{
pShape->line->point[0].x = 20037508 - (pShape->line->point[1].x -
pShape->line->point[0].x);
pShape->line->point[1].x = 20037508;
}
else if( pLayer->map->projection.gt.need_geotransform &&
ePosition == posRight &&
pLayer->map->projection.gt.geotransform[0] +
pShape->line->point[1].x *
pLayer->map->projection.gt.geotransform[1] +
pShape->line->point[1].y *
pLayer->map->projection.gt.geotransform[2] > 20037508)
{
double y_tmp;
double width = pShape->line->point[1].x - pShape->line->point[0].x;

y_tmp = pLayer->map->projection.gt.geotransform[3] +
pShape->line->point[1].x *
pLayer->map->projection.gt.geotransform[4] +
pShape->line->point[1].y *
pLayer->map->projection.gt.geotransform[5];
pShape->line->point[1].x =
pLayer->map->projection.gt.invgeotransform[0] +
20037508 * pLayer->map->projection.gt.invgeotransform[1] +
y_tmp * pLayer->map->projection.gt.invgeotransform[2];
pShape->line->point[0].x = pShape->line->point[1].x - width;
}
}

msProjectShape( &pLayer->map->projection, &pLayer->projection, pShape );
}
#endif

switch( ePosition ) {
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,75 @@
#
# Test WMS
#
# REQUIRES: INPUT=GDAL OUTPUT=PNG SUPPORTS=WMS
#
# Check that labels are in the left and right
#
# RUN_PARMS: wms_grid_reproj_to_3857_square_pixels_within_validity.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image/png&TRANSPARENT=false&LAYERS=grid4326&CRS=EPSG:3857&STYLES=&WIDTH=2000&HEIGHT=1500&BBOX=-20000000,-15000000,20000000,15000000" > [RESULT_DEMIME]
#
# RUN_PARMS: wms_grid_reproj_to_3857_square_pixels_beyond_validity.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image/png&TRANSPARENT=false&LAYERS=grid4326&CRS=EPSG:3857&STYLES=&WIDTH=2036&HEIGHT=739&BBOX=-39996745.16861447,-14460662.759102784,39683659.10075838,14460662.759102784" > [RESULT_DEMIME]
#
# RUN_PARMS: wms_grid_reproj_to_3857_non_square_pixels_beyond_validity.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image/png&TRANSPARENT=false&LAYERS=grid4326&CRS=EPSG:3857&STYLES=&WIDTH=2036&HEIGHT=735&BBOX=-39996745.16861447,-14460662.759102784,39683659.10075838,14460662.759102784" > [RESULT_DEMIME]
#

MAP
NAME WMS_GRID_TEST
EXTENT -180 -90 180 90
UNITS DD
FONTSET "../misc/fonts.lst"

WEB
METADATA
wms_enable_request "*"
END
END

PROJECTION
"init=epsg:4326"
END

OUTPUTFORMAT
NAME GDPNG
DRIVER "GD/PNG"
MIMETYPE "image/png"
EXTENSION "png"
END

LAYER
NAME "grid4326"

METADATA
"wms_srs" "EPSG:4326 EPSG:3857"
"wms_extent" "-180 -90 180 90"
END

TYPE LINE

CLASS
NAME "Graticule"
COLOR 255 153 0
LABEL
COLOR 0 0 0
FONT lucida
TYPE truetype
SIZE 8
POSITION AUTO
PARTIALS FALSE
BUFFER 5
OUTLINECOLOR 255 255 255
END
END

PROJECTION
"init=epsg:4326"
END

GRID
LABELFORMAT 'DDMMSS' # nice if a projected SRS used
MININTERVAL 30
MAXINTERVAL 30
END

END # Layer

END

0 comments on commit fc36c0a

Please sign in to comment.
You can’t perform that action at this time.