[mapserver-commits] r13230 - trunk/mapserver
svn at osgeo.org
svn at osgeo.org
Sat Mar 10 12:59:45 EST 2012
Author: tbonfort
Date: 2012-03-10 09:59:44 -0800 (Sat, 10 Mar 2012)
New Revision: 13230
Modified:
trunk/mapserver/mapdraw.c
trunk/mapserver/maplabel.c
trunk/mapserver/mapserver.h
Log:
remove unused labelCacheMemberObj fields
rework msDrawShape() to call msClipXXXRect before calling msTransformShape
Modified: trunk/mapserver/mapdraw.c
===================================================================
--- trunk/mapserver/mapdraw.c 2012-03-10 14:54:42 UTC (rev 13229)
+++ trunk/mapserver/mapdraw.c 2012-03-10 17:59:44 UTC (rev 13230)
@@ -1559,7 +1559,6 @@
}
int annotationLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj *shape) {
- int bClipShape;
int c = shape->classindex;
rectObj cliprect;
labelObj *label;
@@ -1582,32 +1581,8 @@
cliprect.maxx = image->width;
cliprect.maxy = image->height;
-#ifdef USE_PROJ
- if (layer->transform == MS_TRUE && layer->project && msProjectionsDiffer(&(layer->projection), &(map->projection)))
- msProjectShape(&layer->projection, &map->projection, shape);
- else
- layer->project = MS_FALSE;
-#endif
- bClipShape = MS_FALSE;
- /* check if we need to clip the shape */
- if(!msLayerGetProcessingKey(layer, "LABEL_NO_CLIP") &&
- (
- shape->bounds.minx < map->extent.minx ||
- shape->bounds.miny < map->extent.miny ||
- shape->bounds.maxx > map->extent.maxx ||
- shape->bounds.maxy > map->extent.maxy
- )) {
- bClipShape = MS_TRUE;
- }
-
- if (layer->transform == MS_TRUE) {
- msTransformShape(shape, map->extent, map->cellsize, image);
- } else {
- msOffsetShapeRelativeTo(shape, layer);
- }
- msComputeBounds(shape);
-
+
/* annotation layers can only have one layer, don't treat the multi layer case */
label = layer->class[c]->labels[0]; /* for brevity */
minfeaturesize = label->minfeaturesize * image->resolutionfactor;
@@ -1616,12 +1591,6 @@
switch (shape->type) {
case(MS_SHAPE_LINE):
- if(bClipShape) {
- msClipPolylineRect(shape, cliprect);
- if (shape->numlines == 0) return (MS_SUCCESS);
- }
-
-
if (label->anglemode == MS_FOLLOW) { /* bug #1620 implementation */
#ifndef NDEBUG
/* this test should already occur at the parser level in loadLabel() */
@@ -1702,12 +1671,6 @@
return ret;
case(MS_SHAPE_POLYGON):
- if(bClipShape) {
- msClipPolygonRect(shape, cliprect);
- if (shape->numlines == 0) return (MS_SUCCESS);
- }
- msComputeBounds(shape);
-
if (msPolygonLabelPoint(shape, &annopnt, minfeaturesize) == MS_SUCCESS) {
if(annopnt.x>0 && annopnt.y >0 && annopnt.x <= image->width && annopnt.y<=image->height) {
if (label->angle != 0)
@@ -1755,13 +1718,14 @@
int pointLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj *shape) {
int l, c = shape->classindex, j, i, s;
pointObj *point;
+
#ifdef USE_PROJ
- if (layer->transform == MS_TRUE && layer->project && msProjectionsDiffer(&(layer->projection), &(map->projection)))
+ if (layer->project && layer->transform == MS_TRUE && msProjectionsDiffer(&(layer->projection), &(map->projection)))
msProjectShape(&layer->projection, &map->projection, shape);
else
layer->project = MS_FALSE;
#endif
-
+
for (l = 0; l < layer->class[c]->numlabels; l++)
if (layer->class[c]->labels[l]->angle != 0) layer->class[c]->labels[l]->angle -= map->gt.rotation_angle; /* TODO: is this right???? */
@@ -1790,7 +1754,8 @@
return MS_SUCCESS;
}
-int lineLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj *shape, int style) {
+int lineLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj *shape,
+ shapeObj *anno_shape, shapeObj *unclipped_shape, int style) {
int c = shape->classindex;
double minfeaturesize;
labelPathObj **annopaths = NULL; /* Curved label path. Bug #1620 implementation */
@@ -1799,105 +1764,7 @@
double** angles = NULL, **lengths = NULL;
int ret = MS_SUCCESS;
int numpaths = 1, numpoints = 1, numRegularLines = 0, i, j, s, l = 0;
- int bClipShape = MS_FALSE, bNeedUnclippedShape = MS_FALSE, bHasGeomTransform = MS_FALSE;
- shapeObj *unclipped_shape = NULL;
- if (shape->type != MS_SHAPE_POLYGON && shape->type != MS_SHAPE_LINE) {
- msSetError(MS_MISCERR, "Only polygon or line shapes can be drawn using a line layer definition.", "msDrawShape()");
- return (MS_FAILURE);
- }
-
-#ifdef USE_PROJ
- if (layer->transform == MS_TRUE && layer->project && msProjectionsDiffer(&(layer->projection), &(map->projection)))
- msProjectShape(&layer->projection, &map->projection, shape);
- else
- layer->project = MS_FALSE;
-#endif
-
-
- for (s = 0; s < layer->class[c]->numstyles; s++) {
- if (layer->class[c]->styles[s]->_geomtransform.type != MS_GEOMTRANSFORM_NONE) {
- bHasGeomTransform = MS_TRUE;
- break;
- }
- }
- /* check if we need to clip the shape */
- if (shape->bounds.minx < map->extent.minx ||
- shape->bounds.miny < map->extent.miny ||
- shape->bounds.maxx > map->extent.maxx ||
- shape->bounds.maxy > map->extent.maxy) {
- bClipShape = MS_TRUE;
- }
-
- if (bClipShape &&
- (
- bHasGeomTransform ||
- (layer->class[c]->numlabels>0 && msLayerGetProcessingKey(layer, "LABEL_NO_CLIP"))
- )) {
- bNeedUnclippedShape = MS_TRUE;
- }
-
- if (layer->transform == MS_TRUE) {
- msTransformShape(shape, map->extent, map->cellsize, image);
- } else {
- msOffsetShapeRelativeTo(shape, layer);
- }
- msComputeBounds(shape);
-
-
- if (bNeedUnclippedShape) {
- unclipped_shape = (shapeObj *) msSmallMalloc(sizeof (shapeObj));
- msInitShape(unclipped_shape);
- msCopyShape(shape, unclipped_shape);
- } else {
- unclipped_shape = shape;
- }
-
- if (bClipShape) {
- rectObj cliprect;
- /* adjust the clipping rectangle so that clipped polygon shapes with thick lines
- * do not enter the image */
- int clip_buf;
- if (layer->class[c]->numstyles > 0 && layer->class[c]->styles[0] != NULL) {
- double maxsize, maxunscaledsize;
- symbolObj *symbol;
- styleObj *style = layer->class[c]->styles[0];
- if (!MS_IS_VALID_ARRAY_INDEX(style->symbol, map->symbolset.numsymbols)) {
- msSetError(MS_SYMERR, "Invalid symbol index: %d", "msDrawShape()", style->symbol);
- return MS_FAILURE;
- }
- symbol = map->symbolset.symbol[style->symbol];
- if (symbol->type == MS_SYMBOL_PIXMAP) {
- if (MS_SUCCESS != msPreloadImageSymbol(MS_MAP_RENDERER(map), symbol))
- return MS_FAILURE;
- } else if (symbol->type == MS_SYMBOL_SVG) {
-#ifdef USE_SVG_CAIRO
- if (MS_SUCCESS != msPreloadSVGSymbol(symbol))
- return MS_FAILURE;
-#else
- msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msDrawShape()");
- return MS_FAILURE;
-#endif
- }
- maxsize = MS_MAX(msSymbolGetDefaultSize(symbol), MS_MAX(style->size, style->width));
- maxunscaledsize = MS_MAX(style->minsize, style->minwidth);
- clip_buf = MS_NINT(MS_MAX(maxsize * layer->scalefactor, maxunscaledsize) + 1);
- } else {
- clip_buf = 0;
- }
-
- cliprect.minx = cliprect.miny = -clip_buf;
- cliprect.maxx = image->width + clip_buf;
- cliprect.maxy = image->height + clip_buf;
- if (shape->type == MS_SHAPE_POLYGON)
- msClipPolygonRect(shape, cliprect);
- else
- msClipPolylineRect(shape, cliprect);
- if (shape->numlines == 0) {
- goto line_cleanup;
- }
- }
-
/* RFC48: loop through the styles, and pass off to the type-specific
function if the style has an appropriate type */
for (s = 0; s < layer->class[c]->numstyles; s++) {
@@ -1919,8 +1786,7 @@
ret = MS_FAILURE;
goto line_cleanup;
}
- /* NOTE: here "unclipped_shape" can actually be a pointer to "shape" */
- annopaths = msPolylineLabelPath(map, image, unclipped_shape, minfeaturesize, &(map->fontset),
+ annopaths = msPolylineLabelPath(map, image, anno_shape, minfeaturesize, &(map->fontset),
label->annotext, label, layer->scalefactor, &numpaths, ®ularLines, &numRegularLines);
for (i = 0; i < numpaths; i++) {
@@ -1928,7 +1794,7 @@
if (annopaths[i]) {
if (layer->labelcache) {
- if (msAddLabel(map, label, layer->index, c, unclipped_shape, NULL, annopaths[i], -1) != MS_SUCCESS) {
+ if (msAddLabel(map, label, layer->index, c, anno_shape, NULL, annopaths[i], -1) != MS_SUCCESS) {
ret = MS_FAILURE;
goto line_cleanup;
}
@@ -1942,13 +1808,13 @@
/* handle regular lines that have to be drawn with the regular algorithm */
if (numRegularLines > 0) {
- annopoints = msPolylineLabelPointExtended(unclipped_shape, minfeaturesize, label->repeatdistance,
+ annopoints = msPolylineLabelPointExtended(anno_shape, minfeaturesize, label->repeatdistance,
&angles, &lengths, &numpoints, regularLines, numRegularLines, MS_FALSE);
for (i = 0; i < numpoints; i++) {
label->angle = *angles[i];
if (layer->labelcache) {
- if (msAddLabel(map, label, layer->index, c, unclipped_shape, annopoints[i], NULL, *lengths[i]) != MS_SUCCESS) {
+ if (msAddLabel(map, label, layer->index, c, anno_shape, annopoints[i], NULL, *lengths[i]) != MS_SUCCESS) {
ret = MS_FAILURE;
goto line_cleanup;
}
@@ -1958,7 +1824,7 @@
}
}
} else {
- annopoints = msPolylineLabelPoint(unclipped_shape, minfeaturesize, label->repeatdistance, &angles,
+ annopoints = msPolylineLabelPoint(anno_shape, minfeaturesize, label->repeatdistance, &angles,
&lengths, &numpoints, label->anglemode);
if (label->angle != 0)
@@ -1968,7 +1834,7 @@
if (label->anglemode != MS_NONE) label->angle = *angles[i]; /* angle derived from line overrides even the rotation value. */
if (layer->labelcache) {
- if (msAddLabel(map, label, layer->index, c, unclipped_shape, annopoints[i], NULL, *lengths[i]) != MS_SUCCESS) {
+ if (msAddLabel(map, label, layer->index, c, anno_shape, annopoints[i], NULL, *lengths[i]) != MS_SUCCESS) {
ret = MS_FAILURE;
goto line_cleanup;
}
@@ -2008,146 +1874,46 @@
}
} /* next label */
- if (bNeedUnclippedShape == MS_TRUE) {
- msFreeShape(unclipped_shape);
- free(unclipped_shape);
- }
return ret;
}
-int polygonLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj *shape) {
+int polygonLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer,
+ shapeObj *shape, shapeObj *anno_shape, shapeObj *unclipped_shape) {
int c = shape->classindex;
- int ret = MS_SUCCESS;
pointObj annopnt;
- int s, l;
- int bClipShape = MS_FALSE, bNeedUnclippedShape = MS_FALSE, bHasGeomTransform = MS_FALSE;
- shapeObj *unclipped_shape = NULL;
-
- if (shape->type != MS_SHAPE_POLYGON) {
- msSetError(MS_MISCERR, "Only polygon shapes can be drawn using a polygon layer definition.", "polygonLayerDrawShape()");
- return (MS_FAILURE);
- }
-
-#ifdef USE_PROJ
- if (layer->transform == MS_TRUE && layer->project && msProjectionsDiffer(&(layer->projection), &(map->projection)))
- msProjectShape(&layer->projection, &map->projection, shape);
- else
- layer->project = MS_FALSE;
-#endif
-
- for (s = 0; s < layer->class[c]->numstyles; s++) {
- if (layer->class[c]->styles[s]->_geomtransform.type != MS_GEOMTRANSFORM_NONE) {
- bHasGeomTransform = MS_TRUE;
- break;
- }
- }
- /* check if we need to clip the shape */
- if (shape->bounds.minx < map->extent.minx ||
- shape->bounds.miny < map->extent.miny ||
- shape->bounds.maxx > map->extent.maxx ||
- shape->bounds.maxy > map->extent.maxy) {
- bClipShape = MS_TRUE;
- }
-
- if (bClipShape &&
- (
- bHasGeomTransform ||
- (layer->class[c]->numlabels>0 && msLayerGetProcessingKey(layer, "LABEL_NO_CLIP"))
- )) {
- bNeedUnclippedShape = MS_TRUE;
- }
-
- if (layer->transform == MS_TRUE) {
- msTransformShape(shape, map->extent, map->cellsize, image);
- } else {
- msOffsetShapeRelativeTo(shape, layer);
- }
- msComputeBounds(shape);
-
- if (bNeedUnclippedShape) {
- unclipped_shape = (shapeObj *) msSmallMalloc(sizeof (shapeObj));
- msInitShape(unclipped_shape);
- msCopyShape(shape, unclipped_shape);
- } else {
- unclipped_shape = shape;
- }
-
- if (bClipShape) {
- rectObj cliprect;
- /* adjust the clipping rectangle so that clipped polygon shapes with thick lines
- * do not enter the image */
- int clip_buf;
- if (layer->class[c]->numstyles > 0 && layer->class[c]->styles[0] != NULL) {
- double maxsize, maxunscaledsize;
- symbolObj *symbol;
- styleObj *style = layer->class[c]->styles[0];
- if (!MS_IS_VALID_ARRAY_INDEX(style->symbol, map->symbolset.numsymbols)) {
- msSetError(MS_SYMERR, "Invalid symbol index: %d", "msDrawShape()", style->symbol);
- return MS_FAILURE;
- }
- symbol = map->symbolset.symbol[style->symbol];
- if (symbol->type == MS_SYMBOL_PIXMAP) {
- if (MS_SUCCESS != msPreloadImageSymbol(MS_MAP_RENDERER(map), symbol))
- return MS_FAILURE;
- } else if (symbol->type == MS_SYMBOL_SVG) {
-#ifdef USE_SVG_CAIRO
- if (MS_SUCCESS != msPreloadSVGSymbol(symbol))
- return MS_FAILURE;
-#else
- msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msDrawShape()");
- return MS_FAILURE;
-#endif
- }
- maxsize = MS_MAX(msSymbolGetDefaultSize(symbol), MS_MAX(style->size, style->width));
- maxunscaledsize = MS_MAX(style->minsize, style->minwidth);
- clip_buf = MS_NINT(MS_MAX(maxsize * layer->scalefactor, maxunscaledsize) + 1);
- } else {
- clip_buf = 0;
- }
-
- cliprect.minx = cliprect.miny = -clip_buf;
- cliprect.maxx = image->width + clip_buf;
- cliprect.maxy = image->height + clip_buf;
- msClipPolygonRect(shape, cliprect);
- if (shape->numlines == 0) {
- goto poly_cleanup;
- }
- }
-
- for (s = 0; s < layer->class[c]->numstyles; s++) {
- if (msScaleInBounds(map->scaledenom, layer->class[c]->styles[s]->minscaledenom, layer->class[c]->styles[s]->maxscaledenom)) {
- if (layer->class[c]->styles[s]->_geomtransform.type == MS_GEOMTRANSFORM_NONE)
- msDrawShadeSymbol(&map->symbolset, image, shape, layer->class[c]->styles[s], layer->scalefactor);
+ int i;
+
+ for (i = 0; i < layer->class[c]->numstyles; i++) {
+ if (msScaleInBounds(map->scaledenom, layer->class[c]->styles[i]->minscaledenom,
+ layer->class[c]->styles[i]->maxscaledenom)) {
+ if (layer->class[c]->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE)
+ msDrawShadeSymbol(&map->symbolset, image, shape, layer->class[c]->styles[i], layer->scalefactor);
else
- msDrawTransformedShape(map, &map->symbolset, image, unclipped_shape, layer->class[c]->styles[s], layer->scalefactor);
+ msDrawTransformedShape(map, &map->symbolset, image, unclipped_shape,
+ layer->class[c]->styles[i], layer->scalefactor);
}
}
if (layer->class[c]->numlabels > 0) {
double minfeaturesize = layer->class[c]->labels[0]->minfeaturesize * image->resolutionfactor;
- if (msPolygonLabelPoint(unclipped_shape, &annopnt, minfeaturesize) == MS_SUCCESS) {
- for (l = 0; l < layer->class[c]->numlabels; l++)
- if (layer->class[c]->labels[l]->angle != 0) layer->class[c]->labels[l]->angle -= map->gt.rotation_angle; /* TODO: is this correct ??? */
+ if (msPolygonLabelPoint(anno_shape, &annopnt, minfeaturesize) == MS_SUCCESS) {
+ for (i = 0; i < layer->class[c]->numlabels; i++)
+ if (layer->class[c]->labels[i]->angle != 0) layer->class[c]->labels[i]->angle -= map->gt.rotation_angle; /* TODO: is this correct ??? */
if (layer->labelcache) {
- if (msAddLabelGroup(map, layer->index, c, shape, &annopnt,
+ if (msAddLabelGroup(map, layer->index, c, anno_shape, &annopnt,
MS_MIN(shape->bounds.maxx - shape->bounds.minx, shape->bounds.maxy - shape->bounds.miny)) != MS_SUCCESS) {
- ret = MS_FAILURE;
- goto poly_cleanup;
+ return MS_FAILURE;
}
} else {
- for (l = 0; l < layer->class[c]->numlabels; l++)
- msDrawLabel(map, image, annopnt, layer->class[c]->labels[l]->annotext, layer->class[c]->labels[l], layer->scalefactor);
+ for (i = 0; i < layer->class[c]->numlabels; i++)
+ msDrawLabel(map, image, annopnt, layer->class[c]->labels[i]->annotext,
+ layer->class[c]->labels[i], layer->scalefactor);
}
}
}
-poly_cleanup:
- if (bNeedUnclippedShape == MS_TRUE) {
- msFreeShape(unclipped_shape);
- free(unclipped_shape);
- }
- return ret;
+ return MS_SUCCESS;
}
/*
@@ -2159,6 +1925,10 @@
int msDrawShape(mapObj *map, layerObj *layer, shapeObj *shape, imageObj *image, int style, int querymapMode)
{
int c,s,ret=MS_SUCCESS;
+ shapeObj *anno_shape, *unclipped_shape = shape;
+ int bNeedUnclippedShape = MS_FALSE;
+ int bNeedUnclippedAnnoShape = MS_FALSE;
+ int bShapeNeedsClipping = MS_TRUE;
msDrawStartShape(map, layer, image, shape);
c = shape->classindex;
@@ -2171,32 +1941,182 @@
if(style->rangeitem != NULL)
msShapeToRange((layer->class[c]->styles[s]), shape);
}
+
+ /* circle and point layers go through their own treatment */
+ if(layer->type == MS_LAYER_CIRCLE) {
+ if(msBindLayerToShape(layer, shape, querymapMode) != MS_SUCCESS) return MS_FAILURE;
+ ret = circleLayerDrawShape(map,image,layer,shape);
+ msDrawEndShape(map,layer,image,shape);
+ return ret;
+ } else if(layer->type == MS_LAYER_POINT || layer->type == MS_LAYER_RASTER) {
+ if(msBindLayerToShape(layer, shape, querymapMode) != MS_SUCCESS) return MS_FAILURE;
+ ret = pointLayerDrawShape(map,image,layer,shape);
+ msDrawEndShape(map,layer,image,shape);
+ return ret;
+ }
- if(msBindLayerToShape(layer, shape, querymapMode) != MS_SUCCESS)
- return MS_FAILURE; /* error message is set in msBindLayerToShape() */
+ if (layer->type == MS_LAYER_POLYGON && shape->type != MS_SHAPE_POLYGON) {
+ msSetError(MS_MISCERR, "Only polygon shapes can be drawn using a polygon layer definition.", "polygonLayerDrawShape()");
+ return (MS_FAILURE);
+ }
+ if (layer->type == MS_LAYER_LINE && shape->type != MS_SHAPE_POLYGON && shape->type != MS_SHAPE_LINE) {
+ msSetError(MS_MISCERR, "Only polygon or line shapes can be drawn using a line layer definition.", "msDrawShape()");
+ return (MS_FAILURE);
+ }
+#ifdef USE_PROJ
+ if (layer->project && layer->transform == MS_TRUE && msProjectionsDiffer(&(layer->projection), &(map->projection)))
+ msProjectShape(&layer->projection, &map->projection, shape);
+ else
+ layer->project = MS_FALSE;
+#endif
+
+ if (shape->type != MS_SHAPE_POINT) {
+ for (s = 0; s < layer->class[c]->numstyles; s++) {
+ styleObj *style = layer->class[c]->styles[s];
+ if (style->_geomtransform.type != MS_GEOMTRANSFORM_NONE)
+ bNeedUnclippedShape = MS_TRUE;
+ }
+ /* check if we need to clip the shape */
+ if (shape->bounds.minx < map->extent.minx ||
+ shape->bounds.miny < map->extent.miny ||
+ shape->bounds.maxx > map->extent.maxx ||
+ shape->bounds.maxy > map->extent.maxy) {
+ bShapeNeedsClipping = MS_TRUE;
+ }
+
+ if (msLayerGetProcessingKey(layer, "LABEL_NO_CLIP")) {
+ bNeedUnclippedAnnoShape = MS_TRUE;
+ bNeedUnclippedShape = MS_TRUE;
+ }
+ } else {
+ bShapeNeedsClipping = MS_FALSE;
+ }
+
+ if(layer->transform == MS_TRUE && bShapeNeedsClipping) {
+ /* compute the size of the clipping buffer, in pixels. This buffer must account
+ for the size of symbols drawn to avoid artifacts around the image edges */
+ int clip_buf = 0;
+ rectObj cliprect;
+ if (layer->class[c]->numstyles > 0) {
+ double maxsize, maxunscaledsize;
+ symbolObj *symbol;
+ styleObj *style = layer->class[c]->styles[0];
+ if (!MS_IS_VALID_ARRAY_INDEX(style->symbol, map->symbolset.numsymbols)) {
+ msSetError(MS_SYMERR, "Invalid symbol index: %d", "msDrawShape()", style->symbol);
+ return MS_FAILURE;
+ }
+ symbol = map->symbolset.symbol[style->symbol];
+ if (symbol->type == MS_SYMBOL_PIXMAP) {
+ if (MS_SUCCESS != msPreloadImageSymbol(MS_MAP_RENDERER(map), symbol))
+ return MS_FAILURE;
+ } else if (symbol->type == MS_SYMBOL_SVG) {
+#ifdef USE_SVG_CAIRO
+ if (MS_SUCCESS != msPreloadSVGSymbol(symbol))
+ return MS_FAILURE;
+#else
+ msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msDrawShape()");
+ return MS_FAILURE;
+#endif
+ }
+ maxsize = MS_MAX(msSymbolGetDefaultSize(symbol), MS_MAX(style->size, style->width));
+ maxunscaledsize = MS_MAX(style->minsize, style->minwidth);
+ clip_buf = MS_NINT(MS_MAX(maxsize * layer->scalefactor, maxunscaledsize) + 1);
+ }
+
+
+ /* if we need a copy of the unclipped shape, transform first, then clip to avoid transforming twice */
+ if(bNeedUnclippedShape) {
+ msTransformShape(shape, map->extent, map->cellsize, image);
+ if(shape->numlines == 0) return MS_SUCCESS;
+ msComputeBounds(shape);
+
+ /* TODO: there's an optimization here that can be implemented:
+ - no need to allocate unclipped_shape for each call to this function
+ - the calls to msClipXXXRect will discard the original lineObjs, whereas
+ we have just copied them because they where needed. These two functions
+ could be changed so they are instructed not to free the original lineObjs. */
+ unclipped_shape = (shapeObj *) msSmallMalloc(sizeof (shapeObj));
+ msInitShape(unclipped_shape);
+ msCopyShape(shape, unclipped_shape);
+
+ cliprect.minx = cliprect.miny = -clip_buf;
+ cliprect.maxx = image->width + clip_buf;
+ cliprect.maxy = image->height + clip_buf;
+ if(shape->type == MS_SHAPE_POLYGON) {
+ msClipPolygonRect(shape, cliprect);
+ } else {
+ assert(shape->type == MS_SHAPE_LINE);
+ msClipPolylineRect(shape, cliprect);
+ }
+ if(bNeedUnclippedAnnoShape) {
+ anno_shape = unclipped_shape;
+ } else {
+ anno_shape = shape;
+ }
+ } else {
+ /* clip first, then transform. This means we are clipping in geogaphical space */
+ cliprect.minx = map->extent.minx - clip_buf*map->cellsize;
+ cliprect.miny = map->extent.miny - clip_buf*map->cellsize;
+ cliprect.maxx = map->extent.maxx + clip_buf*map->cellsize;
+ cliprect.maxy = map->extent.maxy + clip_buf*map->cellsize;
+ if(shape->type == MS_SHAPE_POLYGON) {
+ msClipPolygonRect(shape, cliprect);
+ } else {
+ assert(shape->type == MS_SHAPE_LINE);
+ msClipPolylineRect(shape, cliprect);
+ }
+ msTransformShape(shape, map->extent, map->cellsize, image);
+ msComputeBounds(shape);
+ anno_shape = shape;
+ }
+
+ } else {
+ /* the shape is fully in the map extent,
+ * or is a point type layer where out of bounds points are treated differently*/
+ if (layer->transform == MS_TRUE) {
+ msTransformShape(shape, map->extent, map->cellsize, image);
+ msComputeBounds(shape);
+ } else {
+ msOffsetShapeRelativeTo(shape, layer);
+ }
+ anno_shape = shape;
+ }
+ if(shape->numlines == 0) {
+ ret = MS_SUCCESS; /* error message is set in msBindLayerToShape() */
+ goto draw_shape_cleanup;
+ }
+
+ if(msBindLayerToShape(layer, shape, querymapMode) != MS_SUCCESS) {
+ ret = MS_FAILURE; /* error message is set in msBindLayerToShape() */
+ goto draw_shape_cleanup;
+ }
+
switch(layer->type) {
- case MS_LAYER_CIRCLE:
- ret = circleLayerDrawShape(map, image, layer, shape);
- break;
case MS_LAYER_ANNOTATION:
- ret = annotationLayerDrawShape(map, image, layer, shape);
+ ret = annotationLayerDrawShape(map, image, layer, anno_shape);
break;
case MS_LAYER_POINT:
case MS_LAYER_RASTER:
ret = pointLayerDrawShape(map, image, layer, shape);
break;
case MS_LAYER_LINE:
- ret = lineLayerDrawShape(map, image, layer, shape, style);
+ ret = lineLayerDrawShape(map, image, layer, shape, anno_shape, unclipped_shape, style);
break;
case MS_LAYER_POLYGON:
- ret = polygonLayerDrawShape(map, image, layer, shape);
+ ret = polygonLayerDrawShape(map, image, layer, shape, anno_shape, unclipped_shape);
break;
default:
msSetError(MS_MISCERR, "Unknown layer type.", "msDrawShape()");
ret = MS_FAILURE;
}
+
+draw_shape_cleanup:
msDrawEndShape(map,layer,image,shape);
+ if(unclipped_shape != shape) {
+ msFreeShape(unclipped_shape);
+ msFree(unclipped_shape);
+ }
return ret;
}
@@ -2646,8 +2566,8 @@
markerPoly->numlines = 1;
markerPoly->bounds.minx = cachePtr->point.x - .5 * marker_width;
markerPoly->bounds.miny = cachePtr->point.y - .5 * marker_height;
- markerPoly->bounds.maxx = markerPoly->bounds.minx + (marker_width-1);
- markerPoly->bounds.maxy = markerPoly->bounds.miny + (marker_height-1);
+ markerPoly->bounds.maxx = markerPoly->bounds.minx + marker_width;
+ markerPoly->bounds.maxy = markerPoly->bounds.miny + marker_height;
point[0].x = markerPoly->bounds.minx;
point[0].y = markerPoly->bounds.miny;
point[1].x = markerPoly->bounds.minx;
@@ -2917,7 +2837,7 @@
/* compute the poly of the label styles */
computeLabelMarkerPoly(map,image,cachePtr,labelPtr,&label_marker_poly);
if(label_marker_poly.numlines) {
- if(cachePtr->numlabels > 1) {
+ if(cachePtr->numlabels > 1) { /* FIXME this test doesn't seem right, should probably check if we have an annotation layer with a regular style defined */
marker_offset_x = (label_marker_poly.bounds.maxx-label_marker_poly.bounds.minx)/2.0;
marker_offset_y = (label_marker_poly.bounds.maxy-label_marker_poly.bounds.miny)/2.0;
} else {
@@ -2951,6 +2871,12 @@
}
if(msGetLabelSize(map, labelPtr, labelPtr->annotext, size, &r, NULL) != MS_SUCCESS)
return MS_FAILURE;
+ /* if our label has an outline, adjust the marker offset so the outlinecolor does
+ * not bleed into the marker */
+ if(marker_offset_x && MS_VALID_COLOR(labelPtr->outlinecolor)) {
+ marker_offset_x += labelPtr->outlinewidth/2.0;
+ marker_offset_y += labelPtr->outlinewidth/2.0;
+ }
if(labelPtr->autominfeaturesize && (cachePtr->featuresize != -1) && ((r.maxx-r.minx) > cachePtr->featuresize)) {
/* label too large relative to the feature */
@@ -3165,29 +3091,35 @@
if(labelPtr->annotext)
msDrawText(image, labelPtr->annopoint, labelPtr->annotext, labelPtr, &(map->fontset), layerPtr->scalefactor); /* actually draw the label */
}
-
- /*
- styleObj tstyle;
- static int foo =0;
- if(!foo) {
- srand(time(NULL));
- foo = 1;
- initStyle(&tstyle);
- tstyle.width = 0.5;
- tstyle.color.alpha = 255;
- }
- tstyle.color.red = random()%255;
- tstyle.color.green = random()%255;
- tstyle.color.blue =random()%255;
- msDrawLineSymbol(&map->symbolset, image, cachePtr->poly, &tstyle, layerPtr->scalefactor);
- */
-
-
} /* end else */
} /* next label(group) from cacheslot */
msDrawOffsettedLabels(image, map, priority);
} /* next priority */
+#ifdef TBDEBUG
+ styleObj tstyle;
+ initStyle(&tstyle);
+ tstyle.width = 1;
+ tstyle.color.alpha = 255;
+ tstyle.color.red = 255;
+ tstyle.color.green = 0;
+ tstyle.color.blue = 0;
+ for(priority=MS_MAX_LABEL_PRIORITY-1; priority>=0; priority--) {
+ labelCacheSlotObj *cacheslot;
+ cacheslot = &(map->labelcache.slots[priority]);
+ for(l=cacheslot->numlabels-1; l>=0; l--) {
+ cachePtr = &(cacheslot->labels[l]); /* point to right spot in the label cache */
+ /*
+ assert((cachePtr->poly == NULL && cachePtr->status == MS_OFF) ||
+ (cachePtr->poly && (cachePtr->status == MS_ON));
+ */
+ if(cachePtr->status) {
+ msDrawLineSymbol(&map->symbolset, image, cachePtr->poly, &tstyle, layerPtr->scalefactor);
+ }
+ }
+ }
+#endif
+
return MS_SUCCESS; /* necessary? */
} else if( MS_RENDERER_IMAGEMAP(image->format) ) {
nReturnVal = msDrawLabelCacheIM(image, map);
Modified: trunk/mapserver/maplabel.c
===================================================================
--- trunk/mapserver/maplabel.c 2012-03-10 14:54:42 UTC (rev 13229)
+++ trunk/mapserver/maplabel.c 2012-03-10 17:59:44 UTC (rev 13230)
@@ -380,14 +380,10 @@
cachePtr->layerindex = layerindex; /* so we can get back to this *raw* data if necessary */
cachePtr->classindex = classindex;
-
if(shape) {
- cachePtr->tileindex = shape->tileindex;
- cachePtr->shapeindex = shape->index;
- cachePtr->shapetype = shape->type;
+ cachePtr->shapetype = shape->type;
} else {
- cachePtr->tileindex = cachePtr->shapeindex = -1;
- cachePtr->shapetype = MS_SHAPE_POINT;
+ cachePtr->shapetype = MS_SHAPE_POINT;
}
cachePtr->point = *point; /* the actual label point */
@@ -560,29 +556,22 @@
cachePtr->layerindex = layerindex; /* so we can get back to this *raw* data if necessary */
cachePtr->classindex = classindex;
- cachePtr->leaderline = NULL;
- cachePtr->leaderbbox = NULL;
-
if(shape) {
- cachePtr->tileindex = shape->tileindex;
- cachePtr->shapeindex = shape->index;
- cachePtr->shapetype = shape->type;
+ cachePtr->shapetype = shape->type;
} else {
- cachePtr->tileindex = cachePtr->shapeindex = -1;
- cachePtr->shapetype = MS_SHAPE_POINT;
+ cachePtr->shapetype = MS_SHAPE_POINT;
}
+ cachePtr->leaderline = NULL;
+ cachePtr->leaderbbox = NULL;
/* Store the label point or the label path (Bug #1620) */
if ( point ) {
cachePtr->point = *point; /* the actual label point */
cachePtr->labelpath = NULL;
} else if ( labelpath ) {
- int i;
cachePtr->labelpath = labelpath;
/* Use the middle point of the labelpath for mindistance calculations */
- i = labelpath->path.numpoints / 2;
- cachePtr->point.x = labelpath->path.point[i].x;
- cachePtr->point.y = labelpath->path.point[i].y;
+ cachePtr->point = labelpath->path.point[labelpath->path.numpoints / 2];
}
/* TODO: perhaps we can get rid of this next section and just store a marker size? Why do we cache the styles for a point layer? */
Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h 2012-03-10 14:54:42 UTC (rev 13229)
+++ trunk/mapserver/mapserver.h 2012-03-10 17:59:44 UTC (rev 13230)
@@ -1101,11 +1101,9 @@
int layerindex; /* indexes */
int classindex;
- int tileindex;
- int shapeindex;
+
+ int shapetype; /* source geometry type, can be removed once annotation layers are dropped */
- int shapetype; /* source geometry type */
-
pointObj point; /* label point */
shapeObj *poly; /* label bounding box, accumulation of individual label's bounding boxes */
More information about the mapserver-commits
mailing list