protected virtual IShape BufferShape(IShape shape, double distErr)
{
//TODO move this generic code elsewhere? Spatial4j?
if (distErr <= 0)
{
throw new ArgumentException("distErr must be > 0");
}
SpatialContext ctx = grid.SpatialContext;
if (shape is IPoint)
{
return ctx.MakeCircle((IPoint)shape, distErr);
}
else if (shape is ICircle)
{
var circle = (ICircle)shape;
double newDist = circle.Radius + distErr;
if (ctx.IsGeo && newDist > 180)
{
newDist = 180;
}
return ctx.MakeCircle(circle.Center, newDist);
}
else
{
IRectangle bbox = shape.BoundingBox;
double newMinX = bbox.MinX - distErr;
double newMaxX = bbox.MaxX + distErr;
double newMinY = bbox.MinY - distErr;
double newMaxY = bbox.MaxY + distErr;
if (ctx.IsGeo)
{
if (newMinY < -90)
{
newMinY = -90;
}
if (newMaxY > 90)
{
newMaxY = 90;
}
if (newMinY == -90 || newMaxY == 90 || bbox.Width + 2 * distErr > 360)
{
newMinX = -180;
newMaxX = 180;
}
else
{
newMinX = DistanceUtils.NormLonDEG(newMinX);
newMaxX = DistanceUtils.NormLonDEG(newMaxX);
}
}
else
{
//restrict to world bounds
newMinX = Math.Max(newMinX, ctx.WorldBounds.MinX);
newMaxX = Math.Min(newMaxX, ctx.WorldBounds.MaxX);
newMinY = Math.Max(newMinY, ctx.WorldBounds.MinY);
newMaxY = Math.Min(newMaxY, ctx.WorldBounds.MaxY);
}
return ctx.MakeRectangle(newMinX, newMaxX, newMinY, newMaxY);
}
}