Permalink
Browse files

RFC86 implementation (#4538)

  • Loading branch information...
tbonfort committed Dec 14, 2012
1 parent 523c005 commit 93600d27ababddb002ed78abb5a3a3417647676a
Showing with 2,156 additions and 1,338 deletions.
  1. +26 −0 mapcopy.c
  2. +137 −0 mapfile.c
  3. +4 −0 mapfile.h
  4. +112 −1 maplayer.c
  5. +1,846 −1,336 maplexer.c
  6. +2 −0 maplexer.l
  7. +28 −0 mapserver.h
  8. +1 −1 msautotest
View
@@ -840,6 +840,24 @@ int msCopyLegend(legendObj *dst, legendObj *src, mapObj *map)
return MS_SUCCESS;
}
int msCopyScaleTokenEntry(scaleTokenEntryObj *src, scaleTokenEntryObj *dst) {
MS_COPYSTRING(dst->value,src->value);
MS_COPYSTELEM(minscale);
MS_COPYSTELEM(maxscale);
return MS_SUCCESS;
}
int msCopyScaleToken(scaleTokenObj *src, scaleTokenObj *dst) {
int i;
MS_COPYSTRING(dst->name,src->name);
MS_COPYSTELEM(n_entries);
dst->tokens = (scaleTokenEntryObj*)msSmallCalloc(src->n_entries,sizeof(scaleTokenEntryObj));
for(i=0;i<src->n_entries;i++) {
msCopyScaleTokenEntry(&src->tokens[i],&dst->tokens[i]);
}
return MS_SUCCESS;
}
/***********************************************************************
* msCopyLayer() *
* *
@@ -860,6 +878,14 @@ int msCopyLayer(layerObj *dst, layerObj *src)
MS_COPYSTELEM(classitemindex);
for(i = 0; i < src->numscaletokens; i++) {
if(msGrowLayerScaletokens(dst) == NULL)
return MS_FAILURE;
initScaleToken(&dst->scaletokens[i]);
msCopyScaleToken(&src->scaletokens[i],&dst->scaletokens[i]);
dst->numscaletokens++;
}
for (i = 0; i < src->numclasses; i++) {
if (msGrowLayerClasses(dst) == NULL)
return MS_FAILURE;
View
137 mapfile.c
@@ -32,6 +32,7 @@
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <float.h>
#include "mapserver.h"
#include "mapfile.h"
@@ -768,6 +769,23 @@ int loadJoin(joinObj *join)
} /* next token */
}
static void writeScaleToken(FILE *stream, int indent, scaleTokenObj *token) {
int i;
indent++;
writeBlockBegin(stream,indent,"SCALETOKEN");
writeString(stream, indent, "NAME", NULL, token->name);
indent++;
writeBlockBegin(stream,indent,"VALUES");
for(i=0;i<token->n_entries;i++) {
char minscale[32];
sprintf(minscale,"%g",token->tokens[i].minscale);
writeNameValuePair(stream, indent, minscale, token->tokens[i].value);
}
writeBlockEnd(stream,indent,"VALUES");
indent--;
writeBlockEnd(stream,indent,"SCALETOKEN");
}
static void writeJoin(FILE *stream, int indent, joinObj *join)
{
indent++;
@@ -3687,6 +3705,9 @@ int initLayer(layerObj *layer, mapObj *map)
layer->maxfeatures = -1; /* no quota */
layer->startindex = -1; /*used for pagination*/
layer->scaletokens = NULL;
layer->numscaletokens = 0;
layer->template = layer->header = layer->footer = NULL;
layer->transform = MS_TRUE;
@@ -3770,6 +3791,28 @@ int initLayer(layerObj *layer, mapObj *map)
return(0);
}
int initScaleToken(scaleTokenObj* token) {
token->n_entries = 0;
token->name = NULL;
token->tokens = NULL;
return MS_SUCCESS;
}
int freeScaleTokenEntry( scaleTokenEntryObj *token) {
msFree(token->value);
return MS_SUCCESS;
}
int freeScaleToken(scaleTokenObj *scaletoken) {
int i;
msFree(scaletoken->name);
for(i=0;i<scaletoken->n_entries;i++) {
freeScaleTokenEntry(&scaletoken->tokens[i]);
}
msFree(scaletoken->tokens);
return MS_SUCCESS;
}
int freeLayer(layerObj *layer)
{
int i;
@@ -3815,6 +3858,13 @@ int freeLayer(layerObj *layer)
}
msFree(layer->class);
if(layer->numscaletokens>0) {
for(i=0;i<layer->numscaletokens;i++) {
freeScaleToken(&layer->scaletokens[i]);
}
msFree(layer->scaletokens);
}
if(layer->features)
freeFeatureList(layer->features);
@@ -3895,6 +3945,85 @@ classObj *msGrowLayerClasses( layerObj *layer )
return layer->class[layer->numclasses];
}
scaleTokenObj *msGrowLayerScaletokens( layerObj *layer )
{
layer->scaletokens = msSmallRealloc(layer->scaletokens,(layer->numscaletokens+1)*sizeof(scaleTokenObj));
memset(&layer->scaletokens[layer->numscaletokens],0,sizeof(scaleTokenObj));
return &layer->scaletokens[layer->numscaletokens];
}
int loadScaletoken(scaleTokenObj *token, layerObj *layer) {
for(;;) {
int stop = 0;
switch(msyylex()) {
case(EOF):
msSetError(MS_EOFERR, NULL, "loadScaletoken()");
return(MS_FAILURE);
case(NAME):
if(getString(&token->name) == MS_FAILURE) return(MS_FAILURE);
break;
case(VALUES):
for(;;) {
if(stop) break;
switch(msyylex()) {
case(EOF):
msSetError(MS_EOFERR, NULL, "loadScaletoken()");
return(MS_FAILURE);
case(END):
stop = 1;
if(token->n_entries == 0) {
msSetError(MS_PARSEERR,"Scaletoken (line:%d) has no VALUES defined","loadScaleToken()",msyylineno);
return(MS_FAILURE);
}
token->tokens[token->n_entries-1].maxscale = DBL_MAX;
break;
case(MS_STRING):
/* we have a key */
token->tokens = msSmallRealloc(token->tokens,(token->n_entries+1)*sizeof(scaleTokenEntryObj));
if(1 != sscanf(msyystring_buffer,"%lf",&token->tokens[token->n_entries].minscale)) {
msSetError(MS_PARSEERR, "failed to parse SCALETOKEN VALUE (%s):(line %d), expecting \"minscale\"", "loadScaletoken()",
msyystring_buffer,msyylineno);
return(MS_FAILURE);
}
if(token->n_entries == 0) {
/* check supplied value was 0*/
if(token->tokens[0].minscale != 0) {
msSetError(MS_PARSEERR, "First SCALETOKEN VALUE (%s):(line %d) must be zero, expecting \"0\"", "loadScaletoken()",
msyystring_buffer,msyylineno);
return(MS_FAILURE);
}
} else {
/* set max scale of previous token */
token->tokens[token->n_entries-1].maxscale = token->tokens[token->n_entries].minscale;
}
token->tokens[token->n_entries].value = NULL;
if(getString(&(token->tokens[token->n_entries].value)) == MS_FAILURE) return(MS_FAILURE);
token->n_entries++;
break;
default:
msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadScaletoken()", msyystring_buffer, msyylineno );
return(MS_FAILURE);
}
}
break;
case(END):
if(!token->name || !*(token->name)) {
msSetError(MS_PARSEERR,"ScaleToken missing mandatory NAME entry (line %d)","loadScaleToken()",msyylineno);
return MS_FAILURE;
}
if(token->n_entries == 0) {
msSetError(MS_PARSEERR,"ScaleToken missing at least one VALUES entry (line %d)","loadScaleToken()",msyylineno);
return MS_FAILURE;
}
return MS_SUCCESS;
default:
msSetError(MS_IDENTERR, "Parsing error 2 near (%s):(line %d)", "loadScaletoken()", msyystring_buffer, msyylineno );
return(MS_FAILURE);
}
} /* next token*/
}
int loadLayer(layerObj *layer, mapObj *map)
{
int type;
@@ -4211,6 +4340,13 @@ int loadLayer(layerObj *layer, mapObj *map)
}
}
break;
case(SCALETOKEN):
if (msGrowLayerScaletokens(layer) == NULL)
return(-1);
initScaleToken(&layer->scaletokens[layer->numscaletokens]);
if(loadScaletoken(&layer->scaletokens[layer->numscaletokens], layer) == -1) return(-1);
layer->numscaletokens++;
break;
case(SIZEUNITS):
if((layer->sizeunits = getSymbol(8, MS_INCHES,MS_FEET,MS_MILES,MS_METERS,MS_KILOMETERS,MS_NAUTICALMILES,MS_DD,MS_PIXELS)) == -1) return(-1);
break;
@@ -4391,6 +4527,7 @@ static void writeLayer(FILE *stream, int indent, layerObj *layer)
writeHashTable(stream, indent, "VALIDATION", &(layer->validation));
/* write potentially multiply occuring objects last */
for(i=0; i<layer->numscaletokens; i++) writeScaleToken(stream, indent, &(layer->scaletokens[i]));
for(i=0; i<layer->numjoins; i++) writeJoin(stream, indent, &(layer->joins[i]));
for(i=0; i<layer->numclasses; i++) writeClass(stream, indent, layer->class[i]);
View
@@ -308,6 +308,10 @@ enum MS_TOKEN_SOURCES {MS_FILE_TOKENS=0, MS_STRING_TOKENS, MS_URL_TOKENS};
#define LEADER 1260
#define GRIDSTEP 1261
/* rfc 86 scale-dependant token substitutions */
#define SCALETOKEN 1270
#define VALUES 1271
/* rfc59 bindvals objects */
#define BINDVALS 2000
View
@@ -68,11 +68,121 @@ void msLayerFreeItemInfo(layerObj *layer)
layer->vtable->LayerFreeItemInfo(layer);
}
int msLayerRestoreFromScaletokens(layerObj *layer)
{
if(!layer->scaletokens) {
return MS_SUCCESS;
}
if(layer->orig_data) {
msFree(layer->data);
layer->data = layer->orig_data;
layer->orig_data = NULL;
}
if(layer->orig_tileindex) {
msFree(layer->tileindex);
layer->tileindex = layer->orig_tileindex;
layer->orig_tileindex = NULL;
}
if(layer->orig_tileitem) {
msFree(layer->tileitem);
layer->tileitem = layer->orig_tileitem;
layer->orig_tileitem = NULL;
}
if(layer->orig_filter) {
msLoadExpressionString(&(layer->filter),layer->orig_filter);
msFree(layer->orig_filter);
layer->orig_filter = NULL;
}
if(layer->orig_filteritem) {
msFree(layer->filteritem);
layer->filteritem = layer->orig_filteritem;
layer->orig_filteritem = NULL;
}
return MS_SUCCESS;
}
int msLayerApplyScaletokens(layerObj *layer, double scale)
{
int i;
if(!layer->scaletokens) {
return MS_SUCCESS;
}
msLayerRestoreFromScaletokens(layer);
for(i=0;i<layer->numscaletokens;i++) {
int tokenindex=0;
scaleTokenObj *st = &layer->scaletokens[i];
scaleTokenEntryObj *ste = NULL;
while(tokenindex<st->n_entries) {
ste = &(st->tokens[tokenindex]);
if(scale < ste->maxscale && scale >= ste->minscale) break; /* current token is the correct one */
tokenindex++;
ste = NULL;
}
assert(ste);
if(layer->data && strstr(layer->data,st->name)) {
if(layer->debug >= MS_DEBUGLEVEL_DEBUG) {
msDebug("replacing scaletoken (%s) with (%s) in layer->data (%s) for scale=%f\n",
st->name,ste->value,layer->name,scale);
}
layer->orig_data = layer->data;
layer->data = msStrdup(layer->data);
layer->data = msReplaceSubstring(layer->data,st->name,ste->value);
}
if(layer->tileindex && strstr(layer->tileindex,st->name)) {
if(layer->debug >= MS_DEBUGLEVEL_DEBUG) {
msDebug("replacing scaletoken (%s) with (%s) in layer->tileindex (%s) for scale=%f\n",
st->name,ste->value,layer->name,scale);
}
layer->orig_tileindex = layer->tileindex;
layer->tileindex = msStrdup(layer->tileindex);
layer->tileindex = msReplaceSubstring(layer->tileindex,st->name,ste->value);
}
if(layer->tileitem && strstr(layer->tileitem,st->name)) {
if(layer->debug >= MS_DEBUGLEVEL_DEBUG) {
msDebug("replacing scaletoken (%s) with (%s) in layer->tileitem (%s) for scale=%f\n",
st->name,ste->value,layer->name,scale);
}
layer->orig_tileitem = layer->tileitem;
layer->tileitem = msStrdup(layer->tileitem);
layer->tileitem = msReplaceSubstring(layer->tileitem,st->name,ste->value);
}
if(layer->filteritem && strstr(layer->filteritem,st->name)) {
if(layer->debug >= MS_DEBUGLEVEL_DEBUG) {
msDebug("replacing scaletoken (%s) with (%s) in layer->filteritem (%s) for scale=%f\n",
st->name,ste->value,layer->name,scale);
}
layer->orig_filteritem = layer->filteritem;
layer->filteritem = msStrdup(layer->filteritem);
layer->filteritem = msReplaceSubstring(layer->filteritem,st->name,ste->value);
}
if(layer->filter.string && strstr(layer->filter.string,st->name)) {
char *tmpval;
if(layer->debug >= MS_DEBUGLEVEL_DEBUG) {
msDebug("replacing scaletoken (%s) with (%s) in layer->filter (%s) for scale=%f\n",
st->name,ste->value,layer->name,scale);
}
layer->orig_filter = msStrdup(layer->filter.string);
tmpval = msStrdup(layer->filter.string);
tmpval = msReplaceSubstring(tmpval,st->name,ste->value);
if(msLoadExpressionString(&(layer->filter),tmpval) == -1) return(MS_FAILURE); /* loadExpression() cleans up previously allocated expression */
msFree(tmpval);
}
}
return MS_SUCCESS;
}
/*
** Does exactly what it implies, readies a layer for processing.
*/
int msLayerOpen(layerObj *layer)
{
int rv;
/* RFC-86 Scale dependant token replacements*/
rv = msLayerApplyScaletokens(layer,(layer->map)?layer->map->scaledenom:-1);
if (rv != MS_SUCCESS) return rv;
/* RFC-69 clustering support */
if (layer->cluster.region)
return msClusterLayerOpen(layer);
@@ -87,7 +197,7 @@ int msLayerOpen(layerObj *layer)
layer->connectiontype = MS_RASTER;
if ( ! layer->vtable) {
int rv = msInitializeVirtualTable(layer);
rv = msInitializeVirtualTable(layer);
if (rv != MS_SUCCESS)
return rv;
}
@@ -232,6 +342,7 @@ void msLayerClose(layerObj *layer)
if (layer->vtable) {
layer->vtable->LayerClose(layer);
}
msLayerRestoreFromScaletokens(layer);
}
/*
Oops, something went wrong.

0 comments on commit 93600d2

Please sign in to comment.