[mapserver-commits] r9111 - sandbox/aboudreault

svn at osgeo.org svn at osgeo.org
Fri Jun 19 09:58:12 EDT 2009


Author: aboudreault
Date: 2009-06-19 09:58:12 -0400 (Fri, 19 Jun 2009)
New Revision: 9111

Modified:
   sandbox/aboudreault/mapdraw.c
   sandbox/aboudreault/mapprimitive.c
   sandbox/aboudreault/mapserver.h
Log:
Added a few improvements in the labeling enhancements code

Modified: sandbox/aboudreault/mapdraw.c
===================================================================
--- sandbox/aboudreault/mapdraw.c	2009-06-18 16:39:51 UTC (rev 9110)
+++ sandbox/aboudreault/mapdraw.c	2009-06-19 13:58:12 UTC (rev 9111)
@@ -1425,10 +1425,11 @@
   int csz; /* clip over size */
   double buffer;
   int minfeaturesize;
-  int *num, numpaths = 1, numpoints = 1;
+  int numpaths = 1, numpoints = 1, numRegularLines = 0;
 
   labelPathObj **annopaths = NULL; /* Curved label path. Bug #1620 implementation */
   pointObj     **annopoints = NULL;
+  int           *regularLines = NULL;
 
   /* set clipping rectangle just a bit larger than the map extent */
 /* Steve's original code 
@@ -1544,7 +1545,7 @@
         msTransformShape(&annoshape, map->extent, map->cellsize, image);
 
         if(layer->class[c]->label.autofollow == MS_TRUE ) {
-          annopaths = msPolylineLabelPath(image,&annoshape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths);
+          annopaths = msPolylineLabelPath(image,&annoshape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
         } else {
           annopoints = msPolylineLabelPoint(&annoshape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints);
         }
@@ -1560,24 +1561,25 @@
         msOffsetShapeRelativeTo(shape, layer);
 
       
-      /* Determine the label path if it has not been computed above */
-      if ( (layer->class[c]->label.autofollow == MS_TRUE) && (bLabelNoClip == MS_FALSE) ) {
-        if ( annopaths ) {
-          for (j = 0; j<numpaths;j++)
-            if (annopaths[j])
-              msFreeLabelPathObj(annopaths[j]);
-          free(annopaths);
-          annopaths = NULL;
+      if (layer->class[c]->label.autofollow == MS_TRUE) 
+      {
+        /* Determine the label path if it has not been computed above */
+        if (bLabelNoClip == MS_FALSE) {
+          if ( annopaths ) {
+            for (j = 0; j<numpaths;j++)
+              if (annopaths[j])
+                msFreeLabelPathObj(annopaths[j]);
+            free(annopaths);
+            annopaths = NULL;
+          }
+          if ( regularLines ) {
+            free(regularLines);
+            regularLines =  NULL;
+          }
+          annopaths = msPolylineLabelPath(image,shape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
         }
-        annopaths = msPolylineLabelPath(image,shape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths);
-      }
 
-       if (layer->class[c]->label.autofollow == MS_TRUE)
-           num = &numpaths;
-       else
-           num = &numpoints;
-
-        for (i = 0; i < *num; i++)
+        for (i = 0; i < numpaths; i++)
         {
           /* Bug #1620 implementation */
           if(layer->class[c]->label.autofollow == MS_TRUE) {
@@ -1603,84 +1605,109 @@
               }
             }
           }
+        }
+
+        /* handle regular lines that have to be drawn with the regular algorithm */
+        if (numRegularLines > 0)
+        {
+
+          annopoints = msPolylineLabelPointExtended(shape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, regularLines, numRegularLines);
+          
+          for (i = 0; i < numRegularLines; i++)
+            {
+              labelObj label = layer->class[c]->label;
+              
+              if(label.angle != 0)
+                label.angle -= map->gt.rotation_angle;
+              
+              if(label.autoangle) label.angle = *angles[i];
+              
+              if(layer->labelcache) {
+                if(msAddLabel(map, layer->index, c, shape, annopoints[i], NULL, shape->text, *lengths[i], &label) != MS_SUCCESS) return(MS_FAILURE);
+              } else
+                msDrawLabel(map, image, *annopoints[i], shape->text, &label, layer->scalefactor);
+            }
+        }
+
+      } else {
+          /* Regular labels: Only attempt to find the label point if we have not */
+          /* succesfully calculated it previously                                */
+          if ( !(bLabelNoClip == MS_TRUE && annopoints) ) {
+            if ( annopoints ) {
+              for (j = 0; j<numpoints;j++) {
+                if (annopoints[j])
+                  free(annopoints[j]);
+                if (angles[j])
+                  free(angles[j]);
+                if (lengths[j])
+                  free(lengths[j]);
+              }
+              free(lengths);
+              free(angles);
+              free(annopoints);
+              annopoints = NULL;
+              angles = NULL;
+              lengths = NULL;
+            }
+            annopoints = msPolylineLabelPoint(shape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints);
+          }
+          
+          for (i = 0; i < numpoints; i++) {
+              labelObj label = layer->class[c]->label;
+              
+              if(label.angle != 0)
+                label.angle -= map->gt.rotation_angle;
+              
+              /* Angle derived from line overrides even the rotation value. */
+              if(label.autoangle) label.angle = *angles[i];
+              
+              if(layer->labelcache) {
+                if(msAddLabel(map, layer->index, c, shape, annopoints[i], NULL, shape->text, *lengths[i], &label) != MS_SUCCESS) return(MS_FAILURE);
+              } else {
+                if(layer->class[c]->numstyles > 0 && MS_VALID_COLOR(layer->class[c]->styles[0]->color)) {
+                  for(s=0; s<layer->class[c]->numstyles; s++) {
+                    styleObj *curStyle = layer->class[c]->styles[s];
+                    if(map->scaledenom > 0) {
+                      if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
+                        continue;
+                      if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
+                        continue;
+                    }
+                    msDrawMarkerSymbol(&map->symbolset, image,  annopoints[i], curStyle, layer->scalefactor);
+                  }
+                }
+                msDrawLabel(map, image, *annopoints[i], shape->text, &label, layer->scalefactor);
+              }
+            }
+      }
       
-           /* Use regular label algorithm if angle is AUTO or a number, or if ANGLE FOLLOW failed */
-           if ( layer->class[c]->label.autofollow == MS_FALSE || (!annopaths[i]) ) {
-  
-             /* Regular labels: Only attempt to find the label point if we have not */
-             /* succesfully calculated it previously                                */
-             if ( !(bLabelNoClip == MS_TRUE && annopoints) ) {
-               if ( annopoints ) {
-                 for (j = 0; j<numpoints;j++) {
-                   if (annopoints[j])
-                     free(annopoints[j]);
-                   if (angles[j])
-                     free(angles[j]);
-                   if (lengths[j])
-                     free(lengths[j]);
-                 }
-                 free(lengths);
-                 free(angles);
-                 free(annopoints);
-                 annopoints = NULL;
-                 angles = NULL;
-                 lengths = NULL;
-               }
-               annopoints = msPolylineLabelPoint(shape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints);
-             }
-               
-               if (i < numpoints && annopoints[i]) {
-                 labelObj label = layer->class[c]->label;
-                 
-                 if(label.angle != 0)
-                   label.angle -= map->gt.rotation_angle;
-                   
-                 /* Angle derived from line overrides even the rotation value. */
-                 if(label.autoangle) label.angle = *angles[i];
-                 
-                 if(layer->labelcache) {
-                   if(msAddLabel(map, layer->index, c, shape, annopoints[i], NULL, shape->text, *lengths[i], &label) != MS_SUCCESS) return(MS_FAILURE);
-                 } else {
-                   if(layer->class[c]->numstyles > 0 && MS_VALID_COLOR(layer->class[c]->styles[0]->color)) {
-                     for(s=0; s<layer->class[c]->numstyles; s++) {
-                       styleObj *curStyle = layer->class[c]->styles[s];
-                       if(map->scaledenom > 0) {
-                         if((curStyle->maxscaledenom != -1) && (map->scaledenom >= curStyle->maxscaledenom))
-                           continue;
-                         if((curStyle->minscaledenom != -1) && (map->scaledenom < curStyle->minscaledenom))
-                           continue;
-                       }
-                       msDrawMarkerSymbol(&map->symbolset, image,  annopoints[i], curStyle, layer->scalefactor);
-                     }
-                   }
-                   msDrawLabel(map, image, *annopoints[i], shape->text, &label, layer->scalefactor);
-                 }
-               }
-           }
+      if ( annopaths ) {
+        free(annopaths);
+        annopaths = NULL;
+      }
+      
+      if ( regularLines ) {
+        free(regularLines);
+        regularLines =  NULL;
+      }
+      
+      if ( annopoints ) {
+        for (j = 0; j<numpoints;j++) {
+          if (annopoints[j])
+            free(annopoints[j]);
+          if (angles[j])
+            free(angles[j]);
+          if (lengths[j])
+            free(lengths[j]);
         }
+        free(angles);
+        free(annopoints);
+        free(lengths);
+        annopoints = NULL;
+        angles = NULL;
+        lengths = NULL;
+      }
   
-         if ( annopaths ) {
-           free(annopaths);
-           annopaths = NULL;
-         }
-
-         if ( annopoints ) {
-           for (j = 0; j<numpoints;j++) {
-             if (annopoints[j])
-               free(annopoints[j]);
-             if (angles[j])
-               free(angles[j]);
-             if (lengths[j])
-               free(lengths[j]);
-           }
-           free(angles);
-           free(annopoints);
-           free(lengths);
-           annopoints = NULL;
-           angles = NULL;
-           lengths = NULL;
-         }
-  
       break;
     case(MS_SHAPE_POLYGON):
       /* No-clip labeling support */
@@ -1843,7 +1870,7 @@
       msTransformShape(&annoshape, map->extent, map->cellsize, image);
 
       if(layer->class[c]->label.autofollow == MS_TRUE) {
-        annopaths = msPolylineLabelPath(image,&annoshape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths);
+        annopaths = msPolylineLabelPath(image,&annoshape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
       } else {
         annopoints = msPolylineLabelPoint(&annoshape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints);
       }
@@ -1901,32 +1928,32 @@
     
     if(shape->text) {
 
-      /* Determine the label path if it has not been computed above */
-      if ( (layer->class[c]->label.autofollow == MS_TRUE) && (bLabelNoClip == MS_FALSE) ) {
-        if ( annopaths ) {
-          for (j = 0; j<numpaths;j++)
-            if (annopaths[j])
-              msFreeLabelPathObj(annopaths[j]);
-          free(annopaths);
-          annopaths = NULL;
+      if (layer->class[c]->label.autofollow == MS_TRUE) 
+      {
+        /* Determine the label path if it has not been computed above */
+        if (bLabelNoClip == MS_FALSE) {
+          if ( annopaths ) {
+            for (j = 0; j<numpaths;j++)
+              if (annopaths[j])
+                msFreeLabelPathObj(annopaths[j]);
+            free(annopaths);
+            annopaths = NULL;
+          }
+          if ( regularLines ) {
+            free(regularLines);
+            regularLines =  NULL;
+          }
+          annopaths = msPolylineLabelPath(image,shape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, &regularLines, &numRegularLines);
         }
-        annopaths = msPolylineLabelPath(image,shape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths);
-      }
 
-      if (layer->class[c]->label.autofollow == MS_TRUE)
-          num = &numpaths;
-      else
-          num = &numpoints;
-
-      for (i = 0; i < *num; i++)
-      {
-        /* Bug #1620 implementation */
-        if(layer->class[c]->label.autofollow == MS_TRUE) {
-          layer->class[c]->label.position = MS_CC; /* Force all label positions to MS_CC regardless if a path is computed */
-
-          if( annopaths[i] ) {
+        for (i = 0; i < numpaths; i++)
+        {
+          /* Bug #1620 implementation */
+          if(layer->class[c]->label.autofollow == MS_TRUE) {
+            layer->class[c]->label.position = MS_CC; /* Force all label positions to MS_CC regardless if a path is computed */
+            
             labelObj label = layer->class[c]->label;
-          
+            
             if(layer->labelcache) {
               if(msAddLabel(map, layer->index, c, shape, NULL, annopaths[i], shape->text, 0.0, &label) != MS_SUCCESS) return(MS_FAILURE);
             } else {
@@ -1937,44 +1964,61 @@
             }
           }
         }
-      
-         /* Use regular label algorithm if angle is AUTO or a number, or if ANGLE FOLLOW failed */
-        if ( layer->class[c]->label.autofollow == MS_FALSE || (!annopaths[i]) ) {
-  
-          if ( !(bLabelNoClip == MS_TRUE && annopoints) ) {
-            if ( annopoints ) {
-              for (j = 0; j<numpoints;j++) {
-                if (annopoints[j])
-                  free(annopoints[j]);
-                if (angles[j])
-                  free(angles[j]);
-                if (lengths[j])
-                  free(lengths[j]);
-              }
-              free(lengths);
-              free(angles);
-              free(annopoints);
-              annopoints = NULL;
-              angles = NULL;
-              lengths = NULL;
-            }
-            annopoints = msPolylineLabelPoint(shape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints);
-          }
+        /* handle regular lines that have to be drawn with the regular algorithm */
+        if (numRegularLines > 0)
+        {
 
-          if (i < numpoints && annopoints[i]) {
+          annopoints = msPolylineLabelPointExtended(shape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints, regularLines, numRegularLines);
+          
+          for (i = 0; i < numRegularLines; i++)
+          {
             labelObj label = layer->class[c]->label;
-             
+            
             if(label.angle != 0)
               label.angle -= map->gt.rotation_angle;
-             
+            
             if(label.autoangle) label.angle = *angles[i];
-             
+            
             if(layer->labelcache) {
               if(msAddLabel(map, layer->index, c, shape, annopoints[i], NULL, shape->text, *lengths[i], &label) != MS_SUCCESS) return(MS_FAILURE);
             } else
               msDrawLabel(map, image, *annopoints[i], shape->text, &label, layer->scalefactor);
           }
         }
+      } else {
+        if ( !(bLabelNoClip == MS_TRUE && annopoints) ) {
+          if ( annopoints ) {
+            for (j = 0; j<numpoints;j++) {
+              if (annopoints[j])
+                free(annopoints[j]);
+              if (angles[j])
+                free(angles[j]);
+              if (lengths[j])
+                free(lengths[j]);
+            }
+            free(lengths);
+            free(angles);
+            free(annopoints);
+            annopoints = NULL;
+            angles = NULL;
+            lengths = NULL;
+          }
+          annopoints = msPolylineLabelPoint(shape, minfeaturesize, (layer->class[c]->label).repeatdistance, &angles, &lengths, &numpoints);
+        }
+
+        for (i = 0; i < numpoints; i++) {
+          labelObj label = layer->class[c]->label;
+          
+          if(label.angle != 0)
+            label.angle -= map->gt.rotation_angle;
+          
+          if(label.autoangle) label.angle = *angles[i];
+          
+          if(layer->labelcache) {
+            if(msAddLabel(map, layer->index, c, shape, annopoints[i], NULL, shape->text, *lengths[i], &label) != MS_SUCCESS) return(MS_FAILURE);
+          } else
+            msDrawLabel(map, image, *annopoints[i], shape->text, &label, layer->scalefactor);
+        }
       }
     }
 
@@ -1983,6 +2027,11 @@
       annopaths = NULL;
     }
 
+    if ( regularLines ) {
+      free(regularLines);
+      regularLines =  NULL;
+    }
+    
     if ( annopoints ) {
       for (j = 0; j<numpoints;j++) {
         if (annopoints[j])

Modified: sandbox/aboudreault/mapprimitive.c
===================================================================
--- sandbox/aboudreault/mapprimitive.c	2009-06-18 16:39:51 UTC (rev 9110)
+++ sandbox/aboudreault/mapprimitive.c	2009-06-19 13:58:12 UTC (rev 9111)
@@ -1298,16 +1298,65 @@
     return(MS_FAILURE);
 }
 
+/* Compute all the lineString/segment lengths and determine the longest lineString of a multiLineString  
+ * shape: in paramater, the multiLineString to compute.
+ * segment_lengths: out parameter, the segment lengths of all lineString.
+ * line_lengths: out parameter, the lineString lengths of the multiLineString.
+ * max_line_index: out parameter, the index of the longest lineString of the multiLineString.
+ * max_line_length: out parameter, the length of the longest lineString of the multiLineString.
+ * total_length: out parameter, the total length of the MultiLineString
+*/
+void msPolylineComputeLineSegments(shapeObj *shape, double ***segment_lengths, double **line_lengths, int *max_line_index, double *max_line_length, double *total_length)
+{
+  int i, j, segment_index, temp_segment_index;
+  double segment_length, max_segment_length;
 
+  (*segment_lengths) = (double **) malloc(sizeof(double *) * shape->numlines);
+  (*line_lengths) = (double *) malloc(sizeof(double) * shape->numlines);
+
+  temp_segment_index = segment_index = *max_line_index = 0;
+
+  *total_length = 0;
+  *max_line_length = 0;
+  for(i=0; i<shape->numlines; i++) {
+    
+    (*segment_lengths)[i] = (double*) malloc(sizeof(double) * shape->line[i].numpoints);    
+    
+    (*line_lengths)[i] = 0;
+    max_segment_length = 0;
+    for(j=1;j<shape->line[i].numpoints;j++) {
+      segment_length = sqrt((pow((shape->line[i].point[j].x-shape->line[i].point[j-1].x),2.0) + pow((shape->line[i].point[j].y-shape->line[i].point[j-1].y),2.0)));
+      (*line_lengths)[i] += segment_length;
+      (*segment_lengths)[i][j-1] = segment_length;
+      if(segment_length > max_segment_length) {
+        max_segment_length = segment_length;
+        temp_segment_index = j;
+      }
+    }
+
+    *total_length += (*line_lengths)[i];
+
+    if((*line_lengths)[i] > *max_line_length) {
+      *max_line_length = (*line_lengths)[i];
+      *max_line_index = i;
+      segment_index = temp_segment_index;
+    }
+  }
+}
+
 /*
 ** If no repeatdistance, find center of longest segment in polyline p. The polyline must have been converted
 ** to image coordinates before calling this function.
 */
 pointObj** msPolylineLabelPoint(shapeObj *p, int min_length, int repeat_distance, double ***angles, double ***lengths, int *numpoints)
 {
-  double segment_length, total_length, max_segment_length, max_line_length;
-  int segment_index, line_index, temp_segment_index;
-  int i, j, labelpoints_index, labelpoints_size;
+  return msPolylineLabelPointExtended(p, min_length, repeat_distance, angles, lengths, numpoints, NULL, 0);
+}
+
+pointObj** msPolylineLabelPointExtended(shapeObj *p, int min_length, int repeat_distance, double ***angles, double ***lengths, int *numpoints, int *regularLines, int numlines)
+{
+  double total_length, max_line_length;
+  int i,j, max_line_index, labelpoints_index, labelpoints_size;
   double** segment_lengths;
   double* line_lengths;
   pointObj** labelpoints;
@@ -1319,47 +1368,27 @@
   labelpoints = (pointObj **) malloc(sizeof(pointObj *) * labelpoints_size);
   (*angles) = (double **) malloc(sizeof(double *) * labelpoints_size);
   (*lengths) = (double **) malloc(sizeof(double *) * labelpoints_size);
-  segment_lengths = (double **) malloc(sizeof(double *) * p->numlines);
-  line_lengths = (double *) malloc(sizeof(double) * p->numlines);
 
-  temp_segment_index = segment_index = line_index = 0;
+  msPolylineComputeLineSegments(p, &segment_lengths, &line_lengths, &max_line_index, &max_line_length, &total_length);
 
-  total_length = 0;
-  max_line_length = 0;
-  for(i=0; i<p->numlines; i++) {
-
-    segment_lengths[i] = (double*) malloc(sizeof(double) * p->line[i].numpoints);    
-    
-    line_lengths[i] = 0;
-    max_segment_length = 0;
-    for(j=1;j<p->line[i].numpoints;j++) {
-      segment_length = sqrt((pow((p->line[i].point[j].x-p->line[i].point[j-1].x),2.0) + pow((p->line[i].point[j].y-p->line[i].point[j-1].y),2.0)));
-      line_lengths[i] += segment_length;
-      segment_lengths[i][j-1] = segment_length;
-      if(segment_length > max_segment_length) {
-        max_segment_length = segment_length;
-        temp_segment_index = j;
+  if (repeat_distance > 0) {
+    for(i=0; i<p->numlines; i++)
+      if (numlines > 0) {
+        for (j=0; j<numlines; j++)
+          if (regularLines[j] == i) {
+            msPolylineLabelPointLineString(p, min_length, repeat_distance, angles, lengths, segment_lengths, i, line_lengths[i], total_length, &labelpoints_index, &labelpoints_size, &labelpoints);
+            break;
+          }
+      } else {
+        msPolylineLabelPointLineString(p, min_length, repeat_distance, angles, lengths, segment_lengths, i, line_lengths[i], total_length, &labelpoints_index, &labelpoints_size, &labelpoints);
       }
-    }
-
-    total_length += line_lengths[i];
-
-    if(line_lengths[i] > max_line_length) {
-      max_line_length = line_lengths[i];
-      line_index = i;
-      segment_index = temp_segment_index;
-    }
   }
-
-  if (repeat_distance > 0)
-    for(i=0; i<p->numlines; i++)
-      msPolylineLabelPointLine(p, min_length, repeat_distance, angles, lengths, segment_lengths, i, line_lengths[i], total_length, &labelpoints_index, &labelpoints_size, &labelpoints );
   else
-    msPolylineLabelPointLine(p, min_length, repeat_distance, angles, lengths, segment_lengths, line_index, max_line_length, total_length, &labelpoints_index, &labelpoints_size, &labelpoints );
+    msPolylineLabelPointLineString(p, min_length, repeat_distance, angles, lengths, segment_lengths, max_line_index, max_line_length, total_length, &labelpoints_index, &labelpoints_size, &labelpoints);
 
   *numpoints = labelpoints_index;
 
-  /* freeing memory */
+  /* freeing memory: allocated by msPolylineComputeLineSegments */
   if ( segment_lengths ) {
     for ( i = 0; i < p->numlines; i++ )
       free(segment_lengths[i]);
@@ -1371,8 +1400,8 @@
   return labelpoints;
 }
 
-void msPolylineLabelPointLine(shapeObj *p, int min_length, int repeat_distance, double ***angles, double ***lengths, double** segment_lengths,
-                               int line_index, double line_length, double total_length, int* labelpoints_index, int* labelpoints_size, pointObj ***labelpoints)
+void msPolylineLabelPointLineString(shapeObj *p, int min_length, int repeat_distance, double ***angles, double ***lengths, double** segment_lengths,
+                                    int line_index, double line_length, double total_length, int* labelpoints_index, int* labelpoints_size, pointObj ***labelpoints)
 {
   int i, j, k, l, index, point_repeat, point_distance;
   double t, tmp_length, theta, point_start_position, fwd_length;
@@ -1384,17 +1413,16 @@
   if((min_length != -1) && (tmp_length < min_length)) /* too short to label */
     return;
 
-  /* ok, now we know which line and which segment within that line */
   i = line_index;
   point_distance = 0;
 
   if (repeat_distance > 0) {
-    point_repeat = line_length / repeat_distance;
+    point_repeat = line_length / (repeat_distance);
     point_distance = (line_length / point_repeat); // buffer allowed per point
   }
 
   if (repeat_distance > 0 && point_repeat > 1) {
-    point_start_position = (point_distance / 2);
+    point_start_position = (point_distance / 2); 
   }
   else
   {
@@ -1457,55 +1485,37 @@
 }
 
 /* Calculate the labelpath for each line if repeatdistance is enabled, else the labelpath of the longest line segment */
-labelPathObj** msPolylineLabelPath(imageObj *img,shapeObj *p, int min_length, fontSetObj *fontset, char *string, labelObj *label, double scalefactor, int *numpaths)
+labelPathObj** msPolylineLabelPath(imageObj *img,shapeObj *p, int min_length, fontSetObj *fontset, char *string, labelObj *label, double scalefactor, int *numpaths,
+                                   int** regular_lines, int* num_regular_lines)
 {
-  double line_length, segment_length, max_line_length, total_length;
+  double max_line_length, total_length;
   double **segment_lengths, *line_lengths;
-  int i, j, segment_index, max_line_index, labelpaths_index, labelpaths_size;
+  int i, segment_index, max_line_index, labelpaths_index, labelpaths_size, regular_lines_index, regular_lines_size;
   labelPathObj** labelpaths;
 
   labelpaths_index = 0;
   labelpaths_size = p->numlines; // minimal array size
+  regular_lines_index = 0;
+  regular_lines_size = 1;
   *numpaths = 0;
   segment_index = max_line_index = 0;
   total_length = max_line_length = 0.0;
 
   labelpaths = (labelPathObj **) malloc(sizeof(labelPathObj *) * labelpaths_size);
+  (*regular_lines) = (int *) malloc(sizeof(int) * regular_lines_size);
 
-  /* determine longest line segment */
-  segment_lengths = (double **) malloc(sizeof(double *) * p->numlines);
-  line_lengths = (double *) malloc(sizeof(double) * p->numlines);
-
-  for(i=0; i<p->numlines; i++) {
-    
-    segment_lengths[i] = (double*) malloc(sizeof(double) * p->line[i].numpoints);    
-    line_length = 0;
-    
-    for (j=1; j<p->line[i].numpoints; j++) {
-      segment_length = sqrt( pow((p->line[i].point[j].x - p->line[i].point[j-1].x), 2.0) +
-                             pow((p->line[i].point[j].y - p->line[i].point[j-1].y), 2.0) );
-      line_length += segment_length;
-      segment_lengths[i][j-1] = segment_length;      
-    }
-
-    total_length += line_length;
-    line_lengths[i] = line_length;
-    if(line_length > max_line_length) {
-      max_line_index = i;
-      max_line_length = line_length;
-    } 
-  }
+  msPolylineComputeLineSegments(p, &segment_lengths, &line_lengths, &max_line_index, &max_line_length, &total_length);
  
   if (label->repeatdistance > 0)
     for(i=0; i<p->numlines; i++) {
-      msPolylineLabelPathLine(img, p,min_length, fontset, string, label, scalefactor, i, segment_lengths, line_lengths[i], total_length, 
-                                 &labelpaths_index, &labelpaths_size, &labelpaths);
+      msPolylineLabelPathLineString(img, p,min_length, fontset, string, label, scalefactor, i, segment_lengths, line_lengths[i], total_length, 
+                                    &labelpaths_index, &labelpaths_size, &labelpaths, regular_lines, &regular_lines_index, &regular_lines_size);
     }
   else
-    msPolylineLabelPathLine(img, p,min_length, fontset, string, label, scalefactor, max_line_index, segment_lengths, line_lengths[max_line_index], total_length, 
-                               &labelpaths_index, &labelpaths_size, &labelpaths);
+    msPolylineLabelPathLineString(img, p,min_length, fontset, string, label, scalefactor, max_line_index, segment_lengths, line_lengths[max_line_index], total_length, 
+                                  &labelpaths_index, &labelpaths_size, &labelpaths, regular_lines, &regular_lines_index, &regular_lines_size);
 
-  /* freeing memory */
+  /* freeing memory: allocated by msPolylineComputeLineSegments */
   if ( segment_lengths ) {
     for ( i = 0; i < p->numlines; i++ )
       free(segment_lengths[i]);
@@ -1516,6 +1526,7 @@
 
   /* set the number of paths in the array */
   *numpaths = labelpaths_index;
+  *num_regular_lines = regular_lines_index;
   return labelpaths;
 }
 
@@ -1526,8 +1537,9 @@
  * are allocated in this function.  The polyline must be converted to image 
  * coordinates before calling this function.
  */
-void msPolylineLabelPathLine(imageObj *img, shapeObj *p, int min_length, fontSetObj *fontset, char *string, labelObj *label, double scalefactor, int line_index, 
-                                double** segment_lengths, double line_length, double total_length, int* labelpaths_index, int* labelpaths_size, labelPathObj*** labelpaths)
+void msPolylineLabelPathLineString(imageObj *img, shapeObj *p, int min_length, fontSetObj *fontset, char *string, labelObj *label, double scalefactor, int line_index, 
+                                   double** segment_lengths, double line_length, double total_length, int* labelpaths_index, int* labelpaths_size, labelPathObj*** labelpaths, 
+                                   int** regular_lines, int *regular_lines_index, int* regular_lines_size)
 {
   double distance_along_segment;
   double segment_length, fwd_line_length, rev_line_length, text_length, text_start_length, label_buffer, text_end_length;
@@ -1896,14 +1908,14 @@
   goto END; // normal exit
 #endif
 
-  ANGLEFOLLOW_FAILURE: // Angle follow failure: add a null path to use regular algorithm
-  if (*labelpaths_index == *labelpaths_size) {
-      *labelpaths_size *= 2;
-      (*labelpaths) = (labelPathObj **) realloc(*labelpaths,sizeof(labelPathObj *) * (*labelpaths_size));
+  ANGLEFOLLOW_FAILURE: // Angle follow failure: add the line index in the arrays
+  if (*regular_lines_index == *regular_lines_size) {
+      *regular_lines_size *= 2;
+      (*regular_lines) = (int*) realloc(*regular_lines,sizeof(int) * (*regular_lines_size));
   }
-  (*labelpaths)[(*labelpaths_index)++] = NULL;
+  (*regular_lines)[(*regular_lines_index)++] = line_index;
 
-  FAILURE: // Global failure... do not add a NULL PATH.    
+  FAILURE: // Global failure   
 
   END:
     if ( offsets )

Modified: sandbox/aboudreault/mapserver.h
===================================================================
--- sandbox/aboudreault/mapserver.h	2009-06-18 16:39:51 UTC (rev 9110)
+++ sandbox/aboudreault/mapserver.h	2009-06-19 13:58:12 UTC (rev 9111)
@@ -1797,14 +1797,16 @@
 MS_DLL_EXPORT void msTransformShapeToPixel(shapeObj *shape, rectObj extent, double cellsize);
 MS_DLL_EXPORT void msTransformPixelToShape(shapeObj *shape, rectObj extent, double cellsize);
 MS_DLL_EXPORT void msImageCartographicPolyline(gdImagePtr im, shapeObj *p, styleObj *style, symbolObj *symbol, int c, double size, double scalefactor);
+MS_DLL_EXPORT void msPolylineComputeLineSegments(shapeObj *shape, double ***segment_lengths, double **line_lengths, int *max_line_index, double *max_line_length, double *total_length);
 MS_DLL_EXPORT pointObj** msPolylineLabelPoint(shapeObj *p, int min_length, int repeat_distance, double ***angles, double ***lengths, int *numpoints);
-MS_DLL_EXPORT void msPolylineLabelPointLine(shapeObj *p, int min_length, int repeat_distance, double ***angles, double ***lengths, double** segment_lengths, 
-                                            int line_index, double line_length, double total_length,
-                                            int* labelpoints_index, int* labelpoints_size, pointObj ***labelpoints);
-MS_DLL_EXPORT labelPathObj** msPolylineLabelPath(imageObj *img, shapeObj *p, int min_length, fontSetObj *fontset, char *string, labelObj *label, double scalefactor, int *numpaths);
-MS_DLL_EXPORT void msPolylineLabelPathLine(imageObj *img, shapeObj *p, int min_length, fontSetObj *fontset, char *string, labelObj *label, double scalefactor,
-                                              int line_index, double** segment_lengths, double line_length, double total_length, 
-                                              int* labelpaths_index, int* labelpaths_size, labelPathObj ***labelpaths);
+MS_DLL_EXPORT pointObj** msPolylineLabelPointExtended(shapeObj *p, int min_length, int repeat_distance, double ***angles, double ***lengths, int *numpoints, int *regularLines, int numlines);
+MS_DLL_EXPORT void msPolylineLabelPointLineString(shapeObj *p, int min_length, int repeat_distance, double ***angles, double ***lengths, double** segment_lengths, 
+                                                  int line_index, double line_length, double total_length,
+                                                  int* labelpoints_index, int* labelpoints_size, pointObj ***labelpoints);
+MS_DLL_EXPORT labelPathObj** msPolylineLabelPath(imageObj *img, shapeObj *p, int min_length, fontSetObj *fontset, char *string, labelObj *label, double scalefactor, int *numpaths, int** regular_lines, int* num_regular_Lines);
+MS_DLL_EXPORT void msPolylineLabelPathLineString(imageObj *img, shapeObj *p, int min_length, fontSetObj *fontset, char *string, labelObj *label, double scalefactor,
+                                                 int line_index, double** segment_lengths, double line_length, double total_length, 
+                                                 int* labelpaths_index, int* labelpaths_size, labelPathObj ***labelpaths, int** regular_lines, int *regular_lines_index, int* regular_lines_size);
 MS_DLL_EXPORT int msPolygonLabelPoint(shapeObj *p, pointObj *lp, double min_dimension);
 MS_DLL_EXPORT int msAddLine(shapeObj *p, lineObj *new_line);
 MS_DLL_EXPORT int msAddLineDirectly(shapeObj *p, lineObj *new_line);



More information about the mapserver-commits mailing list