[mapserver-commits] r8995 - sandbox/graphics

svn at osgeo.org svn at osgeo.org
Sat May 2 05:57:05 EDT 2009


Author: tbonfort
Date: 2009-05-02 05:57:05 -0400 (Sat, 02 May 2009)
New Revision: 8995

Modified:
   sandbox/graphics/maprendering.c
Log:
modify line symbols to be displayed at the middle of the linestring if the 
linestring was too short for the asked gap.


Modified: sandbox/graphics/maprendering.c
===================================================================
--- sandbox/graphics/maprendering.c	2009-05-01 22:07:31 UTC (rev 8994)
+++ sandbox/graphics/maprendering.c	2009-05-02 09:57:05 UTC (rev 8995)
@@ -242,16 +242,26 @@
     int i,j;
     pointObj point;
     double original_rotation = style->rotation;
-    double symbol_width = MS_MAX(1,symbol->sizex*style->scale);
+    double symbol_width;
+    if(symbol->type != MS_SYMBOL_TRUETYPE)
+        symbol_width = MS_MAX(1,symbol->sizex*style->scale);
+    else {
+        rectObj rect;
+        r->getTruetypeTextBBox(image,symbol->full_font_path,style->scale,
+                symbol->character,&rect,NULL);
+        symbol_width=rect.maxx-rect.minx;
+    }
     for(i=0; i<p->numlines; i++)
     {
-        int in;
-        double length;
-        double current_length = 1+symbol_width/2.0; // initial padding for each line
+        int line_in = 0;
+        double current_length = (spacing+symbol_width)/2.0; // initial padding for each line
+        double line_length=0;
         for(j=1;j<p->line[i].numpoints;j++)
         {
-            double rx,ry,theta;
+            double rx,ry,theta,length;
+            int in;
             length = sqrt((pow((p->line[i].point[j].x - p->line[i].point[j-1].x),2) + pow((p->line[i].point[j].y - p->line[i].point[j-1].y),2)));
+            line_length += length;
             if(length==0)continue;
             rx = (p->line[i].point[j].x - p->line[i].point[j-1].x)/length;
             ry = (p->line[i].point[j].y - p->line[i].point[j-1].y)/length;
@@ -284,6 +294,7 @@
                 }
                 current_length += symbol_width + spacing;
                 in = 1;
+                line_in=1;
             }
 
             if (in)
@@ -292,7 +303,63 @@
             }
             else current_length -= length;
         }
+        
+        /* if we couldn't place a symbol on the line, add one now
+        we don't add the symbol if the line is shorter than the
+        length of the symbol itself */
+        if(!line_in && line_length>symbol_width) {
+            
+            /* total lengths of beginnning and end of current segment */
+            double before_length=0,after_length=0;
+            
+            /*optimize*/
+            line_length /= 2.0;
 
+            for(j=1;j<p->line[i].numpoints;j++)
+            {
+                double length;
+                length = sqrt((pow((p->line[i].point[j].x - p->line[i].point[j-1].x),2) + pow((p->line[i].point[j].y - p->line[i].point[j-1].y),2)));
+                after_length += length;
+                if(after_length>line_length) {
+                    double rx,ry,theta;
+                    /* offset where the symbol should be drawn on the current
+                     * segment */
+                    double offset = line_length - before_length;
+
+                    rx = (p->line[i].point[j].x - p->line[i].point[j-1].x)/length;
+                    ry = (p->line[i].point[j].y - p->line[i].point[j-1].y)/length;
+                    if (auto_angle) {
+                        theta = asin(ry);
+                        if(rx < 0) {
+                            theta += MS_PI;
+                        }
+                        else theta = -theta;
+                        style->rotation = original_rotation + theta;
+                    }
+
+                    MS_INIT_COLOR(style->color,255,0,0);
+                    point.x = p->line[i].point[j - 1].x + offset * rx;
+                    point.y = p->line[i].point[j - 1].y + offset * ry;
+                    switch (symbol->type) {
+                        case MS_SYMBOL_PIXMAP:
+                            r->renderPixmapSymbol(image, point.x, point.y, symbol, style);
+                            break;
+                        case MS_SYMBOL_ELLIPSE:
+                            r->renderEllipseSymbol(image, point.x, point.y, symbol, style);
+                            break;
+                        case MS_SYMBOL_VECTOR:
+                            r->renderVectorSymbol(image, point.x, point.y, symbol, style);
+                            break;
+                        case MS_SYMBOL_TRUETYPE:
+                            r->renderTruetypeSymbol(image, point.x, point.y, symbol, style);
+                            break;
+                    }
+                    break;
+                }
+                before_length += length;
+            }
+        }
+
     }
 }
 



More information about the mapserver-commits mailing list