[geos-commits] r3605 - in trunk: . include/geos/precision src/precision tests/unit tests/unit/precision

svn_geos at osgeo.org svn_geos at osgeo.org
Tue Apr 10 04:38:19 EDT 2012


Author: strk
Date: 2012-04-10 01:38:18 -0700 (Tue, 10 Apr 2012)
New Revision: 3605

Added:
   trunk/include/geos/precision/GeometryPrecisionReducer.h
   trunk/include/geos/precision/PrecisionReducerCoordinateOperation.h
   trunk/src/precision/GeometryPrecisionReducer.cpp
   trunk/src/precision/PrecisionReducerCoordinateOperation.cpp
   trunk/tests/unit/precision/GeometryPrecisionReducerTest.cpp
Modified:
   trunk/NEWS
   trunk/include/geos/precision/Makefile.am
   trunk/src/precision/Makefile.am
   trunk/src/precision/SimpleGeometryPrecisionReducer.cpp
   trunk/tests/unit/Makefile.am
Log:
Port GeometryPrecisionReducer, include testcase

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2012-04-06 19:04:01 UTC (rev 3604)
+++ trunk/NEWS	2012-04-10 08:38:18 UTC (rev 3605)
@@ -3,6 +3,7 @@
 
 - New things:
   - CAPI: GEOSNode (#496)
+  - GeometryPrecisionReducer class
 - C++ API changes:
   - New noding::GeometryNoder class
   - Added BufferOp::setSingleSided 

Added: trunk/include/geos/precision/GeometryPrecisionReducer.h
===================================================================
--- trunk/include/geos/precision/GeometryPrecisionReducer.h	                        (rev 0)
+++ trunk/include/geos/precision/GeometryPrecisionReducer.h	2012-04-10 08:38:18 UTC (rev 3605)
@@ -0,0 +1,159 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2012 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: precision/GeometryPrecisionReducer.cpp rev. 1.10 (JTS-1.7)
+ *
+ **********************************************************************/
+
+#ifndef GEOS_PRECISION_GEOMETRYPRECISIONREDUCER_H
+#define GEOS_PRECISION_GEOMETRYPRECISIONREDUCER_H
+
+#include <geos/export.h>
+#include <memory> // for auto_ptr
+
+// Forward declarations
+namespace geos {
+  namespace geom { 
+    class PrecisionModel;
+    class GeometryFactory;
+    class Geometry;
+  }
+}
+
+namespace geos {
+namespace precision { // geos.precision
+
+/** \brief
+ * Reduces the precision of a {@link Geometry}
+ * according to the supplied {@link PrecisionModel}, 
+ * ensuring that the result is topologically valid.
+ */
+class GEOS_DLL GeometryPrecisionReducer {
+
+private:
+
+  // Externally owned
+  const geom::GeometryFactory *newFactory;
+
+  const geom::PrecisionModel &targetPM;
+
+  bool removeCollapsed;
+
+  bool isPointwise;
+
+  std::auto_ptr<geom::Geometry> reducePointwise( const geom::Geometry& geom );
+
+  std::auto_ptr<geom::Geometry> fixPolygonalTopology(
+                                                 const geom::Geometry& geom );
+
+  std::auto_ptr<geom::GeometryFactory> createFactory(
+                                          const geom::GeometryFactory& oldGF,
+                                          const geom::PrecisionModel& newPM );
+
+public:
+
+  /**
+   * Convenience method for doing precision reduction
+   * on a single geometry,
+   * with collapses removed
+   * and keeping the geometry precision model the same,
+   * and preserving polygonal topology.
+   *
+   * @param g the geometry to reduce
+   * @param precModel the precision model to use
+   * @return the reduced geometry
+   */
+  static std::auto_ptr<geom::Geometry> reduce(
+                                const geom::Geometry &g,
+                                const geom::PrecisionModel &precModel )
+  {
+    GeometryPrecisionReducer reducer(precModel);
+    return reducer.reduce(g);
+  }
+
+  /**
+   * Convenience method for doing precision reduction
+   * on a single geometry,
+   * with collapses removed
+   * and keeping the geometry precision model the same,
+   * but NOT preserving valid polygonal topology.
+   *
+   * @param g the geometry to reduce
+   * @param precModel the precision model to use
+   * @return the reduced geometry
+   */
+  static std::auto_ptr<geom::Geometry> reducePointwise(
+                                const geom::Geometry &g,
+                                const geom::PrecisionModel &precModel )
+  {
+    GeometryPrecisionReducer reducer(precModel);
+    reducer.setPointwise(true);
+    return reducer.reduce(g);
+  }
+
+  GeometryPrecisionReducer(const geom::PrecisionModel &pm)
+      :
+      newFactory(0),
+      targetPM(pm),
+      removeCollapsed(true),
+      isPointwise(false)
+  {}
+
+  /**
+   * \brief
+   * Create a reducer that will change the precision model of the
+   * new reduced Geometry
+   *
+   * @param gf the factory for the created Geometry.
+   *           Its PrecisionModel will be used for the reduction.
+   *           NOTE: ownership left to caller must be kept alive for
+   *           the whole lifetime of the returned Geometry.
+   */
+  GeometryPrecisionReducer(const geom::GeometryFactory &gf);
+
+  /**
+   * Sets whether the reduction will result in collapsed components
+   * being removed completely, or simply being collapsed to an (invalid)
+   * Geometry of the same type.
+   *
+   * @param remove if <code>true</code> collapsed components will be removed
+   */
+  void setRemoveCollapsedComponents(bool remove) {
+    removeCollapsed = remove;
+  }
+
+  /** \brief
+   * Sets whether the precision reduction will be done
+   * in pointwise fashion only.
+   *
+   * Pointwise precision reduction reduces the precision
+   * of the individual coordinates only, but does
+   * not attempt to recreate valid topology.
+   * This is only relevant for geometries containing polygonal components.
+   *
+   * @param pointwise if reduction should be done pointwise only
+   */
+  void setPointwise(bool pointwise)
+  {
+    isPointwise = pointwise;
+  }
+
+  std::auto_ptr<geom::Geometry> reduce(const geom::Geometry& geom);
+
+};
+
+} // namespace geos.precision
+} // namespace geos
+
+#endif // GEOS_PRECISION_GEOMETRYPRECISIONREDUCER_H

Modified: trunk/include/geos/precision/Makefile.am
===================================================================
--- trunk/include/geos/precision/Makefile.am	2012-04-06 19:04:01 UTC (rev 3604)
+++ trunk/include/geos/precision/Makefile.am	2012-04-10 08:38:18 UTC (rev 3605)
@@ -12,4 +12,6 @@
     CommonBitsOp.h \
     CommonBitsRemover.h \
     EnhancedPrecisionOp.h \
+    GeometryPrecisionReducer.h \
+    PrecisionReducerCoordinateOperation.h \
     SimpleGeometryPrecisionReducer.h

Added: trunk/include/geos/precision/PrecisionReducerCoordinateOperation.h
===================================================================
--- trunk/include/geos/precision/PrecisionReducerCoordinateOperation.h	                        (rev 0)
+++ trunk/include/geos/precision/PrecisionReducerCoordinateOperation.h	2012-04-10 08:38:18 UTC (rev 3605)
@@ -0,0 +1,66 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2012 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: precision/PrecisionreducerCoordinateOperation.java r591 (JTS-1.12)
+ *
+ **********************************************************************/
+
+#ifndef GEOS_PRECISION_PRECISIONREDUCERCOORDINATEOPERATION_H
+#define GEOS_PRECISION_PRECISIONREDUCERCOORDINATEOPERATION_H
+
+#include <geos/geom/util/CoordinateOperation.h>
+
+// Forward declarations
+namespace geos {
+  namespace geom { 
+    class PrecisionModel;
+    class CoordinateSequence;
+    class Geometry;
+  }
+}
+
+namespace geos {
+namespace precision { // geos.precision
+
+class PrecisionReducerCoordinateOperation :
+		public geom::util::CoordinateOperation
+{
+using CoordinateOperation::edit;
+private:
+
+	const geom::PrecisionModel& targetPM;
+
+	bool removeCollapsed;
+
+public:
+
+	PrecisionReducerCoordinateOperation( const geom::PrecisionModel& pm,
+                                       bool doRemoveCollapsed )
+      :
+      targetPM(pm),
+      removeCollapsed(doRemoveCollapsed)
+  {}
+
+	/// Ownership of returned CoordinateSequence to caller
+  //
+  /// virtual function
+	geom::CoordinateSequence* edit(const geom::CoordinateSequence *coordinates,
+	                         const geom::Geometry *geom);
+};
+
+} // namespace geos.precision
+} // namespace geos
+
+#endif // GEOS_PRECISION_PRECISIONREDUCERCOORDINATEOPERATION_H
+

Added: trunk/src/precision/GeometryPrecisionReducer.cpp
===================================================================
--- trunk/src/precision/GeometryPrecisionReducer.cpp	                        (rev 0)
+++ trunk/src/precision/GeometryPrecisionReducer.cpp	2012-04-10 08:38:18 UTC (rev 3605)
@@ -0,0 +1,145 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2005-2006 Refractions Research Inc.
+ * Copyright (C) 2001-2002 Vivid Solutions Inc.
+ *
+ * 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: precision/GeometryPrecisionReducer.cpp rev. 1.10 (JTS-1.7)
+ *
+ **********************************************************************/
+
+#include <geos/precision/GeometryPrecisionReducer.h>
+#include <geos/precision/PrecisionReducerCoordinateOperation.h>
+#include <geos/geom/util/GeometryEditor.h>
+#include <geos/geom/util/CoordinateOperation.h>
+#include <geos/geom/Coordinate.h>
+#include <geos/geom/CoordinateSequence.h>
+#include <geos/geom/CoordinateSequenceFactory.h>
+#include <geos/geom/PrecisionModel.h>
+#include <geos/geom/GeometryFactory.h>
+#include <geos/geom/LineString.h>
+#include <geos/geom/LinearRing.h>
+
+#include <vector>
+#include <typeinfo>
+
+using namespace std;
+using namespace geos::geom;
+using namespace geos::geom::util;
+
+namespace geos {
+namespace precision { // geos.precision
+
+
+/* private */
+auto_ptr<Geometry>
+GeometryPrecisionReducer::reducePointwise(const Geometry &geom)
+{
+	auto_ptr<GeometryEditor> geomEdit;
+
+  if ( newFactory ) {
+      geomEdit.reset( new GeometryEditor(newFactory) );
+  } else {
+      geomEdit.reset( new GeometryEditor() );
+  }
+
+  /**
+   * For polygonal geometries, collapses are always removed, in order
+   * to produce correct topology
+   */
+  bool finalRemoveCollapsed = removeCollapsed;
+  if (geom.getDimension() >= 2)
+    finalRemoveCollapsed = true;
+
+	PrecisionReducerCoordinateOperation prco(targetPM, finalRemoveCollapsed);
+
+	std::auto_ptr<Geometry> g ( geomEdit->edit(&geom, &prco) );
+
+	return g;
+}
+
+/* public */
+auto_ptr<Geometry>
+GeometryPrecisionReducer::reduce(const Geometry &geom)
+{
+  auto_ptr<Geometry> reducePW = reducePointwise(geom);
+
+  if ( isPointwise ) return reducePW;
+
+  //TODO: handle GeometryCollections containing polys
+  if (! (dynamic_cast<const Polygonal*>(reducePW.get())) )
+    return reducePW;
+
+  // Geometry is polygonal - test if topology needs to be fixed
+  if (reducePW->isValid()) return reducePW;
+
+  // hack to fix topology.
+  // TODO: implement snap-rounding and use that.
+  return fixPolygonalTopology(*reducePW);
+  
+}
+
+
+/* public */
+GeometryPrecisionReducer::GeometryPrecisionReducer(const GeometryFactory &changeFactory)
+      :
+      newFactory(&changeFactory),
+      targetPM(*(changeFactory.getPrecisionModel())),
+      removeCollapsed(true),
+      isPointwise(false)
+{}
+
+/* private */
+auto_ptr<Geometry>
+GeometryPrecisionReducer::fixPolygonalTopology(const geom::Geometry& geom )
+{
+  /**
+   * If precision model was *not* changed, need to flip
+   * geometry to targetPM, buffer in that model, then flip back
+   */
+  auto_ptr<Geometry> tmp;
+  auto_ptr<GeometryFactory> tmpFactory;
+
+  const Geometry* geomToBuffer = &geom;
+
+  if ( ! newFactory ) {
+    tmpFactory = createFactory(*geom.getFactory(), targetPM);
+    tmp.reset( tmpFactory->createGeometry(&geom) );
+    geomToBuffer = tmp.get();
+  }
+
+  auto_ptr<Geometry> bufGeom ( geomToBuffer->buffer(0) );
+
+  if ( ! newFactory ) {
+    // a slick way to copy the geometry with the original precision factory
+    bufGeom.reset( geom.getFactory()->createGeometry(bufGeom.get()) );
+  }
+
+  return bufGeom;
+}
+
+/* private */
+auto_ptr<GeometryFactory>
+GeometryPrecisionReducer::createFactory( const GeometryFactory& oldGF,
+                                         const PrecisionModel& newPM )
+{
+  auto_ptr<GeometryFactory> newFactory(
+    new GeometryFactory(&newPM,
+                        oldGF.getSRID(),
+                        const_cast<CoordinateSequenceFactory*>(oldGF.getCoordinateSequenceFactory()))
+  );
+  return newFactory;
+}
+
+} // namespace geos.precision
+} // namespace geos
+

Modified: trunk/src/precision/Makefile.am
===================================================================
--- trunk/src/precision/Makefile.am	2012-04-06 19:04:01 UTC (rev 3604)
+++ trunk/src/precision/Makefile.am	2012-04-10 08:38:18 UTC (rev 3605)
@@ -12,6 +12,8 @@
 	CommonBitsOp.cpp \
 	CommonBitsRemover.cpp \
 	EnhancedPrecisionOp.cpp \
+	GeometryPrecisionReducer.cpp \
+	PrecisionReducerCoordinateOperation.cpp \
 	SimpleGeometryPrecisionReducer.cpp 
 
 libprecision_la_LIBADD = 

Added: trunk/src/precision/PrecisionReducerCoordinateOperation.cpp
===================================================================
--- trunk/src/precision/PrecisionReducerCoordinateOperation.cpp	                        (rev 0)
+++ trunk/src/precision/PrecisionReducerCoordinateOperation.cpp	2012-04-10 08:38:18 UTC (rev 3605)
@@ -0,0 +1,97 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2012 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: precision/PrecisionreducerCoordinateOperation.java r591 (JTS-1.12)
+ *
+ **********************************************************************/
+
+#include <geos/precision/PrecisionReducerCoordinateOperation.h>
+#include <geos/geom/PrecisionModel.h>
+#include <geos/geom/CoordinateSequenceFactory.h>
+#include <geos/geom/CoordinateSequence.h>
+#include <geos/geom/GeometryFactory.h>
+#include <geos/geom/Geometry.h>
+#include <geos/geom/LineString.h>
+#include <geos/geom/LinearRing.h>
+
+#include <vector>
+
+using namespace geos::geom;
+using namespace std;
+
+namespace geos {
+namespace precision { // geos.precision
+
+CoordinateSequence*
+PrecisionReducerCoordinateOperation::edit(const CoordinateSequence *cs,
+                                          const Geometry *geom)
+{
+	unsigned int csSize = cs->getSize();
+
+	if ( csSize == 0 ) return NULL;
+
+	vector<Coordinate> *vc = new vector<Coordinate>(csSize);
+
+	// copy coordinates and reduce
+	for (unsigned int i=0; i<csSize; ++i) {
+		Coordinate coord=cs->getAt(i);
+		targetPM.makePrecise(&coord);
+		(*vc)[i] = coord;
+	}
+
+	// reducedCoords take ownership of 'vc'
+	CoordinateSequence *reducedCoords =
+		geom->getFactory()->getCoordinateSequenceFactory()->create(vc);
+
+	// remove repeated points, to simplify returned geometry as
+	// much as possible.
+	// 
+	CoordinateSequence *noRepeatedCoords=CoordinateSequence::removeRepeatedPoints(reducedCoords);
+
+	/**
+	 * Check to see if the removal of repeated points
+	 * collapsed the coordinate List to an invalid length
+	 * for the type of the parent geometry.
+	 * It is not necessary to check for Point collapses,
+	 * since the coordinate list can
+	 * never collapse to less than one point.
+	 * If the length is invalid, return the full-length coordinate array
+	 * first computed, or null if collapses are being removed.
+	 * (This may create an invalid geometry - the client must handle this.)
+	 */
+	unsigned int minLength = 0;
+	if ( dynamic_cast<const LineString*>(geom) ) minLength = 2;
+	if ( dynamic_cast<const LinearRing*>(geom) ) minLength = 4;
+
+	CoordinateSequence *collapsedCoords = reducedCoords;
+	if ( removeCollapsed )
+	{
+		delete reducedCoords; reducedCoords=0;
+		collapsedCoords=0;
+	}
+
+	// return null or orginal length coordinate array
+	if ( noRepeatedCoords->getSize() < minLength ) {
+		delete noRepeatedCoords;
+		return collapsedCoords;
+	}
+
+	// ok to return shorter coordinate array
+	delete reducedCoords;
+	return noRepeatedCoords;
+}
+
+
+} // namespace geos.precision
+} // namespace geos

Modified: trunk/src/precision/SimpleGeometryPrecisionReducer.cpp
===================================================================
--- trunk/src/precision/SimpleGeometryPrecisionReducer.cpp	2012-04-06 19:04:01 UTC (rev 3604)
+++ trunk/src/precision/SimpleGeometryPrecisionReducer.cpp	2012-04-10 08:38:18 UTC (rev 3605)
@@ -38,6 +38,8 @@
 namespace geos {
 namespace precision { // geos.precision
 
+namespace {
+
 class PrecisionReducerCoordinateOperation :
 		public geom::util::CoordinateOperation
 {
@@ -119,6 +121,7 @@
 	return noRepeatedCoords;
 }
 
+} // anonymous namespace
 
 //---------------------------------------------------------------
 

Modified: trunk/tests/unit/Makefile.am
===================================================================
--- trunk/tests/unit/Makefile.am	2012-04-06 19:04:01 UTC (rev 3604)
+++ trunk/tests/unit/Makefile.am	2012-04-10 08:38:18 UTC (rev 3605)
@@ -97,6 +97,7 @@
 	operation/valid/ValidClosedRingTest.cpp \
 	operation/valid/ValidSelfTouchingRingFormingHoleTest.cpp \
 	precision/SimpleGeometryPrecisionReducerTest.cpp \
+	precision/GeometryPrecisionReducerTest.cpp \
 	simplify/DouglasPeuckerSimplifierTest.cpp \
 	simplify/TopologyPreservingSimplifierTest.cpp \
 	util/UniqueCoordinateArrayFilterTest.cpp \

Added: trunk/tests/unit/precision/GeometryPrecisionReducerTest.cpp
===================================================================
--- trunk/tests/unit/precision/GeometryPrecisionReducerTest.cpp	                        (rev 0)
+++ trunk/tests/unit/precision/GeometryPrecisionReducerTest.cpp	2012-04-10 08:38:18 UTC (rev 3605)
@@ -0,0 +1,193 @@
+// $Id$
+// 
+// Test Suite for geos::precision::GeometryPrecisionReducer class.
+
+// tut
+#include <tut.hpp>
+// geos
+#include <geos/precision/GeometryPrecisionReducer.h>
+#include <geos/geom/Geometry.h>
+#include <geos/geom/GeometryFactory.h>
+#include <geos/geom/PrecisionModel.h>
+#include <geos/io/WKTReader.h>
+// std
+#include <string>
+#include <vector>
+#include <iostream>
+
+namespace tut
+{
+    //
+    // Test Group
+    //
+
+    // Common data used by tests
+    struct test_gpr_data
+    {
+        typedef std::auto_ptr<geos::geom::Geometry> GeometryPtr;
+
+        geos::geom::PrecisionModel pm_float_;
+        geos::geom::PrecisionModel pm_fixed_;
+        geos::geom::GeometryFactory factory_;
+        geos::geom::GeometryFactory factory_fixed_;
+        geos::io::WKTReader reader_;
+        geos::precision::GeometryPrecisionReducer reducer_;
+        geos::precision::GeometryPrecisionReducer reducerKeepCollapse_; // keep collapse
+        geos::precision::GeometryPrecisionReducer reducerChangePM_; // change precision model
+
+        test_gpr_data() :
+            pm_float_(),
+            pm_fixed_(1),
+            factory_(&pm_float_, 0),
+            factory_fixed_(&pm_fixed_, 0),
+            reader_(&factory_),
+            reducer_(pm_fixed_),
+            reducerKeepCollapse_(pm_fixed_),
+            reducerChangePM_(factory_fixed_)
+        {
+            reducerKeepCollapse_.setRemoveCollapsedComponents(false);
+        }
+};
+
+    typedef test_group<test_gpr_data> group;
+    typedef group::object object;
+
+    group test_gpr_group("geos::precision::GeometryPrecisionReducer");
+
+    //
+    // Test Cases
+    //
+
+    // Test square
+    template<>
+    template<>
+    void object::test<1>()
+    {
+        GeometryPtr g1(reader_.read("POLYGON (( 0 0, 0 1.4, 1.4 1.4, 1.4 0, 0 0 ))"));
+        GeometryPtr g2(reader_.read("POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0 ))"));
+
+        GeometryPtr result(reducer_.reduce(*g1));
+
+        ensure( result->equalsExact(g2.get()) );
+        ensure( result->getFactory() == g2->getFactory() );
+    }
+
+    // Test tiny square collapse
+    template<>
+    template<>
+    void object::test<2>()
+    {
+        GeometryPtr g1(reader_.read("POLYGON (( 0 0, 0 .4, .4 .4, .4 0, 0 0 ))"));
+        GeometryPtr g2(reader_.read("POLYGON EMPTY"));
+
+        GeometryPtr result(reducer_.reduce(*g1));
+
+        ensure( result->equalsExact(g2.get()) );
+        ensure( result->getFactory() == g2->getFactory() );
+    }
+
+    // Test square collapse
+    template<>
+    template<>
+    void object::test<3>()
+    {
+        GeometryPtr g1(reader_.read("POLYGON (( 0 0, 0 1.4, .4 .4, .4 0, 0 0 ))"));
+        GeometryPtr g2(reader_.read("POLYGON EMPTY"));
+
+        GeometryPtr result(reducer_.reduce(*g1));
+
+        ensure( result->equalsExact(g2.get()) );
+        ensure( result->getFactory() == g2->getFactory() );
+    }
+
+    // Test square keep collapse
+    template<>
+    template<>
+    void object::test<4>()
+    {
+        GeometryPtr g1(reader_.read("POLYGON (( 0 0, 0 1.4, .4 .4, .4 0, 0 0 ))"));
+        /**
+         * For polygonal geometries, collapses are always removed, in order
+         * to produce correct topology
+         */
+        GeometryPtr g2(reader_.read("POLYGON EMPTY"));
+
+        GeometryPtr result(reducerKeepCollapse_.reduce(*g1));
+
+        ensure( result->equalsExact(g2.get()) );
+        ensure( result->getFactory() == g2->getFactory() );
+    }
+
+    // Test line
+    template<>
+    template<>
+    void object::test<5>()
+    {
+        GeometryPtr g1(reader_.read("LINESTRING ( 0 0, 0 1.4 )"));
+        GeometryPtr g2(reader_.read("LINESTRING (0 0, 0 1)"));
+
+        GeometryPtr result(reducer_.reduce(*g1));
+
+        ensure( result->equalsExact(g2.get()) );
+        ensure( result->getFactory() == g2->getFactory() );
+    }
+
+    // Test line remove collapse
+    template<>
+    template<>
+    void object::test<6>()
+    {
+        GeometryPtr g1(reader_.read("LINESTRING ( 0 0, 0 .4 )"));
+        GeometryPtr g2(reader_.read("LINESTRING EMPTY"));
+
+        GeometryPtr result(reducer_.reduce(*g1));
+
+        ensure( result->equalsExact(g2.get()) );
+        ensure( result->getFactory() == g2->getFactory() );
+    }
+
+    // Test line keep collapse
+    template<>
+    template<>
+    void object::test<7>()
+    {
+        GeometryPtr g1(reader_.read("LINESTRING ( 0 0, 0 .4 )"));
+        GeometryPtr g2(reader_.read("LINESTRING ( 0 0, 0 0 )"));
+
+        GeometryPtr result(reducerKeepCollapse_.reduce(*g1));
+
+        ensure( result->equalsExact(g2.get()) );
+        ensure( result->getFactory() == g2->getFactory() );
+    }
+
+    // Test square with changed PM
+    template<>
+    template<>
+    void object::test<8>()
+    {
+        GeometryPtr g1(reader_.read("POLYGON (( 0 0, 0 1.4, 1.4 1.4, 1.4 0, 0 0 ))"));
+        GeometryPtr g2(reader_.read("POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0 ))"));
+
+        GeometryPtr result(reducerChangePM_.reduce(*g1));
+
+        ensure( result->equalsExact(g2.get()) );
+        ensure( result->getFactory() == &factory_fixed_ );
+    }
+
+    // Test points with changed PM
+    template<>
+    template<>
+    void object::test<9>()
+    {
+        GeometryPtr g1(reader_.read("MULTIPOINT ((0 0), (0 1.4), (1.4 1.4), (1.4 0), (0.9 0) ))"));
+        GeometryPtr g2(reader_.read("MULTIPOINT ((0 0), (0 1), (1 1), (1 0), (1 0) ))"));
+
+        GeometryPtr result(reducerChangePM_.reduce(*g1));
+
+        ensure( result->equalsExact(g2.get()) );
+        ensure( result->getFactory() == &factory_fixed_ );
+    }
+
+
+} // namespace tut
+



More information about the geos-commits mailing list