Skip to content
Permalink
Browse files
UVRaster: fix reprojection issue of map extent to layer projection (f…
…ixes #5501)
  • Loading branch information
rouault committed Nov 3, 2017
1 parent 1ee7e0e commit 2a990dc46f13ed8b965f0d83cde7df7da17b831f
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 3 deletions.
@@ -956,8 +956,100 @@ int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image)
if(layer->transform == MS_TRUE) {
searchrect = map->extent;
#ifdef USE_PROJ
if((map->projection.numargs > 0) && (layer->projection.numargs > 0))
msProjectRect(&map->projection, &layer->projection, &searchrect); /* project the searchrect to source coords */
if((map->projection.numargs > 0) && (layer->projection.numargs > 0)) {
int bDone = MS_FALSE;

/* For UVRaster, it is important that the searchrect is not too large */
/* to avoid insufficient intermediate raster resolution, which could */
/* happen if we use the default code path, given potential reprojection */
/* issues when using a map extent that is not in the validity area of */
/* the layer projection. */
if( layer->connectiontype == MS_UVRASTER &&
!layer->projection.gt.need_geotransform &&
!(pj_is_latlong(map->projection.proj) &&
pj_is_latlong(layer->projection.proj)) ) {
rectObj layer_ori_extent;

if( msLayerGetExtent(layer, &layer_ori_extent) == MS_SUCCESS ) {
projectionObj map_proj;

double map_extent_minx = map->extent.minx;
double map_extent_miny = map->extent.miny;
double map_extent_maxx = map->extent.maxx;
double map_extent_maxy = map->extent.maxy;
rectObj layer_extent = layer_ori_extent;

/* Create a variant of map->projection without geotransform for */
/* conveniency */
msInitProjection(&map_proj);
msCopyProjection(&map_proj, &map->projection);
map_proj.gt.need_geotransform = MS_FALSE;
if( map->projection.gt.need_geotransform ) {
map_extent_minx = map->projection.gt.geotransform[0]
+ map->projection.gt.geotransform[1] * map->extent.minx
+ map->projection.gt.geotransform[2] * map->extent.miny;
map_extent_miny = map->projection.gt.geotransform[3]
+ map->projection.gt.geotransform[4] * map->extent.minx
+ map->projection.gt.geotransform[5] * map->extent.miny;
map_extent_maxx = map->projection.gt.geotransform[0]
+ map->projection.gt.geotransform[1] * map->extent.maxx
+ map->projection.gt.geotransform[2] * map->extent.maxy;
map_extent_maxy = map->projection.gt.geotransform[3]
+ map->projection.gt.geotransform[4] * map->extent.maxx
+ map->projection.gt.geotransform[5] * map->extent.maxy;
}

/* Reproject layer extent to map projection */
msProjectRect(&layer->projection, &map_proj, &layer_extent);

if( layer_extent.minx <= map_extent_minx &&
layer_extent.miny <= map_extent_miny &&
layer_extent.maxx >= map_extent_maxx &&
layer_extent.maxy >= map_extent_maxy ) {
/* do nothing special if area to map is inside layer extent */
}
else {
if( layer_extent.minx >= map_extent_minx &&
layer_extent.maxx <= map_extent_maxx &&
layer_extent.miny >= map_extent_miny &&
layer_extent.maxy <= map_extent_maxy ) {
/* if the area to map is larger than the layer extent, then */
/* use full layer extent and add some margin to reflect the */
/* proportion of the useful area over the requested bbox */
double extra_x =
(map_extent_maxx - map_extent_minx) /
(layer_extent.maxx - layer_extent.minx) *
(layer_ori_extent.maxx - layer_ori_extent.minx);
double extra_y =
(map_extent_maxy - map_extent_miny) /
(layer_extent.maxy - layer_extent.miny) *
(layer_ori_extent.maxy - layer_ori_extent.miny);
searchrect.minx = layer_ori_extent.minx - extra_x / 2;
searchrect.maxx = layer_ori_extent.maxx + extra_x / 2;
searchrect.miny = layer_ori_extent.miny - extra_y / 2;
searchrect.maxy = layer_ori_extent.maxy + extra_y / 2;
}
else
{
/* otherwise clip the map extent with the reprojected layer */
/* extent */
searchrect.minx = MAX( map_extent_minx, layer_extent.minx );
searchrect.maxx = MIN( map_extent_maxx, layer_extent.maxx );
searchrect.miny = MAX( map_extent_miny, layer_extent.miny );
searchrect.maxy = MIN( map_extent_maxy, layer_extent.maxy );
/* and reproject into the layer projection */
msProjectRect(&map_proj, &layer->projection, &searchrect);
}
bDone = MS_TRUE;
}

msFreeProjection(&map_proj);
}
}

if( !bDone )
msProjectRect(&map->projection, &layer->projection, &searchrect); /* project the searchrect to source coords */
}
#endif
} else {
searchrect.minx = searchrect.miny = 0;
@@ -930,7 +930,7 @@ msProjectRectAsPolygon(projectionObj *in, projectionObj *out,
/* logic. */
/* -------------------------------------------------------------------- */
if( out && pj_is_latlong(out->proj) && in && !pj_is_latlong(in->proj)
&& rect->maxx - rect->minx > 360.0 ) {
&& rect->maxx - rect->minx > 360.0 && !out->gt.need_geotransform ) {
rect->maxx = 180;
rect->minx = -180;
}
@@ -698,6 +698,8 @@ int msUVRASTERLayerGetExtent(layerObj *layer, rectObj *extent)
msTryBuildPath3(szPath, map->mappath, map->shapepath, layer->data);
decrypted_path = msDecryptStringTokens( map, szPath );

GDALAllRegister();

msAcquireLock( TLOCK_GDAL );
if( decrypted_path ) {
hDS = GDALOpen(decrypted_path, GA_ReadOnly );
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,77 @@
#
# Test WMS
#
# REQUIRES: INPUT=GDAL OUTPUT=PNG SUPPORTS=WMS
#
# RUN_PARMS: wms_uvraster_map_reprojection_extent_larger_than_layer.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=-85,-500,190,200&CRS=EPSG:4326&WIDTH=946&HEIGHT=583&LAYERS=test&STYLES=&FORMAT=image/png&DPI=98&MAP_RESOLUTION=98&FORMAT_OPTIONS=dpi:98&TRANSPARENT=TRUE" > [RESULT_DEMIME]
#
# RUN_PARMS: wms_uvraster_map_reprojection_extent_smaller_than_layer.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=30,-170,60,-100&CRS=EPSG:4326&WIDTH=400&HEIGHT=200&LAYERS=test&STYLES=&FORMAT=image/png&TRANSPARENT=TRUE" > [RESULT_DEMIME]
#
# RUN_PARMS: wms_uvraster_map_reprojection_extent_intersecting_layer.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=30,-200,60,-100&CRS=EPSG:4326&WIDTH=400&HEIGHT=200&LAYERS=test&STYLES=&FORMAT=image/png&TRANSPARENT=TRUE" > [RESULT_DEMIME]

MAP
NAME test
EXTENT -180 -90 180 90
MAXSIZE 4096
SIZE 500 300
SHAPEPATH ./data

SYMBOL
NAME "arrow_wind"
TYPE vector
FILLED true
POINTS
0 1.2
6 1.2
6 3
10 0
6 -3
6 -1.2
0 -1.2
0 1.2
END
END

PROJECTION
"init=epsg:4326"
END

WEB
METADATA
"ows_enable_request" "*"
END
END

LAYER
NAME "test"
TYPE POINT
CONNECTIONTYPE uvraster
PROCESSING "BANDS=1,2"
PROCESSING "UV_SPACING=20"

PROJECTION
"proj=stere"
"lat_0=90"
"lat_ts=60"
"lon_0=249"
"k=90"
"x_0=0"
"y_0=0"
"a=6371229"
"b=6371229"
"units=m"
"no_defs"
END

DATA 'wms_uvraster_map_reprojection.tif'

CLASS
STYLE
COLOR 0 0 127
SYMBOL "arrow_wind"
ANGLE [uv_angle]
SIZE 12
END
END
END
END

0 comments on commit 2a990dc

Please sign in to comment.