Skip to content
Permalink
Browse files

OGR style: support more options for Pen and Brush (#4982, #4983)

- For pen, support 'p' (pattern), 'cap', 'j' (join) and 'dp' (perpendicular offset)
- For brush, support 'a' (angle), 's' (size), 'dx'='dy' (gap)
  • Loading branch information
rouault committed Oct 1, 2014
1 parent d597a28 commit 18ef92da99f3a91e1c3bccad883a8050a026e730
Showing with 122 additions and 5 deletions.
  1. +121 −4 mapogr.cpp
  2. +1 −1 msautotest
@@ -3076,18 +3076,25 @@ static int msOGRUpdateStyle(OGRStyleMgrH hStyleMgr, mapObj *map, layerObj *layer
} else if (eStylePartType == OGRSTCPen) {
OGRStyleToolH hPenStyle = hStylePart;

const char *pszPenName = OGR_ST_GetParamStr(hPenStyle,
OGRSTPenId,
&bIsNull);
if (bIsNull) pszPenName = NULL;
const char *pszPenName, *pszPattern, *pszCap, *pszJoin;
colorObj oPenColor;
int nPenSymbol = 0;
int nPenSize = 1;
t =-1;
double pattern[MS_MAXPATTERNLENGTH];
int patternlength = 0;
int linecap = MS_CJC_DEFAULT_CAPS;
int linejoin = MS_CJC_DEFAULT_JOINS;
double offsetx = 0.0;
double offsety = 0.0;

// Make sure pen is always initialized
MS_INIT_COLOR(oPenColor, -1, -1, -1,255);

pszPenName = OGR_ST_GetParamStr(hPenStyle,
OGRSTPenId,
&bIsNull);
if (bIsNull) pszPenName = NULL;
// Check for Pen Pattern "ogr-pen-1": the invisible pen
// If that's what we have then set pen color to -1
if (pszPenName && strstr(pszPenName, "ogr-pen-1") != NULL) {
@@ -3113,8 +3120,83 @@ static int msOGRUpdateStyle(OGRStyleMgrH hStyleMgr, mapObj *map, layerObj *layer
pszPenName, NULL, MS_FALSE);
}
}

if (layer->debug >= MS_DEBUGLEVEL_VVV)
msDebug("** PEN COLOR = %d %d %d **\n", oPenColor.red,oPenColor.green,oPenColor.blue);

pszPattern = OGR_ST_GetParamStr(hPenStyle, OGRSTPenPattern, &bIsNull);
if (bIsNull) pszPattern = NULL;
if( pszPattern != NULL )
{
char** papszTokens = CSLTokenizeStringComplex(pszPattern, " ", FALSE, FALSE);
int nTokenCount = CSLCount(papszTokens);
int bValidFormat = TRUE;
if( nTokenCount >= 2 && nTokenCount <= MS_MAXPATTERNLENGTH)
{
for(int i=0;i<nTokenCount;i++)
{
if( strlen(papszTokens[i]) > 2 &&
strcmp(papszTokens[i] + strlen(papszTokens[i]) - 2, "px") == 0 )
{
pattern[patternlength++] = CPLAtof(papszTokens[i]);
}
else
{
bValidFormat = FALSE;
patternlength = 0;
break;
}
}
}
else
bValidFormat = FALSE;
if( !bValidFormat && layer->debug >= MS_DEBUGLEVEL_VVV)
msDebug("Invalid/unhandled pen pattern format = %s\n", pszPattern);
CSLDestroy(papszTokens);
}

pszCap = OGR_ST_GetParamStr(hPenStyle, OGRSTPenCap, &bIsNull);
if (bIsNull) pszCap = NULL;
if( pszCap != NULL )
{
/* Note: the default in OGR Feature style is BUTT, but the MapServer */
/* default is ROUND. Currently use MapServer default. */
if( strcmp(pszCap, "b") == 0 ) /* BUTT */
linecap = MS_CJC_BUTT;
else if( strcmp(pszCap, "r") == 0 ) /* ROUND */
linecap = MS_CJC_ROUND;
else if( strcmp(pszCap, "p") == 0 ) /* PROJECTING */
linecap = MS_CJC_SQUARE;
else if( layer->debug >= MS_DEBUGLEVEL_VVV)
msDebug("Invalid/unhandled pen cap = %s\n", pszCap);
}

pszJoin = OGR_ST_GetParamStr(hPenStyle, OGRSTPenJoin, &bIsNull);
if (bIsNull) pszJoin = NULL;
if( pszJoin != NULL )
{
/* Note: the default in OGR Feature style is MITER, but the MapServer */
/* default is NONE. Currently use MapServer default. */
if( strcmp(pszJoin, "m") == 0 ) /* MITTER */
linejoin = MS_CJC_MITER;
else if( strcmp(pszJoin, "r") == 0 ) /* ROUND */
linejoin = MS_CJC_ROUND;
else if( strcmp(pszJoin, "b") == 0 ) /* BEVEL */
linejoin = MS_CJC_BEVEL;
else if( layer->debug >= MS_DEBUGLEVEL_VVV)
msDebug("Invalid/unhandled pen join = %s\n", pszJoin);
}

offsetx = OGR_ST_GetParamDbl(hPenStyle, OGRSTPenPerOffset, &bIsNull);
if( bIsNull ) offsetx = 0;
if( offsetx != 0.0 )
{
/* OGR feature style and MapServer conventions related to offset */
/* sign are the same : negative values for left of line, positive for */
/* right of line */
offsety = MS_STYLE_SINGLE_SIDED_OFFSET;
}

if (bIsBrush || layer->type == MS_LAYER_POLYGON) {
// This is a multipart symbology, so pen defn goes in the
// overlaysymbol params
@@ -3127,6 +3209,13 @@ static int msOGRUpdateStyle(OGRStyleMgrH hStyleMgr, mapObj *map, layerObj *layer
c->styles[1]->size = nPenSize;
c->styles[1]->symbol = nPenSymbol;
c->styles[1]->width = nPenSize;
c->styles[1]->linecap = linecap;
c->styles[1]->linejoin = linejoin;
c->styles[1]->offsetx = offsetx;
c->styles[1]->offsety = offsety;
c->styles[1]->patternlength = patternlength;
if( patternlength > 0 )
memcpy(c->styles[1]->pattern, pattern, sizeof(double) * patternlength);
} else {
// Single part symbology
if (msMaybeAllocateClassStyle(c, 0)) {
@@ -3142,6 +3231,13 @@ static int msOGRUpdateStyle(OGRStyleMgrH hStyleMgr, mapObj *map, layerObj *layer
c->styles[0]->symbol = nPenSymbol;
c->styles[0]->size = nPenSize;
c->styles[0]->width = nPenSize;
c->styles[0]->linecap = linecap;
c->styles[0]->linejoin = linejoin;
c->styles[0]->offsetx = offsetx;
c->styles[0]->offsety = offsety;
c->styles[0]->patternlength = patternlength;
if( patternlength > 0 )
memcpy(c->styles[0]->pattern, pattern, sizeof(double) * patternlength);
}

} else if (eStylePartType == OGRSTCBrush) {
@@ -3194,6 +3290,27 @@ static int msOGRUpdateStyle(OGRStyleMgrH hStyleMgr, mapObj *map, layerObj *layer
&bIsNull);
c->styles[0]->symbol = msOGRGetSymbolId(&(map->symbolset),
pszName, NULL, MS_FALSE);

double angle = OGR_ST_GetParamDbl(hBrushStyle, OGRSTBrushAngle, &bIsNull);
if( !bIsNull )
c->styles[0]->angle = angle;

double size = OGR_ST_GetParamDbl(hBrushStyle, OGRSTBrushSize, &bIsNull);
if( !bIsNull )
c->styles[0]->size = size;

double spacingx = OGR_ST_GetParamDbl(hBrushStyle, OGRSTBrushDx, &bIsNull);
if( !bIsNull )
{
double spacingy = OGR_ST_GetParamDbl(hBrushStyle, OGRSTBrushDy, &bIsNull);
if( !bIsNull )
{
if( spacingx == spacingy )
c->styles[0]->gap = spacingx;
else if( layer->debug >= MS_DEBUGLEVEL_VVV )
msDebug("Ignoring brush dx and dy since they don't have the same value\n");
}
}
}
} else if (eStylePartType == OGRSTCSymbol) {
OGRStyleToolH hSymbolStyle = hStylePart;
Submodule msautotest updated from 85a91d to df6241

0 comments on commit 18ef92d

Please sign in to comment.
You can’t perform that action at this time.