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

svn_geos at osgeo.org svn_geos at osgeo.org
Wed May 19 01:22:25 EDT 2010


Author: warmerdam
Date: 2010-05-19 01:22:24 -0400 (Wed, 19 May 2010)
New Revision: 2993

Added:
   trunk/tests/unit/io/WKTReaderTest.cpp
   trunk/tests/unit/io/WKTWriterTest.cpp
Modified:
   trunk/capi/geos_c.cpp
   trunk/capi/geos_c.h.in
   trunk/capi/geos_ts_c.cpp
   trunk/include/geos/io/WKTWriter.h
   trunk/src/io/WKTWriter.cpp
   trunk/tests/unit/Makefile.am
Log:
added setPrecision, setTrim support on WKTWriter and provided tests (#341)

Modified: trunk/capi/geos_c.cpp
===================================================================
--- trunk/capi/geos_c.cpp	2010-05-18 20:28:50 UTC (rev 2992)
+++ trunk/capi/geos_c.cpp	2010-05-19 05:22:24 UTC (rev 2993)
@@ -811,13 +811,24 @@
     GEOSWKTWriter_destroy_r( handle, Writer );
 }
 
-
 char*
 GEOSWKTWriter_write(WKTWriter *writer, const Geometry *geom)
 {
     return GEOSWKTWriter_write_r( handle, writer, geom );
 }
 
+void
+GEOSWKTWriter_setTrim(WKTWriter *writer, char trim)
+{
+	GEOSWKTWriter_setTrim_r(handle, writer, trim);
+}
+
+void
+GEOSWKTWriter_setRoundingPrecision(WKTWriter *writer, int precision)
+{
+	return GEOSWKTWriter_setRoundingPrecision_r(handle, writer, precision);
+}
+
 /* WKB Reader */
 WKBReader *
 GEOSWKBReader_create()

Modified: trunk/capi/geos_c.h.in
===================================================================
--- trunk/capi/geos_c.h.in	2010-05-18 20:28:50 UTC (rev 2992)
+++ trunk/capi/geos_c.h.in	2010-05-19 05:22:24 UTC (rev 2993)
@@ -993,6 +993,8 @@
 extern GEOSWKTWriter GEOS_DLL *GEOSWKTWriter_create();
 extern void GEOS_DLL GEOSWKTWriter_destroy(GEOSWKTWriter* writer);
 extern char GEOS_DLL *GEOSWKTWriter_write(GEOSWKTWriter* reader, const GEOSGeometry* g);
+extern void GEOS_DLL GEOSWKTWriter_setTrim(GEOSWKTWriter *writer, char trim);
+extern void GEOS_DLL GEOSWKTWriter_setRoundingPrecision(GEOSWKTWriter *writer, int precision);
 
 extern GEOSWKTWriter GEOS_DLL *GEOSWKTWriter_create_r(
                                              GEOSContextHandle_t handle);
@@ -1001,6 +1003,12 @@
 extern char GEOS_DLL *GEOSWKTWriter_write_r(GEOSContextHandle_t handle,
                                             GEOSWKTWriter* reader,
                                             const GEOSGeometry* g);
+extern void GEOS_DLL GEOSWKTWriter_setTrim_r(GEOSContextHandle_t handle,
+                                            GEOSWKTWriter *writer,
+                                            char trim);
+extern void GEOS_DLL GEOSWKTWriter_setRoundingPrecision_r(GEOSContextHandle_t handle,
+                                            GEOSWKTWriter *writer,
+                                            int precision);
 
 /* WKB Reader */
 extern GEOSWKBReader GEOS_DLL *GEOSWKBReader_create();

Modified: trunk/capi/geos_ts_c.cpp
===================================================================
--- trunk/capi/geos_ts_c.cpp	2010-05-18 20:28:50 UTC (rev 2992)
+++ trunk/capi/geos_ts_c.cpp	2010-05-19 05:22:24 UTC (rev 2993)
@@ -4065,6 +4065,46 @@
     return NULL;
 }
 
+void
+GEOSWKTWriter_setTrim_r(GEOSContextHandle_t extHandle, WKTWriter *writer, char trim)
+{
+    assert(0 != writer);
+
+    if ( 0 == extHandle )
+    {
+        return;
+    }
+
+    GEOSContextHandleInternal_t *handle = 0;
+    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
+    if ( 0 == handle->initialized )
+    {
+        return;
+    }
+
+    writer->setTrim(trim);
+}
+
+void
+GEOSWKTWriter_setRoundingPrecision_r(GEOSContextHandle_t extHandle, WKTWriter *writer, int precision)
+{
+    assert(0 != writer);
+
+    if ( 0 == extHandle )
+    {
+        return;
+    }
+
+    GEOSContextHandleInternal_t *handle = 0;
+    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
+    if ( 0 == handle->initialized )
+    {
+        return;
+    }
+
+    writer->setRoundingPrecision(precision);
+}
+
 /* WKB Reader */
 WKBReader *
 GEOSWKBReader_create_r(GEOSContextHandle_t extHandle)

Modified: trunk/include/geos/io/WKTWriter.h
===================================================================
--- trunk/include/geos/io/WKTWriter.h	2010-05-18 20:28:50 UTC (rev 2992)
+++ trunk/include/geos/io/WKTWriter.h	2010-05-19 05:22:24 UTC (rev 2993)
@@ -122,7 +122,23 @@
 	 */
 	static std::string toPoint(const geom::Coordinate& p0);
  
+	/**
+	 * Sets the rounding precision when writing the WKT
+	 * a precision of -1 disables it
+	 *
+	 * @param p0 the new precision to use
+	 *
+	 */
+	void setRoundingPrecision(int p0);
 
+	/**
+	 * Enables/disables trimming of unnecessary decimals
+	 *
+	 * @param p0 the trim boolean
+	 *
+	 */
+	void setTrim(bool p0);
+
 protected:
 
 	std::string formatter;
@@ -202,10 +218,15 @@
 //	static const int INDENT = 2;
 
 	static std::string createFormatter(
-			const geom::PrecisionModel* precisionModel);
+			const geom::PrecisionModel* precisionModel,
+			int overwritePrecision);
 
 	bool isFormatted;
 
+	int roundingPrecision;
+
+	bool trim;
+
 	int level;
 
 	void writeFormatted(

Modified: trunk/src/io/WKTWriter.cpp
===================================================================
--- trunk/src/io/WKTWriter.cpp	2010-05-18 20:28:50 UTC (rev 2992)
+++ trunk/src/io/WKTWriter.cpp	2010-05-19 05:22:24 UTC (rev 2993)
@@ -48,6 +48,8 @@
 
 WKTWriter::WKTWriter() {
 	isFormatted=false;
+	roundingPrecision=-1;
+	trim = false;
 	level=0;
 	formatter="%f";
 }
@@ -114,12 +116,31 @@
 	return ret.str();
 }
 
+void
+WKTWriter::setRoundingPrecision(int p0)
+{
+	if(p0 < -1) {
+		p0 = -1;
+	}
+	roundingPrecision = p0;
+}
+
+void
+WKTWriter::setTrim(bool p0)
+{
+	trim = p0;
+}
+
 string
-WKTWriter::createFormatter(const PrecisionModel* precisionModel)
+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);
@@ -165,7 +186,7 @@
 {
         CLocalizer clocale;
 	this->isFormatted=isFormatted;
-	formatter=createFormatter(geometry->getPrecisionModel());
+	formatter=createFormatter(geometry->getPrecisionModel(), roundingPrecision);
 	appendGeometryTaggedText(geometry, 0, writer);
 }
 
@@ -283,6 +304,69 @@
 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;
+
+		//count the length of the string
+		while(buffer[i] != '\0') {
+			i++;
+		}
+		//arrays go to length-1 of course
+		i--;
+
+		/*
+		 * 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;
+		}
+
+		/*
+		 * 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;

Modified: trunk/tests/unit/Makefile.am
===================================================================
--- trunk/tests/unit/Makefile.am	2010-05-18 20:28:50 UTC (rev 2992)
+++ trunk/tests/unit/Makefile.am	2010-05-19 05:22:24 UTC (rev 2993)
@@ -62,6 +62,8 @@
 	index/quadtree/DoubleBitsTest.cpp \
 	io/ByteOrderValuesTest.cpp \
 	io/WKBReaderTest.cpp \
+	io/WKTReaderTest.cpp \
+	io/WKTWriterTest.cpp \
 	linearref/LengthIndexedLineTest.cpp \
 	noding/BasicSegmentStringTest.cpp \
 	noding/NodedSegmentStringTest.cpp \

Added: trunk/tests/unit/io/WKTReaderTest.cpp
===================================================================
--- trunk/tests/unit/io/WKTReaderTest.cpp	                        (rev 0)
+++ trunk/tests/unit/io/WKTReaderTest.cpp	2010-05-19 05:22:24 UTC (rev 2993)
@@ -0,0 +1,93 @@
+// $Id: WKBReaderTest.cpp 2344 2009-04-09 21:46:30Z mloskot $
+// 
+// Test Suite for geos::io::WKTReader 
+
+// tut
+#include <tut.hpp>
+// geos
+#include <geos/io/WKTReader.h>
+#include <geos/geom/PrecisionModel.h>
+#include <geos/geom/GeometryFactory.h>
+#include <geos/geom/Geometry.h>
+#include <geos/geom/CoordinateSequence.h>
+// std
+#include <sstream>
+#include <string>
+#include <memory>
+
+namespace tut
+{
+	//
+	// Test Group
+	//
+
+	// dummy data, not used
+	struct test_wktreader_data
+	{
+		geos::geom::PrecisionModel pm;
+		geos::geom::GeometryFactory gf;
+		geos::io::WKTReader wktreader;
+
+		typedef std::auto_ptr<geos::geom::Geometry> GeomPtr;
+
+		test_wktreader_data()
+			:
+			pm(1.0),
+			gf(&pm),
+			wktreader(&gf)
+		{}
+
+	};
+
+	typedef test_group<test_wktreader_data> group;
+	typedef group::object object;
+
+	group test_wktreader_group("geos::io::WKTReader");
+
+
+	//
+	// Test Cases
+	//
+
+	// 1 - Read a point, confirm 2D.
+	template<>
+	template<>
+	void object::test<1>()
+	{         
+            GeomPtr geom(wktreader.read("POINT(-117 33)"));
+            geos::geom::CoordinateSequence *coords = geom->getCoordinates();
+
+            ensure( coords->getDimension() == 2 );
+            ensure( coords->getX(0) == -117 );
+            ensure( coords->getY(0) == 33 );
+            delete coords;
+        }
+
+	// 2 - Read a point, confirm 3D.
+	template<>
+	template<>
+	void object::test<2>()
+	{         
+            GeomPtr geom(wktreader.read("POINT(-117 33 10)"));
+            geos::geom::CoordinateSequence *coords = geom->getCoordinates();
+
+            ensure( coords->getDimension() == 3 );
+            ensure( coords->getOrdinate(0,geos::geom::CoordinateSequence::Z) == 10.0 );
+            delete coords;
+        }
+
+	// 3 - Linestring dimension preserved.
+	template<>
+	template<>
+	void object::test<3>()
+	{         
+            GeomPtr geom(wktreader.read("LINESTRING(-117 33, -116 34)"));
+            geos::geom::CoordinateSequence *coords = geom->getCoordinates();
+
+            ensure( coords->getDimension() == 2 );
+
+            delete coords;
+        }
+
+} // namespace tut
+

Added: trunk/tests/unit/io/WKTWriterTest.cpp
===================================================================
--- trunk/tests/unit/io/WKTWriterTest.cpp	                        (rev 0)
+++ trunk/tests/unit/io/WKTWriterTest.cpp	2010-05-19 05:22:24 UTC (rev 2993)
@@ -0,0 +1,94 @@
+// $Id: WKBReaderTest.cpp 2344 2009-04-09 21:46:30Z mloskot $
+// 
+// Test Suite for geos::io::WKTReader 
+
+// tut
+#include <tut.hpp>
+// geos
+#include <geos/io/WKTReader.h>
+#include <geos/io/WKTWriter.h>
+#include <geos/geom/PrecisionModel.h>
+#include <geos/geom/GeometryFactory.h>
+#include <geos/geom/Geometry.h>
+// std
+#include <sstream>
+#include <string>
+#include <memory>
+
+namespace tut
+{
+	//
+	// Test Group
+	//
+
+	// dummy data, not used
+	struct test_wktwriter_data
+	{
+		geos::geom::PrecisionModel pm;
+		geos::geom::GeometryFactory gf;
+		geos::io::WKTReader wktreader;
+		geos::io::WKTWriter wktwriter;
+
+		test_wktwriter_data()
+			:
+			pm(1000.0),
+			gf(&pm),
+			wktreader(&gf)
+		{}
+
+	};
+
+	typedef test_group<test_wktwriter_data> group;
+	typedef group::object object;
+
+	group test_wktwriter_group("geos::io::WKTWriter");
+
+
+	//
+	// Test Cases
+	//
+
+	// 1 - Test the trim capability.
+	template<>
+	template<>
+	void object::test<1>()
+	{         
+            geos::geom::Geometry *geom = wktreader.read("POINT(-117 33)");
+            std::string  result;
+
+            wktwriter.setTrim(false);
+            result = wktwriter.write( geom );
+
+            ensure( result == "POINT (-117.0000 33.0000)" );
+
+            wktwriter.setTrim(true);
+            result = wktwriter.write( geom );
+
+            ensure( result == "POINT (-117 33)" );
+
+            delete geom;
+        }
+
+	// 2 - Test the output precision capability
+	template<>
+	template<>
+	void object::test<2>()
+	{         
+            geos::geom::Geometry *geom = wktreader.read("POINT(-117.1234567 33.1234567)");
+            std::string  result;
+
+            wktwriter.setTrim(false);
+            result = wktwriter.write( geom );
+
+            ensure( result == "POINT (-117.1230 33.1230)" );
+
+            wktwriter.setRoundingPrecision(2);
+            result = wktwriter.write( geom );
+
+            ensure( result == "POINT (-117.12 33.12)" );
+
+            delete geom;
+        }
+
+} // namespace tut
+



More information about the geos-commits mailing list