1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2010 Sandro Santilli <strk@keybit.net>
7 * Copyright (C) 2005-2006 Refractions Research Inc.
8 * Copyright (C) 2001-2002 Vivid Solutions Inc.
10 * This is free software; you can redistribute and/or modify it under
11 * the terms of the GNU Lesser General Public Licence as published
12 * by the Free Software Foundation.
13 * See the COPYING file for more information.
15 **********************************************************************
17 * Last port: operation/polygonize/Polygonizer.java rev. 1.6 (JTS-1.10)
19 **********************************************************************/
21 #include <geos/operation/polygonize/Polygonizer.h>
22 #include <geos/operation/polygonize/PolygonizeGraph.h>
23 #include <geos/operation/polygonize/EdgeRing.h>
24 #include <geos/geom/LineString.h>
25 #include <geos/geom/Geometry.h>
26 #include <geos/geom/Polygon.h>
31 #pragma warning(disable:4355)
39 using namespace geos::geom
;
42 namespace operation
{ // geos.operation
43 namespace polygonize
{ // geos.operation.polygonize
45 Polygonizer::LineStringAdder::LineStringAdder(Polygonizer
*p
):
51 Polygonizer::LineStringAdder::filter_ro(const Geometry
*g
)
53 const LineString
*ls
= dynamic_cast<const LineString
*>(g
);
54 if ( ls
) pol
->add(ls
);
59 * Create a polygonizer with the same GeometryFactory
60 * as the input Geometry
62 Polygonizer::Polygonizer():
63 lineStringAdder(this),
74 Polygonizer::~Polygonizer()
78 for (unsigned int i
=0, n
=invalidRingLines
.size(); i
<n
; ++i
)
79 delete invalidRingLines
[i
];
83 for (unsigned int i
=0, n
=polyList
->size(); i
<n
; ++i
)
84 delete (*polyList
)[i
];
90 * Add a collection of geometries to be polygonized.
91 * May be called multiple times.
92 * Any dimension of Geometry may be added;
93 * the constituent linework will be extracted and used
95 * @param geomList a list of {@link Geometry}s with linework to be polygonized
98 Polygonizer::add(vector
<Geometry
*> *geomList
)
100 for(unsigned int i
=0, n
=geomList
->size(); i
<n
; ++i
)
102 const Geometry
*geometry
=(*geomList
)[i
];
108 * Add a collection of geometries to be polygonized.
109 * May be called multiple times.
110 * Any dimension of Geometry may be added;
111 * the constituent linework will be extracted and used
113 * @param geomList a list of {@link Geometry}s with linework to be polygonized
116 Polygonizer::add(vector
<const Geometry
*> *geomList
)
118 for(unsigned int i
=0, n
=geomList
->size(); i
<n
; ++i
)
120 const Geometry
*geometry
=(*geomList
)[i
];
126 * Add a geometry to the linework to be polygonized.
127 * May be called multiple times.
128 * Any dimension of Geometry may be added;
129 * the constituent linework will be extracted and used
131 * @param g a Geometry with linework to be polygonized
134 Polygonizer::add(Geometry
*g
)
136 g
->apply_ro(&lineStringAdder
);
140 * Add a geometry to the linework to be polygonized.
141 * May be called multiple times.
142 * Any dimension of Geometry may be added;
143 * the constituent linework will be extracted and used
145 * @param g a Geometry with linework to be polygonized
148 Polygonizer::add(const Geometry
*g
)
150 g
->apply_ro(&lineStringAdder
);
154 * Add a linestring to the graph of polygon edges.
156 * @param line the LineString to add
159 Polygonizer::add(const LineString
*line
)
161 // create a new graph using the factory from the input Geometry
163 graph
=new PolygonizeGraph(line
->getFactory());
164 graph
->addEdge(line
);
168 * Gets the list of polygons formed by the polygonization.
169 * @return a collection of Polygons
172 Polygonizer::getPolygons()
175 vector
<Polygon
*> *ret
= polyList
;
181 const vector
<const LineString
*>&
182 Polygonizer::getDangles()
189 const vector
<const LineString
*>&
190 Polygonizer::getCutEdges()
197 const vector
<LineString
*>&
198 Polygonizer::getInvalidRingLines()
201 return invalidRingLines
;
206 Polygonizer::polygonize()
208 // check if already computed
209 if (polyList
!=NULL
) return;
211 polyList
=new vector
<Polygon
*>();
213 // if no geometries were supplied it's possible graph could be null
214 if (graph
==NULL
) return;
216 graph
->deleteDangles(dangles
);
218 graph
->deleteCutEdges(cutEdges
);
220 vector
<EdgeRing
*> edgeRingList
;
221 graph
->getEdgeRings(edgeRingList
);
223 cerr
<<"Polygonizer::polygonize(): "<<edgeRingList
.size()<<" edgeRings in graph"<<endl
;
225 vector
<EdgeRing
*> validEdgeRingList
;
226 invalidRingLines
.clear(); /* what if it was populated already ? we should clean ! */
227 findValidRings(edgeRingList
, validEdgeRingList
, invalidRingLines
);
229 cerr
<<" "<<validEdgeRingList
.size()<<" valid"<<endl
;
230 cerr
<<" "<<invalidRingLines
.size()<<" invalid"<<endl
;
233 findShellsAndHoles(validEdgeRingList
);
235 cerr
<<" "<<holeList
.size()<<" holes"<<endl
;
236 cerr
<<" "<<shellList
.size()<<" shells"<<endl
;
239 assignHolesToShells(holeList
, shellList
);
241 for (unsigned int i
=0, n
=shellList
.size(); i
<n
; ++i
)
243 EdgeRing
*er
=shellList
[i
];
244 polyList
->push_back(er
->getPolygon());
250 Polygonizer::findValidRings(const vector
<EdgeRing
*>& edgeRingList
,
251 vector
<EdgeRing
*>& validEdgeRingList
,
252 vector
<LineString
*>& invalidRingList
)
254 typedef vector
<EdgeRing
*> EdgeRingList
;
256 for (EdgeRingList::size_type i
=0, n
=edgeRingList
.size(); i
<n
; ++i
)
258 EdgeRing
*er
= edgeRingList
[i
];
261 validEdgeRingList
.push_back(er
);
265 // NOTE: polygonize::EdgeRing::getLineString
266 // returned LineString ownership is transferred.
267 invalidRingList
.push_back(er
->getLineString());
274 Polygonizer::findShellsAndHoles(const vector
<EdgeRing
*>& edgeRingList
)
278 for (unsigned int i
=0, n
=edgeRingList
.size(); i
<n
; ++i
)
280 EdgeRing
*er
=edgeRingList
[i
];
282 holeList
.push_back(er
);
284 shellList
.push_back(er
);
290 Polygonizer::assignHolesToShells(const vector
<EdgeRing
*>& holeList
, vector
<EdgeRing
*>& shellList
)
292 for (unsigned int i
=0, n
=holeList
.size(); i
<n
; ++i
)
294 EdgeRing
*holeER
=holeList
[i
];
295 assignHoleToShell(holeER
, shellList
);
301 Polygonizer::assignHoleToShell(EdgeRing
*holeER
,
302 vector
<EdgeRing
*>& shellList
)
304 EdgeRing
*shell
= EdgeRing::findEdgeRingContaining(holeER
, &shellList
);
307 shell
->addHole(holeER
->getRingOwnership());
311 } // namespace geos.operation.polygonize
312 } // namespace geos.operation
315 /**********************************************************************
317 * Revision 1.13 2006/03/22 11:19:06 strk
318 * opPolygonize.h headers split.
320 * Revision 1.12 2006/03/03 10:46:22 strk
321 * Removed 'using namespace' from headers, added missing headers in .cpp files, removed useless includes in headers (bug#46)
323 * Revision 1.11 2006/03/02 12:12:01 strk
324 * Renamed DEBUG macros to GEOS_DEBUG, all wrapped in #ifndef block to allow global override (bug#43)
326 * Revision 1.10 2006/02/19 19:46:49 strk
327 * Packages <-> namespaces mapping for most GEOS internal code (uncomplete, but working). Dir-level libs for index/ subdirs.
329 * Revision 1.9 2005/12/09 10:32:28 strk
330 * Cleaned up debugging line left over from previous commit
332 * Revision 1.8 2005/12/09 10:03:46 strk
333 * Fixed a bug making PolygonizeGraph choking on invalid LineStrings.
334 * Minor optimizations in Polygonizer loops.
336 * Revision 1.7 2005/06/17 15:08:06 strk
337 * Polygonizer segfault fix
339 * Revision 1.6 2004/12/08 13:54:44 strk
340 * gcc warnings checked and fixed, general cleanups.
342 * Revision 1.5 2004/10/27 13:57:07 strk
343 * Added some debugging lines (disabled by default)
345 * Revision 1.4 2004/10/26 16:09:21 strk
346 * Some more intentation and envelope equality check fix.
348 * Revision 1.3 2004/10/19 19:51:14 strk
349 * Fixed many leaks and bugs in Polygonizer.
350 * Output still bogus.
352 * Revision 1.2 2004/07/02 13:28:29 strk
353 * Fixed all #include lines to reflect headers layout change.
354 * Added client application build tips in README.
356 * Revision 1.1 2004/04/08 04:53:56 ybychkov
357 * "operation/polygonize" ported from JTS 1.4
360 **********************************************************************/