[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, ®ularLines, &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, ®ularLines, &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, ®ularLines, &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, ®ularLines, &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, ®ular_lines_index, ®ular_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, ®ular_lines_index, ®ular_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