Using JTS and GeoTools to buffer a Point

February 17th, 2009

I recently needed to be able to create a buffer around a Point stored in a database to a distance of n kilometres. I couldn’t find a code sample on the web for how to do this so here’s an example.

 

In this case the Point object is from the Java Topology Suite

 

public com.vividsolutions.jts.geom.Geometry bufferInKm(com.vividsolutions.jts.geom.Point p,
                                                       Double radiusKm) 
{
    org.geotools.referencing.GeodeticCalculator c = new org.geotools.referencing.GeodeticCalculator();
    c.setStartingGeographicPoint(p.getX(), p.getY());
    javax.units.Unit u = c.getEllipsoid().getAxisUnit();
    javax.units.Unit km = javax.units.Unit.valueOf("km");
    if (u.isCompatible(km)) {
        javax.units.Converter converter = km.getConverterTo(u);
        double converted = converter.convert(radiusKm);
        c.setDirection(0, converted);
        java.awt.geom.Point2D p2 = c.getDestinationGeographicPoint();
        double difference = p2.getY() - p.getY();
        com.vividsolutions.jts.geom.Geometry buffer = p.buffer(difference);
        if (buffer.getSRID() != p.getSRID()) {
            buffer.setSRID(p.getSRID());
        }
        return buffer;
    }
    throw new IllegalStateException("Unable to convert between " + u + " and " + km);    
}

 

A couple of things here, firstly GeoTools relies on an implementation of JSR 108 for the javax.unit.*, since 108 was withdrawn it seems as though they are looking to move to one of it’s replacements: http://docs.codehaus.org/display/GEOTOOLS/Switch+from+JSR-108+to+JSR-275+for+Units

 

In testing I found that the result of the Point.buffer(Double) call sometimes lost its SRID. Even though the input might be set to 4326 the result would come out with 0, hence the explicit setting of the SRID on the result. Is this expected?

 

Not being a spatial data guru I don’t know if this example holds for all cases, but for the data I’m working with at the moment, everything in WGS84, it seems to work great.

Comments are closed.