Class com.vividsolutions.jts.algorithm.distance.PointPairDistance is
not thread safe as it uses tempSegment as a single temporary variable
for all threads.
In my case computeDistance() was called concurrently and in some rare
cases the PointPairDistance passed as a parameter had invalid
coordinates (ppd.getCoordinate(0) was (NaN, NaN, NaN)).
My suggestion is to make the field non-static and create a new
instance of the class for each call, e.g.:
--------------
public class DistanceToPointThreadSafe
{
// used for point-line distance calculation
private final LineSegment tempSegment = new LineSegment();
private DistanceToPointThreadSafe()
{
}
public static PointPairDistance computeDistance(Geometry geom,
Coordinate pt)
{
final PointPairDistance pointPairDistance = new PointPairDistance();
new DistanceToPointThreadSafe().computeDistance(geom, pt,
pointPairDistance);
return pointPairDistance;
}
private void computeDistance(Geometry geom, Coordinate pt,
PointPairDistance ptDist)
{
if (geom instanceof LineString)
{
computeDistance((LineString)geom, pt, ptDist);
}
else if (geom instanceof Polygon)
{
computeDistance((Polygon)geom, pt, ptDist);
}
else if (geom instanceof GeometryCollection)
{
final GeometryCollection gc = (GeometryCollection)geom;
for (int i = 0; i < gc.getNumGeometries(); i++)
{
final Geometry g = gc.getGeometryN(i);
computeDistance(g, pt, ptDist);
}
}
else
{ // assume geom is Point
ptDist.setMinimum(geom.getCoordinate(), pt);
}
}
private void computeDistance(LineString line, Coordinate pt,
PointPairDistance ptDist)
{
final Coordinate[] coords = line.getCoordinates();
for (int i = 0; i < coords.length - 1; i++)
{
tempSegment.setCoordinates(coords[i], coords[i + 1]);
// this is somewhat inefficient - could do better
final Coordinate closestPt = tempSegment.closestPoint(pt);
ptDist.setMinimum(closestPt, pt);
}
}
private void computeDistance(Polygon poly, Coordinate pt,
PointPairDistance ptDist)
{
computeDistance(poly.getExteriorRing(), pt, ptDist);
for (int i = 0; i < poly.getNumInteriorRing(); i++)
{
computeDistance(poly.getInteriorRingN(i), pt, ptDist);
}
}
}
-------------
Kind regards,
Christoph.
------------------------------------------------------------------------------
_______________________________________________
Jts-topo-suite-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jts-topo-suite-user