[geos-commits] r3293 - in trunk: include/geos/io src/io tests/unit/io

svn_geos at osgeo.org svn_geos at osgeo.org
Fri Apr 22 09:51:38 EDT 2011


Author: strk
Date: 2011-04-22 06:51:38 -0700 (Fri, 22 Apr 2011)
New Revision: 3293

Modified:
   trunk/include/geos/io/WKTWriter.h
   trunk/src/io/WKTWriter.cpp
   trunk/tests/unit/io/WKTWriterTest.cpp
Log:
Use stringstream to format strings rather than printf-like statements. Simplifies things a lot.

Modified: trunk/include/geos/io/WKTWriter.h
===================================================================
--- trunk/include/geos/io/WKTWriter.h	2011-04-22 13:04:20 UTC (rev 3292)
+++ trunk/include/geos/io/WKTWriter.h	2011-04-22 13:51:38 UTC (rev 3293)
@@ -4,6 +4,7 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.refractions.net
  *
+ * Copyright (C) 2011 Sandro Santilli <strk at keybit.net>
  * Copyright (C) 2005-2006 Refractions Research Inc.
  * Copyright (C) 2001-2002 Vivid Solutions Inc.
  *
@@ -169,7 +170,7 @@
 	
 protected:
 
-	std::string formatter;
+  int decimalPlaces;
 
 	void appendGeometryTaggedText(const geom::Geometry *geometry, int level, Writer *writer);
 
@@ -245,10 +246,6 @@
 
 //	static const int INDENT = 2;
 
-	static std::string createFormatter(
-			const geom::PrecisionModel* precisionModel,
-			int overwritePrecision);
-
 	bool isFormatted;
 
 	int roundingPrecision;

Modified: trunk/src/io/WKTWriter.cpp
===================================================================
--- trunk/src/io/WKTWriter.cpp	2011-04-22 13:04:20 UTC (rev 3292)
+++ trunk/src/io/WKTWriter.cpp	2011-04-22 13:51:38 UTC (rev 3293)
@@ -4,6 +4,7 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.refractions.net
  *
+ * Copyright (C) 2011 Sandro Santilli <strk at keybit.net>
  * Copyright (C) 2005-2006 Refractions Research Inc.
  * Copyright (C) 2001-2002 Vivid Solutions Inc.
  *
@@ -39,6 +40,7 @@
 #include <sstream>
 #include <cassert>
 #include <cmath>
+#include <iomanip>
 
 using namespace std;
 using namespace geos::geom;
@@ -47,7 +49,7 @@
 namespace io { // geos.io
 
 WKTWriter::WKTWriter():
-	formatter("%f"),
+  decimalPlaces(6),
 	isFormatted(false),
 	roundingPrecision(-1),
 	trim(false),
@@ -143,37 +145,9 @@
 	trim = p0;
 }
 
-string
-WKTWriter::createFormatter(const PrecisionModel* precisionModel, int overwritePrecision)
-{
-	// the default number of decimal places is 16, which is sufficient
-	// to accomodate the maximum precision of a double.
-	// if roundingPrecision is specified (not -1) it will be used instead
-	int decimalPlaces = precisionModel->getMaximumSignificantDigits();
-	if(overwritePrecision != -1) {
-		decimalPlaces = overwritePrecision;
-	}
-    std::string fmt("%.");
-    char buffer[255] = { 0 };
-	sprintf(buffer,"%i",decimalPlaces);
-	fmt.append(buffer);
-	fmt.append("f");
-	return fmt;
-}
-
-//string WKTWriter::stringOfChar(char ch, int count) {
-	//string str="";
-	//for (int i=0;i<count;i++) str+=ch;
-	//return string(count, ch);
-//}
-
 string WKTWriter::write(const Geometry *geometry) {
 	Writer sw;
-//	try {
-		writeFormatted(geometry,false,&sw);
-//	} catch (const IOException ex) {
-//		Assert::shouldNeverReachHere();
-//	}
+  writeFormatted(geometry,false,&sw);
 	string res=sw.toString();
 	return res;
 }
@@ -198,7 +172,7 @@
 {
         CLocalizer clocale;
 	this->isFormatted=isFormatted;
-	formatter=createFormatter(geometry->getPrecisionModel(), roundingPrecision);
+  decimalPlaces = roundingPrecision == -1 ? geometry->getPrecisionModel()->getMaximumSignificantDigits() : roundingPrecision;
 	appendGeometryTaggedText(geometry, 0, writer);
 }
 
@@ -340,6 +314,7 @@
 	}
 }
 
+/* pritected */
 void
 WKTWriter::appendCoordinate(const Coordinate* coordinate,
 		Writer *writer)
@@ -359,75 +334,16 @@
 	writer->write(out);
 }
 
-string WKTWriter::writeNumber(double d) {
-    char buffer[255] = { 0 };
-	sprintf(buffer,formatter.c_str(),d);
-	//If we've set trim to true, do it here
-	if(trim)	{
-		bool roundNines = false;
-		int i = 0, j;
+/* protected */
+string
+WKTWriter::writeNumber(double d) {
 
-		//count the length of the string
-		while(buffer[i] != '\0') {
-			i++;
-		}
-		//arrays go to length-1 of course
-		i--;
+  std::stringstream ss;
 
-		/*
-		 * Is there a rounding error at the end?
-		 */
-		if(i > 6 &&
-			buffer[i] != '0' &&
-			buffer[i-1] == '0' &&
-			buffer[i-2] == '0' &&
-			buffer[i-3] == '0' &&
-			buffer[i-4] == '0' &&
-			buffer[i-5] == '0') {
-			buffer[i--] = '\0';
-		}
-		/*
-		 * Do we need to round 9's?
-		 */
-		if(i > 6 &&
-			buffer[i] == '9' &&
-			buffer[i-1] == '9' &&
-			buffer[i-2] == '9' &&
-			buffer[i-3] == '9' &&
-			buffer[i-4] == '9' &&
-			buffer[i-5] == '9') {
-			roundNines = true;
-		}
+  if ( ! trim ) ss << std::fixed;
+  ss << std::setprecision(decimalPlaces >= 0 ? decimalPlaces : 0) << d;
 
-		/*
-		 * Now let's format the string
-		 */
-		for(j = i; j >= 0; j--) {
-			if(roundNines) {
-				if(buffer[j] == '9') {
-					buffer[j] = '\0';
-				}
-				else {
-					buffer[j]++;
-					roundNines = false;
-				}
-			}
-			else if(buffer[j] == '0') {
-				buffer[j] = '\0';
-			}
-			else {
-				//remove period if no decimals
-				if(buffer[j] == '.' && buffer[j+1] == '\0') {
-					buffer[j] = '\0';
-				}
-				//and we're done
-				break;
-			}
-		}
-	}
-	std::string out(buffer);
-	out.append("");
-	return out;
+	return ss.str();
 }
 
 void
@@ -570,101 +486,9 @@
 void WKTWriter::indent(int level, Writer *writer) {
 	if (!isFormatted || level<=0) return;
 	writer->write("\n");
-	//writer->write(stringOfChar(' ', INDENT * level));
 	writer->write(string(INDENT * level, ' '));
 }
 
 } // namespace geos.io
 } // namespace geos
 
-/**********************************************************************
- * $Log$
- * Revision 1.35  2006/06/12 16:55:53  strk
- * fixed compiler warnings, fixed some methods to omit unused parameters.
- *
- * Revision 1.34  2006/06/08 17:58:57  strk
- * Polygon::getNumInteriorRing() return size_t, Polygon::interiorRingN() takes size_t.
- *
- * Revision 1.33  2006/06/01 11:49:36  strk
- * Reduced installed headers form geomgraph namespace
- *
- * Revision 1.32  2006/04/28 11:12:31  strk
- * removed warnings related to change in getNumPoints() return type.
- *
- * Revision 1.31  2006/04/07 09:54:30  strk
- * Geometry::getNumGeometries() changed to return 'unsigned int'
- * rather then 'int'
- *
- * Revision 1.30  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.
- *
- * Revision 1.29  2006/03/20 18:18:15  strk
- * io.h header split
- *
- * Revision 1.28  2006/03/09 16:46:49  strk
- * geos::geom namespace definition, first pass at headers split
- *
- * Revision 1.27  2006/03/06 19:40:47  strk
- * geos::util namespace. New GeometryCollection::iterator interface, many cleanups.
- *
- * Revision 1.26  2006/03/06 15:23:14  strk
- * geos::io namespace
- *
- * Revision 1.25  2006/03/03 10:46:21  strk
- * Removed 'using namespace' from headers, added missing headers in .cpp files, removed useless includes in headers (bug#46)
- *
- * Revision 1.24  2006/02/09 15:52:47  strk
- * GEOSException derived from std::exception; always thrown and cought by const ref.
- *
- * Revision 1.23  2006/02/08 17:18:28  strk
- * - New WKTWriter::toLineString and ::toPoint convenience methods
- * - New IsValidOp::setSelfTouchingRingFormingHoleValid method
- * - New Envelope::centre()
- * - New Envelope::intersection(Envelope)
- * - New Envelope::expandBy(distance, [ydistance])
- * - New LineString::reverse()
- * - New MultiLineString::reverse()
- * - New Geometry::buffer(distance, quadSeg, endCapStyle)
- * - Obsoleted toInternalGeometry/fromInternalGeometry
- * - More const-correctness in Buffer "package"
- *
- * Revision 1.22  2006/01/18 17:46:57  strk
- * Fixed leak in ::writeFormatted(Geometry *)
- *
- * Revision 1.21  2004/12/08 13:54:43  strk
- * gcc warnings checked and fixed, general cleanups.
- *
- * Revision 1.20  2004/10/21 22:29:54  strk
- * Indentation changes and some more COMPUTE_Z rules
- *
- * Revision 1.19  2004/10/20 17:32:14  strk
- * Initial approach to 2.5d intersection()
- *
- * Revision 1.18  2004/07/19 13:19:31  strk
- * Documentation fixes
- *
- * Revision 1.17  2004/07/07 09:38:12  strk
- * Dropped WKTWriter::stringOfChars (implemented by std::string).
- * Dropped WKTWriter default constructor (internally created GeometryFactory).
- * Updated XMLTester to respect the changes.
- * Main documentation page made nicer.
- *
- * Revision 1.16  2004/07/02 13:28:27  strk
- * Fixed all #include lines to reflect headers layout change.
- * Added client application build tips in README.
- *
- * Revision 1.15  2004/03/18 10:42:44  ybychkov
- * "IO" and "Util" upgraded to JTS 1.4
- * "Geometry" partially upgraded.
- *
- * Revision 1.14  2003/11/07 01:23:42  pramsey
- * Add standard CVS headers licence notices and copyrights to all cpp and h
- * files.
- *
- *
- **********************************************************************/
-
-

Modified: trunk/tests/unit/io/WKTWriterTest.cpp
===================================================================
--- trunk/tests/unit/io/WKTWriterTest.cpp	2011-04-22 13:04:20 UTC (rev 3292)
+++ trunk/tests/unit/io/WKTWriterTest.cpp	2011-04-22 13:51:38 UTC (rev 3293)
@@ -24,11 +24,17 @@
 	// dummy data, not used
 	struct test_wktwriter_data
 	{
-		geos::geom::PrecisionModel pm;
-		geos::geom::GeometryFactory gf;
-		geos::io::WKTReader wktreader;
-		geos::io::WKTWriter wktwriter;
+		typedef geos::geom::PrecisionModel PrecisionModel;
+		typedef geos::geom::GeometryFactory GeometryFactory;
+		typedef geos::io::WKTReader WKTReader;
+		typedef geos::io::WKTWriter WKTWriter;
+		typedef std::auto_ptr<geos::geom::Geometry> GeomPtr;
 
+		PrecisionModel pm;
+		GeometryFactory gf;
+		WKTReader wktreader;
+		WKTWriter wktwriter;
+
 		test_wktwriter_data()
                 :
                 pm(1000.0),
@@ -53,20 +59,18 @@
 	template<>
 	void object::test<1>()
 	{         
-        geos::geom::Geometry *geom = wktreader.read("POINT(-117 33)");
+        GeomPtr geom ( wktreader.read("POINT(-117 33)") );
         std::string  result;
 
         wktwriter.setTrim(false);
-        result = wktwriter.write( geom );
+        result = wktwriter.write( geom.get() );
 
         ensure_equals( result , "POINT (-117.000 33.000)" );
 
         wktwriter.setTrim(true);
-        result = wktwriter.write( geom );
+        result = wktwriter.write( geom.get() );
 
         ensure_equals( result , "POINT (-117 33)" );
-
-        delete geom;
     }
 
 	// 2 - Test the output precision capability
@@ -74,20 +78,19 @@
 	template<>
 	void object::test<2>()
 	{         
-        geos::geom::Geometry *geom = wktreader.read("POINT(-117.1234567 33.1234567)");
+        GeomPtr geom ( wktreader.read("POINT(-117.1234567 33.1234567)") );
         std::string  result;
 
         wktwriter.setTrim(false);
-        result = wktwriter.write( geom );
+        result = wktwriter.write( geom.get() );
 
         ensure_equals( result , "POINT (-117.123 33.123)" );
 
         wktwriter.setRoundingPrecision(2);
-        result = wktwriter.write( geom );
+        result = wktwriter.write( geom.get() );
 
         ensure_equals( result , "POINT (-117.12 33.12)" );
 
-        delete geom;
     }
     
 	// 3 - Test 3D generation from a 3D geometry.
@@ -95,23 +98,22 @@
 	template<>
 	void object::test<3>()
 	{         
-        geos::geom::Geometry *geom = wktreader.read("POINT Z (-117 33 120)");
+        GeomPtr geom ( wktreader.read("POINT Z (-117 33 120)") );
         std::string  result;
 
         wktwriter.setOutputDimension(3);
         wktwriter.setTrim( true );
         wktwriter.setOld3D( false );
 
-        result = wktwriter.write( geom );
+        result = wktwriter.write( geom.get() );
 
         ensure_equals( result, std::string("POINT Z (-117 33 120)") );
 
         wktwriter.setOld3D( true );
-        result = wktwriter.write( geom );
+        result = wktwriter.write( geom.get() );
 
         ensure_equals( result, std::string("POINT (-117 33 120)") );
 
-        delete geom;
     }
     
 	// 4 - Test 2D generation from a 3D geometry.
@@ -119,41 +121,30 @@
 	template<>
 	void object::test<4>()
 	{         
-        geos::geom::Geometry *geom = wktreader.read("POINT(-117 33 120)");
+        GeomPtr geom ( wktreader.read("POINT(-117 33 120)") );
         std::string  result;
 
         wktwriter.setOutputDimension(2);
         wktwriter.setTrim( true );
         wktwriter.setOld3D( false );
 
-        result = wktwriter.write( geom );
+        result = wktwriter.write( geom.get() );
 
         ensure_equals( result, std::string("POINT (-117 33)") );
-
-        delete geom;
     }
 
-  // 5 - Test fixed precision model geometries
+  // 5 - Test negative number of digits in precision model 
   template<>
   template<>
   void object::test<5>()
   {         
+    PrecisionModel pm3(0.001);
+    GeometryFactory gf3(&pm3);
+    WKTReader wktreader3(&gf3);
+    GeomPtr geom ( wktreader3.read("POINT(123456 654321)") );
 
-/*
- * For example, to specify 3 decimal places of precision, use a scale factor
- * of 1000. To specify -3 decimal places of precision (i.e. rounding to
- * the nearest 1000), use a scale factor of 0.001.
- */
-
-    geos::geom::PrecisionModel pm3(1000, 0, 0);
-    geos::geom::GeometryFactory gf3(&pm3);
-    geos::io::WKTReader wktreader3(&gf3);
-    geos::geom::Geometry *geom = wktreader3.read("POINT(0.123456 1.98765)");
-
-    std::string  result = wktwriter.write( geom );
-    ensure_equals( result, std::string("POINT (0.123 1.988)") );
-
-    delete geom;
+    std::string  result = wktwriter.write( geom.get() );
+    ensure_equals( result, std::string("POINT (123000 654000)") );
   }
     
 } // namespace tut



More information about the geos-commits mailing list