[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