static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_renderer *r) { /* We need a GDAL 1.10 PDF driver at runtime, but as far as the C API is concerned, GDAL 1.9 is */ /* largely sufficient. */ #if defined(USE_GDAL) && defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900 GDALDatasetH hDS = NULL; const char* pszGEO_ENCODING = NULL; GDALDriverH hPDFDriver = NULL; const char* pszVirtualIO = NULL; int bVirtualIO = FALSE; char* pszTmpFilename = NULL; VSILFILE* fp = NULL; if (map == NULL) return; pszGEO_ENCODING = msGetOutputFormatOption(img->format, "GEO_ENCODING", NULL); if (pszGEO_ENCODING == NULL) return; msGDALInitialize(); hPDFDriver = GDALGetDriverByName("PDF"); if (hPDFDriver == NULL) return; /* When compiled against libpoppler, the PDF driver is VirtualIO capable */ /* but not, when it is compiled against libpodofo. */ pszVirtualIO = GDALGetMetadataItem( hPDFDriver, GDAL_DCAP_VIRTUALIO, NULL ); if (pszVirtualIO) bVirtualIO = CSLTestBoolean(pszVirtualIO); if (bVirtualIO) pszTmpFilename = msTmpFile(map, NULL, "/vsimem/mscairopdf/", "pdf"); else pszTmpFilename = msTmpFile(map, map->mappath, NULL, "pdf"); /* Copy content of outputStream buffer into file */ fp = VSIFOpenL(pszTmpFilename, "wb"); if (fp == NULL) { msFree(pszTmpFilename); return; } VSIFWriteL(r->outputStream->data, 1, r->outputStream->size, fp); VSIFCloseL(fp); fp = NULL; hDS = GDALOpen(pszTmpFilename, GA_Update); if ( hDS != NULL ) { char* pszWKT = msProjectionObj2OGCWKT( &(map->projection) ); if( pszWKT != NULL ) { double adfGeoTransform[6]; int i; /* Add user-specified options */ for( i = 0; i < img->format->numformatoptions; i++ ) { const char* pszOption = img->format->formatoptions[i]; if( strncasecmp(pszOption,"METADATA_ITEM:",14) == 0 ) { char* pszKey = NULL; const char* pszValue = CPLParseNameValue(pszOption + 14, &pszKey); if( pszKey != NULL ) { GDALSetMetadataItem(hDS, pszKey, pszValue, NULL); CPLFree(pszKey); } } } /* We need to rescale the geotransform because GDAL will not necessary */ /* open the PDF with the DPI that was used to generate it */ memcpy(adfGeoTransform, map->gt.geotransform, 6 * sizeof(double)); adfGeoTransform[1] = adfGeoTransform[1] * map->width / GDALGetRasterXSize(hDS); adfGeoTransform[5] = adfGeoTransform[5] * map->height / GDALGetRasterYSize(hDS); GDALSetGeoTransform(hDS, adfGeoTransform); GDALSetProjection(hDS, pszWKT); msFree( pszWKT ); pszWKT = NULL; CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", pszGEO_ENCODING); GDALClose(hDS); hDS = NULL; CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", NULL); /* We need to replace the buffer with the content of the GDAL file */ fp = VSIFOpenL(pszTmpFilename, "rb"); if( fp != NULL ) { int nFileSize; VSIFSeekL(fp, 0, SEEK_END); nFileSize = (int)VSIFTellL(fp); msBufferResize(r->outputStream, nFileSize); VSIFSeekL(fp, 0, SEEK_SET); r->outputStream->size = VSIFReadL(r->outputStream->data, 1, nFileSize, fp); VSIFCloseL(fp); fp = NULL; } } } if ( hDS != NULL ) GDALClose(hDS); VSIUnlink(pszTmpFilename); msFree(pszTmpFilename); #endif }
int KmlRenderer::saveImage(imageObj *, FILE *fp, outputFormatObj *format) { /* -------------------------------------------------------------------- */ /* Write out the document. */ /* -------------------------------------------------------------------- */ int bufSize = 0; xmlChar *buf = NULL; msIOContext *context = NULL; int chunkSize = 4096; #if defined(CPL_ZIP_API_OFFERED) int bZip = MS_FALSE; #endif if( msIO_needBinaryStdout() == MS_FAILURE ) return MS_FAILURE; xmlDocDumpFormatMemoryEnc(XmlDoc, &buf, &bufSize, "UTF-8", 1); #if defined(USE_OGR) if (format && format->driver && strcasecmp(format->driver, "kmz") == 0) { #if defined(CPL_ZIP_API_OFFERED) bZip = MS_TRUE; #else msSetError( MS_MISCERR, "kmz format support unavailable, perhaps you need to upgrade to GDAL/OGR 1.8?", "KmlRenderer::saveImage()"); xmlFree(buf); return MS_FAILURE; #endif } #if defined(CPL_ZIP_API_OFFERED) if (bZip) { VSILFILE *fpZip; int bytes_read; char buffer[1024]; char *zip_filename =NULL; void *hZip=NULL; zip_filename = msTmpFile(NULL, NULL, "/vsimem/kmlzip/", "kmz" ); hZip = CPLCreateZip( zip_filename, NULL ); CPLCreateFileInZip( hZip, "mapserver.kml", NULL ); for (int i=0; i<bufSize; i+=chunkSize) { int size = chunkSize; if (i + size > bufSize) size = bufSize - i; CPLWriteFileInZip( hZip, buf+i, size); } CPLCloseFileInZip( hZip ); CPLCloseZip( hZip ); context = msIO_getHandler(fp); fpZip = VSIFOpenL( zip_filename, "r" ); while( (bytes_read = VSIFReadL( buffer, 1, sizeof(buffer), fpZip )) > 0 ) { if (context) msIO_contextWrite(context, buffer, bytes_read); else msIO_fwrite( buffer, 1, bytes_read, fp ); } VSIFCloseL( fpZip ); msFree( zip_filename); xmlFree(buf); return(MS_SUCCESS); } #endif #endif context = msIO_getHandler(fp); for (int i=0; i<bufSize; i+=chunkSize) { int size = chunkSize; if (i + size > bufSize) size = bufSize - i; if (context) msIO_contextWrite(context, buf+i, size); else msIO_fwrite(buf+i, 1, size, fp); } xmlFree(buf); return(MS_SUCCESS); }
int msWFSLayerOpen(layerObj *lp, const char *pszGMLFilename, rectObj *defaultBBOX) { #ifdef USE_WFS_LYR int status = MS_SUCCESS; msWFSLayerInfo *psInfo = NULL; if ( msCheckParentPointer(lp->map,"map")==MS_FAILURE ) return MS_FAILURE; if (lp->wfslayerinfo != NULL) { psInfo =(msWFSLayerInfo*)lp->wfslayerinfo; /* Layer already opened. If explicit filename requested then check */ /* that file was already opened with the same filename. */ /* If no explicit filename requested then we'll try to reuse the */ /* previously opened layer... this will happen in a msDrawMap() call. */ if (pszGMLFilename == NULL || (psInfo->pszGMLFilename && pszGMLFilename && strcmp(psInfo->pszGMLFilename, pszGMLFilename) == 0) ) { if (lp->layerinfo == NULL) { if (msWFSLayerWhichShapes(lp, psInfo->rect, MS_FALSE) == MS_FAILURE) /* no access to context (draw vs. query) here, although I doubt it matters... */ return MS_FAILURE; } return MS_SUCCESS; /* Nothing to do... layer is already opened */ } else { /* Hmmm... should we produce a fatal error? */ /* For now we'll just close the layer and reopen it. */ if (lp->debug) msDebug("msWFSLayerOpen(): Layer already opened (%s)\n", lp->name?lp->name:"(null)" ); msWFSLayerClose(lp); } } /* ------------------------------------------------------------------ * Alloc and fill msWFSLayerInfo inside layer obj * ------------------------------------------------------------------ */ lp->wfslayerinfo = psInfo = msAllocWFSLayerInfo(); if (pszGMLFilename) psInfo->pszGMLFilename = msStrdup(pszGMLFilename); else { psInfo->pszGMLFilename = msTmpFile(lp->map, lp->map->mappath, NULL, "tmp.gml"); } if (defaultBBOX) { /* __TODO__ If new bbox differs from current one then we should */ /* invalidate current GML file in cache */ psInfo->rect = *defaultBBOX; } else { /* Use map bbox by default */ psInfo->rect = lp->map->extent; } /* We will call whichshapes() now and force downloading layer right */ /* away. This saves from having to call DescribeFeatureType and */ /* parsing the response (being lazy I guess) and anyway given the */ /* way we work with layers right now the bbox is unlikely to change */ /* between now and the time whichshapes() would have been called by */ /* the MapServer core. */ #ifdef USE_PROJ if((lp->map->projection.numargs > 0) && (lp->projection.numargs > 0)) msProjectRect(&lp->map->projection, &lp->projection, &psInfo->rect); /* project the searchrect to source coords */ #endif if (msWFSLayerWhichShapes(lp, psInfo->rect, MS_FALSE) == MS_FAILURE) /* no access to context (draw vs. query) here, although I doubt it matters... */ status = MS_FAILURE; return status; #else /* ------------------------------------------------------------------ * WFS CONNECTION Support not included... * ------------------------------------------------------------------ */ msSetError(MS_WFSCONNERR, "WFS CLIENT CONNECTION support is not available.", "msWFSLayerOpen()"); return(MS_FAILURE); #endif /* USE_WFS_LYR */ }
int msSaveImageGDAL( mapObj *map, imageObj *image, char *filename ) { int bFileIsTemporary = MS_FALSE; GDALDatasetH hMemDS, hOutputDS; GDALDriverH hMemDriver, hOutputDriver; int nBands = 1; int iLine; GByte *pabyAlphaLine = NULL; char **papszOptions = NULL; outputFormatObj *format = image->format; rasterBufferObj rb; GDALDataType eDataType = GDT_Byte; int bUseXmp = MS_FALSE; msGDALInitialize(); memset(&rb,0,sizeof(rasterBufferObj)); #ifdef USE_EXEMPI bUseXmp = msXmpPresent(map); #endif /* -------------------------------------------------------------------- */ /* Identify the proposed output driver. */ /* -------------------------------------------------------------------- */ msAcquireLock( TLOCK_GDAL ); hOutputDriver = GDALGetDriverByName( format->driver+5 ); if( hOutputDriver == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to find %s driver.", "msSaveImageGDAL()", format->driver+5 ); return MS_FAILURE; } /* -------------------------------------------------------------------- */ /* We will need to write the output to a temporary file and */ /* then stream to stdout if no filename is passed. If the */ /* driver supports virtualio then we hold the temporary file in */ /* memory, otherwise we try to put it in a reasonable temporary */ /* file location. */ /* -------------------------------------------------------------------- */ if( filename == NULL ) { const char *pszExtension = format->extension; if( pszExtension == NULL ) pszExtension = "img.tmp"; if( bUseXmp == MS_FALSE && GDALGetMetadataItem( hOutputDriver, GDAL_DCAP_VIRTUALIO, NULL ) != NULL ) { CleanVSIDir( "/vsimem/msout" ); filename = msTmpFile(map, NULL, "/vsimem/msout/", pszExtension ); } if( filename == NULL && map != NULL) filename = msTmpFile(map, map->mappath,NULL,pszExtension); else if( filename == NULL ) { filename = msTmpFile(map, NULL, NULL, pszExtension ); } bFileIsTemporary = MS_TRUE; } /* -------------------------------------------------------------------- */ /* Establish the characteristics of our memory, and final */ /* dataset. */ /* -------------------------------------------------------------------- */ if( format->imagemode == MS_IMAGEMODE_RGB ) { nBands = 3; assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer ); format->vtable->getRasterBufferHandle(image,&rb); } else if( format->imagemode == MS_IMAGEMODE_RGBA ) { pabyAlphaLine = (GByte *) calloc(image->width,1); if (pabyAlphaLine == NULL) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()", image->width); return MS_FAILURE; } nBands = 4; assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer ); format->vtable->getRasterBufferHandle(image,&rb); } else if( format->imagemode == MS_IMAGEMODE_INT16 ) { nBands = format->bands; eDataType = GDT_Int16; } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) { nBands = format->bands; eDataType = GDT_Float32; } else if( format->imagemode == MS_IMAGEMODE_BYTE ) { nBands = format->bands; eDataType = GDT_Byte; } else { #ifdef USE_GD assert( format->imagemode == MS_IMAGEMODE_PC256 && format->renderer == MS_RENDER_WITH_GD ); #else { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MEMERR, "GD not compiled in. This is a bug.", "msSaveImageGDAL()"); return MS_FAILURE; } #endif } /* -------------------------------------------------------------------- */ /* Create a memory dataset which we can use as a source for a */ /* CreateCopy(). */ /* -------------------------------------------------------------------- */ hMemDriver = GDALGetDriverByName( "MEM" ); if( hMemDriver == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to find MEM driver.", "msSaveImageGDAL()" ); return MS_FAILURE; } hMemDS = GDALCreate( hMemDriver, "msSaveImageGDAL_temp", image->width, image->height, nBands, eDataType, NULL ); if( hMemDS == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to create MEM dataset.", "msSaveImageGDAL()" ); return MS_FAILURE; } /* -------------------------------------------------------------------- */ /* Copy the gd image into the memory dataset. */ /* -------------------------------------------------------------------- */ for( iLine = 0; iLine < image->height; iLine++ ) { int iBand; for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 ); if( format->imagemode == MS_IMAGEMODE_INT16 ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, image->img.raw_16bit + iLine * image->width + iBand * image->width * image->height, image->width, 1, GDT_Int16, 2, 0 ); } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, image->img.raw_float + iLine * image->width + iBand * image->width * image->height, image->width, 1, GDT_Float32, 4, 0 ); } else if( format->imagemode == MS_IMAGEMODE_BYTE ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, image->img.raw_byte + iLine * image->width + iBand * image->width * image->height, image->width, 1, GDT_Byte, 1, 0 ); } #ifdef USE_GD else if(format->renderer == MS_RENDER_WITH_GD) { gdImagePtr img = (gdImagePtr)image->img.plugin; GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, img->pixels[iLine], image->width, 1, GDT_Byte, 0, 0 ); } #endif else { GByte *pabyData; unsigned char *pixptr = NULL; assert( rb.type == MS_BUFFER_BYTE_RGBA ); switch(iBand) { case 0: pixptr = rb.data.rgba.r; break; case 1: pixptr = rb.data.rgba.g; break; case 2: pixptr = rb.data.rgba.b; break; case 3: pixptr = rb.data.rgba.a; break; } assert(pixptr); if( pixptr == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Missing RGB or A buffer.\n", "msSaveImageGDAL()" ); return MS_FAILURE; } pabyData = (GByte *)(pixptr + iLine*rb.data.rgba.row_step); if( rb.data.rgba.a == NULL || iBand == 3 ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, pabyData, image->width, 1, GDT_Byte, rb.data.rgba.pixel_step, 0 ); } else { /* We need to un-pre-multiple RGB by alpha. */ GByte *pabyUPM = (GByte*) malloc(image->width); GByte *pabyAlpha= (GByte *)(rb.data.rgba.a + iLine*rb.data.rgba.row_step); int i; for( i = 0; i < image->width; i++ ) { int alpha = pabyAlpha[i*rb.data.rgba.pixel_step]; if( alpha == 0 ) pabyUPM[i] = 0; else { int result = (pabyData[i*rb.data.rgba.pixel_step] * 255) / alpha; if( result > 255 ) result = 255; pabyUPM[i] = result; } } GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, pabyUPM, image->width, 1, GDT_Byte, 1, 0 ); free( pabyUPM ); } } } } if( pabyAlphaLine != NULL ) free( pabyAlphaLine ); /* -------------------------------------------------------------------- */ /* Attach the palette if appropriate. */ /* -------------------------------------------------------------------- */ #ifdef USE_GD if( format->renderer == MS_RENDER_WITH_GD ) { GDALColorEntry sEntry; int iColor; GDALColorTableH hCT; gdImagePtr img = (gdImagePtr)image->img.plugin; hCT = GDALCreateColorTable( GPI_RGB ); for( iColor = 0; iColor < img->colorsTotal; iColor++ ) { sEntry.c1 = img->red[iColor]; sEntry.c2 = img->green[iColor]; sEntry.c3 = img->blue[iColor]; if( iColor == gdImageGetTransparent( img ) ) sEntry.c4 = 0; else if( iColor == 0 && gdImageGetTransparent( img ) == -1 && format->transparent ) sEntry.c4 = 0; else sEntry.c4 = 255; GDALSetColorEntry( hCT, iColor, &sEntry ); } GDALSetRasterColorTable( GDALGetRasterBand( hMemDS, 1 ), hCT ); GDALDestroyColorTable( hCT ); } else #endif if( format->imagemode == MS_IMAGEMODE_RGB ) { GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand ); } else if( format->imagemode == MS_IMAGEMODE_RGBA ) { GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 4 ), GCI_AlphaBand ); } /* -------------------------------------------------------------------- */ /* Assign the projection and coordinate system to the memory */ /* dataset. */ /* -------------------------------------------------------------------- */ if( map != NULL ) { char *pszWKT; GDALSetGeoTransform( hMemDS, map->gt.geotransform ); pszWKT = msProjectionObj2OGCWKT( &(map->projection) ); if( pszWKT != NULL ) { GDALSetProjection( hMemDS, pszWKT ); msFree( pszWKT ); } } /* -------------------------------------------------------------------- */ /* Possibly assign a nodata value. */ /* -------------------------------------------------------------------- */ if( msGetOutputFormatOption(format,"NULLVALUE",NULL) != NULL ) { int iBand; const char *nullvalue = msGetOutputFormatOption(format, "NULLVALUE",NULL); for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 ); GDALSetRasterNoDataValue( hBand, atof(nullvalue) ); } } /* -------------------------------------------------------------------- */ /* Try to save resolution in the output file. */ /* -------------------------------------------------------------------- */ if( image->resolution > 0 ) { char res[30]; sprintf( res, "%lf", image->resolution ); GDALSetMetadataItem( hMemDS, "TIFFTAG_XRESOLUTION", res, NULL ); GDALSetMetadataItem( hMemDS, "TIFFTAG_YRESOLUTION", res, NULL ); GDALSetMetadataItem( hMemDS, "TIFFTAG_RESOLUTIONUNIT", "2", NULL ); } /* -------------------------------------------------------------------- */ /* Create a disk image in the selected output format from the */ /* memory image. */ /* -------------------------------------------------------------------- */ papszOptions = (char**)calloc(sizeof(char *),(format->numformatoptions+1)); if (papszOptions == NULL) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()", (unsigned int)(sizeof(char *)*(format->numformatoptions+1))); return MS_FAILURE; } memcpy( papszOptions, format->formatoptions, sizeof(char *) * format->numformatoptions ); hOutputDS = GDALCreateCopy( hOutputDriver, filename, hMemDS, FALSE, papszOptions, NULL, NULL ); free( papszOptions ); if( hOutputDS == NULL ) { GDALClose( hMemDS ); msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to create output %s file.\n%s", "msSaveImageGDAL()", format->driver+5, CPLGetLastErrorMsg() ); return MS_FAILURE; } /* closing the memory DS also frees all associated resources. */ GDALClose( hMemDS ); GDALClose( hOutputDS ); msReleaseLock( TLOCK_GDAL ); /* -------------------------------------------------------------------- */ /* Are we writing license info into the image? */ /* If so, add it to the temp file on disk now. */ /* -------------------------------------------------------------------- */ #ifdef USE_EXEMPI if ( bUseXmp == MS_TRUE ) { if( msXmpWrite(map, filename) == MS_FAILURE ) { /* Something bad happened. */ msSetError( MS_MISCERR, "XMP write to %s failed.\n%s", "msSaveImageGDAL()", filename); return MS_FAILURE; } } #endif /* -------------------------------------------------------------------- */ /* Is this supposed to be a temporary file? If so, stream to */ /* stdout and delete the file. */ /* -------------------------------------------------------------------- */ if( bFileIsTemporary ) { FILE *fp; unsigned char block[4000]; int bytes_read; if( msIO_needBinaryStdout() == MS_FAILURE ) return MS_FAILURE; /* We aren't sure how far back GDAL exports the VSI*L API, so we only use it if we suspect we need it. But we do need it if holding temporary file in memory. */ fp = VSIFOpenL( filename, "rb" ); if( fp == NULL ) { msSetError( MS_MISCERR, "Failed to open %s for streaming to stdout.", "msSaveImageGDAL()", filename ); return MS_FAILURE; } while( (bytes_read = VSIFReadL(block, 1, sizeof(block), fp)) > 0 ) msIO_fwrite( block, 1, bytes_read, stdout ); VSIFCloseL( fp ); VSIUnlink( filename ); CleanVSIDir( "/vsimem/msout" ); free( filename ); } return MS_SUCCESS; }
int msPrepareWFSLayerRequest(int nLayerId, mapObj *map, layerObj *lp, httpRequestObj *pasReqInfo, int *numRequests) { #ifdef USE_WFS_LYR char *pszURL = NULL; const char *pszTmp; rectObj bbox; int nTimeout; int nStatus = MS_SUCCESS; msWFSLayerInfo *psInfo = NULL; int bPostRequest = 0; wfsParamsObj *psParams = NULL; char *pszHTTPCookieData = NULL; if (lp->connectiontype != MS_WFS || lp->connection == NULL) return MS_FAILURE; /* ------------------------------------------------------------------ * Build a params object that will be used by to build the request, this will also set layer projection and compute BBOX in that projection. * ------------------------------------------------------------------ */ psParams = msBuildRequestParams(map, lp, &bbox); if (!psParams) return MS_FAILURE; /* -------------------------------------------------------------------- */ /* Depending on the metadata wfs_request_method, build a Get or */ /* a Post URL. */ /* If it is a Get request the URL would contain all the parameters in*/ /* the string; */ /* If it is a Post request, the URL will only contain the */ /* connection string comming from the layer. */ /* -------------------------------------------------------------------- */ if ((pszTmp = msOWSLookupMetadata(&(lp->metadata), "FO", "request_method")) != NULL) { if (strncmp(pszTmp, "GET", 3) ==0) { pszURL = msBuildWFSLayerGetURL(map, lp, &bbox, psParams); if (!pszURL) { /* an error was already reported. */ return MS_FAILURE; } } } /* else it is a post request and just get the connection string */ if (!pszURL) { bPostRequest = 1; pszURL = msStrdup(lp->connection); } /* ------------------------------------------------------------------ * check to see if a the metadata wfs_connectiontimeout is set. If it is * the case we will use it, else we use the default which is 30 seconds. * First check the metadata in the layer object and then in the map object. * ------------------------------------------------------------------ */ nTimeout = 30; /* Default is 30 seconds */ if ((pszTmp = msOWSLookupMetadata(&(lp->metadata), "FO", "connectiontimeout")) != NULL) { nTimeout = atoi(pszTmp); } else if ((pszTmp = msOWSLookupMetadata(&(map->web.metadata), "FO", "connectiontimeout")) != NULL) { nTimeout = atoi(pszTmp); } /*------------------------------------------------------------------ * Check to see if there's a HTTP Cookie to forward * If Cookie differ between the two connection, it's NOT OK to merge * the connection * ------------------------------------------------------------------ */ if ((pszTmp = msOWSLookupMetadata(&(lp->metadata), "MO", "http_cookie")) != NULL) { if(strcasecmp(pszTmp, "forward") == 0) { pszTmp= msLookupHashTable(&(map->web.metadata),"http_cookie_data"); if(pszTmp != NULL) { pszHTTPCookieData = msStrdup(pszTmp); } } else { pszHTTPCookieData = msStrdup(pszTmp); } } else if ((pszTmp = msOWSLookupMetadata(&(map->web.metadata), "MO", "http_cookie")) != NULL) { if(strcasecmp(pszTmp, "forward") == 0) { pszTmp= msLookupHashTable(&(map->web.metadata),"http_cookie_data"); if(pszTmp != NULL) { pszHTTPCookieData = msStrdup(pszTmp); } } else { pszHTTPCookieData = msStrdup(pszTmp); } } /* ------------------------------------------------------------------ * If nLayerId == -1 then we need to figure it * ------------------------------------------------------------------ */ if (nLayerId == -1) { int iLayer; for(iLayer=0; iLayer < map->numlayers; iLayer++) { if (GET_LAYER(map, iLayer) == lp) { nLayerId = iLayer; break; } } } /* ------------------------------------------------------------------ * Add a request to the array (already preallocated) * ------------------------------------------------------------------ */ pasReqInfo[(*numRequests)].nLayerId = nLayerId; pasReqInfo[(*numRequests)].pszGetUrl = pszURL; if (bPostRequest) { pasReqInfo[(*numRequests)].pszPostRequest = msBuildWFSLayerPostRequest(map, lp, &bbox, psParams); pasReqInfo[(*numRequests)].pszPostContentType = msStrdup("text/xml"); } /* We'll store the remote server's response to a tmp file. */ pasReqInfo[(*numRequests)].pszOutputFile = msTmpFile(map, map->mappath, NULL, "tmp.gml"); /* TODO: Implement Caching of GML responses. There was an older caching * method, but it suffered from a race condition. See #3137. */ pasReqInfo[(*numRequests)].pszHTTPCookieData = pszHTTPCookieData; pszHTTPCookieData = NULL; pasReqInfo[(*numRequests)].nStatus = 0; pasReqInfo[(*numRequests)].nTimeout = nTimeout; pasReqInfo[(*numRequests)].bbox = bbox; pasReqInfo[(*numRequests)].debug = lp->debug; /* ------------------------------------------------------------------ * Pre-Open the layer now, (i.e. alloc and fill msWFSLayerInfo inside * layer obj). Layer will be ready for use when the main mapserver * code calls msLayerOpen(). * ------------------------------------------------------------------ */ if (lp->wfslayerinfo != NULL) { psInfo =(msWFSLayerInfo*)(lp->wfslayerinfo); } else { lp->wfslayerinfo = psInfo = msAllocWFSLayerInfo(); } if (psInfo->pszGMLFilename) free(psInfo->pszGMLFilename); psInfo->pszGMLFilename=msStrdup(pasReqInfo[(*numRequests)].pszOutputFile); psInfo->rect = pasReqInfo[(*numRequests)].bbox; if (psInfo->pszGetUrl) free(psInfo->pszGetUrl); psInfo->pszGetUrl = msStrdup(pasReqInfo[(*numRequests)].pszGetUrl); psInfo->nStatus = 0; (*numRequests)++; if (psParams) { msWFSFreeParamsObj(psParams); psParams = NULL; } return nStatus; #else /* ------------------------------------------------------------------ * WFS CONNECTION Support not included... * ------------------------------------------------------------------ */ msSetError(MS_WFSCONNERR, "WFS CLIENT CONNECTION support is not available.", "msPrepareWFSLayerRequest"); return(MS_FAILURE); #endif /* USE_WFS_LYR */ }