[geos-commits] r3313 - in trunk: doc include/geos/geom/util include/geos/util src/geom/util src/util

svn_geos at osgeo.org svn_geos at osgeo.org
Thu Apr 28 06:04:27 EDT 2011


Author: strk
Date: 2011-04-28 03:04:27 -0700 (Thu, 28 Apr 2011)
New Revision: 3313

Added:
   trunk/include/geos/geom/util/SineStarFactory.h
   trunk/src/geom/util/SineStarFactory.cpp
Modified:
   trunk/doc/example.cpp
   trunk/include/geos/geom/util/Makefile.am
   trunk/include/geos/util/GeometricShapeFactory.h
   trunk/src/geom/util/Makefile.am
   trunk/src/util/GeometricShapeFactory.cpp
Log:
Port geos::geom::util::SineStarFactory from JTS-1.12, useful for profile-test RectangleIntersects.

Modified: trunk/doc/example.cpp
===================================================================
--- trunk/doc/example.cpp	2011-04-28 10:04:11 UTC (rev 3312)
+++ trunk/doc/example.cpp	2011-04-28 10:04:27 UTC (rev 3313)
@@ -44,6 +44,7 @@
 #include <geos/io/WKBWriter.h>
 #include <geos/io/WKTWriter.h>
 #include <geos/util/GeometricShapeFactory.h>
+#include <geos/geom/util/SineStarFactory.h>
 #include <geos/util/GEOSException.h>
 #include <geos/util/IllegalArgumentException.h>
 #include <geos/opLinemerge.h>
@@ -71,6 +72,8 @@
 using namespace geos::geom;
 using namespace geos::operation::polygonize;
 using namespace geos::operation::linemerge;
+using geos::util::GEOSException;
+using geos::util::IllegalArgumentException;
 
 
 // Prototypes
@@ -333,7 +336,7 @@
 Polygon *
 create_circle(double centerX, double centerY, double radius)
 {
-	util::GeometricShapeFactory shapefactory(global_factory);
+	geos::util::GeometricShapeFactory shapefactory(global_factory);
 	shapefactory.setCentre(Coordinate(centerX, centerY));
 	shapefactory.setSize(radius);
 	// same as:
@@ -349,7 +352,7 @@
 Polygon *
 create_ellipse(double centerX, double centerY, double width, double height)
 {
-	util::GeometricShapeFactory shapefactory(global_factory);
+	geos::util::GeometricShapeFactory shapefactory(global_factory);
 	shapefactory.setCentre(Coordinate(centerX, centerY));
 	shapefactory.setHeight(height);
 	shapefactory.setWidth(width);
@@ -364,7 +367,7 @@
 Polygon *
 create_rectangle(double llX, double llY, double width, double height)
 {
-	util::GeometricShapeFactory shapefactory(global_factory);
+	geos::util::GeometricShapeFactory shapefactory(global_factory);
 	shapefactory.setBase(Coordinate(llX, llY));
 	shapefactory.setHeight(height);
 	shapefactory.setWidth(width);
@@ -381,7 +384,7 @@
 LineString *
 create_arc(double llX, double llY, double width, double height, double startang, double endang)
 {
-	util::GeometricShapeFactory shapefactory(global_factory);
+	geos::util::GeometricShapeFactory shapefactory(global_factory);
 	shapefactory.setBase(Coordinate(llX, llY));
 	shapefactory.setHeight(height);
 	shapefactory.setWidth(width);
@@ -390,6 +393,18 @@
 	return shapefactory.createArc(startang, endang);
 }
 
+auto_ptr<Polygon>
+create_sinestar(double cx, double cy, double size, int nArms, double armLenRat)
+{
+	geos::geom::util::SineStarFactory fact(global_factory);
+	fact.setCentre(Coordinate(cx, cy));
+	fact.setSize(size);
+	fact.setNumPoints(nArms*5);
+  fact.setArmLengthRatio(armLenRat);
+	fact.setNumArms(nArms);
+	return fact.createSineStar();
+}
+
 // Start reading here
 void do_all()
 {
@@ -429,6 +444,7 @@
 	geoms->push_back(create_rectangle(-5, -5, 10, 20)); // a rectangle
 	// The upper-right quarter of a vertical ellipse
 	geoms->push_back(create_arc(0, 0, 10, 20, 0, M_PI/2));
+	geoms->push_back(create_sinestar(10, 10, 100, 5, 2).release()); // a sine star
 #endif
 
 	// Print all geoms.
@@ -474,7 +490,7 @@
 			Geometry *g2 = g->buffer(10);
 			newgeoms->push_back(g2);
 		}
-		catch (const util::GEOSException& exc) {
+		catch (const GEOSException& exc) {
 			cerr <<"GEOS Exception: geometry "<<i<<"->buffer(10): "<<exc.what()<<"\n";
 		}
 	}
@@ -540,7 +556,7 @@
 				else cout<<" 0\t";
 			}
 			// Geometry Collection is not a valid argument
-			catch (const util::IllegalArgumentException& exc) {
+			catch (const IllegalArgumentException& exc) {
 				cout<<" X\t";
 			}
 			catch (const std::exception& exc) {
@@ -570,7 +586,7 @@
 				else cout<<" 0\t";
 			}
 			// Geometry Collection is not a valid argument
-			catch (const util::IllegalArgumentException& exc) {
+			catch (const IllegalArgumentException& exc) {
 				cout<<" X\t";
 			}
 			catch (const std::exception& exc) {
@@ -600,7 +616,7 @@
 				else cout<<" 0\t";
 			}
 			// Geometry Collection is not a valid argument
-			catch (const util::IllegalArgumentException& exc) {
+			catch (const IllegalArgumentException& exc) {
 				cout<<" X\t";
 			}
 			catch (const std::exception& exc) {
@@ -630,7 +646,7 @@
 				else cout<<" 0\t";
 			}
 			// Geometry Collection is not a valid argument
-			catch (const util::IllegalArgumentException& exc) {
+			catch (const IllegalArgumentException& exc) {
 				cout<<" X\t";
 			}
 			catch (const std::exception& exc) {
@@ -660,7 +676,7 @@
 				else cout<<" 0\t";
 			}
 			// Geometry Collection is not a valid argument
-			catch (const util::IllegalArgumentException& exc) {
+			catch (const IllegalArgumentException& exc) {
 				cout<<" X\t";
 			}
 			catch (const std::exception& exc) {
@@ -690,7 +706,7 @@
 				else cout<<" 0\t";
 			}
 			// Geometry Collection is not a valid argument
-			catch (const util::IllegalArgumentException& exc) {
+			catch (const IllegalArgumentException& exc) {
 				cout<<" X\t";
 			}
 			catch (const std::exception& exc) {
@@ -720,7 +736,7 @@
 				else cout<<" 0\t";
 			}
 			// Geometry Collection is not a valid argument
-			catch (const util::IllegalArgumentException& exc) {
+			catch (const IllegalArgumentException& exc) {
 				cout<<" X\t";
 			}
 			catch (const std::exception& exc) {
@@ -757,7 +773,7 @@
 				delete im; // delete afterwards
 			}
 			// Geometry Collection is not a valid argument
-			catch (const util::IllegalArgumentException& exc) {
+			catch (const IllegalArgumentException& exc) {
 				cout<<" X\t";
 			}
 			catch (const std::exception& exc) {
@@ -787,7 +803,7 @@
 				else cout<<" 0\t";
 			}
 			// Geometry Collection is not a valid argument
-			catch (const util::IllegalArgumentException& exc) {
+			catch (const IllegalArgumentException& exc) {
 				cout<<" X\t";
 			}
 			catch (const std::exception& exc) {
@@ -818,7 +834,7 @@
 				else cout<<" 0\t";
 			}
 			// Geometry Collection is not a valid argument
-			catch (const util::IllegalArgumentException& exc) {
+			catch (const IllegalArgumentException& exc) {
 				cout<<" X\t";
 			}
 			catch (const std::exception& exc) {
@@ -849,7 +865,7 @@
 				else cout<<" 0\t";
 			}
 			// Geometry Collection is not a valid argument
-			catch (const util::IllegalArgumentException& exc) {
+			catch (const IllegalArgumentException& exc) {
 				cout<<" X\t";
 			}
 			catch (const std::exception& exc) {
@@ -887,7 +903,7 @@
 				newgeoms->push_back(g3);
 			}
 			// It's illegal to union a collection ...
-			catch (const util::IllegalArgumentException& ill) {
+			catch (const IllegalArgumentException& ill) {
 				//cerr <<ill.toString()<<"\n";
 			}
 			catch (const std::exception& exc) {
@@ -922,7 +938,7 @@
 				newgeoms->push_back(g3);
 			}
 			// Collection are illegal as intersection argument
-			catch (const util::IllegalArgumentException& ill) {
+			catch (const IllegalArgumentException& ill) {
 				//cerr <<ill.toString()<<"\n";
 			}
 			catch (const std::exception& exc) {
@@ -955,7 +971,7 @@
 				newgeoms->push_back(g3);
 			}
 			// Collection are illegal as difference argument
-			catch (const util::IllegalArgumentException& ill) {
+			catch (const IllegalArgumentException& ill) {
 				//cerr <<ill.toString()<<"\n";
 			}
 			catch (const std::exception& exc) {
@@ -988,7 +1004,7 @@
 				newgeoms->push_back(g3);
 			}
 			// Collection are illegal as symdifference argument
-			catch (const util::IllegalArgumentException& ill) {
+			catch (const IllegalArgumentException& ill) {
 				//cerr <<ill.toString()<<"\n";
 			}
 			catch (const std::exception& exc) {
@@ -1079,7 +1095,7 @@
 	}
 	// All exception thrown by GEOS are subclasses of this
 	// one, so this is a catch-all 
-	catch (const util::GEOSException& exc)
+	catch (const GEOSException& exc)
 	{
 		cerr <<"GEOS Exception: "<<exc.what()<<"\n";
 		exit(1);

Modified: trunk/include/geos/geom/util/Makefile.am
===================================================================
--- trunk/include/geos/geom/util/Makefile.am	2011-04-28 10:04:11 UTC (rev 3312)
+++ trunk/include/geos/geom/util/Makefile.am	2011-04-28 10:04:27 UTC (rev 3313)
@@ -19,4 +19,5 @@
     LinearComponentExtracter.h \
     PointExtracter.h \
     PolygonExtracter.h \
-    ShortCircuitedGeometryVisitor.h
+    ShortCircuitedGeometryVisitor.h \
+    SineStarFactory.h

Added: trunk/include/geos/geom/util/SineStarFactory.h
===================================================================
--- trunk/include/geos/geom/util/SineStarFactory.h	                        (rev 0)
+++ trunk/include/geos/geom/util/SineStarFactory.h	2011-04-28 10:04:27 UTC (rev 3313)
@@ -0,0 +1,122 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.refractions.net
+ *
+ * Copyright (C) 2011 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: geom/util/SineStarFactory.java r378 (JTS-1.12)
+ *
+ **********************************************************************/
+
+#ifndef GEOS_UTIL_SINESTARFACTORY_H
+#define GEOS_UTIL_SINESTARFACTORY_H
+
+#include <geos/export.h>
+
+#include <geos/util/GeometricShapeFactory.h> // for inheritance
+
+#include <memory>
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class
+#endif
+
+// Forward declarations
+namespace geos {
+	namespace geom { 
+		class Coordinate;
+		class Envelope;
+		class Polygon;
+		class GeometryFactory;
+		class PrecisionModel;
+		class LineString;
+	}
+}
+
+namespace geos {
+namespace geom { // geos::geom
+namespace util { // geos::geom::util
+
+/**
+ * Creates geometries which are shaped like multi-armed stars
+ * with each arm shaped like a sine wave.
+ * These kinds of geometries are useful as a more complex
+ * geometry for testing algorithms.
+ *
+ * @author Martin Davis
+ *
+ */
+class GEOS_DLL SineStarFactory : public geos::util::GeometricShapeFactory  {
+
+protected:
+
+  int numArms;
+  double armLengthRatio;
+
+public:
+
+  /**
+   * Creates a factory which will create sine stars using the given
+   * {@link GeometryFactory}.
+   *
+	 * @param fact the factory to use. You need to keep the
+	 *	factory alive for the whole SineStarFactory
+	 *	life time.
+   */
+	SineStarFactory(const geom::GeometryFactory* fact)
+    :
+    geos::util::GeometricShapeFactory(fact),
+    numArms(8),
+    armLengthRatio(0.5)
+  {}
+
+  /**
+   * Sets the number of arms in the star
+   *
+   * @param nArms the number of arms to generate
+   */
+  void setNumArms(int nArms)
+  {
+    numArms = numArms;
+  }
+
+  /**
+   * Sets the ration of the length of each arm to the distance from the tip
+   * of the arm to the centre of the star.
+   * Value should be between 0.0 and 1.0
+   *
+   * @param armLenRatio
+   */
+  void setArmLengthRatio(double armLenRatio)
+  {
+        armLengthRatio = armLenRatio;
+  }
+
+  /**
+   * Generates the geometry for the sine star
+   *
+   * @return the geometry representing the sine star
+   */
+  std::auto_ptr<Polygon> createSineStar() const;
+
+
+};
+
+} // namespace geos::geom::util
+} // namespace geos::geom
+} // namespace geos
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // GEOS_UTIL_SINESTARFACTORY_H

Modified: trunk/include/geos/util/GeometricShapeFactory.h
===================================================================
--- trunk/include/geos/util/GeometricShapeFactory.h	2011-04-28 10:04:11 UTC (rev 3312)
+++ trunk/include/geos/util/GeometricShapeFactory.h	2011-04-28 10:04:27 UTC (rev 3313)
@@ -80,14 +80,14 @@
 		void setHeight(double nHeight);
 
 		// Return newly-allocated object, ownership transferred
-		geom::Envelope* getEnvelope();
+		geom::Envelope* getEnvelope() const;
 	};
 	const geom::GeometryFactory* geomFact; // externally owned
 	const geom::PrecisionModel* precModel; // externally owned
 	Dimensions dim;
 	int nPts;
 
-	geom::Coordinate createCoord(double x, double y) const;
+	geom::Coordinate coord(double x, double y) const;
 
 public:
 
@@ -103,7 +103,7 @@
 	 */
 	GeometricShapeFactory(const geom::GeometryFactory *factory);
 
-	~GeometricShapeFactory();
+	virtual ~GeometricShapeFactory() {}
 
 	/**
 	 * \brief Creates an elliptical arc, as a LineString.

Modified: trunk/src/geom/util/Makefile.am
===================================================================
--- trunk/src/geom/util/Makefile.am	2011-04-28 10:04:11 UTC (rev 3312)
+++ trunk/src/geom/util/Makefile.am	2011-04-28 10:04:27 UTC (rev 3313)
@@ -12,4 +12,5 @@
     GeometryEditor.cpp \
     GeometryTransformer.cpp \
     ShortCircuitedGeometryVisitor.cpp \
+    SineStarFactory.cpp \
     GeometryCombiner.cpp

Added: trunk/src/geom/util/SineStarFactory.cpp
===================================================================
--- trunk/src/geom/util/SineStarFactory.cpp	                        (rev 0)
+++ trunk/src/geom/util/SineStarFactory.cpp	2011-04-28 10:04:27 UTC (rev 3313)
@@ -0,0 +1,93 @@
+/**********************************************************************
+ * $Id$
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.refractions.net
+ *
+ * Copyright (C) 2011 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: geom/util/SineStarFactory.java r378 (JTS-1.12)
+ *
+ **********************************************************************/
+
+#include <geos/geom/util/SineStarFactory.h>
+#include <geos/geom/Coordinate.h>
+#include <geos/geom/CoordinateSequenceFactory.h>
+#include <geos/geom/GeometryFactory.h>
+#include <geos/geom/Envelope.h>
+
+#include <vector>
+#include <cmath>
+#include <memory>
+
+#ifndef M_PI
+#define M_PI        3.14159265358979323846
+#endif
+
+using namespace std;
+//using namespace geos::geom;
+
+namespace geos {
+namespace geom { // geos::geom
+namespace util { // geos::geom::util
+
+/* public */
+auto_ptr<Polygon>
+SineStarFactory::createSineStar() const
+{
+  auto_ptr<Envelope> env ( dim.getEnvelope() );
+  double radius = env->getWidth() / 2.0;
+
+  double armRatio = armLengthRatio;
+  if (armRatio < 0.0) armRatio = 0.0;
+  if (armRatio > 1.0) armRatio = 1.0;
+
+  double armMaxLen = armRatio * radius;
+  double insideRadius = (1 - armRatio) * radius;
+
+  double centreX = env->getMinX() + radius;
+  double centreY = env->getMinY() + radius;
+
+  auto_ptr< vector<Coordinate> > pts ( new vector<Coordinate>(nPts+1) );
+  int iPt = 0;
+  for (int i = 0; i < nPts; i++) {
+    // the fraction of the way thru the current arm - in [0,1]
+    double ptArcFrac = (i / (double) nPts) * numArms;
+    double armAngFrac = ptArcFrac - floor(ptArcFrac);
+
+    // the angle for the current arm - in [0,2Pi]
+    // (each arm is a complete sine wave cycle)
+    double armAng = 2 * M_PI * armAngFrac;
+    // the current length of the arm
+    double armLenFrac = (cos(armAng) + 1.0) / 2.0;
+
+    // the current radius of the curve (core + arm)
+    double curveRadius = insideRadius + armMaxLen * armLenFrac;
+
+    // the current angle of the curve
+    double ang = i * (2 * M_PI / nPts);
+    double x = curveRadius * cos(ang) + centreX;
+    double y = curveRadius * sin(ang) + centreY;
+    (*pts)[iPt++] = coord(x, y);
+  }
+  (*pts)[iPt] = Coordinate((*pts)[0]);
+
+  auto_ptr<CoordinateSequence> cs (
+    geomFact->getCoordinateSequenceFactory()->create( pts.release() )
+  );
+  auto_ptr<LinearRing> ring ( geomFact->createLinearRing( cs.release() ) );
+  auto_ptr<Polygon> poly ( geomFact->createPolygon(ring.release(), 0) );
+  return poly;
+}
+
+} // namespace geos::geom::util
+} // namespace geos::geom
+} // namespace geos
+

Modified: trunk/src/util/GeometricShapeFactory.cpp
===================================================================
--- trunk/src/util/GeometricShapeFactory.cpp	2011-04-28 10:04:11 UTC (rev 3312)
+++ trunk/src/util/GeometricShapeFactory.cpp	2011-04-28 10:04:27 UTC (rev 3313)
@@ -47,11 +47,6 @@
 {
 }
 
-GeometricShapeFactory::~GeometricShapeFactory()
-{
-	//delete dim;
-}
-
 void
 GeometricShapeFactory::setBase(const Coordinate& base) 
 {
@@ -105,22 +100,22 @@
 	for (i = 0; i < nSide; i++) {
 		double x = env->getMinX() + i * XsegLen;
 		double y = env->getMinY();
-		(*vc)[ipt++] = createCoord(x, y); 
+		(*vc)[ipt++] = coord(x, y); 
 	}
 	for (i = 0; i < nSide; i++) {
 		double x = env->getMaxX();
 		double y = env->getMinY() + i * YsegLen;
-		(*vc)[ipt++] = createCoord(x, y); 
+		(*vc)[ipt++] = coord(x, y); 
 	}
 	for (i = 0; i < nSide; i++) {
 		double x = env->getMaxX() - i * XsegLen;
 		double y = env->getMaxY();
-		(*vc)[ipt++] = createCoord(x, y); 
+		(*vc)[ipt++] = coord(x, y); 
 	}
 	for (i = 0; i < nSide; i++) {
 		double x = env->getMinX();
 		double y = env->getMaxY() - i * YsegLen;
-		(*vc)[ipt++] = createCoord(x, y); 
+		(*vc)[ipt++] = coord(x, y); 
 	}
 	(*vc)[ipt++] = (*vc)[0];
 	CoordinateSequence *cs = geomFact->getCoordinateSequenceFactory()->create(vc);
@@ -146,7 +141,7 @@
 		double ang = i * (2 * 3.14159265358979 / nPts);
 		double x = xRadius * cos(ang) + centreX;
 		double y = yRadius * sin(ang) + centreY;
-		(*pts)[iPt++] = createCoord(x, y);
+		(*pts)[iPt++] = coord(x, y);
 	}
 	(*pts)[iPt++] = (*pts)[0];
 	CoordinateSequence *cs=geomFact->getCoordinateSequenceFactory()->create(pts);
@@ -177,7 +172,7 @@
 		double ang = startAng + i * angInc;
 		double x = xRadius * cos(ang) + centreX;
 		double y = yRadius * sin(ang) + centreY;
-		(*pts)[iPt++] = createCoord(x, y);
+		(*pts)[iPt++] = coord(x, y);
 	}
 	CoordinateSequence *cs = geomFact->getCoordinateSequenceFactory()->create(pts);
 	LineString* line = geomFact->createLineString(cs);
@@ -202,14 +197,14 @@
 
 	vector<Coordinate> *pts = new vector<Coordinate>(nPts + 2);
 	int iPt = 0;
-	(*pts)[iPt++] = createCoord(centreX, centreY);
+	(*pts)[iPt++] = coord(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++] = coord(x, y);
 	}
-	(*pts)[iPt++] = createCoord(centreX, centreY);
+	(*pts)[iPt++] = coord(centreX, centreY);
 
 	CoordinateSequence *cs = geomFact->getCoordinateSequenceFactory()->create(pts);
 	LinearRing* ring = geomFact->createLinearRing(cs);
@@ -255,7 +250,7 @@
 }
 
 Envelope*
-GeometricShapeFactory::Dimensions::getEnvelope()
+GeometricShapeFactory::Dimensions::getEnvelope() const
 {
 	if (!base.isNull()) {
 		return new Envelope(base.x, base.x + width, base.y, base.y + height);
@@ -268,7 +263,7 @@
 
 /*protected*/
 Coordinate
-GeometricShapeFactory::createCoord(double x, double y) const
+GeometricShapeFactory::coord(double x, double y) const
 {
 	Coordinate ret(x, y);
 	precModel->makePrecise(&ret);
@@ -278,13 +273,3 @@
 } // namespace geos.util
 } // namespace geos
 
-/**********************************************************************
- * $Log$
- * Revision 1.15  2006/03/22 16:58:35  strk
- * Removed (almost) all inclusions of geom.h.
- * Removed obsoleted .cpp files.
- * Fixed a bug in WKTReader not using the provided CoordinateSequence
- * implementation, optimized out some memory allocations.
- *
- **********************************************************************/
-



More information about the geos-commits mailing list