From b5c02b4c6c485126d414cd0c4fffd05b2c28d25d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 22 Dec 2016 10:14:02 +0100 Subject: [PATCH 1/3] WFS: avoid 'eating' the last character of WFS 2.0 stored queries stored in an external file --- mapwfs20.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/mapwfs20.c b/mapwfs20.c index b4402ec073..50da8443e6 100644 --- a/mapwfs20.c +++ b/mapwfs20.c @@ -824,15 +824,44 @@ static char* msWFSGetStoredQuery(mapObj *map, const char* pszURN) FILE* f = fopen(value, "rb"); if( f != NULL ) { - char* pszBuffer = (char*) msSmallMalloc(32000); - int nread = fread(pszBuffer, 1, 32000-1, f); - fclose(f); - if( nread > 0 ) + char* pszBuffer; + int nread; + long length; + + fseek(f, 0, SEEK_END); + length = ftell(f); + if( length > 1000000 ) + { + msSetError(MS_WFSERR, "%s: too big (%ld bytes > 1000000)", + "msWFSGetStoredQuery()", value, length); + fclose(f); + } + else { - pszBuffer[nread-1] = '\0'; - return pszBuffer; + fseek(f, 0, SEEK_SET); + pszBuffer = (char*) malloc((int)length + 1); + if( pszBuffer == NULL ) + { + msSetError(MS_WFSERR, "Cannot allocate %d bytes to read %s", + "msWFSGetStoredQuery()", + (int)length + 1, value); + fclose(f); + } + else + { + nread = (int)fread(pszBuffer, 1, length, f); + fclose(f); + if( nread == length ) + { + pszBuffer[nread] = '\0'; + return pszBuffer; + } + msSetError(MS_WFSERR, "Could only read %d bytes / %d of %s", + "msWFSGetStoredQuery()", + nread, (int)length, value); + msFree(pszBuffer); + } } - msFree(pszBuffer); } else { From 722716c49de2399f54b275ab31437f0e8c92cd63 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 2 Jan 2017 18:37:54 +0100 Subject: [PATCH 2/3] msTransformMapToSource(): fix behaviour at lon_wrap +/- 180 deg This fixes an issue when drawing a raster whose extent is e.g. [0,360] with a projection with +lon_wrap=180. Before this fix, when drawing the extent [-180,180], there was a gap around lon=0 due to the discontinuity during the computation of the source coordinates. --- mapresample.c | 101 ++++++++++++++++++++++ msautotest/gdal/data/lon_wrap_180.asc | 25 ++++++ msautotest/gdal/data/lon_wrap_180.prj | 1 + msautotest/gdal/expected/lon_wrap_180.png | Bin 0 -> 109 bytes 4 files changed, 127 insertions(+) create mode 100644 msautotest/gdal/data/lon_wrap_180.asc create mode 100644 msautotest/gdal/data/lon_wrap_180.prj create mode 100644 msautotest/gdal/expected/lon_wrap_180.png diff --git a/mapresample.c b/mapresample.c index 7107bcbc55..c1a98b2d25 100644 --- a/mapresample.c +++ b/mapresample.c @@ -1123,6 +1123,107 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize, } } + /* -------------------------------------------------------------------- */ + /* Deal with discontinuities related to lon_wrap=XXX in source */ + /* projection. In that case we must check if the points at */ + /* lon_wrap +/- 180deg are in the output raster. */ + /* -------------------------------------------------------------------- */ + if( bOutInit && pj_is_latlong(psSrcProj->proj) ) + { + int bHasLonWrap = MS_FALSE; + double dfLonWrap = 0; + for( i = 0; i < psSrcProj->numargs; i++ ) + { + if( strncmp(psSrcProj->args[i], "lon_wrap=", + strlen("lon_wrap=")) == 0 ) + { + bHasLonWrap = MS_TRUE; + dfLonWrap = atof( psSrcProj->args[i] + strlen("lon_wrap=") ); + break; + } + } + + if( bHasLonWrap ) + { + double x2[2], y2[2], z2[2]; + int nCountY = 0; + double dfY = 0.0; + double dfXMinOut = 0.0; + double dfYMinOut = 0.0; + double dfXMaxOut = 0.0; + double dfYMaxOut = 0.0; + + /* Find out average y coordinate in src projection */ + for( i = 0; i < nSamples; i++ ) { + if( y[i] != HUGE_VAL ) { + dfY += y[i]; + nCountY ++; + } + } + dfY /= nCountY; + + /* Compute bounds of output raster */ + for( i = 0; i < 4; i ++ ) + { + double dfX = adfDstGeoTransform[0] + + ((i == 1 || i == 2) ? nDstXSize : 0) * adfDstGeoTransform[1] + + ((i == 1 || i == 3 ) ? nDstYSize : 0) * adfDstGeoTransform[2]; + double dfY = adfDstGeoTransform[3] + + ((i == 1 || i == 2) ? nDstXSize : 0) * adfDstGeoTransform[4] + + ((i == 1 || i == 3 ) ? nDstYSize : 0) * adfDstGeoTransform[5]; + if( i == 0 || dfX < dfXMinOut ) dfXMinOut = dfX; + if( i == 0 || dfY < dfYMinOut ) dfYMinOut = dfY; + if( i == 0 || dfX > dfXMaxOut ) dfXMaxOut = dfX; + if( i == 0 || dfY > dfYMaxOut ) dfYMaxOut = dfY; + } + + x2[0] = dfLonWrap-180+1e-7; + y2[0] = dfY; + z2[0] = 0.0; + + x2[1] = dfLonWrap+180-1e-7; + y2[1] = dfY; + z2[1] = 0.0; + + msAcquireLock( TLOCK_PROJ ); + pj_transform( psSrcProj->proj, psDstProj->proj, + 2, 1, x2, y2, z2 ); + msReleaseLock( TLOCK_PROJ ); + + if( x2[0] >= dfXMinOut && x2[0] <= dfXMaxOut && + y2[0] >= dfYMinOut && y2[0] <= dfYMaxOut ) + { + double x_out = adfInvSrcGeoTransform[0] + + (dfLonWrap-180)*adfInvSrcGeoTransform[1] + + dfY*adfInvSrcGeoTransform[2]; + double y_out = adfInvSrcGeoTransform[3] + + (dfLonWrap-180)*adfInvSrcGeoTransform[4] + + dfY*adfInvSrcGeoTransform[5]; + + 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); + } + + if( x2[1] >= dfXMinOut && x2[1] <= dfXMaxOut && + x2[1] >= dfYMinOut && y2[1] <= dfYMaxOut ) + { + double x_out = adfInvSrcGeoTransform[0] + + (dfLonWrap+180)*adfInvSrcGeoTransform[1] + + dfY*adfInvSrcGeoTransform[2]; + double y_out = adfInvSrcGeoTransform[3] + + (dfLonWrap+180)*adfInvSrcGeoTransform[4] + + dfY*adfInvSrcGeoTransform[5]; + + 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); + } + } + } + if( !bOutInit ) return MS_FALSE; diff --git a/msautotest/gdal/data/lon_wrap_180.asc b/msautotest/gdal/data/lon_wrap_180.asc new file mode 100644 index 0000000000..fa82f27009 --- /dev/null +++ b/msautotest/gdal/data/lon_wrap_180.asc @@ -0,0 +1,25 @@ +ncols 40 +nrows 20 +xllcorner -0.1 +yllcorner -90.000000000000 +cellsize 9.000000000000 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 + 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 127 diff --git a/msautotest/gdal/data/lon_wrap_180.prj b/msautotest/gdal/data/lon_wrap_180.prj new file mode 100644 index 0000000000..a30c00a55d --- /dev/null +++ b/msautotest/gdal/data/lon_wrap_180.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] \ No newline at end of file diff --git a/msautotest/gdal/expected/lon_wrap_180.png b/msautotest/gdal/expected/lon_wrap_180.png new file mode 100644 index 0000000000000000000000000000000000000000..e5f7b5063855573921e2640ee0c7e9fb1dd5def0 GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^8bB< Date: Wed, 4 Jan 2017 16:17:20 +0100 Subject: [PATCH 3/3] Fix cluster with WMS dimension issue (#5364) --- mapcluster.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mapcluster.c b/mapcluster.c index 39d6a5dee7..46b6844371 100644 --- a/mapcluster.c +++ b/mapcluster.c @@ -1440,7 +1440,12 @@ int msClusterLayerOpen(layerObj *layer) return MS_FAILURE; if (layer->layerinfo) - return MS_SUCCESS; /* already open */ + { + if (layer->vtable->LayerOpen != msClusterLayerOpen) + msLayerClose(layer); + else + return MS_SUCCESS; /* already open */ + } layerinfo = msClusterInitialize(layer);