int renderVectorSymbolGD(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style) { int bRotated = MS_FALSE; int j,k; gdImagePtr ip; gdPoint mPoints[MS_MAXVECTORPOINTS]; gdPoint oldpnt,newpnt; int fc,oc; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; SETPEN(ip, style->color); SETPEN(ip, style->outlinecolor); fc = style->color ? style->color->pen : -1; oc = style->outlinecolor ? style->outlinecolor->pen : -1; if(oc==-1 && fc ==-1) { return MS_SUCCESS; } if (style->rotation != 0.0) { bRotated = MS_TRUE; symbol = rotateVectorSymbolPoints(symbol, style->rotation); if(!symbol) { return MS_FAILURE; } } /* We avoid MS_NINT in this context because the potentially variable handling of 0.5 rounding is often a problem for symbols which are often an odd size (ie. 7pixels) and so if "p" is integral the value is always on a 0.5 boundary - bug 1716 */ x -= style->scale*.5*symbol->sizex; y -= style->scale*.5*symbol->sizey; if(symbol->filled) { /* if filled */ k = 0; /* point counter */ for(j=0;j < symbol->numpoints;j++) { if((symbol->points[j].x == -99) && (symbol->points[j].x == -99)) { /* new polygon (PENUP) */ if(k>2) { if(fc >= 0) gdImageFilledPolygon(ip, mPoints, k, fc); if(oc >= 0) gdImagePolygon(ip, mPoints, k, oc); } k = 0; /* reset point counter */ } else { mPoints[k].x = MS_NINT(style->scale*symbol->points[j].x + x); mPoints[k].y = MS_NINT(style->scale*symbol->points[j].y + y); k++; } } if(fc >= 0) gdImageFilledPolygon(ip, mPoints, k, fc); if(oc >= 0) gdImagePolygon(ip, mPoints, k, oc); } else { /* NOT filled */ if(oc >= 0) fc = oc; /* try the outline color (reference maps sometimes do this when combining a box and a custom vector marker */ oldpnt.x = MS_NINT(style->scale*symbol->points[0].x + x); /* convert first point in marker */ oldpnt.y = MS_NINT(style->scale*symbol->points[0].y + y); gdImageSetThickness(ip, style->outlinewidth); for(j=1;j < symbol->numpoints;j++) { /* step through the marker */ if((symbol->points[j].x != -99) || (symbol->points[j].x != -99)) { if((symbol->points[j-1].x == -99) && (symbol->points[j-1].y == -99)) { /* Last point was PENUP, now a new beginning */ oldpnt.x = MS_NINT(style->scale*symbol->points[j].x + x); oldpnt.y = MS_NINT(style->scale*symbol->points[j].y + y); } else { newpnt.x = MS_NINT(style->scale*symbol->points[j].x + x); newpnt.y = MS_NINT(style->scale*symbol->points[j].y + y); gdImageLine(ip, oldpnt.x, oldpnt.y, newpnt.x, newpnt.y, fc); oldpnt = newpnt; } } } /* end for loop */ gdImageSetThickness(ip, 1); /* restore thinkness */ } /* end if-then-else */ if(bRotated) { msFreeSymbol(symbol); /* clean up */ msFree(symbol); } return MS_SUCCESS; }
int msUVRASTERLayerGetExtent(layerObj *layer, rectObj *extent) { char szPath[MS_MAXPATHLEN]; mapObj *map = layer->map; double adfGeoTransform[6]; int nXSize, nYSize; GDALDatasetH hDS; shapefileObj *tileshpfile; int tilelayerindex = -1; CPLErr eErr = CE_Failure; char *decrypted_path; if( (!layer->data || strlen(layer->data) == 0) && layer->tileindex == NULL) { /* should we be issuing a specific error about not supporting extents for tileindexed raster layers? */ return MS_FAILURE; } if( map == NULL ) return MS_FAILURE; /* If the layer use a tileindex, return the extent of the tileindex shapefile/referenced layer */ if (layer->tileindex) { tilelayerindex = msGetLayerIndex(map, layer->tileindex); if(tilelayerindex != -1) /* does the tileindex reference another layer */ return msLayerGetExtent(GET_LAYER(map, tilelayerindex), extent); else { tileshpfile = (shapefileObj *) malloc(sizeof(shapefileObj)); MS_CHECK_ALLOC(tileshpfile, sizeof(shapefileObj), MS_FAILURE); if(msShapefileOpen(tileshpfile, "rb", msBuildPath3(szPath, map->mappath, map->shapepath, layer->tileindex), MS_TRUE) == -1) if(msShapefileOpen(tileshpfile, "rb", msBuildPath(szPath, map->mappath, layer->tileindex), MS_TRUE) == -1) return MS_FAILURE; *extent = tileshpfile->bounds; msShapefileClose(tileshpfile); free(tileshpfile); return MS_SUCCESS; } } msTryBuildPath3(szPath, map->mappath, map->shapepath, layer->data); decrypted_path = msDecryptStringTokens( map, szPath ); msAcquireLock( TLOCK_GDAL ); if( decrypted_path ) { hDS = GDALOpen(decrypted_path, GA_ReadOnly ); msFree( decrypted_path ); } else hDS = NULL; if( hDS != NULL ) { nXSize = GDALGetRasterXSize( hDS ); nYSize = GDALGetRasterYSize( hDS ); eErr = GDALGetGeoTransform( hDS, adfGeoTransform ); GDALClose( hDS ); } msReleaseLock( TLOCK_GDAL ); if( hDS == NULL || eErr != CE_None ) { return MS_FAILURE; } /* If this appears to be an ungeoreferenced raster than flip it for mapservers purposes. */ if( adfGeoTransform[5] == 1.0 && adfGeoTransform[3] == 0.0 ) { adfGeoTransform[5] = -1.0; adfGeoTransform[3] = nYSize; } extent->minx = adfGeoTransform[0]; extent->maxy = adfGeoTransform[3]; extent->maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1]; extent->miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5]; return MS_SUCCESS; }
int main(int argc, char *argv[]) { int i,j,k; mapObj *map=NULL; imageObj *image = NULL; char **layers=NULL; int num_layers=0; int layer_found=0; char *outfile=NULL; /* no -o sends image to STDOUT */ int iterations = 1; int draws = 0; for(i=1;i<argc;i++) { if (strcmp(argv[i],"-c") == 0) { /* user specified number of draws */ iterations = atoi(argv[i+1]); printf("We will draw %d times...\n", iterations); continue; } if(strcmp(argv[i], "-all_debug") == 0 && i < argc-1 ) /* global debug */ { int debug_level = atoi(argv[++i]); msSetGlobalDebugLevel(debug_level); /* Send output to stderr by default */ if (msGetErrorFile() == NULL) msSetErrorFile("stderr", NULL); continue; } } for(draws=0; draws<iterations; draws++) { struct mstimeval requeststarttime, requestendtime; if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) msGettimeofday(&requeststarttime, NULL); if(argc > 1 && strcmp(argv[1], "-v") == 0) { printf("%s\n", msGetVersion()); exit(0); } /* ---- check the number of arguments, return syntax if not correct ---- */ if( argc < 3 ) { fprintf(stdout, "\nPurpose: convert a mapfile to an image\n\n"); fprintf(stdout, "Syntax: shp2img -m mapfile [-o image] [-e minx miny maxx maxy] [-s sizex sizey]\n" " [-l \"layer1 [layers2...]\"] [-i format]\n" " [-all_debug n] [-map_debug n] [-layer_debug n] [-p n] [-c n] [-d layername datavalue]\n"); fprintf(stdout," -m mapfile: Map file to operate on - required\n" ); fprintf(stdout," -i format: Override the IMAGETYPE value to pick output format\n" ); fprintf(stdout," -o image: output filename (stdout if not provided)\n"); fprintf(stdout," -e minx miny maxx maxy: extents to render\n"); fprintf(stdout," -s sizex sizey: output image size\n"); fprintf(stdout," -l layers: layers / groups to enable - make sure they are quoted and space seperated if more than one listed\n" ); fprintf(stdout," -all_debug n: Set debug level for map and all layers\n" ); fprintf(stdout," -map_debug n: Set map debug level\n" ); fprintf(stdout," -layer_debug layer_name n: Set layer debug level\n" ); fprintf(stdout," -c n: draw map n number of times\n" ); fprintf(stdout," -p n: pause for n seconds after reading the map\n" ); fprintf(stdout," -d layername datavalue: change DATA value for layer\n" ); exit(0); } if ( msSetup() != MS_SUCCESS ) { msWriteError(stderr); exit(1); } /* Use MS_ERRORFILE and MS_DEBUGLEVEL env vars if set */ if ( msDebugInitFromEnv() != MS_SUCCESS ) { msWriteError(stderr); msCleanup(0); exit(1); } for(i=1;i<argc;i++) { /* Step though the user arguments, 1st to find map file */ if(strcmp(argv[i],"-m") == 0) { map = msLoadMap(argv[i+1], NULL); if(!map) { msWriteError(stderr); msCleanup(0); exit(1); } msApplyDefaultSubstitutions(map); } } if(!map) { fprintf(stderr, "Mapfile (-m) option not specified.\n"); msCleanup(0); exit(1); } for(i=1;i<argc;i++) { /* Step though the user arguments */ if(strcmp(argv[i],"-m") == 0) { /* skip it */ i+=1; } if(strcmp(argv[i],"-p") == 0) { int pause_length = atoi(argv[i+1]); time_t start_time = time(NULL); printf( "Start pause of %d seconds.\n", pause_length ); while( time(NULL) < start_time + pause_length ) {} printf( "Done pause.\n" ); i+=1; } if(strcmp(argv[i],"-o") == 0) { /* load the output image filename */ outfile = argv[i+1]; i+=1; } if(strcmp(argv[i],"-i") == 0) { outputFormatObj *format; format = msSelectOutputFormat( map, argv[i+1] ); if( format == NULL ) printf( "No such OUTPUTFORMAT as %s.\n", argv[i+1] ); else { msFree( (char *) map->imagetype ); map->imagetype = msStrdup( argv[i+1] ); msApplyOutputFormat( &(map->outputformat), format, map->transparent, map->interlace, map->imagequality ); } i+=1; } if(strcmp(argv[i],"-d") == 0) { /* swap layer data */ for(j=0; j<map->numlayers; j++) { if(strcmp(GET_LAYER(map, j)->name, argv[i+1]) == 0) { free(GET_LAYER(map, j)->data); GET_LAYER(map, j)->data = msStrdup(argv[i+2]); break; } } i+=2; } if(strcmp(argv[i], "-all_debug") == 0 && i < argc-1 ) /* global debug */ { int debug_level = atoi(argv[++i]); /* msSetGlobalDebugLevel() already called. Just need to force debug * level in map and all layers */ map->debug = debug_level; for(j=0; j<map->numlayers; j++) { GET_LAYER(map, j)->debug = debug_level; } } if(strcmp(argv[i], "-map_debug") == 0 && i < argc-1 ) /* debug */ { map->debug = atoi(argv[++i]); /* Send output to stderr by default */ if (msGetErrorFile() == NULL) msSetErrorFile("stderr", NULL); } if(strcmp(argv[i], "-layer_debug") == 0 && i < argc-1 ) /* debug */ { const char *layer_name = argv[++i]; int debug_level = atoi(argv[++i]); int got_layer = 0; for(j=0; j<map->numlayers; j++) { if(strcmp(GET_LAYER(map, j)->name,layer_name) == 0 ) { GET_LAYER(map, j)->debug = debug_level; got_layer = 1; } } if( !got_layer ) fprintf( stderr, " Did not find layer '%s' from -layer_debug switch.\n", layer_name ); /* Send output to stderr by default */ if (msGetErrorFile() == NULL) msSetErrorFile("stderr", NULL); } if(strcmp(argv[i],"-e") == 0) { /* change extent */ if( argc <= i+4 ) { fprintf( stderr, "Argument -e needs 4 space separated numbers as argument.\n" ); msCleanup(0); exit(1); } map->extent.minx = atof(argv[i+1]); map->extent.miny = atof(argv[i+2]); map->extent.maxx = atof(argv[i+3]); map->extent.maxy = atof(argv[i+4]); i+=4; } if (strcmp(argv[i], "-s") == 0) { msMapSetSize(map, atoi(argv[i+1]), atoi(argv[i+2])); i+=2; } if(strcmp(argv[i],"-l") == 0) { /* load layer list */ layers = msStringSplit(argv[i+1], ' ', &(num_layers)); for(j=0; j<num_layers; j++) { /* loop over -l */ layer_found=0; for(k=0; k<map->numlayers; k++) { if((GET_LAYER(map, k)->name && strcasecmp(GET_LAYER(map, k)->name, layers[j]) == 0) || (GET_LAYER(map, k)->group && strcasecmp(GET_LAYER(map, k)->group, layers[j]) == 0)) { layer_found = 1; break; } } if (layer_found==0) { fprintf(stderr, "Layer (-l) \"%s\" not found\n", layers[j]); msCleanup(0); exit(1); } } for(j=0; j<map->numlayers; j++) { if(GET_LAYER(map, j)->status == MS_DEFAULT) continue; else { GET_LAYER(map, j)->status = MS_OFF; for(k=0; k<num_layers; k++) { if((GET_LAYER(map, j)->name && strcasecmp(GET_LAYER(map, j)->name, layers[k]) == 0) || (GET_LAYER(map, j)->group && strcasecmp(GET_LAYER(map, j)->group, layers[k]) == 0)) { GET_LAYER(map, j)->status = MS_ON; break; } } } } msFreeCharArray(layers, num_layers); i+=1; } } image = msDrawMap(map, MS_FALSE); if(!image) { msWriteError(stderr); msFreeMap(map); msCleanup(0); exit(1); } if( msSaveImage(map, image, outfile) != MS_SUCCESS ) { msWriteError(stderr); } msFreeImage(image); msFreeMap(map); if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&requestendtime, NULL); msDebug("shp2img total time: %.3fs\n", (requestendtime.tv_sec+requestendtime.tv_usec/1.0e6)- (requeststarttime.tv_sec+requeststarttime.tv_usec/1.0e6) ); } msCleanup(0); } /* for(draws=0; draws<iterations; draws++) { */ return(0); } /* ---- END Main Routine ---- */
static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_renderer *r) { /* We need a GDAL 2.0 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); VSIFReadL(r->outputStream->data, 1, nFileSize, fp); r->outputStream->size = nFileSize; VSIFCloseL(fp); fp = NULL; } } } if ( hDS != NULL ) GDALClose(hDS); VSIUnlink(pszTmpFilename); msFree(pszTmpFilename); #endif }
int msContourLayerOpen(layerObj *layer) { char *decrypted_path; char szPath[MS_MAXPATHLEN]; contourLayerInfo *clinfo; if (layer->debug) msDebug("Entering msContourLayerOpen().\n"); /* If we don't have info, initialize an empty one now */ if (layer->layerinfo == NULL) msContourLayerInfoInitialize(layer); clinfo = (contourLayerInfo *) layer->layerinfo; if (layer->data == NULL && layer->tileindex == NULL ) { msSetError(MS_MISCERR, "Layer %s has neither DATA nor TILEINDEX defined.", "msContourLayerOpen()", layer->name); return MS_FAILURE; } if( layer->tileindex != NULL ) { char szTilename[MS_MAXPATHLEN]; int status; int tilelayerindex, tileitemindex, tilesrsindex; rectObj searchrect; layerObj* tlp; shapeObj tshp; char tilesrsname[1]; msInitShape(&tshp); searchrect = layer->map->extent; status = msDrawRasterSetupTileLayer(layer->map, layer, &searchrect, MS_FALSE, &tilelayerindex, &tileitemindex, &tilesrsindex, &tlp); if( status == MS_FAILURE ) { return MS_FAILURE; } status = msDrawRasterIterateTileIndex(layer, tlp, &tshp, tileitemindex, -1, szTilename, sizeof(szTilename), tilesrsname, sizeof(tilesrsname)); if( status == MS_FAILURE || status == MS_DONE ) { if( status == MS_DONE ) { if (layer->debug) msDebug("No raster matching filter.\n"); } msDrawRasterCleanupTileLayer(tlp, tilelayerindex); return MS_FAILURE; } msDrawRasterCleanupTileLayer(tlp, tilelayerindex); msDrawRasterBuildRasterPath(layer->map, layer, szTilename, szPath); decrypted_path = msStrdup(szPath); /* Cancel the time filter that might have been set on ours in case of */ /* a inline tileindex */ msFreeExpression(&layer->filter); msInitExpression(&layer->filter); } else { msTryBuildPath3(szPath, layer->map->mappath, layer->map->shapepath, layer->data); decrypted_path = msDecryptStringTokens(layer->map, szPath); } GDALAllRegister(); /* Open the original Dataset */ msAcquireLock(TLOCK_GDAL); if (decrypted_path) { clinfo->hOrigDS = GDALOpen(decrypted_path, GA_ReadOnly); msFree(decrypted_path); } else clinfo->hOrigDS = NULL; msReleaseLock(TLOCK_GDAL); if (clinfo->hOrigDS == NULL) { msSetError(MS_IMGERR, "Unable to open GDAL dataset.", "msContourLayerOpen()"); return MS_FAILURE; } /* Open the raster source */ if (msContourLayerReadRaster(layer, layer->map->extent) != MS_SUCCESS) return MS_FAILURE; /* Generate Contour Dataset */ if (msContourLayerGenerateContour(layer) != MS_SUCCESS) return MS_FAILURE; if (clinfo->hDS) { GDALClose(clinfo->hDS); clinfo->hDS = NULL; free(clinfo->buffer); } /* Open our virtual ogr layer */ if (clinfo->hOGRDS && (msLayerOpen(&clinfo->ogrLayer) != MS_SUCCESS)) return MS_FAILURE; return MS_SUCCESS; }
int KmlRenderer::startNewLayer(imageObj *img, layerObj *layer) { char *layerName=NULL; const char *value=NULL; LayerNode = xmlNewNode(NULL, BAD_CAST "Folder"); layerName = getLayerName(layer); xmlNewChild(LayerNode, NULL, BAD_CAST "name", BAD_CAST layerName); msFree(layerName); const char *layerVisibility = layer->status != MS_OFF ? "1" : "0"; xmlNewChild(LayerNode, NULL, BAD_CAST "visibility", BAD_CAST layerVisibility); const char *layerDsiplayFolder = msLookupHashTable(&(layer->metadata), "kml_folder_display"); if (layerDsiplayFolder == NULL) layerDsiplayFolder = msLookupHashTable(&(layer->map->web.metadata), "kml_folder_display"); if (!layerDsiplayFolder || strlen(layerDsiplayFolder)<=0) { xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_check"); } else { if (strcasecmp(layerDsiplayFolder, "checkHideChildren") == 0) xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_checkHideChildren"); else if (strcasecmp(layerDsiplayFolder, "checkOffOnly") == 0) xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_checkOffOnly"); else if (strcasecmp(layerDsiplayFolder, "radioFolder") == 0) xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_radioFolder"); else xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_check"); } /*Init few things on the first layer*/ if (FirstLayer) { FirstLayer = MS_FALSE; map = layer->map; if (layer->map->mappath) snprintf(MapPath, sizeof(MapPath), "%s", layer->map->mappath); /*First rendered layer - check mapfile projection*/ checkProjection(layer->map); /*check for image path and image url*/ if (layer->map->debug && (layer->map->web.imageurl == NULL || layer->map->web.imagepath == NULL)) msDebug("KmlRenderer::startNewLayer: imagepath and imageurl sould be set in the web object\n"); /*map rect for ground overlay*/ MapExtent = layer->map->extent; MapCellsize = layer->map->cellsize; BgColor = layer->map->imagecolor; xmlNewChild(DocNode, NULL, BAD_CAST "name", BAD_CAST layer->map->name); aggFormat = msSelectOutputFormat( layer->map, "png24"); aggFormat->transparent = MS_TRUE; } currentLayer = layer; if (!msLayerIsOpen(layer)) { if (msLayerOpen(layer) != MS_SUCCESS) { msSetError(MS_MISCERR, "msLayerOpen failed", "KmlRenderer::startNewLayer" ); } } /*pre process the layer to set things that make sense for kml output*/ if (img) processLayer(layer, img->format); else processLayer(layer, NULL); if (msLookupHashTable(&layer->metadata, "kml_description")) pszLayerDescMetadata = msLookupHashTable(&layer->metadata, "kml_description"); else if (msLookupHashTable(&layer->metadata, "ows_description")) pszLayerDescMetadata = msLookupHashTable(&layer->metadata, "ows_description"); value=msLookupHashTable(&layer->metadata, "kml_include_items"); if (!value) value=msLookupHashTable(&layer->metadata, "ows_include_items"); if (value) papszLayerIncludeItems = msStringSplit(value, ',', &nIncludeItems); value=msLookupHashTable(&layer->metadata, "kml_exclude_items"); if (!value) value=msLookupHashTable(&layer->metadata, "ows_exclude_items"); if (value) papszLayerExcludeItems = msStringSplit(value, ',', &nExcludeItems); if (msLookupHashTable(&layer->metadata, "kml_name_item")) pszLayerNameAttributeMetadata = msLookupHashTable(&layer->metadata, "kml_name_item"); /*get all attributes*/ msLayerWhichItems(layer, MS_TRUE, NULL); NumItems = layer->numitems; if (NumItems) { Items = (char **)msSmallCalloc(NumItems, sizeof(char *)); for (int i=0; i<NumItems; i++) Items[i] = msStrdup(layer->items[i]); } char* elevationAttribute = msLookupHashTable(&layer->metadata, "kml_elevation_attribute"); if( elevationAttribute ) { mElevationFromAttribute = true; for( int i = 0; i < layer->numitems; ++i ) { if( strcasecmp( layer->items[i], elevationAttribute ) == 0 ) { mElevationAttributeIndex = i; } } } setupRenderingParams(&layer->metadata); return MS_SUCCESS; }
int msLoadImageSymbol(symbolObj *symbol, const char *filename) { msFree(symbol->full_pixmap_path); symbol->full_pixmap_path = msStrdup(filename); return MS_SUCCESS; }
SHPTreeHandle msSHPDiskTreeOpen(struct zzip_dir *zdir, const char * pszTree, int debug) { char *pszFullname, *pszBasename; SHPTreeHandle psTree; char pabyBuf[16]; int i; #ifdef SHAPELIB_DISABLED char bBigEndian; /* -------------------------------------------------------------------- */ /* Establish the byte order on this machine. */ /* -------------------------------------------------------------------- */ i = 1; if( *((uchar *) &i) == 1 ) bBigEndian = MS_FALSE; else bBigEndian = MS_TRUE; #endif /* SHAPELIB_DISABLED */ /* -------------------------------------------------------------------- */ /* Initialize the info structure. */ /* -------------------------------------------------------------------- */ psTree = (SHPTreeHandle) msSmallMalloc(sizeof(SHPTreeInfo)); /* -------------------------------------------------------------------- */ /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ pszBasename = (char *) msSmallMalloc(strlen(pszTree)+5); strcpy( pszBasename, pszTree ); for( i = strlen(pszBasename)-1; i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' && pszBasename[i] != '\\'; i-- ) {} if( pszBasename[i] == '.' ) pszBasename[i] = '\0'; /* -------------------------------------------------------------------- */ /* Open the .shp and .shx files. Note that files pulled from */ /* a PC to Unix with upper case filenames won't work! */ /* -------------------------------------------------------------------- */ pszFullname = (char *) msSmallMalloc(strlen(pszBasename) + 5); sprintf( pszFullname, "%s%s", pszBasename, MS_INDEX_EXTENSION); psTree->fp = zzip_open_rb(zdir, pszFullname); msFree(pszBasename); /* don't need these any more */ msFree(pszFullname); if( psTree->fp == NULL ) { msFree(psTree); return( NULL ); } zzip_fread( pabyBuf, 8, 1, psTree->fp ); memcpy( &psTree->signature, pabyBuf, 3 ); if( strncmp(psTree->signature,"SQT",3) ) { /* ---------------------------------------------------------------------- */ /* must check if the 2 first bytes equal 0 of max depth that cannot */ /* be more than 65535. If yes, we must swap all value. The problem */ /* here is if there's no Depth (bytea 5,6,7,8 in the file) all bytes */ /* will be set to 0. So,we will test with the number of shapes (bytes */ /* 1,2,3,4) that cannot be more than 65535 too. */ /* ---------------------------------------------------------------------- */ if (debug) { msDebug("WARNING in msSHPDiskTreeOpen(): %s is in old index format " "which has been deprecated. It is strongly recommended to " "regenerate it in new format.\n", pszTree); } if((pabyBuf[4] == 0 && pabyBuf[5] == 0 && pabyBuf[6] == 0 && pabyBuf[7] == 0)) { psTree->LSB_order = !(pabyBuf[0] == 0 && pabyBuf[1] == 0); } else { psTree->LSB_order = !(pabyBuf[4] == 0 && pabyBuf[5] == 0); } psTree->needswap = ((psTree->LSB_order) != (!bBigEndian)); /* ---------------------------------------------------------------------- */ /* poor hack to see if this quadtree was created by a computer with a */ /* different Endian */ /* ---------------------------------------------------------------------- */ psTree->version = 0; } else { psTree->needswap = (( pabyBuf[3] == MS_NEW_MSB_ORDER ) ^ ( bBigEndian )); psTree->LSB_order = ( pabyBuf[3] == MS_NEW_LSB_ORDER ); memcpy( &psTree->version, pabyBuf+4, 1 ); memcpy( &psTree->flags, pabyBuf+5, 3 ); zzip_fread( pabyBuf, 8, 1, psTree->fp ); } if( psTree->needswap ) SwapWord( 4, pabyBuf ); memcpy( &psTree->nShapes, pabyBuf, 4 ); if( psTree->needswap ) SwapWord( 4, pabyBuf+4 ); memcpy( &psTree->nDepth, pabyBuf+4, 4 ); return( psTree ); }
SHPTreeHandle msSHPDiskTreeOpen(const TCHAR* pszTree, int debug) { TCHAR *pszFullname, *pszBasename; SHPTreeHandle psTree; char pabyBuf[16]; int i; char bBigEndian; /* -------------------------------------------------------------------- */ /* Establish the byte order on this machine. */ /* -------------------------------------------------------------------- */ i = 1; if( *((uchar *) &i) == 1 ) bBigEndian = MS_FALSE; else bBigEndian = MS_TRUE; /* -------------------------------------------------------------------- */ /* Initialize the info structure. */ /* -------------------------------------------------------------------- */ psTree = (SHPTreeHandle) malloc(sizeof(SHPTreeInfo)); /* -------------------------------------------------------------------- */ /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ pszBasename = (TCHAR *) malloc((_tcslen(pszTree)+5) * sizeof(TCHAR) * 2); _tcscpy( pszBasename, pszTree ); for( i = _tcslen(pszBasename)-1; i > 0 && pszBasename[i] != _T('.') && pszBasename[i] != _T('/') && pszBasename[i] != _T('\\'); i-- ) {} if( pszBasename[i] == _T('.') ) pszBasename[i] = _T('\0'); /* -------------------------------------------------------------------- */ /* Open the .shp and .shx files. Note that files pulled from */ /* a PC to Unix with upper case filenames won't work! */ /* -------------------------------------------------------------------- */ pszFullname = (TCHAR *) malloc((_tcslen(pszBasename) + _tcslen(_T(MS_INDEX_EXTENSION)) + 1) * sizeof(TCHAR) * 2); _stprintf( pszFullname, _T("%s%s"), pszBasename, _T(MS_INDEX_EXTENSION)); if (FileExists(pszFullname)) // prevent codegurad warnings (open unexisting file for reading) psTree->zfp = openzip(pszFullname, "rb" ); else psTree->zfp = NULL; msFree(pszBasename); // don't need these any more msFree(pszFullname); if( psTree->zfp == NULL ) { msFree(psTree); return( NULL ); } zzip_fread( pabyBuf, 8, 1, psTree->zfp ); memcpy( &psTree->signature, pabyBuf, 3 ); if( strncmp(psTree->signature,"SQT",3) ) { /* ---------------------------------------------------------------------- */ /* must check if the 2 first bytes equal 0 of max depth that cannot */ /* be more than 65535. If yes, we must swap all value. The problem */ /* here is if there's no Depth (bytea 5,6,7,8 in the file) all bytes */ /* will be set to 0. So,we will test with the number of shapes (bytes */ /* 1,2,3,4) that cannot be more than 65535 too. */ /* ---------------------------------------------------------------------- */ #if MAPSHAPEERROR if (debug) { msDebug("WARNING in msSHPDiskTreeOpen(): %ls is in old index format " "which has been deprecated. It is strongly recommended to " "regenerate it in new format.\n", pszTree); } #endif if((pabyBuf[4] == 0 && pabyBuf[5] == 0 && pabyBuf[6] == 0 && pabyBuf[7] == 0)) { psTree->LSB_order = !(pabyBuf[0] == 0 && pabyBuf[1] == 0); } else { psTree->LSB_order = !(pabyBuf[4] == 0 && pabyBuf[5] == 0); } psTree->needswap = ((psTree->LSB_order) != (!bBigEndian)); /* ---------------------------------------------------------------------- */ /* poor hack to see if this quadtree was created by a computer with a */ /* different Endian */ /* ---------------------------------------------------------------------- */ psTree->version = 0; } else { psTree->needswap = (( pabyBuf[3] == MS_NEW_MSB_ORDER ) ^ ( bBigEndian )); psTree->LSB_order = ( pabyBuf[3] == MS_NEW_LSB_ORDER ); memcpy( &psTree->version, pabyBuf+4, 1 ); memcpy( &psTree->flags, pabyBuf+5, 3 ); zzip_fread( pabyBuf, 8, 1, psTree->zfp ); } if( psTree->needswap ) SwapWord( 4, pabyBuf ); memcpy( &psTree->nShapes, pabyBuf, 4 ); if( psTree->needswap ) SwapWord( 4, pabyBuf+4 ); memcpy( &psTree->nDepth, pabyBuf+4, 4 ); return( psTree ); }
char *FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, layerObj *lp) { char *pszExpression = NULL; shapeObj *psQueryShape = NULL; double dfDistance = -1; int nUnit = -1; char *pszWktText = NULL; char szBuffer[256]; char *pszTmp=NULL; projectionObj sProjTmp; char *pszEPSG= NULL; rectObj sQueryRect; shapeObj *psTmpShape=NULL, *psBufferShape=NULL; int bBBoxQuery = 0; if (psNode == NULL || lp == NULL) return NULL; if (psNode->eType != FILTER_NODE_TYPE_SPATIAL) return NULL; /* get the shape*/ /*BBOX case: replace it with NOT DISJOINT.*/ if(FLTIsBBoxFilter(psNode)) { pszEPSG = FLTGetBBOX(psNode, &sQueryRect); /*this should be removed and bbox should parse and strore the srs properly, using now legacy code*/ if (pszEPSG) psNode->pszSRS = msStrdup(pszEPSG); psTmpShape = (shapeObj *)msSmallMalloc(sizeof(shapeObj)); msInitShape(psTmpShape); msRectToPolygon(sQueryRect, psTmpShape); bBBoxQuery = 1; } else { /*other geos type operations*/ /*project shape to layer projection. If the proj is not part of the filter query, assume that the cooredinates are in the map projection*/ psQueryShape = FLTGetShape(psNode, &dfDistance, &nUnit); if ((strcasecmp(psNode->pszValue, "DWithin") == 0 || strcasecmp(psNode->pszValue, "Beyond") == 0 ) && dfDistance > 0) { if (nUnit >=0 && nUnit != lp->map->units) dfDistance *= msInchesPerUnit(nUnit,0)/msInchesPerUnit(lp->map->units,0); psBufferShape = msGEOSBuffer(psQueryShape, dfDistance); } if (psBufferShape) psTmpShape = psBufferShape; else psTmpShape = psQueryShape; } if (psTmpShape) { if( lp->projection.numargs > 0) { if (psNode->pszSRS && FTLParseEpsgString(psNode->pszSRS, &sProjTmp)) { msProjectShape(&sProjTmp, &lp->projection, psTmpShape); msFreeProjection(&sProjTmp); } else if (lp->map->projection.numargs > 0) msProjectShape(&lp->map->projection, &lp->projection, psTmpShape); } /* ==================================================================== */ /* use within for bbox. Not Disjoint does not work. */ /* ==================================================================== */ if (bBBoxQuery) sprintf(szBuffer, "%s", " ([shape] "); /* sprintf(szBuffer, "%s", " (NOT ([shape] "); */ else sprintf(szBuffer, "%s", " ([shape] "); pszExpression = msStringConcatenate(pszExpression, szBuffer); if (strncasecmp(psNode->pszValue, "intersect", 9) == 0) pszTmp = msStrdup("intersects"); else pszTmp = msStrdup(psNode->pszValue); msStringToLower(pszTmp); if (bBBoxQuery) sprintf(szBuffer, " %s ", "intersects"); /* sprintf(szBuffer, " %s ", "disjoint"); */ else sprintf(szBuffer, " %s ", pszTmp); pszExpression = msStringConcatenate(pszExpression, szBuffer); msFree(pszTmp); pszWktText = msGEOSShapeToWKT(psTmpShape); sprintf(szBuffer, "%s", " fromText('"); pszExpression = msStringConcatenate(pszExpression, szBuffer); pszExpression = msStringConcatenate(pszExpression, pszWktText); sprintf(szBuffer, "%s", "')"); pszExpression = msStringConcatenate(pszExpression, szBuffer); msGEOSFreeWKT(pszWktText); } if (psBufferShape) msFreeShape(psBufferShape); sprintf(szBuffer, "%s", ")"); pszExpression = msStringConcatenate(pszExpression, szBuffer); if (0) /* bBBoxQuery */ { sprintf(szBuffer, "%s", ")"); pszExpression = msStringConcatenate(pszExpression, szBuffer); } return pszExpression; }
char *FLTGetFeatureIdCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp) { char *pszExpression = NULL; int nTokens = 0, i=0, bString=0; char **tokens = NULL; const char *pszAttribute=NULL; #if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) if (psFilterNode->pszValue) { pszAttribute = msOWSLookupMetadata(&(lp->metadata), "OFG", "featureid"); if (pszAttribute) { tokens = msStringSplit(psFilterNode->pszValue,',', &nTokens); if (tokens && nTokens > 0) { for (i=0; i<nTokens; i++) { char *pszTmp = NULL; int bufferSize = 0; if (i == 0) { if(FLTIsNumeric(tokens[0]) == MS_FALSE) bString = 1; } if (bString) { bufferSize = 11+strlen(tokens[i])+strlen(pszAttribute)+1; pszTmp = (char *)msSmallMalloc(bufferSize); snprintf(pszTmp, bufferSize, "(\"[%s]\" ==\"%s\")" , pszAttribute, tokens[i]); } else { bufferSize = 8+strlen(tokens[i])+strlen(pszAttribute)+1; pszTmp = (char *)msSmallMalloc(bufferSize); snprintf(pszTmp, bufferSize, "([%s] == %s)" , pszAttribute, tokens[i]); } if (pszExpression != NULL) pszExpression = msStringConcatenate(pszExpression, " OR "); else pszExpression = msStringConcatenate(pszExpression, "("); pszExpression = msStringConcatenate(pszExpression, pszTmp); msFree(pszTmp); } msFreeCharArray(tokens, nTokens); } } /*opening and closing brackets are needed for mapserver expressions*/ if (pszExpression) pszExpression = msStringConcatenate(pszExpression, ")"); } #endif return pszExpression; }
char *FLTGetLogicalComparisonCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp) { char *pszExpression = NULL; char *pszTmp = NULL; char szBuffer[256]; if (!psFilterNode || !FLTIsLogicalFilterType(psFilterNode->pszValue)) return NULL; /* -------------------------------------------------------------------- */ /* OR and AND */ /* -------------------------------------------------------------------- */ if (psFilterNode->psLeftNode && psFilterNode->psRightNode) { pszTmp = FLTGetCommonExpression(psFilterNode->psLeftNode, lp); if (!pszTmp) return NULL; sprintf(szBuffer, "%s", " ("); pszExpression = msStringConcatenate(pszExpression, szBuffer); pszExpression = msStringConcatenate(pszExpression, pszTmp); msFree(pszTmp); sprintf(szBuffer, "%s", " "); pszExpression = msStringConcatenate(pszExpression, szBuffer); pszExpression = msStringConcatenate(pszExpression, psFilterNode->pszValue); sprintf(szBuffer, "%s", " "); pszTmp = FLTGetCommonExpression(psFilterNode->psRightNode, lp); if (!pszTmp) return NULL; pszExpression = msStringConcatenate(pszExpression, pszTmp); msFree(pszTmp); sprintf(szBuffer, "%s", ") "); pszExpression = msStringConcatenate(pszExpression, szBuffer); } /* -------------------------------------------------------------------- */ /* NOT */ /* -------------------------------------------------------------------- */ else if (psFilterNode->psLeftNode && strcasecmp(psFilterNode->pszValue, "NOT") == 0) { pszTmp = FLTGetCommonExpression(psFilterNode->psLeftNode, lp); if (!pszTmp) return NULL; sprintf(szBuffer, "%s", " (NOT "); pszExpression = msStringConcatenate(pszExpression, szBuffer); pszExpression = msStringConcatenate(pszExpression, pszTmp); msFree(pszTmp); sprintf(szBuffer, "%s", ") "); pszExpression = msStringConcatenate(pszExpression, szBuffer); } return pszExpression; }
int msWFSGetCapabilities11(mapObj *map, wfsParamsObj *params, cgiRequestObj *req, owsRequestObj *ows_request) { xmlDocPtr psDoc = NULL; /* document pointer */ xmlNodePtr psRootNode, psMainNode, psNode, psFtNode; const char *updatesequence=NULL; xmlNsPtr psNsOws, psNsXLink, psNsOgc; char *schemalocation = NULL; char *xsi_schemaLocation = NULL; const char *user_namespace_prefix = NULL; const char *user_namespace_uri = NULL; gmlNamespaceListObj *namespaceList=NULL; /* for external application schema support */ char *script_url=NULL, *script_url_encoded=NULL, *formats_list; const char *value = NULL; const char *encoding; xmlChar *buffer = NULL; int size = 0, i; msIOContext *context = NULL; int ows_version = OWS_1_0_0; /* -------------------------------------------------------------------- */ /* Handle updatesequence */ /* -------------------------------------------------------------------- */ updatesequence = msOWSLookupMetadata(&(map->web.metadata), "FO", "updatesequence"); encoding = msOWSLookupMetadata(&(map->web.metadata), "FO", "encoding"); if (params->pszUpdateSequence != NULL) { i = msOWSNegotiateUpdateSequence(params->pszUpdateSequence, updatesequence); if (i == 0) { /* current */ msSetError(MS_WFSERR, "UPDATESEQUENCE parameter (%s) is equal to server (%s)", "msWFSGetCapabilities11()", params->pszUpdateSequence, updatesequence); return msWFSException11(map, "updatesequence", "CurrentUpdateSequence", params->pszVersion); } if (i > 0) { /* invalid */ msSetError(MS_WFSERR, "UPDATESEQUENCE parameter (%s) is higher than server (%s)", "msWFSGetCapabilities11()", params->pszUpdateSequence, updatesequence); return msWFSException11(map, "updatesequence", "InvalidUpdateSequence", params->pszVersion); } } /* -------------------------------------------------------------------- */ /* Create document. */ /* -------------------------------------------------------------------- */ psDoc = xmlNewDoc(BAD_CAST "1.0"); psRootNode = xmlNewNode(NULL, BAD_CAST "WFS_Capabilities"); xmlDocSetRootElement(psDoc, psRootNode); /* -------------------------------------------------------------------- */ /* Name spaces */ /* -------------------------------------------------------------------- */ /*default name space*/ xmlNewProp(psRootNode, BAD_CAST "xmlns", BAD_CAST "http://www.opengis.net/wfs"); xmlSetNs(psRootNode, xmlNewNs(psRootNode, BAD_CAST "http://www.opengis.net/gml", BAD_CAST "gml")); xmlSetNs(psRootNode, xmlNewNs(psRootNode, BAD_CAST "http://www.opengis.net/wfs", BAD_CAST "wfs")); psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); psNsXLink = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_W3C_XLINK_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_W3C_XLINK_NAMESPACE_PREFIX); xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_W3C_XSI_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_W3C_XSI_NAMESPACE_PREFIX); xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OGC_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_OGC_NAMESPACE_PREFIX ); value = msOWSLookupMetadata(&(map->web.metadata), "FO", "namespace_uri"); if(value) user_namespace_uri = value; value = msOWSLookupMetadata(&(map->web.metadata), "FO", "namespace_prefix"); if(value) user_namespace_prefix = value; if(user_namespace_prefix != NULL && msIsXMLTagValid(user_namespace_prefix) == MS_FALSE) msIO_printf("<!-- WARNING: The value '%s' is not valid XML namespace. -->\n", user_namespace_prefix); else xmlNewNs(psRootNode, BAD_CAST user_namespace_uri, BAD_CAST user_namespace_prefix); /* any additional namespaces */ namespaceList = msGMLGetNamespaces(&(map->web), "G"); for(i=0; i<namespaceList->numnamespaces; i++) { if(namespaceList->namespaces[i].uri) { xmlNewNs(psRootNode, BAD_CAST namespaceList->namespaces[i].uri, BAD_CAST namespaceList->namespaces[i].prefix); } } msGMLFreeNamespaces(namespaceList); xmlNewProp(psRootNode, BAD_CAST "version", BAD_CAST params->pszVersion ); updatesequence = msOWSLookupMetadata(&(map->web.metadata), "FO", "updatesequence"); if (updatesequence) xmlNewProp(psRootNode, BAD_CAST "updateSequence", BAD_CAST updatesequence); /*schema*/ schemalocation = msEncodeHTMLEntities( msOWSGetSchemasLocation(map) ); xsi_schemaLocation = msStrdup("http://www.opengis.net/wfs"); xsi_schemaLocation = msStringConcatenate(xsi_schemaLocation, " "); xsi_schemaLocation = msStringConcatenate(xsi_schemaLocation, schemalocation); xsi_schemaLocation = msStringConcatenate(xsi_schemaLocation, "/wfs/1.1.0/wfs.xsd"); xmlNewNsProp(psRootNode, NULL, BAD_CAST "xsi:schemaLocation", BAD_CAST xsi_schemaLocation); /* -------------------------------------------------------------------- */ /* Service metadata. */ /* -------------------------------------------------------------------- */ xmlAddChild(psRootNode, msOWSCommonServiceIdentification(psNsOws, map, "OGC WFS", params->pszVersion, "FO")); /*service provider*/ xmlAddChild(psRootNode, msOWSCommonServiceProvider( psNsOws, psNsXLink, map, "FO")); /*operation metadata */ if ((script_url=msOWSGetOnlineResource(map, "FO", "onlineresource", req)) == NULL || (script_url_encoded = msEncodeHTMLEntities(script_url)) == NULL) { msSetError(MS_WFSERR, "Server URL not found", "msWFSGetCapabilities11()"); return msWFSException11(map, "mapserv", "NoApplicableCode", params->pszVersion); } /* -------------------------------------------------------------------- */ /* Operations metadata. */ /* -------------------------------------------------------------------- */ psMainNode= xmlAddChild(psRootNode,msOWSCommonOperationsMetadata(psNsOws)); /* -------------------------------------------------------------------- */ /* GetCapabilities */ /* -------------------------------------------------------------------- */ psNode = xmlAddChild(psMainNode, msOWSCommonOperationsMetadataOperation(psNsOws,psNsXLink,"GetCapabilities", OWS_METHOD_GETPOST, script_url_encoded)); xmlAddChild(psMainNode, psNode); xmlAddChild(psNode, msOWSCommonOperationsMetadataDomainType( ows_version, psNsOws, "Parameter", "service", "WFS")); /*accept version*/ xmlAddChild(psNode, msOWSCommonOperationsMetadataDomainType(ows_version, psNsOws, "Parameter", "AcceptVersions", "1.0.0,1.1.0")); /*format*/ xmlAddChild(psNode, msOWSCommonOperationsMetadataDomainType(ows_version, psNsOws, "Parameter", "AcceptFormats", "text/xml")); /* -------------------------------------------------------------------- */ /* DescribeFeatureType */ /* -------------------------------------------------------------------- */ if (msOWSRequestIsEnabled(map, NULL, "F", "DescribeFeatureType", MS_TRUE)) { psNode = xmlAddChild(psMainNode, msOWSCommonOperationsMetadataOperation(psNsOws,psNsXLink,"DescribeFeatureType", OWS_METHOD_GETPOST, script_url_encoded)); xmlAddChild(psMainNode, psNode); /*output format*/ xmlAddChild(psNode, msOWSCommonOperationsMetadataDomainType(ows_version, psNsOws, "Parameter", "outputFormat", "XMLSCHEMA,text/xml; subtype=gml/2.1.2,text/xml; subtype=gml/3.1.1")); } /* -------------------------------------------------------------------- */ /* GetFeature */ /* -------------------------------------------------------------------- */ if (msOWSRequestIsEnabled(map, NULL, "F", "GetFeature", MS_TRUE)) { psNode = xmlAddChild(psMainNode, msOWSCommonOperationsMetadataOperation(psNsOws,psNsXLink,"GetFeature", OWS_METHOD_GETPOST, script_url_encoded)); xmlAddChild(psMainNode, psNode); xmlAddChild(psNode, msOWSCommonOperationsMetadataDomainType(ows_version, psNsOws, "Parameter", "resultType", "results,hits")); formats_list = msWFSGetOutputFormatList( map, NULL, "1.1.0" ); xmlAddChild(psNode, msOWSCommonOperationsMetadataDomainType(ows_version, psNsOws, "Parameter", "outputFormat", formats_list)); msFree( formats_list ); value = msOWSLookupMetadata(&(map->web.metadata), "FO", "maxfeatures"); if (value) { xmlAddChild(psMainNode, msOWSCommonOperationsMetadataDomainType(ows_version, psNsOws, "Constraint", "DefaultMaxFeatures", (char *)value)); } } /* -------------------------------------------------------------------- */ /* FeatureTypeList */ /* -------------------------------------------------------------------- */ psFtNode = xmlNewNode(NULL, BAD_CAST "FeatureTypeList"); xmlAddChild(psRootNode, psFtNode); psNode = xmlNewChild(psFtNode, NULL, BAD_CAST "Operations", NULL); xmlNewChild(psNode, NULL, BAD_CAST "Operation", BAD_CAST "Query"); for(i=0; i<map->numlayers; i++) { layerObj *lp; lp = GET_LAYER(map, i); if (!msIntegerInArray(lp->index, ows_request->enabled_layers, ows_request->numlayers)) continue; /* List only vector layers in which DUMP=TRUE */ if (msWFSIsLayerSupported(lp)) xmlAddChild(psFtNode, msWFSDumpLayer11(map, lp, psNsOws)); } /* -------------------------------------------------------------------- */ /* Filter capabilities. */ /* -------------------------------------------------------------------- */ psNsOgc = xmlNewNs(NULL, BAD_CAST MS_OWSCOMMON_OGC_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_OGC_NAMESPACE_PREFIX); xmlAddChild(psRootNode, FLTGetCapabilities(psNsOgc, psNsOgc, MS_FALSE)); /* -------------------------------------------------------------------- */ /* Write out the document. */ /* -------------------------------------------------------------------- */ if( msIO_needBinaryStdout() == MS_FAILURE ) return MS_FAILURE; if (encoding) msIO_setHeader("Content-Type","text/xml; charset=%s", encoding); else msIO_setHeader("Content-Type","text/xml"); msIO_sendHeaders(); context = msIO_getHandler(stdout); xmlDocDumpFormatMemoryEnc(psDoc, &buffer, &size, (encoding ? encoding : "ISO-8859-1"), 1); msIO_contextWrite(context, buffer, size); xmlFree(buffer); /*free buffer and the document */ /*xmlFree(buffer);*/ xmlFreeDoc(psDoc); xmlFreeNs(psNsOgc); free(script_url); free(script_url_encoded); free(xsi_schemaLocation); free(schemalocation); xmlCleanupParser(); return(MS_SUCCESS); }
static xmlNodePtr msWFSDumpLayer11(mapObj *map, layerObj *lp, xmlNsPtr psNsOws) { rectObj ext; xmlNodePtr psRootNode, psNode; const char *value = NULL; const char *encoding = NULL; char *encoded=NULL; char *valueToFree; char **tokens; int n=0,i=0; encoding = msOWSLookupMetadata(&(map->web.metadata), "FO", "encoding"); if (!encoding) encoding = "ISO-8859-1"; psRootNode = xmlNewNode(NULL, BAD_CAST "FeatureType"); /* add namespace to layer name */ value = msOWSLookupMetadata(&(map->web.metadata), "FO", "namespace_prefix"); if(value) { n = strlen(value)+strlen(lp->name)+1+1; valueToFree = (char *) msSmallMalloc(sizeof(char*)*n); snprintf(valueToFree, n, "%s%s%s", (value ? value : ""), (value ? ":" : ""), lp->name); /*if there is an encoding using it on some of the items*/ psNode = msOWSCommonxmlNewChildEncoded(psRootNode, NULL, "Name", valueToFree, encoding); msFree(valueToFree); } else { psNode = msOWSCommonxmlNewChildEncoded(psRootNode, NULL, "Name", lp->name, encoding); } if (lp->name && strlen(lp->name) > 0 && (msIsXMLTagValid(lp->name) == MS_FALSE || isdigit(lp->name[0]))) xmlAddSibling(psNode, xmlNewComment(BAD_CAST "WARNING: The layer name '%s' might contain spaces or " "invalid characters or may start with a number. This could lead to potential problems")); value = msOWSLookupMetadata(&(lp->metadata), "FO", "title"); if (!value) value =(const char*)lp->name; psNode = msOWSCommonxmlNewChildEncoded(psRootNode, NULL, "Title", value, encoding); value = msOWSLookupMetadata(&(lp->metadata), "FO", "abstract"); if (value) psNode = msOWSCommonxmlNewChildEncoded(psRootNode, NULL, "Abstract", value, encoding); value = msOWSLookupMetadata(&(lp->metadata), "FO", "keywordlist"); if (value) { if (encoding) encoded = msGetEncodedString(value, encoding); else encoded = msGetEncodedString(value, "ISO-8859-1"); msLibXml2GenerateList( xmlNewChild(psRootNode, psNsOws, BAD_CAST "Keywords", NULL), NULL, "Keyword", encoded, ',' ); msFree(encoded); } /*support DefaultSRS and OtherSRS*/ valueToFree = msOWSGetProjURN(&(map->projection),&(map->web.metadata),"FO",MS_FALSE); if (!valueToFree) valueToFree = msOWSGetProjURN(&(lp->projection), &(lp->metadata), "FO", MS_FALSE); if (valueToFree) { tokens = msStringSplit(valueToFree, ' ', &n); if (tokens && n > 0) { psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "DefaultSRS", BAD_CAST tokens[0]); for (i=1; i<n; i++) psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "OtherSRS", BAD_CAST tokens[i]); msFreeCharArray(tokens, n); } } else xmlAddSibling(psNode, xmlNewComment(BAD_CAST "WARNING: Mandatory mapfile parameter: (at least one of) MAP.PROJECTION, LAYER.PROJECTION or wfs/ows_srs metadata was missing in this context.")); free(valueToFree); valueToFree = NULL; /*TODO: adevertize only gml3?*/ psNode = xmlNewNode(NULL, BAD_CAST "OutputFormats"); xmlAddChild(psRootNode, psNode); { char *formats_list = msWFSGetOutputFormatList( map, lp, "1.1.0" ); int iformat, n; char **tokens; n = 0; tokens = msStringSplit(formats_list, ',', &n); for( iformat = 0; iformat < n; iformat++ ) xmlNewChild(psNode, NULL, BAD_CAST "Format", BAD_CAST tokens[iformat] ); msFree( formats_list ); msFreeCharArray( tokens, n ); } /*bbox*/ if (msOWSGetLayerExtent(map, lp, "FO", &ext) == MS_SUCCESS) { /*convert to latlong*/ if (lp->projection.numargs > 0) { if (!pj_is_latlong(&lp->projection.proj)) msProjectRect(&lp->projection, NULL, &ext); } else if (map->projection.numargs > 0 && !pj_is_latlong(&map->projection.proj)) msProjectRect(&map->projection, NULL, &ext); xmlAddChild(psRootNode, msOWSCommonWGS84BoundingBox( psNsOws, 2, ext.minx, ext.miny, ext.maxx, ext.maxy)); } else { xmlNewChild(psRootNode, psNsOws, BAD_CAST "WGS84BoundingBox", NULL); xmlAddSibling(psNode, xmlNewComment(BAD_CAST "WARNING: Optional WGS84BoundingBox could not be established for this layer. Consider setting the EXTENT in the LAYER object, or wfs_extent metadata. Also check that your data exists in the DATA statement")); } value = msOWSLookupMetadata(&(lp->metadata), "FO", "metadataurl_href"); if (value) { psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "MetadataURL", BAD_CAST value); value = msOWSLookupMetadata(&(lp->metadata), "FO", "metadataurl_format"); if (!value) value = msStrdup("text/html"); /* default */ xmlNewProp(psNode, BAD_CAST "format", BAD_CAST value); value = msOWSLookupMetadata(&(lp->metadata), "FO", "metadataurl_type"); if (!value) value = msStrdup("FGDC"); /* default */ xmlNewProp(psNode, BAD_CAST "type", BAD_CAST value); } return psRootNode; }
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 msWriteTree(treeObj *tree, const TCHAR *filename, int B_order) { char signature[3] = "SQT"; char version = 1; char reserved[3] = {0,0,0}; SHPTreeHandle disktree; int i; char mtBigEndian; char pabyBuf[32]; TCHAR *pszBasename, *pszFullname; disktree = (SHPTreeHandle) malloc(sizeof(SHPTreeInfo)); /* -------------------------------------------------------------------- */ /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ pszBasename = (TCHAR *) malloc((_tcslen(filename) + 1) * sizeof(TCHAR) * 2); _tcscpy( pszBasename, filename ); for( i = _tcslen(pszBasename)-1; i > 0 && pszBasename[i] != _T('.') && pszBasename[i] != _T('/') && pszBasename[i] != _T('\\'); i-- ) {} if( pszBasename[i] == _T('.') ) pszBasename[i] = _T('\0'); /* -------------------------------------------------------------------- */ /* Open the .shp and .shx files. Note that files pulled from */ /* a PC to Unix with upper case filenames won't work! */ /* -------------------------------------------------------------------- */ pszFullname = (TCHAR *) malloc((_tcslen(pszBasename) + _tcslen(_T(MS_INDEX_EXTENSION)) + 1) * sizeof(TCHAR) * 2); _stprintf( pszFullname, _T("%s%s"), pszBasename, _T(MS_INDEX_EXTENSION)); disktree->fp = _tfopen(pszFullname, _T("wb")); msFree(pszBasename); // not needed msFree(pszFullname); if(!disktree->fp) { msFree(disktree); #if MAPSHAPEERROR msSetError(MS_IOERR, NULL, "msWriteTree()"); #endif return(MS_FALSE); } // for efficiency, trim the tree msTreeTrim(tree); /* -------------------------------------------------------------------- */ /* Establish the byte order on this machine. */ /* -------------------------------------------------------------------- */ i = 1; if( *((uchar *) &i) == 1 ) mtBigEndian = MS_FALSE; else mtBigEndian = MS_TRUE; if( !(mtBigEndian ^ ( B_order == MS_LSB_ORDER || B_order == MS_NEW_LSB_ORDER )) ) disktree->needswap = 1; else disktree->needswap = 0; if( B_order == MS_NATIVE_ORDER ) disktree->needswap = 0; // write the header if ( B_order > 0 ) { memcpy( pabyBuf, &signature, 3 ); memcpy (&disktree->signature, &signature, 3); pabyBuf[3] = B_order; memcpy( pabyBuf+4, &version, 1); memcpy( pabyBuf+5, &reserved, 3); memcpy( &disktree->version, &version, 1); memcpy( &disktree->flags, &reserved, 3); fwrite( pabyBuf, 8, 1, disktree->fp ); } memcpy( pabyBuf, &tree->numshapes, 4 ); if( disktree->needswap ) SwapWord( 4, pabyBuf ); memcpy( pabyBuf+4, &tree->maxdepth, 4 ); if( disktree->needswap ) SwapWord( 4, pabyBuf+4 ); i = fwrite( pabyBuf, 8, 1, disktree->fp ); if( !i ) { fprintf (stderr, "unable to write to index file ... exiting \n"); return (MS_FALSE); } writeTreeNode(disktree, tree->root); msSHPDiskTreeClose( disktree ); return(MS_TRUE); }
xmlNodePtr KmlRenderer::createDescriptionNode(shapeObj *shape) { /* <description> <![CDATA[ special characters here ]]> <description> */ /*description nodes for vector layers: - if kml_description is set, use it - if not, dump the attributes */ if (pszLayerDescMetadata) { char *pszTmp=NULL; char *pszTmpDesc = NULL; size_t bufferSize = 0; pszTmpDesc = msStrdup(pszLayerDescMetadata); for (int i=0; i<currentLayer->numitems; i++) { bufferSize = strlen(currentLayer->items[i]) + 3; pszTmp = (char *)msSmallMalloc(bufferSize); snprintf(pszTmp, bufferSize, "%%%s%%",currentLayer->items[i]); if (strcasestr(pszTmpDesc, pszTmp)) pszTmpDesc = msCaseReplaceSubstring(pszTmpDesc, pszTmp, shape->values[i]); msFree(pszTmp); } xmlNodePtr descriptionNode = xmlNewNode(NULL, BAD_CAST "description"); xmlNodeAddContent(descriptionNode, BAD_CAST pszTmpDesc); msFree(pszTmpDesc); return descriptionNode; } else if ((papszLayerIncludeItems && nIncludeItems > 0) || (papszLayerExcludeItems && nExcludeItems > 0)) { /* -------------------------------------------------------------------- */ /* preffered way is to use the ExtendedData tag (#3728) */ /* http://code.google.com/apis/kml/documentation/extendeddata.html */ /* -------------------------------------------------------------------- */ xmlNodePtr extendedDataNode = xmlNewNode(NULL, BAD_CAST "ExtendedData"); xmlNodePtr dataNode = NULL; const char*pszAlias=NULL; int bIncludeAll = MS_FALSE; if(papszLayerIncludeItems && nIncludeItems == 1 && strcasecmp(papszLayerIncludeItems[0], "all") == 0) bIncludeAll = MS_TRUE; for (int i=0; i<currentLayer->numitems; i++) { int j=0,k=0; /*TODO optimize to calculate this only once per layer*/ for (j=0; j<nIncludeItems;j++) { if (strcasecmp(currentLayer->items[i], papszLayerIncludeItems[j]) == 0) break; } if (j<nIncludeItems || bIncludeAll) { if (papszLayerExcludeItems && nExcludeItems > 0) { for (k=0; k<nExcludeItems;k++) { if (strcasecmp(currentLayer->items[i], papszLayerExcludeItems[k]) == 0) break; } } if (nExcludeItems == 0 || k == nExcludeItems) { dataNode = xmlNewNode(NULL, BAD_CAST "Data"); xmlNewProp(dataNode, BAD_CAST "name", BAD_CAST currentLayer->items[i]); pszAlias = getAliasName(currentLayer, currentLayer->items[i], "GO"); if (pszAlias) xmlNewChild(dataNode, NULL, BAD_CAST "displayName", BAD_CAST pszAlias); else xmlNewChild(dataNode, NULL, BAD_CAST "displayName", BAD_CAST currentLayer->items[i]); if (shape->values[i] && strlen(shape->values[i])) xmlNewChild(dataNode, NULL, BAD_CAST "value", BAD_CAST shape->values[i]); else xmlNewChild(dataNode, NULL, BAD_CAST "value", NULL); xmlAddChild(extendedDataNode, dataNode); } } } return extendedDataNode; } return NULL; }
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; }
char* KmlRenderer::lookupPlacemarkStyle() { char lineHexColor[32]; char polygonHexColor[32]; char labelHexColor[32]; char *styleName=NULL; styleName = msStringConcatenate(styleName, "style"); if (SymbologyFlag[Line]) { /* <LineStyle id="ID"> <!-- inherited from ColorStyle --> <color>ffffffff</color> <!-- kml:color --> <colorMode>normal</colorMode> <!-- colorModeEnum: normal or random --> <!-- specific to LineStyle --> <width>1</width> <!-- float --> </LineStyle> */ for (int i=0; i<numLineStyle; i++) { if (currentLayer && currentLayer->opacity > 0 && currentLayer->opacity < 100 && LineStyle[i].color->alpha == 255) LineStyle[i].color->alpha = MS_NINT(currentLayer->opacity*2.55); sprintf(lineHexColor,"%02x%02x%02x%02x", LineStyle[i].color->alpha, LineStyle[0].color->blue, LineStyle[i].color->green, LineStyle[i].color->red); char lineStyleName[32]; sprintf(lineStyleName, "_line_%s_w%.1f", lineHexColor, LineStyle[i].width); styleName = msStringConcatenate(styleName, lineStyleName); } } if (SymbologyFlag[Polygon]) { /* <PolyStyle id="ID"> <!-- inherited from ColorStyle --> <color>ffffffff</color> <!-- kml:color --> <colorMode>normal</colorMode> <!-- kml:colorModeEnum: normal or random --> <!-- specific to PolyStyle --> <fill>1</fill> <!-- boolean --> <outline>1</outline> <!-- boolean --> </PolyStyle> */ if (currentLayer && currentLayer->opacity > 0 && currentLayer->opacity < 100 && PolygonColor.alpha == 255) PolygonColor.alpha = MS_NINT(currentLayer->opacity*2.55); sprintf(polygonHexColor,"%02x%02x%02x%02x", PolygonColor.alpha, PolygonColor.blue, PolygonColor.green, PolygonColor.red); char polygonStyleName[64]; sprintf(polygonStyleName, "_polygon_%s", polygonHexColor); styleName = msStringConcatenate(styleName, polygonStyleName); } if (SymbologyFlag[Label]) { /* <LabelStyle id="ID"> <!-- inherited from ColorStyle --> <color>ffffffff</color> <!-- kml:color --> <colorMode>normal</colorMode> <!-- kml:colorModeEnum: normal or random --> <!-- specific to LabelStyle --> <scale>1</scale> <!-- float --> </LabelStyle> */ if (currentLayer && currentLayer->opacity > 0 && currentLayer->opacity < 100 && LabelStyle.color->alpha == 255) LabelStyle.color->alpha = MS_NINT(currentLayer->opacity*2.55); sprintf(labelHexColor,"%02x%02x%02x%02x", LabelStyle.color->alpha, LabelStyle.color->blue, LabelStyle.color->green, LabelStyle.color->red); // __TODO__ add label scale char labelStyleName[64]; sprintf(labelStyleName, "_label_%s", labelHexColor); styleName = msStringConcatenate(styleName, labelStyleName); } if (SymbologyFlag[Symbol]) { /* <Style id="randomColorIcon"> <IconStyle> <color>ff00ff00</color> <colorMode>random</colorMode> <scale>1.1</scale> <Icon> <href>http://maps.google.com/mapfiles/kml/pal3/icon21.png</href> </Icon> </IconStyle> </Style> */ /* __TODO__ add label scale */ styleName = msStringConcatenate(styleName, "_"); styleName = msStringConcatenate(styleName, SymbolName); } char *styleUrl = msLookupHashTable(StyleHashTable, styleName); if (!styleUrl) { char *styleValue=NULL; styleValue = msStringConcatenate(styleValue, "#"); styleValue = msStringConcatenate(styleValue, styleName); hashObj *hash = msInsertHashTable(StyleHashTable, styleName, styleValue); styleUrl = hash->data; msFree(styleValue); /* Insert new Style node into Document node*/ xmlNodePtr styleNode = xmlNewChild(DocNode, NULL, BAD_CAST "Style", NULL); xmlNewProp(styleNode, BAD_CAST "id", BAD_CAST styleName); if (SymbologyFlag[Polygon]) { xmlNodePtr polyStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "PolyStyle", NULL); xmlNewChild(polyStyleNode, NULL, BAD_CAST "color", BAD_CAST polygonHexColor); } if (SymbologyFlag[Line]) { for (int i=0; i<numLineStyle; i++) { xmlNodePtr lineStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "LineStyle", NULL); sprintf(lineHexColor,"%02x%02x%02x%02x", LineStyle[i].color->alpha, LineStyle[i].color->blue, LineStyle[i].color->green, LineStyle[i].color->red); xmlNewChild(lineStyleNode, NULL, BAD_CAST "color", BAD_CAST lineHexColor); char width[16]; sprintf(width, "%.1f", LineStyle[i].width); xmlNewChild(lineStyleNode, NULL, BAD_CAST "width", BAD_CAST width); } } if (SymbologyFlag[Symbol]) { xmlNodePtr iconStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "IconStyle", NULL); xmlNodePtr iconNode = xmlNewChild(iconStyleNode, NULL, BAD_CAST "Icon", NULL); xmlNewChild(iconNode, NULL, BAD_CAST "href", BAD_CAST SymbolUrl); /*char scale[16]; sprintf(scale, "%.1f", style->scale); xmlNewChild(iconStyleNode, NULL, BAD_CAST "scale", BAD_CAST scale);*/ } else { const char *value=msLookupHashTable(¤tLayer->metadata, "kml_default_symbol_href"); if (value && strlen(value) > 0) { xmlNodePtr iconStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "IconStyle", NULL); xmlNodePtr iconNode = xmlNewChild(iconStyleNode, NULL, BAD_CAST "Icon", NULL); xmlNewChild(iconNode, NULL, BAD_CAST "href", BAD_CAST value); } } if (SymbologyFlag[Label]) { xmlNodePtr labelStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "LabelStyle", NULL); xmlNewChild(labelStyleNode, NULL, BAD_CAST "color", BAD_CAST labelHexColor); /*char scale[16]; sprintf(scale, "%.1f", style->scale); xmlNewChild(iconStyleNode, NULL, BAD_CAST "scale", BAD_CAST scale);*/ } } if (styleName) msFree(styleName); return styleUrl; }
/********************************************************************** * msBuildWFSLayerGetURL() * * Build a WFS GetFeature URL for a Get Request. * * Returns a reference to a newly allocated string that should be freed * by the caller. **********************************************************************/ static char *msBuildWFSLayerGetURL(mapObj *map, layerObj *lp, rectObj *bbox, wfsParamsObj *psParams) { char *pszURL = NULL, *pszOnlineResource=NULL; const char *pszTmp; char *pszVersion, *pszService, *pszTypename = NULL; int bVersionInConnection = 0, bServiceInConnection = 0; int bTypenameInConnection = 0; size_t bufferSize = 0; if (lp->connectiontype != MS_WFS || lp->connection == NULL) { msSetError(MS_WFSCONNERR, "Call supported only for CONNECTIONTYPE WFS", "msBuildWFSLayerGetURL()"); return NULL; } /* -------------------------------------------------------------------- */ /* Find out request version. Look first for the wfs_version */ /* metedata. If not available try to find out if the CONNECTION */ /* string contains the version. This last test is done for */ /* backward compatiblity but is depericated. */ /* -------------------------------------------------------------------- */ pszVersion = psParams->pszVersion; if (!pszVersion) { if ((pszTmp = strstr(lp->connection, "VERSION=")) == NULL && (pszTmp = strstr(lp->connection, "version=")) == NULL ) { msSetError(MS_WFSCONNERR, "Metadata wfs_version must be set in the layer", "msBuildWFSLayerGetURL()"); return NULL; } pszVersion = strchr(pszTmp, '=')+1; bVersionInConnection = 1; } if (strncmp(pszVersion, "0.0.14", 6) != 0 && strncmp(pszVersion, "1.0.0", 5) != 0 && strncmp(pszVersion, "1.1", 3) != 0) { msSetError(MS_WFSCONNERR, "MapServer supports only WFS 1.0.0 or 0.0.14 (please verify the version metadata wfs_version).", "msBuildWFSLayerGetURL()"); return NULL; } /* -------------------------------------------------------------------- */ /* Find out the service. It is always set to WFS in function */ /* msBuildRequestParms (check Bug 1302 for details). */ /* -------------------------------------------------------------------- */ pszService = psParams->pszService; /* -------------------------------------------------------------------- */ /* Find out the typename. Look first for the wfs_tyename */ /* metadata. If not available try to find out if the CONNECTION */ /* string contains it. This last test is done for */ /* backward compatiblity but is depericated. */ /* -------------------------------------------------------------------- */ pszTypename = psParams->pszTypeName; if (!pszTypename) { if ((pszTmp = strstr(lp->connection, "TYPENAME=")) == NULL && (pszTmp = strstr(lp->connection, "typename=")) == NULL ) { msSetError(MS_WFSCONNERR, "Metadata wfs_typename must be set in the layer", "msBuildWFSLayerGetURL()"); return NULL; } bTypenameInConnection = 1; } /* -------------------------------------------------------------------- * Build the request URL. * At this point we set only the following parameters for GetFeature: * REQUEST * BBOX * VERSION * SERVICE * TYPENAME * FILTER * MAXFEATURES * * For backward compatiblity the user could also have in the connection * string the following parameters (but it is depricated): * VERSION * SERVICE * TYPENAME * -------------------------------------------------------------------- */ /* Make sure we have a big enough buffer for the URL */ bufferSize = strlen(lp->connection)+1024; pszURL = (char *)malloc(bufferSize); MS_CHECK_ALLOC(pszURL, bufferSize, NULL); /* __TODO__ We have to urlencode each value... especially the BBOX values */ /* because if they end up in exponent format (123e+06) the + will be seen */ /* as a space by the remote server. */ /* -------------------------------------------------------------------- */ /* build the URL, */ /* -------------------------------------------------------------------- */ /* make sure connection ends with "&" or "?" */ pszOnlineResource = msOWSTerminateOnlineResource(lp->connection); snprintf(pszURL, bufferSize, "%s", pszOnlineResource); msFree(pszOnlineResource); /* REQUEST */ snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&REQUEST=GetFeature"); /* VERSION */ if (!bVersionInConnection) snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&VERSION=%s", pszVersion); /* SERVICE */ if (!bServiceInConnection) snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&SERVICE=%s", pszService); /* TYPENAME */ if (!bTypenameInConnection) snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&TYPENAME=%s", pszTypename); /* -------------------------------------------------------------------- */ /* If the filter parameter is given in the wfs_filter metadata, */ /* we use it and do not send the BBOX paramter as they are */ /* mutually exclusive. */ /* -------------------------------------------------------------------- */ if (psParams->pszFilter) { snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&FILTER=%s", msEncodeUrl(psParams->pszFilter)); } else snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&BBOX=%.15g,%.15g,%.15g,%.15g", bbox->minx, bbox->miny, bbox->maxx, bbox->maxy); if (psParams->nMaxFeatures > 0) snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&MAXFEATURES=%d", psParams->nMaxFeatures); return pszURL; }