Commit e8d57973 authored by Bas Couwenberg's avatar Bas Couwenberg

Imported Upstream version 7.0.5

parent b179a46d
......@@ -17,7 +17,7 @@ include(CheckCSourceCompiles)
set (MapServer_VERSION_MAJOR 7)
set (MapServer_VERSION_MINOR 0)
set (MapServer_VERSION_REVISION 4)
set (MapServer_VERSION_REVISION 5)
set (MapServer_VERSION_SUFFIX "")
set(TARGET_VERSION_MAJOR ${MapServer_VERSION_MAJOR})
......
......@@ -86,6 +86,10 @@ IF(PHP5_CONFIG_EXECUTABLE)
MESSAGE(STATUS ${PHP5_MAIN_INCLUDE_DIR})
IF(NOT PHP5_INCLUDE_PATH)
set(PHP5_INCLUDE_PATH ${PHP5_INCLUDES})
ENDIF(NOT PHP5_INCLUDE_PATH)
IF(PHP5_VERSION LESS 5)
MESSAGE(FATAL_ERROR "PHP version is not 5 or later")
ENDIF(PHP5_VERSION LESS 5)
......
......@@ -55,6 +55,7 @@ imageObj *msPrepareImage(mapObj *map, int allow_nonsquare)
return(NULL);
}
msFreeLabelCache(&(map->labelcache));
msInitLabelCache(&(map->labelcache)); /* this clears any previously allocated cache */
/* clear any previously created mask layer images */
......
......@@ -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,7 +318,11 @@ 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;
......@@ -314,7 +330,7 @@ int msGraticuleLayerNextShape(layerObj *layer, shapeObj *shape)
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,7 +411,11 @@ 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;
......@@ -399,7 +423,7 @@ int msGraticuleLayerNextShape(layerObj *layer, shapeObj *shape)
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 ) {
......
......@@ -187,10 +187,14 @@ int msRemoveHashTable(hashTableObj *table, const char *key)
status = MS_SUCCESS;
if (prev_tp) {
prev_tp->next = tp->next;
msFree(tp->key);
msFree(tp->data);
free(tp);
break;
} else {
table->items[hash(key)] = tp->next;
msFree(tp->key);
msFree(tp->data);
free(tp);
break;
}
......
......@@ -757,6 +757,126 @@ void msIO_installStdinFromBuffer()
&group->stderr_context );
}
/************************************************************************/
/* msIO_getAndStripStdoutBufferMimeHeaders() */
/* */
/************************************************************************/
hashTableObj* msIO_getAndStripStdoutBufferMimeHeaders()
{
/* -------------------------------------------------------------------- */
/* Find stdout buffer. */
/* -------------------------------------------------------------------- */
msIOContext *ctx = msIO_getHandler( (FILE *) "stdout" );
msIOBuffer *buf;
int start_of_mime_header, current_pos;
hashTableObj* hashTable;
if( ctx == NULL || ctx->write_channel == MS_FALSE
|| strcmp(ctx->label,"buffer") != 0 ) {
msSetError( MS_MISCERR, "Can't identify msIO buffer.",
"msIO_getAndStripStdoutBufferMimeHeaders" );
return NULL;
}
buf = (msIOBuffer *) ctx->cbData;
hashTable = msCreateHashTable();
/* -------------------------------------------------------------------- */
/* Loop over all headers. */
/* -------------------------------------------------------------------- */
current_pos = 0;
while( TRUE ) {
int pos_of_column = -1;
char* key, *value;
start_of_mime_header = current_pos;
while( current_pos < buf->data_offset )
{
if( buf->data[current_pos] == '\r' )
{
if( current_pos + 1 == buf->data_offset ||
buf->data[current_pos + 1] != '\n' )
{
pos_of_column = -1;
break;
}
break;
}
if( buf->data[current_pos] == ':' )
{
pos_of_column = current_pos;
if( current_pos + 1 == buf->data_offset ||
buf->data[current_pos + 1] != ' ' )
{
pos_of_column = -1;
break;
}
}
current_pos++;
}
if( pos_of_column < 0 || current_pos == buf->data_offset ) {
msSetError( MS_MISCERR, "Corrupt mime headers.",
"msIO_getAndStripStdoutBufferMimeHeaders" );
msFreeHashTable(hashTable);
return NULL;
}
key = (char*) malloc( pos_of_column - start_of_mime_header + 1 );
memcpy( key, buf->data+start_of_mime_header, pos_of_column - start_of_mime_header);
key[pos_of_column - start_of_mime_header] = '\0';
value = (char*) malloc( current_pos - (pos_of_column+2) + 1 );
memcpy( value, buf->data+pos_of_column+2, current_pos - (pos_of_column+2));
value[current_pos - (pos_of_column+2)] = '\0';
msInsertHashTable( hashTable, key, value );
msFree( key );
msFree( value );
/* -------------------------------------------------------------------- */
/* Go to next line. */
/* -------------------------------------------------------------------- */
current_pos += 2;
if( current_pos == buf->data_offset )
{
msSetError( MS_MISCERR, "Corrupt mime headers.",
"msIO_getAndStripStdoutBufferMimeHeaders" );
msFreeHashTable(hashTable);
return NULL;
}
/* If next line is a '\r', this is the end of mime headers. */
if( buf->data[current_pos] == '\r' )
{
current_pos ++;
if( current_pos == buf->data_offset ||
buf->data[current_pos] != '\n' )
{
msSetError( MS_MISCERR, "Corrupt mime headers.",
"msIO_getAndStripStdoutBufferMimeHeaders" );
msFreeHashTable(hashTable);
return NULL;
}
current_pos ++;
break;
}
}
/* -------------------------------------------------------------------- */
/* Move data to front of buffer, and reset length. */
/* -------------------------------------------------------------------- */
memmove( buf->data, buf->data+current_pos,
buf->data_offset - current_pos );
buf->data[buf->data_offset - current_pos] = '\0';
buf->data_offset -= current_pos;
return hashTable;
}
/************************************************************************/
/* msIO_stripStdoutBufferContentType() */
/* */
......
......@@ -37,6 +37,7 @@
*/
#include <stdarg.h>
#include "maphash.h"
#ifdef __cplusplus
extern "C" {
......@@ -105,7 +106,8 @@ extern "C" {
void MS_DLL_EXPORT msIO_Cleanup(void);
char MS_DLL_EXPORT *msIO_stripStdoutBufferContentType(void);
void MS_DLL_EXPORT msIO_stripStdoutBufferContentHeaders(void);
hashTableObj MS_DLL_EXPORT *msIO_getAndStripStdoutBufferMimeHeaders(void);
msIOContext *msIO_pushStdoutToBufferAndGetOldContext(void);
void msIO_restoreOldStdoutContext(msIOContext *context_to_restore);
......
......@@ -387,6 +387,7 @@ int msDrawLegendIcon(mapObj *map, layerObj *lp, classObj *theclass,
initTextSymbol(&ts);
msPopulateTextSymbolForLabelAndString(&ts,theclass->labels[0],msStrdup("Az"),lp->scalefactor*image_draw->resolutionfactor,image_draw->resolutionfactor, duplicate_always);
ts.label->size = height - 1;
ts.rotation = 0;
ret = msComputeTextPath(map,&ts);
if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
textstartpt = get_metrics(&marker,MS_CC,ts.textpath,0,0,0,0,NULL);
......
......@@ -164,7 +164,8 @@ char *FLTGetExpressionForValuesRanges(layerObj *lp, const char *item, const char
if (paszElements && numelements > 0) {
if (forcecharcter)
bIscharacter = MS_TRUE;
bIscharacter= !FLTIsNumeric(paszElements[0]);
else
bIscharacter= !FLTIsNumeric(paszElements[0]);
pszTmpExpression = msStringConcatenate(pszTmpExpression, "(");
for (i=0; i<numelements; i++) {
......
......@@ -3418,7 +3418,7 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer,
}
} else
bGenerateDefaultSymbol =1;
} else if (psSymbol->type == MS_SYMBOL_PIXMAP) {
} else if (psSymbol->type == MS_SYMBOL_PIXMAP || psSymbol->type == MS_SYMBOL_SVG) {
if (psSymbol->name) {
pszURL = msLookupHashTable(&(psLayer->metadata), "WMS_SLD_SYMBOL_URL");
if (!pszURL)
......@@ -3455,8 +3455,8 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer,
snprintf(szTmp, sizeof(szTmp), "<%sFormat>image/png</%sFormat>\n",
sNameSpace, sNameSpace);
} else
snprintf(szTmp, sizeof(szTmp), "<%sFormat>%s</%sFormat>\n", "image/gif",
sNameSpace, sNameSpace);
snprintf(szTmp, sizeof(szTmp), "<%sFormat>%s</%sFormat>\n", sNameSpace,
(psSymbol->type ==MS_SYMBOL_SVG)?"image/svg+xml":"image/gif",sNameSpace);
pszSLD = msStringConcatenate(pszSLD, szTmp);
......
This diff is collapsed.
......@@ -38,6 +38,7 @@
#include "mapserver.h"
#include "maptime.h"
#include "mapows.h"
#include <assert.h>
......@@ -399,8 +400,10 @@ static int msSplitData( char *data, char **geometry_column_name, char **table_na
break; /* stop on spaces */
/* double the size of the table_name array if necessary */
if (i == table_name_size) {
size_t tgt_offset = tgt - *table_name;
table_name_size *= 2;
*table_name = (char *) realloc(*table_name,sizeof(char *) * table_name_size);
tgt = *table_name + tgt_offset;
}
*tgt = *src;
}
......
......@@ -3636,9 +3636,13 @@ int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *
native_string = msStringConcatenate(native_string, "FALSE");
break;
case MS_TOKEN_LITERAL_NUMBER:
strtmpl = "%lf";
snippet = (char *) msSmallMalloc(strlen(strtmpl) + 16);
sprintf(snippet, strtmpl, node->tokenval.dblval);
snippet = (char *) msSmallMalloc(32);
if( node->tokenval.dblval >= INT_MIN &&
node->tokenval.dblval <= INT_MAX &&
node->tokenval.dblval == (int)node->tokenval.dblval )
sprintf(snippet, "%d", (int)node->tokenval.dblval);
else
sprintf(snippet, "%.18g", node->tokenval.dblval);
native_string = msStringConcatenate(native_string, snippet);
msFree(snippet);
break;
......
......@@ -954,6 +954,40 @@ int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect)
char *over = "+over";
int ret;
projectionObj in_over,out_over,*inp,*outp;
#if USE_PROJ
/* Detect projecting from north polar stereographic to longlat */
if( in && !in->gt.need_geotransform &&
out && !out->gt.need_geotransform &&
!pj_is_latlong(in->proj) && pj_is_latlong(out->proj) )
{
pointObj p;
p.x = 0.0;
p.y = 0.0;
if( msProjectPoint(in, out, &p) == MS_SUCCESS &&
fabs(p.y - 90) < 1e-8 )
{
/* Is the pole in the rectangle ? */
if( 0 >= rect->minx && 0 >= rect->miny &&
0 <= rect->maxx && 0 <= rect->maxy )
{
if( msProjectRectAsPolygon(in, out, rect ) == MS_SUCCESS )
{
rect->minx = -180.0;
rect->maxx = 180.0;
rect->maxy = 90.0;
return MS_SUCCESS;
}
}
/* Are we sure the dateline is not enclosed ? */
else if( rect->maxy < 0 || rect->maxx < 0 || rect->minx > 0 )
{
return msProjectRectAsPolygon(in, out, rect );
}
}
}
#endif
/*
* Issue #4892: When projecting a rectangle we do not want proj to wrap resulting
* coordinates around the dateline, as in practice a requested bounding box of
......
......@@ -673,6 +673,7 @@ int msQueryByFilter(mapObj *map)
const rectObj invalid_rect = MS_INIT_INVALID_RECT;
shapeObj shape;
int paging;
int nclasses = 0;
int *classgroup = NULL;
......@@ -732,12 +733,14 @@ int msQueryByFilter(mapObj *map)
if((lp->mingeowidth > 0) && ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) continue;
}
paging = msLayerGetPaging(lp);
msLayerClose(lp); /* reset */
status = msLayerOpen(lp);
if(status != MS_SUCCESS) goto query_error;
msLayerEnablePaging(lp, paging);
/* disable driver paging */
msLayerEnablePaging(lp, MS_FALSE);
// msLayerEnablePaging(lp, MS_FALSE);
old_filteritem = lp->filteritem; /* cache the existing filter/filteritem */
msInitExpression(&old_filter);
......@@ -815,7 +818,7 @@ int msQueryByFilter(mapObj *map)
#endif
/* Should we skip this feature? */
if (!msLayerGetPaging(lp) && map->query.startindex > 1) {
if (!paging && map->query.startindex > 1) {
--map->query.startindex;
msFreeShape(&shape);
continue;
......
......@@ -83,7 +83,8 @@ msNearestRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb,
imageObj *psDstImage, rasterBufferObj *dst_rb,
int *panCMap,
SimpleTransformer pfnTransform, void *pCBData,
int debug, rasterBufferObj *mask_rb )
int debug, rasterBufferObj *mask_rb,
int bWrapAtLeftRight )
{
double *x, *y;
......@@ -122,6 +123,9 @@ msNearestRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb,
nSrcX = (int) x[nDstX];
nSrcY = (int) y[nDstX];
if( bWrapAtLeftRight && nSrcX >= nSrcXSize && nSrcX < 2 * nSrcXSize )
nSrcX -= nSrcXSize;
/*
* We test the original floating point values to
* avoid errors related to asymmetric rounding around zero.
......@@ -302,7 +306,8 @@ msBilinearRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb,
imageObj *psDstImage, rasterBufferObj *dst_rb,
int *panCMap,
SimpleTransformer pfnTransform, void *pCBData,
int debug, rasterBufferObj *mask_rb )
int debug, rasterBufferObj *mask_rb,
int bWrapAtLeftRight )
{
double *x, *y;
......@@ -359,31 +364,32 @@ msBilinearRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb,
dfRatioY2 = y[nDstX] - nSrcY;
/* If we are right off the source, skip this pixel */
if( nSrcX2 < 0 || nSrcX >= nSrcXSize
if( nSrcX2 < 0 || (!bWrapAtLeftRight && nSrcX >= nSrcXSize)
|| nSrcY2 < 0 || nSrcY >= nSrcYSize )
continue;
/* Trim in stuff one pixel off the edge */
nSrcX = MS_MAX(nSrcX,0);
nSrcY = MS_MAX(nSrcY,0);
nSrcX2 = MS_MIN(nSrcX2,nSrcXSize-1);
if( !bWrapAtLeftRight )
nSrcX2 = MS_MIN(nSrcX2,nSrcXSize-1);
nSrcY2 = MS_MIN(nSrcY2,nSrcYSize-1);
memset( padfPixelSum, 0, sizeof(double) * bandCount);
msSourceSample( psSrcImage, src_rb, nSrcX, nSrcY, padfPixelSum,
msSourceSample( psSrcImage, src_rb, nSrcX % nSrcXSize, nSrcY, padfPixelSum,
(1.0 - dfRatioX2) * (1.0 - dfRatioY2),
&dfWeightSum );
msSourceSample( psSrcImage, src_rb, nSrcX2, nSrcY, padfPixelSum,
msSourceSample( psSrcImage, src_rb, nSrcX2 % nSrcXSize, nSrcY, padfPixelSum,
(dfRatioX2) * (1.0 - dfRatioY2),
&dfWeightSum );
msSourceSample( psSrcImage, src_rb, nSrcX, nSrcY2, padfPixelSum,
msSourceSample( psSrcImage, src_rb, nSrcX % nSrcXSize, nSrcY2, padfPixelSum,
(1.0 - dfRatioX2) * (dfRatioY2),
&dfWeightSum );
msSourceSample( psSrcImage, src_rb, nSrcX2, nSrcY2, padfPixelSum,
msSourceSample( psSrcImage, src_rb, nSrcX2 % nSrcXSize, nSrcY2, padfPixelSum,
(dfRatioX2) * (dfRatioY2),
&dfWeightSum );
......@@ -1200,8 +1206,17 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize,
+ (dfLonWrap-180)*adfInvSrcGeoTransform[4]
+ dfY*adfInvSrcGeoTransform[5];
psSrcExtent->minx = MS_MIN(psSrcExtent->minx, x_out);
psSrcExtent->maxx = MS_MAX(psSrcExtent->maxx, x_out);
/* Does the raster cover a whole 360 deg range ? */
if( nSrcXSize == (int)(adfInvSrcGeoTransform[1] * 360 + 0.5) )
{
psSrcExtent->minx = 0;
psSrcExtent->maxx = nSrcXSize;
}
else
{
psSrcExtent->minx = MS_MIN(psSrcExtent->minx, x_out);
psSrcExtent->maxx = MS_MAX(psSrcExtent->maxx, x_out);
}
psSrcExtent->miny = MS_MIN(psSrcExtent->miny, y_out);
psSrcExtent->maxy = MS_MAX(psSrcExtent->maxy, y_out);
}
......@@ -1216,8 +1231,17 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize,
+ (dfLonWrap+180)*adfInvSrcGeoTransform[4]
+ dfY*adfInvSrcGeoTransform[5];
psSrcExtent->minx = MS_MIN(psSrcExtent->minx, x_out);
psSrcExtent->maxx = MS_MAX(psSrcExtent->maxx, x_out);
/* Does the raster cover a whole 360 deg range ? */
if( nSrcXSize == (int)(adfInvSrcGeoTransform[1] * 360 + 0.5) )
{
psSrcExtent->minx = 0;
psSrcExtent->maxx = nSrcXSize;
}
else
{
psSrcExtent->minx = MS_MIN(psSrcExtent->minx, x_out);
psSrcExtent->maxx = MS_MAX(psSrcExtent->maxx, x_out);
}
psSrcExtent->miny = MS_MIN(psSrcExtent->miny, y_out);
psSrcExtent->maxy = MS_MAX(psSrcExtent->maxy, y_out);
}
......@@ -1282,6 +1306,7 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image,
double dfOversampleRatio;
rasterBufferObj src_rb, *psrc_rb = NULL, *mask_rb = NULL;
int bAddPixelMargin = MS_TRUE;
int bWrapAtLeftRight = MS_FALSE;
const char *resampleMode = CSLFetchNameValue( layer->processing,
......@@ -1471,7 +1496,16 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image,
sqrt(adfSrcGeoTransform[1] * adfSrcGeoTransform[1]
+ adfSrcGeoTransform[2] * adfSrcGeoTransform[2]);
if( (sOrigSrcExtent.maxx - sOrigSrcExtent.minx) > dfOversampleRatio * nDstXSize
/* Check first that the requested extent is not well beyond than the source */
/* raster. This might be the case for example if asking to visualize */
/* -180,-89,180,90 in EPSG:4326 from a raster in Arctic Polar Stereographic */
/* But restrict that to rasters of modest size, otherwise we may end up */
/* requesting very large dimensions in other legit reprojection cases */
/* See https://github.com/mapserver/mapserver/issues/5402 */
if( !(sOrigSrcExtent.minx <= -4 * nSrcXSize && sOrigSrcExtent.miny <= -4 * nSrcYSize &&
sOrigSrcExtent.maxx >= 5 * nSrcXSize && sOrigSrcExtent.maxy >= 5 * nSrcYSize &&
nSrcXSize < 4000 && nSrcYSize < 4000)
&& (sOrigSrcExtent.maxx - sOrigSrcExtent.minx) > dfOversampleRatio * nDstXSize
&& !CSLFetchBoolean( layer->processing, "LOAD_FULL_RES_IMAGE", FALSE ))
sDummyMap.cellsize =
(dfNominalCellSize * (sOrigSrcExtent.maxx - sOrigSrcExtent.minx))
......@@ -1509,6 +1543,18 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image,
adfSrcGeoTransform[4] *= (sDummyMap.cellsize / dfNominalCellSize);
adfSrcGeoTransform[5] *= (sDummyMap.cellsize / dfNominalCellSize);
/* In the non-rotated case, make sure that the geotransform exactly */
/* matches the sSrcExtent, even if that generates non-square pixels (#1715) */
/* The rotated case should ideally be dealt with, but not for now... */
if( adfSrcGeoTransform[2] == 0 && adfSrcGeoTransform[4] == 0 &&
adfSrcGeoTransform[5] < 0 )
{
adfSrcGeoTransform[1] = (sSrcExtent.maxx - sSrcExtent.minx) *
dfNominalCellSize / nLoadImgXSize;
adfSrcGeoTransform[5] = -(sSrcExtent.maxy - sSrcExtent.miny) *
dfNominalCellSize / nLoadImgYSize;
}
papszAlteredProcessing = CSLDuplicate( layer->processing );
papszAlteredProcessing =
CSLSetNameValue( papszAlteredProcessing, "RAW_WINDOW",
......@@ -1629,6 +1675,13 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image,
/* -------------------------------------------------------------------- */
pACBData = msInitApproxTransformer( msProjTransformer, pTCBData, 0.333 );
if( pj_is_latlong(layer->projection.proj) )
{
/* Does the raster cover a whole 360 deg range ? */
if( nSrcXSize == (int)(adfInvSrcGeoTransform[1] * 360 + 0.5) )
bWrapAtLeftRight = MS_TRUE;
}
/* -------------------------------------------------------------------- */