[geos-commits] r2339 - in trunk/source: headers/geos/operation/buffer operation/buffer

svn_geos at osgeo.org svn_geos at osgeo.org
Thu Apr 9 05:45:22 EDT 2009


Author: strk
Date: 2009-04-09 05:45:22 -0400 (Thu, 09 Apr 2009)
New Revision: 2339

Added:
   trunk/source/headers/geos/operation/buffer/BufferParameters.h
   trunk/source/operation/buffer/BufferParameters.cpp
Modified:
   trunk/source/headers/geos/operation/buffer/Makefile.am
   trunk/source/operation/buffer/Makefile.am
Log:
Port BufferParameters from JTS-1.9

Added: trunk/source/headers/geos/operation/buffer/BufferParameters.h
===================================================================
--- trunk/source/headers/geos/operation/buffer/BufferParameters.h	                        (rev 0)
+++ trunk/source/headers/geos/operation/buffer/BufferParameters.h	2009-04-09 09:45:22 UTC (rev 2339)
@@ -0,0 +1,268 @@
+/**********************************************************************
+ * $Id$
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.refractions.net
+ *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation. 
+ * See the COPYING file for more information.
+ *
+ **********************************************************************
+ *
+ * Last port: operation/buffer/BufferParameters.java rev 1.5 (JTS-1.9)
+ *
+ **********************************************************************/
+
+#ifndef GEOS_OP_BUFFER_BUFFERPARAMETERS_H
+#define GEOS_OP_BUFFER_BUFFERPARAMETERS_H
+
+//#include <vector>
+
+//#include <geos/algorithm/LineIntersector.h> // for composition
+//#include <geos/geom/Coordinate.h> // for composition
+//#include <geos/geom/LineSegment.h> // for composition
+
+// Forward declarations
+namespace geos {
+	namespace geom {
+		class CoordinateSequence;
+		class PrecisionModel;
+	}
+	namespace operation {
+		namespace buffer {
+			class OffsetCurveVertexList;
+		}
+	}
+}
+
+namespace geos {
+namespace operation { // geos.operation
+namespace buffer { // geos.operation.buffer
+
+/** \brief
+ * Contains the parameters which
+ * describe how a buffer should be constructed.
+ *
+ */
+class BufferParameters
+{
+
+public:
+
+	/// End cap styles
+        enum EndCapStyle {
+
+                /// Specifies a round line buffer end cap style.
+                CAP_ROUND=1,
+
+                /// Specifies a flat line buffer end cap style.
+                CAP_FLAT=2,
+
+                /// Specifies a square line buffer end cap style.
+                CAP_SQUARE=3
+        };
+
+	/// Join styles
+        enum JoinStyle {
+
+                /// Specifies a round join style.
+                JOIN_ROUND=1,
+
+                /// Specifies a mitre join style.
+                JOIN_MITRE=2,
+
+                /// Specifies a bevel join style.
+                JOIN_BEVEL=3
+        };
+
+	/// \brief
+	/// The default number of facets into which to divide a fillet
+	/// of 90 degrees.
+	//
+	/// A value of 8 gives less than 2% max error in the buffer distance.
+	/// For a max error of < 1%, use QS = 12.
+	/// For a max error of < 0.1%, use QS = 18.
+	///
+	static const int DEFAULT_QUADRANT_SEGMENTS = 8;
+
+	/// The default mitre limit
+	//
+	/// Allows fairly pointy mitres.
+	///
+	static const double DEFAULT_MITRE_LIMIT; // 5.0 (in .cpp file)
+
+	/// Creates a default set of parameters
+	BufferParameters()
+		:
+		quadrantSegments(DEFAULT_QUADRANT_SEGMENTS),
+		endCapStyle(CAP_ROUND),
+		joinStyle(JOIN_ROUND),
+		mitreLimit(DEFAULT_MITRE_LIMIT)
+	{}
+
+	/// Creates a set of parameters with the given quadrantSegments value.
+	//
+	/// @param quadrantSegments the number of quadrant segments to use
+	///
+	BufferParameters(int quadrantSegments);
+
+	/// \brief
+	/// Creates a set of parameters with the
+	/// given quadrantSegments and endCapStyle values.
+	//
+	/// @param quadrantSegments the number of quadrant segments to use
+	/// @param endCapStyle the end cap style to use
+	///
+	BufferParameters(int quadrantSegments, EndCapStyle endCapStyle);
+
+	/// \brief
+	/// Creates a set of parameters with the
+	/// given parameter values.
+	//
+	/// @param quadrantSegments the number of quadrant segments to use
+	/// @param endCapStyle the end cap style to use
+	/// @param joinStyle the join style to use
+	/// @param mitreLimit the mitre limit to use
+	///
+	BufferParameters(int quadrantSegments, EndCapStyle endCapStyle,
+	                 JoinStyle joinStyle, double mitreLimit);
+
+	/// Gets the number of quadrant segments which will be used
+	//
+	/// @return the number of quadrant segments
+	///
+	int getQuandrantSegments() const { return quadrantSegments; }
+
+	/// \brief
+	/// Sets the number of line segments used to approximate
+	/// an angle fillet.
+	// 
+	/// - If <tt>quadSegs</tt> >= 1, joins are round,
+	///   and <tt>quadSegs</tt> indicates the number of
+	///   segments to use to approximate a quarter-circle.
+	/// - If <tt>quadSegs</tt> = 0, joins are bevelled (flat)
+	/// - If <tt>quadSegs</tt> < 0, joins are mitred, and the value of qs
+	///   indicates the mitre ration limit as
+	///   <pre>
+	///    mitreLimit = |<tt>quadSegs</tt>|
+	///    </pre>
+	/// 
+	/// For round joins, <tt>quadSegs</tt> determines the maximum
+	/// error in the approximation to the true buffer curve.
+	///
+	/// The default value of 8 gives less than 2% max error in the
+	/// buffer distance.
+	///
+	/// For a max error of < 1%, use QS = 12.
+	/// For a max error of < 0.1%, use QS = 18.
+	/// The error is always less than the buffer distance
+	/// (in other words, the computed buffer curve is always inside
+	///  the true curve).
+	///
+	/// @param quadrantSegments the number of segments in a
+	///                         fillet for a quadrant
+	////
+	void setQuadrantSegments(int quadSegs);
+
+	/// \brief
+	/// Computes the maximum distance error due to a given level
+	/// of approximation to a true arc.
+	//
+	/// @param quadSegs the number of segments used to approximate
+	///                 a quarter-circle
+	/// @return the error of approximation
+	///
+	static double bufferDistanceError(int quadSegs);
+
+	/// Gets the end cap style.
+	//
+	/// @return the end cap style
+	///
+	EndCapStyle getEndCapStyle() const { return endCapStyle; }
+
+	/// Specifies the end cap style of the generated buffer.
+	//
+	/// The styles supported are CAP_ROUND, CAP_BUTT,
+	/// and CAP_SQUARE.
+	///
+	/// The default is CAP_ROUND.
+	///
+	/// @param style the end cap style to specify
+	///
+	void setEndCapStyle(EndCapStyle style)
+	{
+		endCapStyle = style;
+	}
+
+	/// Gets the join style.
+	//
+	/// @return the join style
+	///
+	JoinStyle getJoinStyle() const { return joinStyle; }
+
+	/// \brief
+	/// Sets the join style for outside (reflex) corners between
+	/// line segments.
+	//
+	/// Allowable values are JOIN_ROUND (which is the default),
+	/// JOIN_MITRE and JOIN_BEVEL.
+	//
+	/// @param style the code for the join style
+	///
+	void setJoinStyle(JoinStyle style)
+	{
+		joinStyle = style;
+	}
+
+	/// Gets the mitre ratio limit.
+	//
+	/// @return the limit value
+	///
+	double getMitreLimit() const { return mitreLimit; }
+ 
+	/// Sets the limit on the mitre ratio used for very sharp corners.
+	//
+	/// The mitre ratio is the ratio of the distance from the corner
+	/// to the end of the mitred offset corner.
+	/// When two line segments meet at a sharp angle,
+	/// a miter join will extend far beyond the original geometry.
+	/// (and in the extreme case will be infinitely far.)
+	/// To prevent unreasonable geometry, the mitre limit
+	/// allows controlling the maximum length of the join corner.
+	/// Corners with a ratio which exceed the limit will be beveled.
+	///
+	/// @param limit the mitre ratio limit
+	///
+	void setMitreLimit(double limit)
+	{
+		mitreLimit = mitreLimit;
+	}
+
+
+private:
+
+	/// Defaults to DEFAULT_QUADRANT_SEGMENTS;
+	int quadrantSegments;
+
+	/// Defaults to CAP_ROUND;
+	EndCapStyle endCapStyle;
+
+	// Defaults to JOIN_ROUND;
+	JoinStyle joinStyle;
+
+	// Defaults to DEFAULT_MITRE_LIMIT;
+	double mitreLimit;
+};
+
+
+
+} // namespace geos::operation::buffer
+} // namespace geos::operation
+} // namespace geos
+
+#endif // ndef GEOS_OP_BUFFER_BUFFERPARAMETERS_H
+

Modified: trunk/source/headers/geos/operation/buffer/Makefile.am
===================================================================
--- trunk/source/headers/geos/operation/buffer/Makefile.am	2009-04-09 08:54:00 UTC (rev 2338)
+++ trunk/source/headers/geos/operation/buffer/Makefile.am	2009-04-09 09:45:22 UTC (rev 2339)
@@ -13,6 +13,7 @@
 
 noinst_HEADERS = \
 	BufferBuilder.h	\
+	BufferParameters.h	\
 	BufferSubgraph.h	\
 	OffsetCurveSetBuilder.h	\
 	RightmostEdgeFinder.h \

Added: trunk/source/operation/buffer/BufferParameters.cpp
===================================================================
--- trunk/source/operation/buffer/BufferParameters.cpp	                        (rev 0)
+++ trunk/source/operation/buffer/BufferParameters.cpp	2009-04-09 09:45:22 UTC (rev 2339)
@@ -0,0 +1,125 @@
+/**********************************************************************
+ * $Id$
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.refractions.net
+ *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation. 
+ * See the COPYING file for more information.
+ *
+ **********************************************************************
+ *
+ * Last port: operation/buffer/BufferParameters.java rev 1.5 (JTS-1.9)
+ *
+ **********************************************************************/
+
+#include <cstdlib> // for std::abs()
+#include <cmath> // for cos
+
+#include <geos/operation/buffer/BufferParameters.h>
+
+
+#ifndef M_PI
+#define M_PI        3.14159265358979323846
+#endif
+
+namespace geos {
+namespace operation { // geos.operation
+namespace buffer { // geos.operation.buffer
+
+// public static const
+const double BufferParameters::DEFAULT_MITRE_LIMIT = 5.0;
+
+// public
+BufferParameters::BufferParameters(int quadrantSegments)
+	:
+	quadrantSegments(DEFAULT_QUADRANT_SEGMENTS),
+	endCapStyle(CAP_ROUND),
+	joinStyle(JOIN_ROUND),
+	mitreLimit(DEFAULT_MITRE_LIMIT)
+{
+	setQuadrantSegments(quadrantSegments);
+}
+
+// public
+BufferParameters::BufferParameters(int quadrantSegments,
+                                   EndCapStyle endCapStyle)
+	:
+	quadrantSegments(DEFAULT_QUADRANT_SEGMENTS),
+	endCapStyle(CAP_ROUND),
+	joinStyle(JOIN_ROUND),
+	mitreLimit(DEFAULT_MITRE_LIMIT)
+{
+	setQuadrantSegments(quadrantSegments);
+	setEndCapStyle(endCapStyle);
+}
+
+// public
+BufferParameters::BufferParameters(int quadrantSegments,
+                                   EndCapStyle endCapStyle,
+                                   JoinStyle joinStyle,
+                                   double mitreLimit)
+	:
+	quadrantSegments(DEFAULT_QUADRANT_SEGMENTS),
+	endCapStyle(CAP_ROUND),
+	joinStyle(JOIN_ROUND),
+	mitreLimit(DEFAULT_MITRE_LIMIT)
+{
+	setQuadrantSegments(quadrantSegments);
+	setEndCapStyle(endCapStyle);
+	setJoinStyle(joinStyle);
+	setMitreLimit(mitreLimit);
+}
+
+// public
+void
+BufferParameters::setQuadrantSegments(int quadSegs)
+{
+	quadrantSegments = quadSegs;
+
+	/**
+	 * Indicates how to construct fillets.
+	 * If qs >= 1, fillet is round, and qs indicates number of
+	 * segments to use to approximate a quarter-circle.
+	 * If qs = 0, fillet is bevelled flat (i.e. no filleting is performed)
+	 * If qs < 0, fillet is mitred, and absolute value of qs
+	 * indicates maximum length of mitre according to
+	 *
+	 * mitreLimit = |qs|
+	 */
+	if (quadrantSegments == 0)
+		joinStyle = JOIN_BEVEL;
+	if (quadrantSegments < 0) {
+		joinStyle = JOIN_MITRE;
+		mitreLimit = std::abs(quadrantSegments);
+	}
+
+	if (quadSegs <= 0) {
+		quadrantSegments = 1;
+	}
+
+	/**
+	 * If join style was set by the quadSegs value,
+	 * use the default for the actual quadrantSegments value.
+	 */
+	if (joinStyle != JOIN_ROUND) {
+		quadrantSegments = DEFAULT_QUADRANT_SEGMENTS;
+	}
+}
+
+// public static
+double
+BufferParameters::bufferDistanceError(int quadSegs)
+{
+	double alpha = M_PI / 2.0 / quadSegs;
+	return 1 - cos(alpha / 2.0);
+}
+
+} // namespace geos.operation.buffer
+} // namespace geos.operation
+} // namespace geos
+

Modified: trunk/source/operation/buffer/Makefile.am
===================================================================
--- trunk/source/operation/buffer/Makefile.am	2009-04-09 08:54:00 UTC (rev 2338)
+++ trunk/source/operation/buffer/Makefile.am	2009-04-09 09:45:22 UTC (rev 2339)
@@ -7,6 +7,7 @@
 libopbuffer_la_SOURCES = \
 	BufferBuilder.cpp \
 	BufferOp.cpp \
+	BufferParameters.cpp \
 	BufferSubgraph.cpp \
 	OffsetCurveBuilder.cpp \
 	OffsetCurveSetBuilder.cpp \



More information about the geos-commits mailing list