Skip to content

Commit

Permalink
Fix TPSimplifier to be deterministic (#718)
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-jts authored Oct 28, 2022
1 parent 04cbcc1 commit e1b10c7
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 67 deletions.
74 changes: 9 additions & 65 deletions src/simplify/TopologyPreservingSimplifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,62 +75,6 @@ class LineStringTransformer: public geom::util::GeometryTransformer {

};

/*
* helper class to transform a map iterator so to return value_type
* on dereference.
* TODO: generalize this to be a "ValueIterator" with specializations
* for std::map and std::vector
*/
class LinesMapValueIterator {

LinesMap::iterator _iter;

public:

LinesMapValueIterator(LinesMap::iterator iter)
:
_iter(iter)
{
}

// copy ctor
LinesMapValueIterator(const LinesMapValueIterator& o)
:
_iter(o._iter)
{
}

// assignment
LinesMapValueIterator&
operator=(const LinesMapValueIterator& o)
{
_iter = o._iter;
return *this;
}

// ++suffix
LinesMapValueIterator&
operator++()
{
++_iter;
return *this;
}

// inequality operator
bool
operator!=(const LinesMapValueIterator& other) const
{
return _iter != other._iter;
}

TaggedLineString*
operator*()
{
return _iter->second;
}
};


/*public*/
LineStringTransformer::LineStringTransformer(LinesMap& nMap)
:
Expand Down Expand Up @@ -205,21 +149,22 @@ class LineStringMapBuilderFilter: public geom::GeometryComponentFilter {
* User's constructor.
* @param nMap - reference to LinesMap instance.
*/
LineStringMapBuilderFilter(LinesMap& nMap);
LineStringMapBuilderFilter(LinesMap& nMap, std::vector<TaggedLineString*>& tlsVec);

private:

LinesMap& linestringMap;
std::vector<TaggedLineString*>& tlsVector;

// Declare type as noncopyable
LineStringMapBuilderFilter(const LineStringMapBuilderFilter& other) = delete;
LineStringMapBuilderFilter& operator=(const LineStringMapBuilderFilter& rhs) = delete;
};

/*public*/
LineStringMapBuilderFilter::LineStringMapBuilderFilter(LinesMap& nMap)
LineStringMapBuilderFilter::LineStringMapBuilderFilter(LinesMap& nMap, std::vector<TaggedLineString*>& tlsVec)
:
linestringMap(nMap)
linestringMap(nMap), tlsVector(tlsVec)
{
}

Expand All @@ -243,6 +188,7 @@ LineStringMapBuilderFilter::filter_ro(const Geometry* geom)
delete taggedLine;
throw util::GEOSException("Duplicated Geometry components detected");
}
tlsVector.push_back(taggedLine);
}


Expand Down Expand Up @@ -296,7 +242,9 @@ TopologyPreservingSimplifier::getResultGeometry()
std::unique_ptr<geom::Geometry> result;

try {
LineStringMapBuilderFilter lsmbf(linestringMap);
//-- vector ensures deterministic simplification order of TaggedLineStrings
std::vector<TaggedLineString*> tlsVector;
LineStringMapBuilderFilter lsmbf(linestringMap, tlsVector);
inputGeom->apply_ro(&lsmbf);

#if GEOS_DEBUG
Expand All @@ -305,10 +253,7 @@ TopologyPreservingSimplifier::getResultGeometry()
<< linestringMap.size() << " elements\n";
#endif

LinesMapValueIterator begin(linestringMap.begin());
LinesMapValueIterator end(linestringMap.end());
lineSimplifier->simplify(begin, end);

lineSimplifier->simplify(tlsVector.begin(), tlsVector.end());

#if GEOS_DEBUG
std::cerr << "all TaggedLineString simplified\n";
Expand Down Expand Up @@ -351,4 +296,3 @@ TopologyPreservingSimplifier::getResultGeometry()

} // namespace geos::simplify
} // namespace geos

6 changes: 4 additions & 2 deletions tests/unit/simplify/TopologyPreservingSimplifierTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,9 @@ void object::test<14>
std::string wkt("MULTILINESTRING((0 0, 50 0, 70 0, 80 0, 100 0), (0 0, 50 1, 60 1, 100 0))");
GeomPtr g(wktreader.read(wkt));

std::string wkt_exp("MULTILINESTRING ((0 0, 100 0), (0 0, 50 1, 100 0))");
//TODO: investigate why TPS does not prevent lines from collapsing (JTS has same behaviour)
//std::string wkt_exp("MULTILINESTRING ((0 0, 100 0), (0 0, 50 1, 100 0))");
std::string wkt_exp("MULTILINESTRING ((0 0, 100 0), (0 0, 100 0))");
GeomPtr exp(wktreader.read(wkt_exp));

GeomPtr simplified = TopologyPreservingSimplifier::simplify(g.get(), 10.0);
Expand Down Expand Up @@ -354,5 +356,5 @@ void object::test<16>
ensure_equals(wktwriter.write(simp.get()),
"GEOMETRYCOLLECTION (LINESTRING (0 0, 10 0))");
}
} // namespace tut

} // namespace tut

0 comments on commit e1b10c7

Please sign in to comment.