package org.geometrycommands;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.operation.buffer.BufferParameters;
import org.geometrycommands.BufferCommand.BufferOptions;
import org.kohsuke.args4j.Option;

/**
 * Buffer a Geometry by a distance.
 * @author Jared Erickson
 */
public class BufferCommand extends GeometryCommand<BufferOptions> {

    /**
     * Get the command name
     * @return The command name
     */
    @Override
    public String getName() {
        return "buffer";
    }

    /**
     * Get a new BufferOptions
     * @return The new BufferOptions
     */
    @Override
    public BufferOptions getOptions() {
        return new BufferOptions();
    }

    /**
     * Buffer a Geometry by a distance.
     * @param geometry The Geometry
     * @param options The BufferOptions
     * @throws Exception if an error occurs
     */
    @Override
    protected void processGeometry(Geometry geometry, BufferOptions options) throws Exception {
        int capStyle;
        if (options.getEndCapStyle().equalsIgnoreCase("butt")
                || options.getEndCapStyle().equalsIgnoreCase("flat")) {
            capStyle = BufferParameters.CAP_FLAT;
        } else if (options.getEndCapStyle().equalsIgnoreCase("square")) {
            capStyle = BufferParameters.CAP_SQUARE;
        } else {
            capStyle = BufferParameters.CAP_ROUND;
        }
        Geometry bufferedGeometry = geometry.buffer(options.getDistance(), options.getQuadrantSegements(), capStyle);
        System.out.println(writeGeoemtry(bufferedGeometry, options));
    }

    /**
     * Options for the BufferCommand
     */
    public static class BufferOptions extends GeometryOptions {
            
        /**
         * The buffer distance
         */
        @Option(name = "-d", usage = "The buffer distance", required = true)
        private double distance;

        /**
         * The number of quadrant segments
         */
        @Option(name = "-quadrantSegments", usage = "The number of quadrant segments", required = false)
        private int quadrantSegements = 8;

        /**
         * The end cap style (round, flat/butt, square)
         */
        @Option(name = "-endCapStyle", usage = "The end cap style (round, flat/butt, square)", required = false)
        private String endCapStyle = "round";

        /**
         * Get the buffer distance
         * @return The buffer distance
         */
        public double getDistance() {
            return distance;
        }

        /**
         * Set the buffer distance
         * @param distance The buffer distance
         */
        public void setDistance(double distance) {
            this.distance = distance;
        }

        /**
         * Get the end cap style (round, flat/butt, square)
         * @return The end cap style (round, flat/butt, square)
         */
        public String getEndCapStyle() {
            return endCapStyle;
        }

        /**
         * Set the end cap style (round, flat/butt, square)
         * @param endCapStyle The end cap style (round, flat/butt, square)
         */
        public void setEndCapStyle(String endCapStyle) {
            this.endCapStyle = endCapStyle;
        }

        /**
         * Get the number of quadrant segments
         * @return The number of quadrant segments
         */
        public int getQuadrantSegements() {
            return quadrantSegements;
        }

        /**
         * Set the number of quadrant segments
         * @param quadrantSegements The number of quadrant segments
         */
        public void setQuadrantSegements(int quadrantSegements) {
            this.quadrantSegements = quadrantSegements;
        }
    }
}

@@ -69,16 +69,73 @@
 ometry;%0A
+import com.vividsolutions.jts.operation.buffer.BufferOp;%0A
 import c
@@ -191,16 +191,16 @@
 meters;%0A
-
 import o
@@ -1463,117 +1463,388 @@
     
-Geometry bufferedGeometry = geometry.buffer(options.getDistance(), options.getQuadrantSegements(), capStyle);
+%0A        BufferParameters params = new BufferParameters();%0A        params.setSingleSided(options.isSingleSided());%0A        params.setQuadrantSegments(options.getQuadrantSegements());%0A        params.setEndCapStyle(capStyle);%0A        %0A        BufferOp bufferOp = new BufferOp(geometry, params);%0A        Geometry bufferedGeometry = bufferOp.getResultGeometry(options.getDistance());%0A
 %0A   
@@ -2038,21 +2038,9 @@
 s %7B%0A
-            
 %0A
+
     
@@ -2657,16 +2657,267 @@
 ound%22;%0A%0A
+        /**%0A         * The flag for whether the buffer should be single sided%0A         */%0A        @Option(name = %22-singleSided%22, usage = %22The flag for whether the buffer should be single sided%22, required = false)%0A        private boolean singleSided;%0A%0A
         
@@ -4209,24 +4209,24 @@
 egements) %7B%0A
-
             
@@ -4274,21 +4274,565 @@
 s;%0A        %7D
+%0A%0A        /**%0A         * Get the flag for whether the buffer should be single sided%0A         * @return The flag for whether the buffer should be single sided%0A         */%0A        public boolean isSingleSided() %7B%0A            return singleSided;%0A        %7D%0A%0A        /**%0A         * Set the flag for whether the buffer should be single sided%0A         * @param singleSided The flag for whether the buffer should be single sided%0A         */%0A        public void setSingleSided(boolean singleSided) %7B%0A            this.singleSided = singleSided;%0A        %7D
 %0A    %7D%0A%7D%0A

Switch to using BufferParams and BufferOp to hangle single sided buffers