[geos-commits] r2421 - in trunk/source: headers/geos/util util

svn_geos at osgeo.org svn_geos at osgeo.org
Wed Apr 29 05:44:37 EDT 2009


Author: strk
Date: 2009-04-29 05:44:37 -0400 (Wed, 29 Apr 2009)
New Revision: 2421

Modified:
   trunk/source/headers/geos/util/GeometricShapeFactory.h
   trunk/source/util/GeometricShapeFactory.cpp
Log:
Sync GeometricShapeFactory to JTS-1.10 (createArcPolygon added)


Modified: trunk/source/headers/geos/util/GeometricShapeFactory.h
===================================================================
--- trunk/source/headers/geos/util/GeometricShapeFactory.h	2009-04-29 08:56:14 UTC (rev 2420)
+++ trunk/source/headers/geos/util/GeometricShapeFactory.h	2009-04-29 09:44:37 UTC (rev 2421)
@@ -12,6 +12,11 @@
  * by the Free Software Foundation. 
  * See the COPYING file for more information.
  *
+ **********************************************************************
+ *
+ * Last port: util/GeometricShapeFactory.java rev 1.14 (JTS-1.10+)
+ * (2009-03-19)
+ *
  **********************************************************************/
 
 #ifndef GEOS_UTIL_GEOMETRICSHAPEFACTORY_H
@@ -24,9 +29,11 @@
 // Forward declarations
 namespace geos {
 	namespace geom { 
+		class Coordinate;
 		class Envelope;
 		class Polygon;
 		class GeometryFactory;
+		class PrecisionModel;
 		class LineString;
 	}
 }
@@ -36,16 +43,23 @@
 
 
 /**
- * \class GeometricShapeFactory util.h geos.h
+ * Computes various kinds of common geometric shapes.
  *
- * \brief
- * Computes various kinds of common geometric shapes.
  * Allows various ways of specifying the location and extent of the shapes,
  * as well as number of line segments used to form them.
  *
+ * Example:
+ * <pre>
+ *  GeometricShapeFactory gsf(factory);
+ *  gsf.setSize(100);
+ *  gsf.setNumPoints(100);
+ *  gsf.setBase(Coordinate(0, 0));
+ *  std::auto_ptr<Polygon> rect ( gsf.createRectangle() );
+ * </pre>
+ *
  */
 class GeometricShapeFactory {
-private:
+protected:
 	class Dimensions {
 	public:
 		Dimensions();
@@ -58,12 +72,19 @@
 		void setSize(double size);
 		void setWidth(double nWidth);
 		void setHeight(double nHeight);
+
+		// Return newly-allocated object, ownership transferred
 		geom::Envelope* getEnvelope();
 	};
-	const geom::GeometryFactory* geomFact;
+	const geom::GeometryFactory* geomFact; // externally owned
+	const geom::PrecisionModel* precModel; // externally owned
 	Dimensions dim;
 	int nPts;
+
+	geom::Coordinate createCoord(double x, double y) const;
+
 public:
+
 	/**
 	 * \brief
 	 * Create a shape factory which will create shapes using the given
@@ -79,13 +100,30 @@
 	~GeometricShapeFactory();
 
 	/**
-	 * \brief Creates a elliptical arc, as a LineString.
+	 * \brief Creates an elliptical arc, as a LineString.
 	 *
+	 * The arc is always created in a counter-clockwise direction.
+	 *
+	 * @param startAng start angle in radians
+	 * @param angExtent size of angle in radians
 	 * @return an elliptical arc
 	 */
-	geom::LineString* createArc(double startAng, double endAng);
+	geom::LineString* createArc(double startAng, double angExtent);
 
 	/**
+	 * \brief Creates an elliptical arc polygon.
+	 *
+	 * The polygon is formed from the specified arc of an ellipse
+	 * and the two radii connecting the endpoints to the centre of
+	 * the ellipse.
+	 *
+	 * @param startAng start angle in radians
+	 * @param angExtent size of angle in radians
+	 * @return an elliptical arc polygon
+	 */
+	geom::Polygon* createArcPolygon(double startAng, double angExt);
+
+	/**
 	 * \brief Creates a circular Polygon.
 	 *
 	 * @return a circle

Modified: trunk/source/util/GeometricShapeFactory.cpp
===================================================================
--- trunk/source/util/GeometricShapeFactory.cpp	2009-04-29 08:56:14 UTC (rev 2420)
+++ trunk/source/util/GeometricShapeFactory.cpp	2009-04-29 09:44:37 UTC (rev 2421)
@@ -11,6 +11,11 @@
  * by the Free Software Foundation. 
  * See the COPYING file for more information.
  *
+ **********************************************************************
+ *
+ * Last port: util/GeometricShapeFactory.java rev 1.14 (JTS-1.10+)
+ * (2009-03-19)
+ *
  **********************************************************************/
 
 #include <geos/util/GeometricShapeFactory.h>
@@ -22,6 +27,7 @@
 
 #include <vector>
 #include <cmath>
+#include <memory>
 
 #ifndef M_PI
 #define M_PI        3.14159265358979323846
@@ -33,130 +39,89 @@
 namespace geos {
 namespace util { // geos.util
 
-/*
- * Create a shape factory which will create shapes using the given
- * GeometryFactory. The given GeometryFactory will need to stay
- * alive for the whole instance lifetime (the object will keep
- * an external reference to it)
- */
-GeometricShapeFactory::GeometricShapeFactory(const GeometryFactory* factory){
-	//dim=new Dimensions();
-	nPts=100;
-	geomFact=factory;
+GeometricShapeFactory::GeometricShapeFactory(const GeometryFactory* factory)
+	:
+	geomFact(factory),
+	precModel(factory->getPrecisionModel()),
+	nPts(100)
+{
 }
 
-GeometricShapeFactory::~GeometricShapeFactory() {
+GeometricShapeFactory::~GeometricShapeFactory()
+{
 	//delete dim;
 }
 
-
-/**
-* Sets the location of the shape by specifying the base coordinate
-* (which in most cases is the
-* lower left point of the envelope containing the shape).
-*
-* @param base the base coordinate of the shape
-*/
-void GeometricShapeFactory::setBase(const Coordinate& base)  {
+void
+GeometricShapeFactory::setBase(const Coordinate& base) 
+{
 	dim.setBase(base);
 }
-/**
-* Sets the location of the shape by specifying the centre of
-* the shape's bounding box
-*
-* @param centre the centre coordinate of the shape
-*/
-void GeometricShapeFactory::setCentre(const Coordinate& centre)  {
+
+void
+GeometricShapeFactory::setCentre(const Coordinate& centre)
+{
 	dim.setCentre(centre);
 }
 
-/**
-* Sets the total number of points in the created Geometry
-*/
-void GeometricShapeFactory::setNumPoints(int nNPts) {
+void
+GeometricShapeFactory::setNumPoints(int nNPts)
+{
 	nPts=nNPts;
 }
 
-/**
-* Sets the size of the extent of the shape in both x and y directions.
-*
-* @param size the size of the shape's extent
-*/
-void GeometricShapeFactory::setSize(double size) { 
+void
+GeometricShapeFactory::setSize(double size)
+{
 	dim.setSize(size);
 }
 
-/**
-* Sets the width of the shape.
-*
-* @param width the width of the shape
-*/
-void GeometricShapeFactory::setWidth(double width) {
+void
+GeometricShapeFactory::setWidth(double width)
+{
 	dim.setWidth(width);
 }
 
-/**
-* Sets the height of the shape.
-*
-* @param height the height of the shape
-*/
-void GeometricShapeFactory::setHeight(double height) { 
+void
+GeometricShapeFactory::setHeight(double height)
+{
 	dim.setHeight(height);
 }
 
-/*
- * Creates a rectangular Polygon.
- */
-Polygon* GeometricShapeFactory::createRectangle(){
+Polygon*
+GeometricShapeFactory::createRectangle()
+{
 	int i;
 	int ipt = 0;
 	int nSide = nPts / 4;
 	if (nSide < 1) nSide = 1;
-	Envelope *env = dim.getEnvelope();
+	std::auto_ptr<Envelope> env ( dim.getEnvelope() );
 	double XsegLen = env->getWidth() / nSide;
 	double YsegLen = env->getHeight() / nSide;
 
 	vector<Coordinate> *vc = new vector<Coordinate>(4*nSide+1);
 	//CoordinateSequence* pts=new CoordinateArraySequence(4*nSide+1);
 
-	//double maxx = env->getMinX() + nSide * XsegLen;
-	//double maxy = env->getMinY() + nSide * XsegLen;
-
-	Coordinate c;
 	for (i = 0; i < nSide; i++) {
 		double x = env->getMinX() + i * XsegLen;
 		double y = env->getMinY();
-		//pts->setAt(Coordinate(x, y),ipt++);
-		c.x = x; c.y = y;
-		(*vc)[ipt++] = c;
+		(*vc)[ipt++] = createCoord(x, y); 
 	}
 	for (i = 0; i < nSide; i++) {
 		double x = env->getMaxX();
 		double y = env->getMinY() + i * YsegLen;
-		//pts->setAt(*(new Coordinate(x, y)),ipt++);
-		//pts->setAt(Coordinate(x, y),ipt++);
-		c.x = x; c.y = y;
-		(*vc)[ipt++] = c;
+		(*vc)[ipt++] = createCoord(x, y); 
 	}
 	for (i = 0; i < nSide; i++) {
 		double x = env->getMaxX() - i * XsegLen;
 		double y = env->getMaxY();
-		//pts->setAt(*(new Coordinate(x, y)),ipt++);
-		//pts->setAt(Coordinate(x, y),ipt++);
-		c.x = x; c.y = y;
-		(*vc)[ipt++] = c;
+		(*vc)[ipt++] = createCoord(x, y); 
 	}
 	for (i = 0; i < nSide; i++) {
 		double x = env->getMinX();
 		double y = env->getMaxY() - i * YsegLen;
-		//pts->setAt(*(new Coordinate(x, y)),ipt++);
-		//pts->setAt(Coordinate(x, y),ipt++);
-		c.x = x; c.y = y;
-		(*vc)[ipt++] = c;
+		(*vc)[ipt++] = createCoord(x, y); 
 	}
-	delete env;
-	//pts->setAt(*(new Coordinate(pts->getAt(0))),ipt++);
-	//pts->setAt(Coordinate(pts->getAt(0)),ipt++);
 	(*vc)[ipt++] = (*vc)[0];
 	CoordinateSequence *cs = geomFact->getCoordinateSequenceFactory()->create(vc);
 	LinearRing* ring=geomFact->createLinearRing(cs);
@@ -164,28 +129,24 @@
 	return poly;
 }
 
-/*
- * Creates a circular Polygon.
- */
-Polygon* GeometricShapeFactory::createCircle() {
-	Envelope* env = dim.getEnvelope();
+Polygon*
+GeometricShapeFactory::createCircle()
+{
+	std::auto_ptr<Envelope> env ( dim.getEnvelope() );
 	double xRadius = env->getWidth() / 2.0;
 	double yRadius = env->getHeight() / 2.0;
 
 	double centreX = env->getMinX() + xRadius;
 	double centreY = env->getMinY() + yRadius;
-	delete env;
+	env.reset();
 
 	vector<Coordinate>*pts=new vector<Coordinate>(nPts+1);
 	int iPt = 0;
-	Coordinate pt;
 	for (int i = 0; i < nPts; i++) {
 		double ang = i * (2 * 3.14159265358979 / nPts);
 		double x = xRadius * cos(ang) + centreX;
 		double y = yRadius * sin(ang) + centreY;
-		pt.x = x;
-		pt.y = y;
-		(*pts)[iPt++] = pt;
+		(*pts)[iPt++] = createCoord(x, y);
 	}
 	(*pts)[iPt++] = (*pts)[0];
 	CoordinateSequence *cs=geomFact->getCoordinateSequenceFactory()->create(pts);
@@ -194,42 +155,68 @@
 	return poly;
 }
 
-/**
-* Creates a elliptical arc, as a LineString.
-*
-* @return an elliptical arc
-*/
-LineString* GeometricShapeFactory::createArc(double startAng,double endAng){
-	Envelope* env = dim.getEnvelope();
+LineString*
+GeometricShapeFactory::createArc(double startAng, double angExtent)
+{
+	std::auto_ptr<Envelope> env ( dim.getEnvelope() );
 	double xRadius = env->getWidth() / 2.0;
 	double yRadius = env->getHeight() / 2.0;
 
 	double centreX = env->getMinX() + xRadius;
 	double centreY = env->getMinY() + yRadius;
-	delete env;
+	env.reset();
 
-	double angSize = (endAng - startAng);
-	if (angSize <= 0.0 || angSize > 2 * M_PI) //3.14159265358979
-		angSize = 2 * M_PI; //3.14159265358979;
-	double angInc = angSize / nPts;
+	double angSize = angExtent;
+	if (angSize <= 0.0 || angSize > 2 * M_PI) 
+		angSize = 2 * M_PI; 
+	double angInc = angSize / ( nPts - 1 );
 
 	vector<Coordinate> *pts = new vector<Coordinate>(nPts);
 	int iPt = 0;
-	Coordinate pt;
 	for (int i = 0; i < nPts; i++) {
 		double ang = startAng + i * angInc;
 		double x = xRadius * cos(ang) + centreX;
 		double y = yRadius * sin(ang) + centreY;
-		pt.x = x;
-		pt.y = y;
-		geomFact->getPrecisionModel()->makePrecise(&pt);
-		(*pts)[iPt++] = pt;
+		(*pts)[iPt++] = createCoord(x, y);
 	}
 	CoordinateSequence *cs = geomFact->getCoordinateSequenceFactory()->create(pts);
 	LineString* line = geomFact->createLineString(cs);
 	return line;
 }
 
+Polygon*
+GeometricShapeFactory::createArcPolygon(double startAng, double angExtent)
+{
+	std::auto_ptr<Envelope> env ( dim.getEnvelope() );
+	double xRadius = env->getWidth() / 2.0;
+	double yRadius = env->getHeight() / 2.0;
+
+	double centreX = env->getMinX() + xRadius;
+	double centreY = env->getMinY() + yRadius;
+	env.reset();
+
+	double angSize = angExtent;
+	if (angSize <= 0.0 || angSize > 2 * M_PI) 
+		angSize = 2 * M_PI; 
+	double angInc = angSize / ( nPts - 1 );
+
+	vector<Coordinate> *pts = new vector<Coordinate>(nPts + 2);
+	int iPt = 0;
+	(*pts)[iPt++] = createCoord(centreX, centreY);
+	for (int i = 0; i < nPts; i++) {
+		double ang = startAng + i * angInc;
+		double x = xRadius * cos(ang) + centreX;
+		double y = yRadius * sin(ang) + centreY;
+		(*pts)[iPt++] = createCoord(x, y);
+	}
+	(*pts)[iPt++] = createCoord(centreX, centreY);
+
+	CoordinateSequence *cs = geomFact->getCoordinateSequenceFactory()->create(pts);
+	LinearRing* ring = geomFact->createLinearRing(cs);
+	Polygon* geom = geomFact->createPolygon(ring, 0);
+	return geom;
+}
+
 GeometricShapeFactory::Dimensions::Dimensions()
 	:
 	base(Coordinate::getNull()),
@@ -237,27 +224,39 @@
 {
 }
 
-void GeometricShapeFactory::Dimensions::setBase(const Coordinate& newBase)  {
+void
+GeometricShapeFactory::Dimensions::setBase(const Coordinate& newBase)
+{
 	base=newBase;
 }
 
-void GeometricShapeFactory::Dimensions::setCentre(const Coordinate& newCentre)  {
+void
+GeometricShapeFactory::Dimensions::setCentre(const Coordinate& newCentre)
+{
 	centre=newCentre;
 }
 
-void GeometricShapeFactory::Dimensions::setSize(double size){
+void
+GeometricShapeFactory::Dimensions::setSize(double size)
+{
 	height = size;
 	width = size;
 }
 
-void GeometricShapeFactory::Dimensions::setWidth(double nWidth) {
+void
+GeometricShapeFactory::Dimensions::setWidth(double nWidth)
+{
 	width=nWidth;
 }
-void GeometricShapeFactory::Dimensions::setHeight(double nHeight) {
+
+void GeometricShapeFactory::Dimensions::setHeight(double nHeight)
+{
 	height=nHeight;
 }
 
-Envelope* GeometricShapeFactory::Dimensions::getEnvelope() {
+Envelope*
+GeometricShapeFactory::Dimensions::getEnvelope()
+{
 	if (base!=Coordinate::getNull()) {
 		return new Envelope(base.x, base.x + width, base.y, base.y + height);
 	}
@@ -267,6 +266,15 @@
 	return new Envelope(0, width, 0, height);
 }
 
+/*protected*/
+Coordinate
+GeometricShapeFactory::createCoord(double x, double y) const
+{
+	Coordinate ret(x, y);
+	precModel->makePrecise(&ret);
+	return ret;
+}
+
 } // namespace geos.util
 } // namespace geos
 



More information about the geos-commits mailing list