Skip to content

Commit

Permalink
Fix segfault when no overlap in kerneldensity layers (#4857)
Browse files Browse the repository at this point in the history
  • Loading branch information
tbonfort committed Sep 23, 2014
1 parent 47f7ba9 commit 5bfaf9b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 60 deletions.
117 changes: 58 additions & 59 deletions kerneldensity.c
Expand Up @@ -85,7 +85,7 @@ int msComputeKernelDensityDataset(mapObj *map, imageObj *image, layerObj *kernel
rectObj searchrect; rectObj searchrect;
shapeObj shape; shapeObj shape;
layerObj *layer; layerObj *layer;
float *values; float *values = NULL;
int radius = 10, im_width = image->width, im_height = image->height; int radius = 10, im_width = image->width, im_height = image->height;
int expand_searchrect=1; int expand_searchrect=1;
float normalization_scale=0.0; float normalization_scale=0.0;
Expand Down Expand Up @@ -187,74 +187,73 @@ int msComputeKernelDensityDataset(mapObj *map, imageObj *image, layerObj *kernel
#endif #endif


status = msLayerWhichShapes(layer, searchrect, MS_FALSE); status = msLayerWhichShapes(layer, searchrect, MS_FALSE);
if(status == MS_DONE) { /* no overlap */ /* nothing to do */
msLayerClose(layer); if(status == MS_SUCCESS) { /* at least one sample may have overlapped */
return MS_SUCCESS;
} else if(status != MS_SUCCESS) { if(layer->classgroup && layer->numclasses > 0)
msLayerClose(layer); classgroup = msAllocateValidClassGroups(layer, &nclasses);
return MS_FAILURE;
} msInitShape(&shape);
values = (float*) msSmallCalloc(im_width * im_height, sizeof(float)); while((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) {

int l,p,s,c;
if(layer->classgroup && layer->numclasses > 0) double weight = 1.0;
classgroup = msAllocateValidClassGroups(layer, &nclasses); if(!values) /* defer allocation until we effectively have a feature */

values = (float*) msSmallCalloc(im_width * im_height, sizeof(float));
msInitShape(&shape);
while((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) {
int l,p,s,c;
double weight = 1.0;
#ifdef USE_PROJ #ifdef USE_PROJ
if(layer->project) if(layer->project)
msProjectShape(&layer->projection, &map->projection, &shape); msProjectShape(&layer->projection, &map->projection, &shape);
#endif #endif


/* the weight for the sample is set to 1.0 by default. If the /* the weight for the sample is set to 1.0 by default. If the
* layer has some classes defined, we will read the weight from * layer has some classes defined, we will read the weight from
* the class->style->size (which can be binded to an attribute) * the class->style->size (which can be binded to an attribute)
*/ */
if(layer->numclasses > 0) { if(layer->numclasses > 0) {
c = msShapeGetClass(layer, map, &shape, classgroup, nclasses); c = msShapeGetClass(layer, map, &shape, classgroup, nclasses);
if((c == -1) || (layer->class[c]->status == MS_OFF)) { if((c == -1) || (layer->class[c]->status == MS_OFF)) {
goto nextshape; /* no class matched, skip */ goto nextshape; /* no class matched, skip */
} }
for (s = 0; s < layer->class[c]->numstyles; s++) { for (s = 0; s < layer->class[c]->numstyles; s++) {
if (msScaleInBounds(map->scaledenom, if (msScaleInBounds(map->scaledenom,
layer->class[c]->styles[s]->minscaledenom, layer->class[c]->styles[s]->minscaledenom,
layer->class[c]->styles[s]->maxscaledenom)) { layer->class[c]->styles[s]->maxscaledenom)) {
if(layer->class[c]->styles[s]->bindings[MS_STYLE_BINDING_SIZE].index != -1) { if(layer->class[c]->styles[s]->bindings[MS_STYLE_BINDING_SIZE].index != -1) {
weight = atof(shape.values[layer->class[c]->styles[s]->bindings[MS_STYLE_BINDING_SIZE].index]); weight = atof(shape.values[layer->class[c]->styles[s]->bindings[MS_STYLE_BINDING_SIZE].index]);
} else { } else {
weight = layer->class[c]->styles[s]->size; weight = layer->class[c]->styles[s]->size;
}
break;
} }
break; }
if(s == layer->class[c]->numstyles) {
/* no style in scale bounds */
goto nextshape;
} }
} }
if(s == layer->class[c]->numstyles) { for(l=0; l<shape.numlines; l++) {
/* no style in scale bounds */ for(p=0; p<shape.line[l].numpoints; p++) {
goto nextshape; int x = MS_MAP2IMAGE_XCELL_IC(shape.line[l].point[p].x, map->extent.minx - georadius, invcellsize);
} int y = MS_MAP2IMAGE_YCELL_IC(shape.line[l].point[p].y, map->extent.maxy + georadius, invcellsize);
} if(x>=0 && y>=0 && x<im_width && y<im_height) {
for(l=0; l<shape.numlines; l++) { float *value = values + y * im_width + x;
for(p=0; p<shape.line[l].numpoints; p++) { (*value) += weight;
int x = MS_MAP2IMAGE_XCELL_IC(shape.line[l].point[p].x, map->extent.minx - georadius, invcellsize); have_sample = 1;
int y = MS_MAP2IMAGE_YCELL_IC(shape.line[l].point[p].y, map->extent.maxy + georadius, invcellsize); }
if(x>=0 && y>=0 && x<im_width && y<im_height) {
float *value = values + y * im_width + x;
(*value) += weight;
have_sample = 1;
} }
} }

nextshape:
msFreeShape(&shape);
} }

} else if(status != MS_DONE) {
nextshape: msLayerClose(layer);
msFreeShape(&shape); return MS_FAILURE;
} }

/* status == MS_DONE */
msLayerClose(layer); msLayerClose(layer);
if(status == MS_DONE) { status = MS_SUCCESS;
status = MS_SUCCESS;
} else {
status = MS_FAILURE;
}


if(have_sample) { /* no use applying the filtering kernel if we have no samples */ if(have_sample) { /* no use applying the filtering kernel if we have no samples */
gaussian_blur(values,im_width, im_height, radius); gaussian_blur(values,im_width, im_height, radius);
Expand Down
2 changes: 1 addition & 1 deletion msautotest
Submodule msautotest updated from df6241 to 85a91d

0 comments on commit 5bfaf9b

Please sign in to comment.