[mapserver-commits] r10976 - trunk/mapserver
svn at osgeo.org
svn at osgeo.org
Tue Feb 8 22:04:53 EST 2011
Author: warmerdam
Date: 2011-02-08 19:04:53 -0800 (Tue, 08 Feb 2011)
New Revision: 10976
Modified:
trunk/mapserver/HISTORY.TXT
trunk/mapserver/mapraster.c
Log:
implement support for classifying rasters with new expression parser (#3663)
Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT 2011-02-08 22:08:22 UTC (rev 10975)
+++ trunk/mapserver/HISTORY.TXT 2011-02-09 03:04:53 UTC (rev 10976)
@@ -14,6 +14,9 @@
Current Version (SVN trunk):
----------------------------
+- Implemented support in for classifying rasters using the new
+ expression parsing (msGetClass()...) (#3663)
+
- Implemented RFC 65 which improves and simplifies one-pass query support. This causes
a few MapScript regressions with getShape/getFeature/getResultsShape. (#3647)
Modified: trunk/mapserver/mapraster.c
===================================================================
--- trunk/mapserver/mapraster.c 2011-02-08 22:08:22 UTC (rev 10975)
+++ trunk/mapserver/mapraster.c 2011-02-09 03:04:53 UTC (rev 10976)
@@ -37,7 +37,9 @@
MS_CVSID("$Id$")
-extern int yyparse(void);
+extern int msyylex_destroy(void);
+extern int yyparse(parseObj *);
+
extern parseResultObj yypresult; /* result of parsing, true/false */
#ifdef USE_GDAL
@@ -54,92 +56,71 @@
#define NUMGRAYS 16
/************************************************************************/
-/* msGetClass() */
+/* msGetClass_String() */
/************************************************************************/
-int msGetClass(layerObj *layer, colorObj *color)
-{
- int i;
- char tmpstr[12]; /* holds either a single color index or something like 'rrr ggg bbb' */
-
- if((layer->numclasses == 1) && !(layer->class[0]->expression.string)) /* no need to do lookup */
- return(0);
+static int msGetClass_String( layerObj *layer, colorObj *color, const char *pixel_value )
- if(!color) return(-1);
-
- for(i=0; i<layer->numclasses; i++) {
- if (layer->class[i]->expression.string == NULL) /* Empty expression - always matches */
- return(i);
- switch(layer->class[i]->expression.type) {
- case(MS_STRING):
- snprintf(tmpstr, sizeof(tmpstr), "%d %d %d", color->red, color->green, color->blue);
- if(strcmp(layer->class[i]->expression.string, tmpstr) == 0) return(i); /* matched */
- snprintf(tmpstr, sizeof(tmpstr), "%d", color->pen);
- if(strcmp(layer->class[i]->expression.string, tmpstr) == 0) return(i); /* matched */
- break;
- case(MS_REGEX):
- if(!layer->class[i]->expression.compiled) {
- if(ms_regcomp(&(layer->class[i]->expression.regex), layer->class[i]->expression.string, MS_REG_EXTENDED|MS_REG_NOSUB) != 0) { /* compile the expression */
- msSetError(MS_REGEXERR, "Invalid regular expression.", "msGetClass()");
- return(-1);
- }
- layer->class[i]->expression.compiled = MS_TRUE;
- }
-
- snprintf(tmpstr, sizeof(tmpstr), "%d %d %d", color->red, color->green, color->blue);
- if(ms_regexec(&(layer->class[i]->expression.regex), tmpstr, 0, NULL, 0) == 0) return(i); /* got a match */
- snprintf(tmpstr, sizeof(tmpstr), "%d", color->pen);
- if(ms_regexec(&(layer->class[i]->expression.regex), tmpstr, 0, NULL, 0) == 0) return(i); /* got a match */
- break;
- case(MS_EXPRESSION):
-
- /*
- ** Big, fat TODO!
- **
- ** See msEvalExpression() in maputil.c for an example of how to do this. Basically need to define some raster bind
- ** variables: namely [red], [green], [blue] and [pixel]. Need to update the lexer and msTokenizeExpression() to
- ** recognize them...
- */
-
- return(-1);
- }
- }
-
- return(-1); /* not found */
-}
-
-/************************************************************************/
-/* msGetClass_FloatRGB() */
-/* */
-/* Returns the class based on classification of a floating */
-/* pixel value. */
-/************************************************************************/
-
-int msGetClass_FloatRGB(layerObj *layer, float fValue,
- int red, int green, int blue )
{
int i;
- char *tmpstr1=NULL;
- char tmpstr2[100];
-
+ const char *tmpstr1=NULL;
+ int numitems;
+ char *item_names[4] = { "pixel", "red", "green", "blue" };
+ char *item_values[4];
+ char red_value[8], green_value[8], blue_value[8];
+
+/* -------------------------------------------------------------------- */
+/* No need to do a lookup in the case of one default class. */
+/* -------------------------------------------------------------------- */
if((layer->numclasses == 1) && !(layer->class[0]->expression.string)) /* no need to do lookup */
return(0);
+/* -------------------------------------------------------------------- */
+/* Setup values list for expressions. */
+/* -------------------------------------------------------------------- */
+ if( color->red != -1 )
+ {
+ sprintf( red_value, "%d", color->red );
+ sprintf( green_value, "%d", color->green );
+ sprintf( blue_value, "%d", color->blue );
+ item_values[1] = red_value;
+ item_values[2] = green_value;
+ item_values[3] = blue_value;
+ numitems = 4;
+ }
+ else
+ {
+ numitems = 1;
+ }
+
+ item_values[0] = (char *)pixel_value;
+
+/* -------------------------------------------------------------------- */
+/* Loop over classes till we find a match. */
+/* -------------------------------------------------------------------- */
for(i=0; i<layer->numclasses; i++) {
- if (layer->class[i]->expression.string == NULL) /* Empty expression - always matches */
+
+ /* Empty expression - always matches */
+ if (layer->class[i]->expression.string == NULL)
return(i);
switch(layer->class[i]->expression.type) {
+
+/* -------------------------------------------------------------------- */
+/* Simple string match */
+/* -------------------------------------------------------------------- */
case(MS_STRING):
- snprintf(tmpstr2, sizeof(tmpstr2), "%18g", fValue );
/* trim junk white space */
- tmpstr1= tmpstr2;
+ tmpstr1= pixel_value;
while( *tmpstr1 == ' ' )
tmpstr1++;
if(strcmp(layer->class[i]->expression.string, tmpstr1) == 0) return(i); /* matched */
break;
+/* -------------------------------------------------------------------- */
+/* Regular expression. Rarely used for raster. */
+/* -------------------------------------------------------------------- */
case(MS_REGEX):
if(!layer->class[i]->expression.compiled) {
if(ms_regcomp(&(layer->class[i]->expression.regex), layer->class[i]->expression.string, MS_REG_EXTENDED|MS_REG_NOSUB) != 0) { /* compile the expression */
@@ -149,20 +130,41 @@
layer->class[i]->expression.compiled = MS_TRUE;
}
- snprintf(tmpstr2, sizeof(tmpstr2), "%18g", fValue );
- if(ms_regexec(&(layer->class[i]->expression.regex), tmpstr2, 0, NULL, 0) == 0) return(i); /* got a match */
+ if(ms_regexec(&(layer->class[i]->expression.regex), pixel_value, 0, NULL, 0) == 0) return(i); /* got a match */
break;
+/* -------------------------------------------------------------------- */
+/* Parsed expression. */
+/* -------------------------------------------------------------------- */
case(MS_EXPRESSION):
- /*
- ** Big, fat TODO!
- **
- ** See msEvalExpression() in maputil.c for an example of how to do this. Basically need to define some raster bind
- ** variables: namely [red], [green], [blue] and [pixel]. Need to update the lexer and msTokenizeExpression() to
- ** recognize them...
- */
+ {
+ int status;
+ parseObj p;
+ shapeObj dummy_shape;
+ expressionObj *expression = &(layer->class[i]->expression);
+
+ dummy_shape.numvalues = numitems;
+ dummy_shape.values = item_values;
- return(-1);
+ if( expression->tokens == NULL )
+ msTokenizeExpression( expression, item_names, &numitems );
+
+ p.shape = &dummy_shape;
+ p.expr = expression;
+ p.expr->curtoken = p.expr->tokens; /* reset */
+ p.type = MS_PARSE_TYPE_BOOLEAN;
+
+ status = yyparse(&p);
+
+ if (status != 0) {
+ msSetError(MS_PARSEERR, "Failed to parse expression: %s", "msGetClass_FloatRGB", expression->string);
+ return -1;
+ }
+
+ if( p.result.intval )
+ return i;
+ break;
+ }
}
}
@@ -170,6 +172,40 @@
}
/************************************************************************/
+/* msGetClass() */
+/************************************************************************/
+
+int msGetClass(layerObj *layer, colorObj *color )
+{
+ char pixel_value[12];
+
+ snprintf( pixel_value, sizeof(pixel_value), "%d", color->pen );
+
+ return msGetClass_String( layer, color, pixel_value );
+}
+
+/************************************************************************/
+/* msGetClass_FloatRGB() */
+/* */
+/* Returns the class based on classification of a floating */
+/* pixel value. */
+/************************************************************************/
+
+int msGetClass_FloatRGB(layerObj *layer, float fValue, int red, int green, int blue )
+{
+ char pixel_value[100];
+ colorObj color;
+
+ color.red = red;
+ color.green = green;
+ color.blue = blue;
+
+ snprintf( pixel_value, sizeof(pixel_value), "%18g", fValue );
+
+ return msGetClass_String( layer, &color, pixel_value );
+}
+
+/************************************************************************/
/* msAddColorGD() */
/* */
/* Function to add a color to an existing color map. It first */
More information about the mapserver-commits
mailing list