1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2006 Refractions Research Inc.
8 * This is free software; you can redistribute and/or modify it under
9 * the terms of the GNU Lesser General Licence as published
10 * by the Free Software Foundation.
11 * See the COPYING file for more information.
13 **********************************************************************
15 * Last port: simplify/DouglasPeuckerSimplifier.java rev. 1.5 (JTS-1.7)
17 **********************************************************************/
19 #include <geos/simplify/DouglasPeuckerSimplifier.h>
20 #include <geos/simplify/DouglasPeuckerLineSimplifier.h>
21 #include <geos/geom/Geometry.h> // for AutoPtr typedefs
22 #include <geos/geom/MultiPolygon.h>
23 #include <geos/geom/CoordinateSequence.h> // for AutoPtr typedefs
24 #include <geos/geom/GeometryFactory.h>
25 #include <geos/geom/CoordinateSequenceFactory.h>
26 #include <geos/geom/util/GeometryTransformer.h> // for DPTransformer inheritance
27 #include <geos/util/IllegalArgumentException.h>
28 #include <geos/util.h>
30 #include <memory> // for auto_ptr
41 using namespace geos::geom
;
44 namespace simplify
{ // geos::simplify
46 class DPTransformer
: public geom::util::GeometryTransformer
{
50 DPTransformer(double tolerance
);
54 CoordinateSequence::AutoPtr
transformCoordinates(
55 const CoordinateSequence
* coords
,
56 const Geometry
* parent
);
58 Geometry::AutoPtr
transformPolygon(
60 const Geometry
* parent
);
62 Geometry::AutoPtr
transformMultiPolygon(
63 const MultiPolygon
* geom
,
64 const Geometry
* parent
);
69 * Creates a valid area geometry from one that possibly has
70 * bad topology (i.e. self-intersections).
71 * Since buffer can handle invalid topology, but always returns
72 * valid geometry, constructing a 0-width buffer "corrects" the
74 * Note this only works for area geometries, since buffer always returns
75 * areas. This also may return empty geometries, if the input
78 * @param roughAreaGeom an area geometry possibly containing
80 * @return a valid area geometry
82 Geometry::AutoPtr
createValidArea(const Geometry
* roughAreaGeom
);
84 double distanceTolerance
;
88 DPTransformer::DPTransformer(double t
)
95 DPTransformer::createValidArea(const Geometry
* roughAreaGeom
)
97 return Geometry::AutoPtr(roughAreaGeom
->buffer(0.0));
100 CoordinateSequence::AutoPtr
101 DPTransformer::transformCoordinates(
102 const CoordinateSequence
* coords
,
103 const Geometry
* parent
)
105 ::geos::ignore_unused_variable_warning(parent
);
107 const Coordinate::Vect
* inputPts
= coords
->toVector();
110 std::auto_ptr
<Coordinate::Vect
> newPts
=
111 DouglasPeuckerLineSimplifier::simplify(*inputPts
,
114 return CoordinateSequence::AutoPtr(
115 factory
->getCoordinateSequenceFactory()->create(
121 DPTransformer::transformPolygon(
123 const Geometry
* parent
)
127 std::cerr
<< "DPTransformer::transformPolygon(Polygon " << geom
<< ", Geometry " << parent
<< ");" << std::endl
;
130 Geometry::AutoPtr
roughGeom(GeometryTransformer::transformPolygon(geom
, parent
));
132 // don't try and correct if the parent is going to do this
133 if ( dynamic_cast<const MultiPolygon
*>(parent
) )
138 return createValidArea(roughGeom
.get());
142 DPTransformer::transformMultiPolygon(
143 const MultiPolygon
* geom
,
144 const Geometry
* parent
)
147 std::cerr
<< "DPTransformer::transformMultiPolygon(MultiPolygon " << geom
<< ", Geometry " << parent
<< ");" << std::endl
;
149 Geometry::AutoPtr
roughGeom(GeometryTransformer::transformMultiPolygon(geom
, parent
));
150 return createValidArea(roughGeom
.get());
153 /************************************************************************/
157 //DouglasPeuckerSimplifier::
161 DouglasPeuckerSimplifier::simplify(const Geometry
* geom
,
164 DouglasPeuckerSimplifier
tss(geom
);
165 tss
.setDistanceTolerance(tolerance
);
166 return tss
.getResultGeometry();
170 DouglasPeuckerSimplifier::DouglasPeuckerSimplifier(const Geometry
* geom
)
178 DouglasPeuckerSimplifier::setDistanceTolerance(double tol
)
181 throw util::IllegalArgumentException("Tolerance must be non-negative");
182 distanceTolerance
= tol
;
186 DouglasPeuckerSimplifier::getResultGeometry()
188 DPTransformer
t(distanceTolerance
);
189 return t
.transform(inputGeom
);
193 } // namespace geos::simplify
196 /**********************************************************************
198 * Revision 1.2 2006/04/13 16:44:49 strk
199 * Fixed a bug in DPTransformer handling of MultiPolygons
201 * Revision 1.1 2006/04/11 16:04:34 strk
202 * geos::simplify::DouglasPeukerSimplifier class + unit test
204 **********************************************************************/