Opened 14 years ago

Closed 14 years ago

#3170 closed defect (fixed)

Unfavorable msTransformShape2Pixel & msGEOSBuffer interaction in template processing.

Reported by: jimk Owned by: sdlime
Priority: normal Milestone:
Component: MapServer C Library Version: svn-trunk (development)
Severity: normal Keywords:
Cc: sdlime, warmerdam

Description

I am seeing a problem in maptemplate.c: processShpxyTag() when buffering with units pixels and proj=image (e.g. [shpxy proj=image buffer=3px]). The problem occurs on short lines (and probably polygons) that are smaller than a pixel when rendered.

The problem is msTransformShapeToPixel removes duplicate vertices thus leaving the short line segment with only one point (numpoints = 1) because it only covers one pixel. Then when msGEOSBufferShape is called on the resulting shape, msGEOSShape2Geometry returns NULL because a shape of type MS_SHAPE_LINE cannot have < 2 points. This in turn causes msGEOSBufferShape to fail and cause processShpxyTag to fail thus terminating the Mapserver response with an error message to the client.

I see a few options to fix this. I am not sure which or any is most correct.

1) Update msTransformShapeToPixel to set the shape type to MS_SHAPE_POINT when there is only one vertex left after removing duplicate points. (And set type to MS_SHAPE_LINE if there are 2 points and the orig. was a Polygon.)

2) Update msTransformShapeToPixel to not remove too many vertices relative to the shape type (leave 2 for lines, 3 for polygons)

3) Update msGEOSShape2Geometry to treat lines with only one point as if they were points. (And similar for polygons)

Attachments (1)

mapprimitive.c.patch (1.5 KB ) - added by jimk 14 years ago.
Implementation of method 2.

Download all attachments as: .zip

Change History (4)

comment:1 by warmerdam, 14 years ago

Cc: warmerdam added

I would think that option (2) seems safest.

by jimk, 14 years ago

Attachment: mapprimitive.c.patch added

Implementation of method 2.

comment:2 by sdlime, 14 years ago

As we talked about updating the function in mapprimitive.c isn't a good idea. The issue being that the GD driver doesn't render degenerate lines and polygons (for better or worse) and the patch would alter that behavior. The trick, I guess is matching the shpxy output to the corresponding image. If GD rendered it then you don't want to output coordinates for those features that are too small and not in the image. AGG on the other hand does preserve those small features but with sub-pixel rendering is able to display them better than GD can.

Two suggestions:

1) call the wrapper transformation/generalization function instead of the GD-specific one. I understand why we did that but it's better to use the renderer specific version.

2) add logic to the shpxy processor to somehow deal with degenerate shapes if they occur in the GD case. One idea might be to output a polygon/line with negative coordinates so that your output isn't screwed up but the geom won't be seen relative to the existing image (with coordinates 0,0 width-1, height-1). That's probably a better response than outputting nothing.

Steve

comment:3 by jimk, 14 years ago

Resolution: fixed
Status: newclosed

The existing behavior for [shpxy proj=image] is to ignore degenerate shape parts. The extension to this is to ignore errors when trying to buffer degenerate shape parts [shpxy proj=image buffer=3px]. This will have the result of not buffering the degenerate shape so that the later normal processing will ignore the degenerate shape.

Fixed in r9825.

Note: See TracTickets for help on using tickets.