[mapserver-commits] r10234 - sandbox/mapserver6
svn at osgeo.org
svn at osgeo.org
Fri Jun 18 04:31:06 EDT 2010
Author: tbonfort
Date: 2010-06-18 08:31:06 +0000 (Fri, 18 Jun 2010)
New Revision: 10234
Modified:
sandbox/mapserver6/mapgd2.c
Log:
vector symbols
Modified: sandbox/mapserver6/mapgd2.c
===================================================================
--- sandbox/mapserver6/mapgd2.c 2010-06-18 07:01:11 UTC (rev 10233)
+++ sandbox/mapserver6/mapgd2.c 2010-06-18 08:31:06 UTC (rev 10234)
@@ -445,8 +445,163 @@
return MS_SUCCESS;
}
+static void get_bbox(pointObj *poiList, int numpoints, double *minx, double *miny, double *maxx, double *maxy) {
+ int j;
+
+ *minx = *maxx = poiList[0].x;
+ *miny = *maxy = poiList[0].y;
+ for(j=1; j<numpoints; j++) {
+ if ((poiList[j].x==-99.0) || (poiList[j].y==-99.0)) continue;
+ *minx = MS_MIN(*minx, poiList[j].x);
+ *maxx = MS_MAX(*maxx, poiList[j].x);
+ *miny = MS_MIN(*miny, poiList[j].y);
+ *maxy = MS_MAX(*maxy, poiList[j].y);
+ }
+
+ return;
+}
+
+symbolObj* rotateVectorSymbolPoints(symbolObj *symbol, double angle_rad) {
+ double dp_x, dp_y, xcor, ycor;
+ double sin_a, cos_a;
+ double minx,miny,maxx,maxy;
+ symbolObj *newSymbol;
+ double TOL=0.00000000001;
+ int i;
+
+ angle_rad = -angle_rad;
+
+ newSymbol = (symbolObj *) malloc(sizeof(symbolObj));
+ msCopySymbol(newSymbol, symbol, NULL);
+
+ sin_a = sin(angle_rad);
+ cos_a = cos(angle_rad);
+
+ dp_x = symbol->sizex * .5; /* get the shift vector at 0,0 */
+ dp_y = symbol->sizey * .5;
+
+ /* center at 0,0 and rotate; then move back */
+ for( i=0;i < symbol->numpoints;i++) {
+ /* don't rotate PENUP commands (TODO: should use a constant here) */
+ if ((symbol->points[i].x == -99.0) && (symbol->points[i].x == -99.0) ) {
+ newSymbol->points[i].x = -99.0;
+ newSymbol->points[i].y = -99.0;
+ continue;
+ }
+
+ newSymbol->points[i].x = dp_x + ((symbol->points[i].x-dp_x)*cos_a - (symbol->points[i].y-dp_y)*sin_a);
+ newSymbol->points[i].y = dp_y + ((symbol->points[i].x-dp_x)*sin_a + (symbol->points[i].y-dp_y)*cos_a);
+ }
+
+ /* get the new bbox of the symbol, because we need it to get the new dimensions of the new symbol */
+ get_bbox(newSymbol->points, newSymbol->numpoints, &minx, &miny, &maxx, &maxy);
+ if ( (fabs(minx)>TOL) || (fabs(miny)>TOL) ) {
+ xcor = minx*-1.0; /* symbols always start at 0,0 so get the shift vector */
+ ycor = miny*-1.0;
+ for( i=0;i < newSymbol->numpoints;i++) {
+ if ((newSymbol->points[i].x == -99.0) && (newSymbol->points[i].x == -99.0))
+ continue;
+ newSymbol->points[i].x = newSymbol->points[i].x + xcor;
+ newSymbol->points[i].y = newSymbol->points[i].y + ycor;
+ }
+
+ /* update the bbox to get the final dimension values for the symbol */
+ get_bbox(newSymbol->points, newSymbol->numpoints, &minx, &miny, &maxx, &maxy);
+ }
+ newSymbol->sizex = maxx;
+ newSymbol->sizey = maxy;
+ return newSymbol;
+}
+
int renderVectorSymbolGD(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style) {
- return MS_SUCCESS;
+ 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;
+
+
+ if(style->color.pen == MS_PEN_UNSET) setPen(ip, &(style->color));
+ if(style->outlinecolor.pen == MS_PEN_UNSET) setPen(ip, &(style->outlinecolor));
+ fc =style->color.pen;
+ oc = style->outlinecolor.pen;
+
+ 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 renderTruetypeSymbolGD(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *s) {
More information about the mapserver-commits
mailing list