mbedward / jaitools

Raster image processing for Java developers
17 stars 15 forks source link

Vectorize operation can fail to assign correct value to polygons #197

Closed mbedward closed 11 years ago

mbedward commented 11 years ago

Original author: michael.bedward@gmail.com (September 21, 2011 06:23:59)

This was reported by John Armstrong on the GeoTools user list in the context of the old RasterToVectorProcess class. I think the same issue will be present in the VectorizeOpImage code.

John's report is at http://jira.codehaus.org/browse/GEOT-3855 and quoted below:

AIUI, the process works by finding edges on a data grid. The edges are assembled into polygons, each of which may be part of the region of interest or a hole in that region. To test, it tries to find an interior point of the polygon to check if it's "inside" or "outside". Usually it's enough to use com.vividsolutions.jts.algorithm.InteriorPointArea, but if that fails the backup plan is to walk around each vertex and check the point one grid-cell-width to the right.

The problem comes up when the grid polygon is an L-shape, like

X XXXX

Here, the InteriorPointArea gives a point on the upper edge of the "right arm" of the shape, which isn't an interior point. Then we check an offset away from all six vertices, all of which are either on the boundary or outside the polygon. The algorithm throws an exception and Dies Horribly.

The solution is to move right and up by half a grid cell. Every grid polygon must have at least one lower-left corner (proof left as exercise to reader), for which this offset will give a point within a grid cell contained within the interior of the polygon. In terms of the code, line 427 should be changed from

c.y = ringC.y;

to

c.y = ringC.y + cellWidthY / 2;

and the algorithm will work as intended.

Original issue: http://code.google.com/p/jaitools/issues/detail?id=199

mbedward commented 11 years ago

From michael.bedward@gmail.com on September 21, 2011 12:56:43 Turned out that the GeoTools bug was not present in the Vectorize operation, but the code for that part of the algorithm was ridiculously complex. Changing it to be similar to the fixed GeoTools 2.7 code made it much shorter and easier to follow. Also added new unit test with L-shape that was causing problems for GeoTools.

Changes committed to 1.2.x branch (r1856) and trunk (r1857)