static void msTileResetMetatileLevel(mapObj *map) { hashTableObj *meta = &(map->web.metadata); const char *zero = "0"; const char *value = NULL; /* Is the tile_metatile_levetl set... */ if((value = msLookupHashTable(meta, "tile_metatile_level")) != NULL) { msRemoveHashTable(meta, "tile_metatile_level"); msInsertHashTable(meta, "tile_metatile_level", zero); } /* No tile_metatile_level value. */ else { msInsertHashTable(meta, "tile_metatile_level", zero); } }
int msSetConfigOption( mapObj *map, const char *key, const char *value) { /* We have special "early" handling of this so that it will be */ /* in effect when the projection blocks are parsed and pj_init is called. */ if( strcasecmp(key,"PROJ_LIB") == 0 ) { /* value may be relative to map path */ msSetPROJ_LIB( value, map->mappath ); } /* Same for MS_ERRORFILE, we want it to kick in as early as possible * to catch parsing errors. * Value can be relative to mapfile, unless it's already absolute */ if( strcasecmp(key,"MS_ERRORFILE") == 0 ) { if (msSetErrorFile( value, map->mappath ) != MS_SUCCESS) return MS_FAILURE; } if( msLookupHashTable( &(map->configoptions), key ) != NULL ) msRemoveHashTable( &(map->configoptions), key ); msInsertHashTable( &(map->configoptions), key, value ); return MS_SUCCESS; }
Handle<Value> MSHashTable::NamedSetter (Local<String> property, Local<Value> value, const AccessorInfo& info) { MSHashTable *table = ObjectWrap::Unwrap<MSHashTable>(info.Holder()); v8::String::AsciiValue key(property); v8::String::AsciiValue val(value); msInsertHashTable(table->this_, *key, *val); RETURN_STRING(*val); }
char* KmlRenderer::lookupSymbolUrl(imageObj *img, symbolObj *symbol, symbolStyleObj *symstyle) { char symbolHexColor[32]; /* <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> */ sprintf(symbolHexColor,"%02x%02x%02x%02x", symstyle->style->color.alpha, symstyle->style->color.blue, symstyle->style->color.green, symstyle->style->color.red); snprintf(SymbolName, sizeof(SymbolName), "symbol_%s_%.1f_%s", symbol->name, symstyle->scale, symbolHexColor); char *symbolUrl = msLookupHashTable(StyleHashTable, SymbolName); if (!symbolUrl) { char iconFileName[MS_MAXPATHLEN]; char iconUrl[MS_MAXPATHLEN]; if (img->imagepath) { char *tmpFileName = msTmpFile(NULL, MapPath, img->imagepath, "png"); snprintf(iconFileName, sizeof(iconFileName), "%s", tmpFileName); msFree(tmpFileName); } else { sprintf(iconFileName, "symbol_%s_%.1f.%s", symbol->name, symstyle->scale, "png"); } if (createIconImage(iconFileName, symbol, symstyle) != MS_SUCCESS) { char errMsg[512]; sprintf(errMsg, "Error creating icon file '%s'", iconFileName); msSetError(MS_IOERR, errMsg, "KmlRenderer::lookupSymbolStyle()" ); return NULL; } if (img->imageurl) sprintf(iconUrl, "%s%s.%s", img->imageurl, msGetBasename(iconFileName), "png"); else snprintf(iconUrl, sizeof(iconUrl), "%s", iconFileName); hashObj *hash = msInsertHashTable(StyleHashTable, SymbolName, iconUrl); symbolUrl = hash->data; } return symbolUrl; }
int msCopyHashTable(hashTableObj *dst, hashTableObj *src) { const char *key=NULL; while (1) { key = msNextKeyFromHashTable(src, key); if (!key) break; else msInsertHashTable(dst, key, msLookupHashTable(src, key)); } return MS_SUCCESS; }
int mapObj_setMetaData(mapObj *self, char *name, char *value) { if (msInsertHashTable(&(self->web.metadata), name, value) == NULL) return MS_FAILURE; return MS_SUCCESS; }
int msLoadFontSet(fontSetObj *fontset, mapObj *map) { FILE *stream; char buffer[MS_BUFFER_LENGTH]; char alias[64], file1[MS_PATH_LENGTH], file2[MS_PATH_LENGTH]; char *path; char szPath[MS_MAXPATHLEN]; int i; int bFullPath = 0; if(fontset->numfonts != 0) /* already initialized */ return(0); if(!fontset->filename) return(0); fontset->map = (mapObj *)map; path = msGetPath(fontset->filename); /* fontset->fonts = msCreateHashTable(); // create font hash */ /* if(!fontset->fonts) { */ /* msSetError(MS_HASHERR, "Error initializing font hash.", "msLoadFontSet()"); */ /* return(-1); */ /* } */ stream = fopen( msBuildPath(szPath, fontset->map->mappath, fontset->filename), "r"); if(!stream) { msSetError(MS_IOERR, "Error opening fontset %s.", "msLoadFontset()", fontset->filename); return(-1); } i = 0; while(fgets(buffer, MS_BUFFER_LENGTH, stream)) { /* while there's something to load */ if(buffer[0] == '#' || buffer[0] == '\n' || buffer[0] == '\r' || buffer[0] == ' ') continue; /* skip comments and blank lines */ sscanf(buffer,"%s %s", alias, file1); if (!(*file1) || !(*alias) || (strlen(file1) <= 0)) continue; bFullPath = 0; #if defined(_WIN32) && !defined(__CYGWIN__) if (file1[0] == '\\' || (strlen(file1) > 1 && (file1[1] == ':'))) bFullPath = 1; #else if(file1[0] == '/') bFullPath = 1; #endif if(bFullPath) { /* already full path */ msInsertHashTable(&(fontset->fonts), alias, file1); } else { snprintf(file2, sizeof(file2), "%s%s", path, file1); /* msInsertHashTable(fontset->fonts, alias, file2); */ /* ** msBuildPath is use here, but if we have to save the fontset file ** the msBuildPath must be done everywhere the fonts are used and ** removed here. */ msInsertHashTable(&(fontset->fonts), alias, msBuildPath(szPath, fontset->map->mappath, file2)); } i++; } fontset->numfonts = i; fclose(stream); /* close the file */ free(path); return(0); }
int updateMap(mapservObj *mapserv, mapObj *map) { int i, j; if(!msLookupHashTable(&(map->web.validation), "immutable")) { /* check for any %variable% substitutions here, also do any map_ changes, we do this here so WMS/WFS */ /* services can take advantage of these "vendor specific" extensions */ for(i=0; i<mapserv->request->NumParams; i++) { /* ** a few CGI variables should be skipped altogether ** ** qstring: there is separate per layer validation for attribute queries and the substitution checks ** below conflict with that so we avoid it here */ if(strncasecmp(mapserv->request->ParamNames[i],"qstring",7) == 0) continue; /* check to see if there are any additions to the mapfile */ if(strncasecmp(mapserv->request->ParamNames[i],"map_",4) == 0 || strncasecmp(mapserv->request->ParamNames[i],"map.",4) == 0) { msAcquireLock( TLOCK_PARSER ); if(msUpdateMapFromURL(map, mapserv->request->ParamNames[i], mapserv->request->ParamValues[i]) != MS_SUCCESS) { msReleaseLock( TLOCK_PARSER ); return MS_FAILURE; } msReleaseLock( TLOCK_PARSER ); continue; } if(strncasecmp(mapserv->request->ParamNames[i],"classgroup",10) == 0) { /* #4207 */ for(j=0; j<map->numlayers; j++) { setClassGroup(GET_LAYER(map, j), mapserv->request->ParamValues[i]); } continue; } } msApplySubstitutions(map, mapserv->request->ParamNames, mapserv->request->ParamValues, mapserv->request->NumParams); msApplyDefaultSubstitutions(map); /* check to see if a ogc map context is passed as argument. if there */ /* is one load it */ for(i=0; i<mapserv->request->NumParams; i++) { if(strcasecmp(mapserv->request->ParamNames[i],"context") == 0) { if(mapserv->request->ParamValues[i] && strlen(mapserv->request->ParamValues[i]) > 0) { if(strncasecmp(mapserv->request->ParamValues[i],"http",4) == 0) { if(msGetConfigOption(map, "CGI_CONTEXT_URL")) msLoadMapContextURL(map, mapserv->request->ParamValues[i], MS_FALSE); } else msLoadMapContext(map, mapserv->request->ParamValues[i], MS_FALSE); } } } } /* * RFC-42 HTTP Cookie Forwarding * Here we set the http_cookie_data metadata to handle the * HTTP Cookie Forwarding. The content of this metadata is the cookie * content. In the future, this metadata will probably be replaced * by an object that is part of the mapObject that would contain * information on the application status (such as cookie). */ if( mapserv->request->httpcookiedata != NULL ) { msInsertHashTable( &(map->web.metadata), "http_cookie_data", mapserv->request->httpcookiedata ); } return MS_SUCCESS; }
static int msContourLayerReadRaster(layerObj *layer, rectObj rect) { mapObj *map = layer->map; char **bands; char pointer[64], memDSPointer[128]; int band = 1; double adfGeoTransform[6], adfInvGeoTransform[6]; double llx, lly, urx, ury; rectObj copyRect, mapRect; int dst_xsize, dst_ysize; int virtual_grid_step_x, virtual_grid_step_y; int src_xoff, src_yoff, src_xsize, src_ysize; double map_cellsize_x, map_cellsize_y, dst_cellsize_x, dst_cellsize_y; GDALRasterBandH hBand = NULL; CPLErr eErr; contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; if (layer->debug) msDebug("Entering msContourLayerReadRaster().\n"); if (clinfo == NULL || clinfo->hOrigDS == NULL) { msSetError(MS_MISCERR, "Assertion failed: Contour layer not opened!!!", "msContourLayerReadRaster()"); return MS_FAILURE; } bands = CSLTokenizeStringComplex( CSLFetchNameValue(layer->processing,"BANDS"), " ,", FALSE, FALSE ); if (CSLCount(bands) > 0) { band = atoi(bands[0]); if (band < 1 || band > GDALGetRasterCount(clinfo->hOrigDS)) { msSetError( MS_IMGERR, "BANDS PROCESSING directive includes illegal band '%d', should be from 1 to %d.", "msContourLayerReadRaster()", band, GDALGetRasterCount(clinfo->hOrigDS)); CSLDestroy(bands); return MS_FAILURE; } } CSLDestroy(bands); hBand = GDALGetRasterBand(clinfo->hOrigDS, band); if (hBand == NULL) { msSetError(MS_IMGERR, "Band %d does not exist on dataset.", "msContourLayerReadRaster()", band); return MS_FAILURE; } if (layer->projection.numargs > 0 && EQUAL(layer->projection.args[0], "auto")) { const char *wkt; wkt = GDALGetProjectionRef(clinfo->hOrigDS); if (wkt != NULL && strlen(wkt) > 0) { if (msOGCWKT2ProjectionObj(wkt, &(layer->projection), layer->debug) != MS_SUCCESS) { char msg[MESSAGELENGTH*2]; errorObj *ms_error = msGetErrorObj(); snprintf( msg, sizeof(msg), "%s\n" "PROJECTION AUTO cannot be used for this " "GDAL raster (`%s').", ms_error->message, layer->data); msg[MESSAGELENGTH-1] = '\0'; msSetError(MS_OGRERR, "%s","msDrawRasterLayer()", msg); return MS_FAILURE; } } } /* * Compute the georeferenced window of overlap, and read the source data * downsampled to match output resolution, or at full resolution if * output resolution is lower than the source resolution. * * A large portion of this overlap calculation code was borrowed from * msDrawRasterLayerGDAL(). * Would be possible to move some of this to a reusable function? * * Note: This code works only if no reprojection is involved. It would * need rework to support cases where output projection differs from source * data file projection. */ src_xsize = GDALGetRasterXSize(clinfo->hOrigDS); src_ysize = GDALGetRasterYSize(clinfo->hOrigDS); /* set the Dataset extent */ msGetGDALGeoTransform(clinfo->hOrigDS, map, layer, adfGeoTransform); clinfo->extent.minx = adfGeoTransform[0]; clinfo->extent.maxy = adfGeoTransform[3]; clinfo->extent.maxx = adfGeoTransform[0] + src_xsize * adfGeoTransform[1]; clinfo->extent.miny = adfGeoTransform[3] + src_ysize * adfGeoTransform[5]; if (layer->transform) { if (layer->debug) msDebug("msContourLayerReadRaster(): Entering transform.\n"); InvGeoTransform(adfGeoTransform, adfInvGeoTransform); mapRect = rect; map_cellsize_x = map_cellsize_y = map->cellsize; #ifdef USE_PROJ /* if necessary, project the searchrect to source coords */ if (msProjectionsDiffer( &(map->projection), &(layer->projection))) { if ( msProjectRect(&map->projection, &layer->projection, &mapRect) != MS_SUCCESS ) { msDebug("msContourLayerReadRaster(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name); return MS_FAILURE; } map_cellsize_x = MS_CELLSIZE(mapRect.minx, mapRect.maxx, map->width); map_cellsize_y = MS_CELLSIZE(mapRect.miny, mapRect.maxy, map->height); /* if the projection failed to project the extent requested, we need to calculate the cellsize to preserve the initial map cellsize ratio */ if ( (mapRect.minx < GEO_TRANS(adfGeoTransform,0,src_ysize)) || (mapRect.maxx > GEO_TRANS(adfGeoTransform,src_xsize,0)) || (mapRect.miny < GEO_TRANS(adfGeoTransform+3,0,src_ysize)) || (mapRect.maxy > GEO_TRANS(adfGeoTransform+3,src_xsize,0)) ) { int src_unit, dst_unit; src_unit = GetMapserverUnitUsingProj(&map->projection); dst_unit = GetMapserverUnitUsingProj(&layer->projection); if (src_unit == -1 || dst_unit == -1) { msDebug("msContourLayerReadRaster(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name); return MS_FAILURE; } map_cellsize_x = MS_CONVERT_UNIT(src_unit, dst_unit, MS_CELLSIZE(rect.minx, rect.maxx, map->width)); map_cellsize_y = MS_CONVERT_UNIT(src_unit, dst_unit, MS_CELLSIZE(rect.miny, rect.maxy, map->height)); } } #endif if (map_cellsize_x == 0 || map_cellsize_y == 0) { if (layer->debug) msDebug("msContourLayerReadRaster(): Cellsize can't be 0.\n"); return MS_FAILURE; } /* Adjust MapServer pixel model to GDAL pixel model */ mapRect.minx -= map_cellsize_x*0.5; mapRect.maxx += map_cellsize_x*0.5; mapRect.miny -= map_cellsize_y*0.5; mapRect.maxy += map_cellsize_y*0.5; /* * If raw data cellsize (from geotransform) is larger than output map_cellsize * then we want to extract only enough data to match the output map resolution * which means that GDAL will automatically sample the data on read. * * To prevent bad contour effects on tile edges, we adjust the target cellsize * to align the extracted window with a virtual grid based on the origin of the * raw data and a virtual grid step size corresponding to an integer sampling step. * * If source data has a greater cellsize (i.e. lower res) that requested ouptut map * then we use the raw data cellsize as target cellsize since there is no point in * interpolating the data for contours in this case. */ virtual_grid_step_x = (int)floor(map_cellsize_x / ABS(adfGeoTransform[1])); if (virtual_grid_step_x < 1) virtual_grid_step_x = 1; /* Do not interpolate data if grid sampling step < 1 */ virtual_grid_step_y = (int)floor(map_cellsize_y / ABS(adfGeoTransform[5])); if (virtual_grid_step_y < 1) virtual_grid_step_y = 1; /* Do not interpolate data if grid sampling step < 1 */ /* target cellsize is a multiple of raw data cellsize based on grid step*/ dst_cellsize_x = ABS(adfGeoTransform[1]) * virtual_grid_step_x; dst_cellsize_y = ABS(adfGeoTransform[5]) * virtual_grid_step_y; /* Compute overlap between source and target views */ copyRect = mapRect; if (copyRect.minx < GEO_TRANS(adfGeoTransform,0,src_ysize)) copyRect.minx = GEO_TRANS(adfGeoTransform,0,src_ysize); if (copyRect.maxx > GEO_TRANS(adfGeoTransform,src_xsize,0)) copyRect.maxx = GEO_TRANS(adfGeoTransform,src_xsize,0); if (copyRect.miny < GEO_TRANS(adfGeoTransform+3,0,src_ysize)) copyRect.miny = GEO_TRANS(adfGeoTransform+3,0,src_ysize); if (copyRect.maxy > GEO_TRANS(adfGeoTransform+3,src_xsize,0)) copyRect.maxy = GEO_TRANS(adfGeoTransform+3,src_xsize,0); if (copyRect.minx >= copyRect.maxx || copyRect.miny >= copyRect.maxy) { if (layer->debug) msDebug("msContourLayerReadRaster(): No overlap.\n"); return MS_SUCCESS; } /* * Convert extraction window to raster coordinates */ llx = GEO_TRANS(adfInvGeoTransform+0,copyRect.minx,copyRect.miny); lly = GEO_TRANS(adfInvGeoTransform+3,copyRect.minx,copyRect.miny); urx = GEO_TRANS(adfInvGeoTransform+0,copyRect.maxx,copyRect.maxy); ury = GEO_TRANS(adfInvGeoTransform+3,copyRect.maxx,copyRect.maxy); /* * Align extraction window with virtual grid * (keep in mind raster coordinates origin is at upper-left) * We also add an extra buffer to fix tile boundarie issues when zoomed */ llx = floor(llx / virtual_grid_step_x) * virtual_grid_step_x - (virtual_grid_step_x*5); urx = ceil(urx / virtual_grid_step_x) * virtual_grid_step_x + (virtual_grid_step_x*5); ury = floor(ury / virtual_grid_step_y) * virtual_grid_step_y - (virtual_grid_step_x*5); lly = ceil(lly / virtual_grid_step_y) * virtual_grid_step_y + (virtual_grid_step_x*5); src_xoff = MAX(0,(int) floor(llx+0.5)); src_yoff = MAX(0,(int) floor(ury+0.5)); src_xsize = MIN(MAX(0,(int) (urx - llx + 0.5)), GDALGetRasterXSize(clinfo->hOrigDS) - src_xoff); src_ysize = MIN(MAX(0,(int) (lly - ury + 0.5)), GDALGetRasterYSize(clinfo->hOrigDS) - src_yoff); /* Update the geographic extent (buffer added) */ /* TODO: a better way to go the geo_trans */ copyRect.minx = GEO_TRANS(adfGeoTransform+0,src_xoff,0); copyRect.maxx = GEO_TRANS(adfGeoTransform+0,src_xoff+src_xsize,0); copyRect.miny = GEO_TRANS(adfGeoTransform+3,0,src_yoff+src_ysize); copyRect.maxy = GEO_TRANS(adfGeoTransform+3,0,src_yoff); /* * If input window is to small then stop here */ if (src_xsize < 2 || src_ysize < 2) { if (layer->debug) msDebug("msContourLayerReadRaster(): input window too small, or no apparent overlap between map view and this window(1).\n"); return MS_SUCCESS; } /* Target buffer size */ dst_xsize = (int)ceil((copyRect.maxx - copyRect.minx) / dst_cellsize_x); dst_ysize = (int)ceil((copyRect.maxy - copyRect.miny) / dst_cellsize_y); if (dst_xsize == 0 || dst_ysize == 0) { if (layer->debug) msDebug("msContourLayerReadRaster(): no apparent overlap between map view and this window(2).\n"); return MS_SUCCESS; } if (layer->debug) msDebug( "msContourLayerReadRaster(): src=%d,%d,%d,%d, dst=%d,%d,%d,%d\n", src_xoff, src_yoff, src_xsize, src_ysize, 0, 0, dst_xsize, dst_ysize ); } else { src_xoff = 0; src_yoff = 0; dst_xsize = src_xsize = MIN(map->width,src_xsize); dst_ysize = src_ysize = MIN(map->height,src_ysize); copyRect.minx = copyRect.miny = 0; copyRect.maxx = map->width; copyRect.maxy = map->height; dst_cellsize_y = dst_cellsize_x = 1; } /* -------------------------------------------------------------------- */ /* Allocate buffer, and read data into it. */ /* -------------------------------------------------------------------- */ clinfo->buffer = (double *) malloc(sizeof(double) * dst_xsize * dst_ysize); if (clinfo->buffer == NULL) { msSetError(MS_MEMERR, "Malloc(): Out of memory.", "msContourLayerReadRaster()"); return MS_FAILURE; } eErr = GDALRasterIO(hBand, GF_Read, src_xoff, src_yoff, src_xsize, src_ysize, clinfo->buffer, dst_xsize, dst_ysize, GDT_Float64, 0, 0); if (eErr != CE_None) { msSetError( MS_IOERR, "GDALRasterIO() failed: %s", "msContourLayerReadRaster()", CPLGetLastErrorMsg() ); free(clinfo->buffer); return MS_FAILURE; } memset(pointer, 0, sizeof(pointer)); CPLPrintPointer(pointer, clinfo->buffer, sizeof(pointer)); sprintf(memDSPointer,"MEM:::DATAPOINTER=%s,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=Float64", pointer, dst_xsize, dst_ysize); clinfo->hDS = GDALOpen(memDSPointer, GA_ReadOnly); if (clinfo->hDS == NULL) { msSetError(MS_IMGERR, "Unable to open GDAL Memory dataset.", "msContourLayerReadRaster()"); free(clinfo->buffer); return MS_FAILURE; } adfGeoTransform[0] = copyRect.minx; adfGeoTransform[1] = dst_cellsize_x; adfGeoTransform[2] = 0; adfGeoTransform[3] = copyRect.maxy; adfGeoTransform[4] = 0; adfGeoTransform[5] = -dst_cellsize_y; clinfo->cellsize = MAX(dst_cellsize_x, dst_cellsize_y); { char buf[64]; sprintf(buf, "%lf", clinfo->cellsize); msInsertHashTable(&layer->metadata, "__data_cellsize__", buf); } GDALSetGeoTransform(clinfo->hDS, adfGeoTransform); return MS_SUCCESS; }
/** * Is there any XMP metadata in the map file for us to worry about? */ int msXmpWrite( mapObj *map, const char *filename ) { #ifdef USE_EXEMPI /* Should hold our keys */ hashTableObj hash_metadata = map->web.metadata; /* Temporary place for custom name spaces */ hashTableObj hash_ns; /* We use regex to strip out the namespace and XMP key value from the metadata key */ regex_t xmp_regex; const char *xmp_ns_str = "^xmp_(.+)_namespace$"; const char *xmp_tag_str = "^xmp_(.+)_(.+)$"; const char *key = NULL; static int regflags = REG_ICASE | REG_EXTENDED; /* XMP object and file pointers */ XmpPtr xmp; XmpFilePtr f; /* Force the hash table to empty */ hash_ns.numitems = 0; /* Prepare XMP library */ xmp_init(); f = xmp_files_open_new(filename, XMP_OPEN_FORUPDATE); if ( ! f ) { msSetError( MS_MISCERR, "Unable to open temporary file '%s' to write XMP info", "msXmpWrite()", filename ); return MS_FAILURE; } /* Create a new XMP structure if the file doesn't already have one */ xmp = xmp_files_get_new_xmp(f); if ( xmp == NULL ) xmp = xmp_new_empty(); /* Check we can write to the file */ if ( ! xmp_files_can_put_xmp(f, xmp) ) { msSetError( MS_MISCERR, "Unable to write XMP information to '%s'", "msXmpWrite()", filename ); return MS_FAILURE; } /* Compile our "xmp_*_namespace" regex */ if ( regcomp(&xmp_regex, xmp_ns_str, regflags) ) { msSetError( MS_MISCERR, "Unable compile regex '%s'", "msXmpWrite()", xmp_ns_str ); return MS_FAILURE; } /* Check all the keys for "xmp_*_namespace" pattern */ initHashTable(&hash_ns); key = msFirstKeyFromHashTable(&hash_metadata); /* No first key? No license info. We shouldn't get here. */ if ( ! key ) return MS_SUCCESS; do { /* Our regex has one match slot */ regmatch_t matches[2]; /* Found a custom namespace entry! Store it for later. */ if ( 0 == regexec(&xmp_regex, key, 2, matches, 0) ) { size_t ns_size = 0; char *ns_name = NULL; const char *ns_uri; /* Copy in the namespace name */ ns_size = matches[1].rm_eo - matches[1].rm_so; ns_name = msSmallMalloc(ns_size + 1); memcpy(ns_name, key + matches[1].rm_so, ns_size); ns_name[ns_size] = 0; /* null terminate */ /* Copy in the namespace uri */ ns_uri = msLookupHashTable(&hash_metadata, key); msInsertHashTable(&hash_ns, ns_name, ns_uri); xmp_register_namespace(ns_uri, ns_name, NULL); msFree(ns_name); } } while( (key = msNextKeyFromHashTable(&hash_metadata, key)) ); /* Clean up regex */ regfree(&xmp_regex); /* Compile our "xmp_*_*" regex */ if ( regcomp(&xmp_regex, xmp_tag_str, regflags) ) { msFreeHashItems(&hash_ns); msSetError( MS_MISCERR, "Unable compile regex '%s'", "msXmpWrite()", xmp_tag_str ); return MS_FAILURE; } /* Check all the keys for "xmp_*_*" pattern */ key = msFirstKeyFromHashTable(&hash_metadata); do { /* Our regex has two match slots */ regmatch_t matches[3]; /* Found a namespace entry! Write it into XMP. */ if ( 0 == regexec(&xmp_regex, key, 3, matches, 0) ) { /* Get the namespace and tag name */ size_t ns_name_size = matches[1].rm_eo - matches[1].rm_so; size_t ns_tag_size = matches[2].rm_eo - matches[2].rm_so; char *ns_name = msSmallMalloc(ns_name_size + 1); char *ns_tag = msSmallMalloc(ns_tag_size + 1); const char *ns_uri = NULL; memcpy(ns_name, key + matches[1].rm_so, ns_name_size); memcpy(ns_tag, key + matches[2].rm_so, ns_tag_size); ns_name[ns_name_size] = 0; /* null terminate */ ns_tag[ns_tag_size] = 0; /* null terminate */ if ( strcmp(ns_tag,"namespace") == 0 ) { msFree(ns_name); msFree(ns_tag); continue; } /* If this is a default name space?... */ if ( (ns_uri = msXmpUri(ns_name)) ) { xmp_register_namespace(ns_uri, ns_name, NULL); xmp_set_property(xmp, ns_uri, ns_tag, msLookupHashTable(&hash_metadata, key), 0); } /* Or maybe it's a custom one?... */ else if ( (ns_uri = msLookupHashTable(&hash_ns, ns_name)) ) { xmp_set_property(xmp, ns_uri, ns_tag, msLookupHashTable(&hash_metadata, key), 0); } /* Or perhaps we're screwed. */ else { msSetError( MS_MISCERR, "Unable to identify XMP namespace '%s' in metadata key '%s'", "msXmpWrite()", ns_name, key ); msFreeHashItems(&hash_ns); msFree(ns_name); msFree(ns_tag); return MS_FAILURE; } msFree(ns_name); msFree(ns_tag); } } while( (key = msNextKeyFromHashTable(&hash_metadata, key)) ); /* Clean up regex */ regfree(&xmp_regex); /* Write out the XMP */ if ( !xmp_files_put_xmp(f, xmp) ) { msFreeHashItems(&hash_ns); msSetError( MS_MISCERR, "Unable to execute '%s' on pointer %p", "msXmpWrite()", "xmp_files_put_xmp", f ); return MS_FAILURE; } /* Write out the file and flush */ if ( !xmp_files_close(f, XMP_CLOSE_SAFEUPDATE) ) { msFreeHashItems(&hash_ns); msSetError( MS_MISCERR, "Unable to execute '%s' on pointer %p", "msXmpWrite()", "xmp_files_close", f ); return MS_FAILURE; } msFreeHashItems(&hash_ns); xmp_free(xmp); xmp_terminate(); return MS_SUCCESS; #else return MS_FAILURE; #endif }
/* ** Extract Map File name from params and load it. ** Returns map object or NULL on error. */ static mapObj* msModuleLoadMap(mapservObj *mapserv, mapserver_dir_config *conf) { int i; /* OK, here's the magic: we take the mapObj from our stored config. * We will use a copy of it created by msCopyMap since MapServer * modifies the object at several places during request processing */ mapObj *map = msNewMapObj (); if(!map) return NULL; msCopyMap (map, conf->map); /* check for any %variable% substitutions here, also do any map_ changes, we do this here so WMS/WFS */ /* services can take advantage of these "vendor specific" extensions */ for(i=0; i<mapserv->request->NumParams; i++) { /* ** a few CGI variables should be skipped altogether ** ** qstring: there is separate per layer validation for attribute queries and the substitution checks ** below conflict with that so we avoid it here */ if(strncasecmp(mapserv->request->ParamNames[i],"qstring",7) == 0) continue; if(strncasecmp(mapserv->request->ParamNames[i],"map_",4) == 0 || strncasecmp(mapserv->request->ParamNames[i],"map.",4) == 0) { /* check to see if there are any additions to the mapfile */ if(msUpdateMapFromURL(map, mapserv->request->ParamNames[i], mapserv->request->ParamValues[i]) != MS_SUCCESS) { msFreeMap(map); return NULL; } continue; } } msApplySubstitutions(map, mapserv->request->ParamNames, mapserv->request->ParamValues, mapserv->request->NumParams); msApplyDefaultSubstitutions(map); /* check to see if a ogc map context is passed as argument. if there */ /* is one load it */ for(i=0; i<mapserv->request->NumParams; i++) { if(strcasecmp(mapserv->request->ParamNames[i],"context") == 0) { if(mapserv->request->ParamValues[i] && strlen(mapserv->request->ParamValues[i]) > 0) { if(strncasecmp(mapserv->request->ParamValues[i],"http",4) == 0) { if(msGetConfigOption(map, "CGI_CONTEXT_URL")) msLoadMapContextURL(map, mapserv->request->ParamValues[i], MS_FALSE); } else msLoadMapContext(map, mapserv->request->ParamValues[i], MS_FALSE); } } } /* * RFC-42 HTTP Cookie Forwarding * Here we set the http_cookie_data metadata to handle the * HTTP Cookie Forwarding. The content of this metadata is the cookie * content. In the future, this metadata will probably be replaced * by an object that is part of the mapObject that would contain * information on the application status (such as cookie). */ if( mapserv->request->httpcookiedata != NULL ) { msInsertHashTable( &(map->web.metadata), "http_cookie_data", mapserv->request->httpcookiedata ); } return map; }
const 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->compositer && currentLayer->compositer->opacity > 0 && currentLayer->compositer->opacity < 100 && LineStyle[i].color->alpha == 255) LineStyle[i].color->alpha = MS_NINT(currentLayer->compositer->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->compositer && currentLayer->compositer->opacity > 0 && currentLayer->compositer->opacity < 100 && PolygonColor.alpha == 255) PolygonColor.alpha = MS_NINT(currentLayer->compositer->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->compositer && currentLayer->compositer->opacity > 0 && currentLayer->compositer->opacity < 100 && LabelColor.alpha == 255) LabelColor.alpha = MS_NINT(currentLayer->compositer->opacity*2.55); sprintf(labelHexColor,"%02x%02x%02x%02x", LabelColor.alpha, LabelColor.blue, LabelColor.green, LabelColor.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); } const 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; }