[geos-commits] r3230 - in trunk: include/geos/operation/linemerge
src/operation/linemerge tests/unit tests/unit/operation/linemerge
svn_geos at osgeo.org
svn_geos at osgeo.org
Mon Feb 21 12:30:45 EST 2011
Author: strk
Date: 2011-02-21 09:30:45 -0800 (Mon, 21 Feb 2011)
New Revision: 3230
Added:
trunk/tests/unit/operation/linemerge/LineSequencerTest.cpp
Modified:
trunk/include/geos/operation/linemerge/LineSequencer.h
trunk/src/operation/linemerge/LineSequencer.cpp
trunk/tests/unit/Makefile.am
Log:
Add LineSequencer unit test, fix memory leaks in the class.
Modified: trunk/include/geos/operation/linemerge/LineSequencer.h
===================================================================
--- trunk/include/geos/operation/linemerge/LineSequencer.h 2011-02-21 17:30:28 UTC (rev 3229)
+++ trunk/include/geos/operation/linemerge/LineSequencer.h 2011-02-21 17:30:45 UTC (rev 3230)
@@ -4,6 +4,7 @@
* GEOS - Geometry Engine Open Source
* http://geos.refractions.net
*
+ * Copyright (C) 2011 Sandro Santilli <strk at keybit.net>
* Copyright (C) 2006 Refractions Research Inc.
*
* This is free software; you can redistribute and/or modify it under
@@ -102,6 +103,8 @@
Sequences* findSequences();
DirEdgeList* findSequence(planargraph::Subgraph& graph);
+ void delAll( Sequences& );
+
/// return a newly allocated LineString
static geom::LineString* reverse(const geom::LineString *line);
@@ -109,8 +112,11 @@
* Builds a geometry ({@link LineString} or {@link MultiLineString} )
* representing the sequence.
*
- * @param sequences a vector of vectors of const planarDirectedEdges
- * with LineMergeEdges as their parent edges.
+ * @param sequences
+ * a vector of vectors of const planarDirectedEdges
+ * with LineMergeEdges as their parent edges.
+ * Ownership of container _and_ contents retained by caller.
+ *
* @return the sequenced geometry, possibly NULL
* if no sequence exists
*/
Modified: trunk/src/operation/linemerge/LineSequencer.cpp
===================================================================
--- trunk/src/operation/linemerge/LineSequencer.cpp 2011-02-21 17:30:28 UTC (rev 3229)
+++ trunk/src/operation/linemerge/LineSequencer.cpp 2011-02-21 17:30:45 UTC (rev 3230)
@@ -4,6 +4,7 @@
* GEOS - Geometry Engine Open Source
* http://geos.refractions.net
*
+ * Copyright (C) 2011 Sandro Santilli <strk at keybit.net>
* Copyright (C) 2006 Refractions Research Inc.
*
* This is free software; you can redistribute and/or modify it under
@@ -123,6 +124,14 @@
return oddDegreeCount <= 2;
}
+void
+LineSequencer::delAll( LineSequencer::Sequences& s)
+{
+ for ( Sequences::iterator i=s.begin(), e=s.end(); i!=e; ++i )
+ {
+ delete *i;
+ }
+}
/*private*/
LineSequencer::Sequences*
@@ -130,7 +139,7 @@
{
Sequences *sequences = new Sequences();
planargraph::algorithm::ConnectedSubgraphFinder csFinder(graph);
- vector<planargraph::Subgraph*>subgraphs;
+ vector<planargraph::Subgraph*> subgraphs;
csFinder.getConnectedSubgraphs(subgraphs);
for (vector<planargraph::Subgraph*>::const_iterator
it=subgraphs.begin(), endIt=subgraphs.end();
@@ -144,8 +153,12 @@
}
else {
// if any subgraph cannot be sequenced, abort
+ delete subgraph;
+ delAll(*sequences);
+ delete sequences;
return NULL;
}
+ delete subgraph;
}
return sequences;
}
@@ -168,12 +181,15 @@
if (isRun) return;
isRun = true;
- Sequences* sequences(findSequences());
+ Sequences* sequences = findSequences();
if (sequences == NULL) return;
sequencedGeometry = auto_ptr<Geometry>(buildSequencedGeometry(*sequences));
isSequenceableVar = true;
+ delAll(*sequences);
+ delete sequences;
+
// Lines were missing from result
assert(lineCount == sequencedGeometry->getNumGeometries());
Modified: trunk/tests/unit/Makefile.am
===================================================================
--- trunk/tests/unit/Makefile.am 2011-02-21 17:30:28 UTC (rev 3229)
+++ trunk/tests/unit/Makefile.am 2011-02-21 17:30:45 UTC (rev 3230)
@@ -75,6 +75,7 @@
operation/distance/DistanceOpTest.cpp \
operation/IsSimpleOpTest.cpp \
operation/linemerge/LineMergerTest.cpp \
+ operation/linemerge/LineSequencerTest.cpp \
operation/overlay/validate/FuzzyPointLocatorTest.cpp \
operation/overlay/validate/OffsetPointGeneratorTest.cpp \
operation/overlay/validate/OverlayResultValidatorTest.cpp \
Added: trunk/tests/unit/operation/linemerge/LineSequencerTest.cpp
===================================================================
--- trunk/tests/unit/operation/linemerge/LineSequencerTest.cpp (rev 0)
+++ trunk/tests/unit/operation/linemerge/LineSequencerTest.cpp 2011-02-21 17:30:45 UTC (rev 3230)
@@ -0,0 +1,289 @@
+//
+// Test Suite for geos::operation::linemerge::LineSequencer class.
+
+// tut
+#include <tut.hpp>
+// geos
+#include <geos/operation/linemerge/LineSequencer.h>
+#include <geos/platform.h>
+#include <geos/geom/GeometryFactory.h>
+#include <geos/geom/Geometry.h>
+#include <geos/geom/LineString.h>
+#include <geos/io/WKTReader.h>
+#include <geos/io/WKTWriter.h>
+#include <geos/util/IllegalArgumentException.h>
+// std
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace tut
+{
+ //
+ // Test Group
+ //
+
+ // Common data used by tests
+ struct test_linesequencer_data
+ {
+ typedef geos::operation::linemerge::LineSequencer LineSequencer;
+ typedef std::vector<geos::geom::Geometry*> GeomVect;
+ typedef std::vector<geos::geom::LineString*> LineVect;
+
+ geos::geom::GeometryFactory gf;
+ geos::io::WKTReader wktreader;
+ geos::io::WKTWriter wktwriter;
+
+ typedef geos::geom::Geometry Geom;
+ typedef geos::geom::Geometry::AutoPtr GeomPtr;
+
+ GeomVect inpGeoms;
+
+ test_linesequencer_data()
+ : gf(), wktreader(&gf), wktwriter()
+ {
+ wktwriter.setTrim(true);
+ }
+
+ ~test_linesequencer_data()
+ {
+ delAll(inpGeoms);
+ }
+
+ GeomPtr readWKT(const std::string& inputWKT)
+ {
+ return GeomPtr(wktreader.read(inputWKT));
+ }
+
+ void readWKT(const char* const* inputWKT, std::vector<Geom*>& geoms)
+ {
+ for (const char* const* ptr=inputWKT; *ptr; ++ptr) {
+ geoms.push_back(readWKT(*ptr).release());
+ }
+ }
+
+ void runLineSequencer(const char * const * inputWKT,
+ const std::string& expectedWKT)
+ {
+ readWKT(inputWKT, inpGeoms);
+
+ LineSequencer sequencer;
+ sequencer.add(inpGeoms);
+
+ if ( ! sequencer.isSequenceable() ) {
+ ensure( expectedWKT.empty() );
+ } else {
+ GeomPtr expected = readWKT(expectedWKT);
+ GeomPtr result ( sequencer.getSequencedLineStrings() );
+ ensure( expected->equalsExact( result.get() ) );
+
+ bool isSequenced = LineSequencer::isSequenced(result.get());
+ ensure( isSequenced );
+ }
+ }
+
+ void runIsSequenced(const std::string& inputWKT, bool exp)
+ {
+ GeomPtr g = readWKT(inputWKT);
+ bool isSequenced = LineSequencer::isSequenced(g.get());
+ ensure_equals( isSequenced, exp );
+ }
+
+ template <class TargetContainer>
+ void delAll(TargetContainer& geoms)
+ {
+ for (typename TargetContainer::const_iterator i = geoms.begin(),
+ e = geoms.end(); i != e; ++i)
+ {
+ Geom* g = dynamic_cast<Geom*>(*i);
+ delete g;
+ }
+ }
+
+
+ private:
+ // noncopyable
+ test_linesequencer_data(test_linesequencer_data const& other);
+ test_linesequencer_data& operator=(test_linesequencer_data const& rhs);
+ };
+
+ typedef test_group<test_linesequencer_data> group;
+ typedef group::object object;
+
+ group test_linesequencer_group("geos::operation::linemerge::LineSequencer");
+
+ //
+ // Test Cases
+ //
+
+ // testSimple
+ template<> template<>
+ void object::test<1>()
+ {
+ const char* inpWKT[] = {
+ "LINESTRING ( 0 0, 0 10 )",
+ "LINESTRING ( 0 20, 0 30 )",
+ "LINESTRING ( 0 10, 0 20 )",
+ NULL };
+ const char* expWKT =
+ "MULTILINESTRING ((0 0, 0 10), (0 10, 0 20), (0 20, 0 30))";
+
+ runLineSequencer(inpWKT, expWKT);
+ }
+
+ // testSimpleLoop
+ template<> template<>
+ void object::test<2>()
+ {
+ const char* inpWKT[] = {
+ "LINESTRING ( 0 0, 0 10 )",
+ "LINESTRING ( 0 10, 0 0 )",
+ NULL };
+ const char* expWKT =
+ "MULTILINESTRING ((0 0, 0 10), (0 10, 0 0))";
+ runLineSequencer(inpWKT, expWKT);
+ }
+
+ // testSimpleBigLoop
+ template<> template<>
+ void object::test<3>()
+ {
+ const char* inpWKT[] = {
+ "LINESTRING ( 0 0, 0 10 )",
+ "LINESTRING ( 0 20, 0 30 )",
+ "LINESTRING ( 0 30, 0 00 )",
+ "LINESTRING ( 0 10, 0 20 )",
+ NULL };
+ const char* expWKT =
+ "MULTILINESTRING ((0 0, 0 10), (0 10, 0 20), (0 20, 0 30), (0 30, 0 0))";
+ runLineSequencer(inpWKT, expWKT);
+ }
+
+ // test2SimpleLoops
+ template<> template<>
+ void object::test<4>()
+ {
+ const char* inpWKT[] = {
+ "LINESTRING ( 0 0, 0 10 )",
+ "LINESTRING ( 0 10, 0 0 )",
+ "LINESTRING ( 0 0, 0 20 )",
+ "LINESTRING ( 0 20, 0 0 )",
+ NULL };
+ const char* expWKT =
+ "MULTILINESTRING ((0 10, 0 0), (0 0, 0 20), (0 20, 0 0), (0 0, 0 10))";
+ runLineSequencer(inpWKT, expWKT);
+ }
+
+ // testWide8WithTail
+ template<> template<>
+ void object::test<5>()
+ {
+ const char* inpWKT[] = {
+ "LINESTRING ( 0 0, 0 10 )",
+ "LINESTRING ( 10 0, 10 10 )",
+ "LINESTRING ( 0 0, 10 0 )",
+ "LINESTRING ( 0 10, 10 10 )",
+ "LINESTRING ( 0 10, 0 20 )",
+ "LINESTRING ( 10 10, 10 20 )",
+ "LINESTRING ( 0 20, 10 20 )",
+
+ "LINESTRING ( 10 20, 30 30 )",
+ NULL };
+ const char* expWKT = "";
+ runLineSequencer(inpWKT, expWKT);
+ }
+
+ // testSimpleLoopWithTail
+ template<> template<>
+ void object::test<6>()
+ {
+ const char* inpWKT[] = {
+ "LINESTRING ( 0 0, 0 10 )",
+ "LINESTRING ( 0 10, 10 10 )",
+ "LINESTRING ( 10 10, 10 20, 0 10 )",
+ NULL };
+ const char* expWKT =
+"MULTILINESTRING ((0 0, 0 10), (0 10, 10 10), (10 10, 10 20, 0 10))";
+ runLineSequencer(inpWKT, expWKT);
+ }
+
+ // testLineWithRing
+ template<> template<>
+ void object::test<7>()
+ {
+ const char* inpWKT[] = {
+ "LINESTRING ( 0 0, 0 10 )",
+ "LINESTRING ( 0 10, 10 10, 10 20, 0 10 )",
+ "LINESTRING ( 0 30, 0 20 )",
+ "LINESTRING ( 0 20, 0 10 )",
+ NULL };
+ const char* expWKT =
+ "MULTILINESTRING ((0 0, 0 10), (0 10, 10 10, 10 20, 0 10), (0 10, 0 20), (0 20, 0 30))";
+ runLineSequencer(inpWKT, expWKT);
+ }
+
+ // testMultipleGraphsWithRing
+ template<> template<>
+ void object::test<8>()
+ {
+ const char* inpWKT[] = {
+ "LINESTRING ( 0 0, 0 10 )",
+ "LINESTRING ( 0 10, 10 10, 10 20, 0 10 )",
+ "LINESTRING ( 0 30, 0 20 )",
+ "LINESTRING ( 0 20, 0 10 )",
+ "LINESTRING ( 0 60, 0 50 )",
+ "LINESTRING ( 0 40, 0 50 )",
+ NULL };
+ const char* expWKT =
+"MULTILINESTRING ((0 0, 0 10), (0 10, 10 10, 10 20, 0 10), (0 10, 0 20), (0 20, 0 30), (0 40, 0 50), (0 50, 0 60))";
+ runLineSequencer(inpWKT, expWKT);
+ }
+
+ // testMultipleGraphsWithMultipeRings
+ template<> template<>
+ void object::test<9>()
+ {
+ const char* inpWKT[] = {
+ "LINESTRING ( 0 0, 0 10 )",
+ "LINESTRING ( 0 10, 10 10, 10 20, 0 10 )",
+ "LINESTRING ( 0 10, 40 40, 40 20, 0 10 )",
+ "LINESTRING ( 0 30, 0 20 )",
+ "LINESTRING ( 0 20, 0 10 )",
+ "LINESTRING ( 0 60, 0 50 )",
+ "LINESTRING ( 0 40, 0 50 )",
+ NULL };
+ const char* expWKT =
+ "MULTILINESTRING ((0 0, 0 10), (0 10, 40 40, 40 20, 0 10), (0 10, 10 10, 10 20, 0 10), (0 10, 0 20), (0 20, 0 30), (0 40, 0 50), (0 50, 0 60))";
+
+ runLineSequencer(inpWKT, expWKT);
+ }
+
+ // testLineSequence
+ template<> template<>
+ void object::test<10>()
+ {
+ const char* expWKT = "LINESTRING ( 0 0, 0 10 )";
+ runIsSequenced(expWKT, true);
+ }
+
+ // testSplitLineSequence
+ template<> template<>
+ void object::test<11>()
+ {
+ const char* expWKT =
+ "MULTILINESTRING ((0 0, 0 1), (0 2, 0 3), (0 3, 0 4) )";
+ runIsSequenced(expWKT, true);
+ }
+
+ // testBadLineSequence
+ template<> template<>
+ void object::test<12>()
+ {
+ const char* expWKT =
+ "MULTILINESTRING ((0 0, 0 1), (0 2, 0 3), (0 1, 0 4) )";
+ runIsSequenced(expWKT, false);
+ }
+
+
+} // namespace tut
+
More information about the geos-commits
mailing list