Regnerate geos wrapper with correct version for this branch
[geos.git] / src / noding / GeometryNoder.cpp
blob68be3371aea2f1f878b24180d42d0942ac75b922
1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
8 * This is free software; you can redistribute and/or modify it under
9 * the terms of the GNU Lesser General Public Licence as published
10 * by the Free Software Foundation.
11 * See the COPYING file for more information.
13 **********************************************************************
15 * NOTE: this is not in JTS. JTS has a snapround/GeometryNoder though
17 **********************************************************************/
19 #include <noding/GeometryNoder.h>
20 #include <noding/SegmentString.h>
21 #include <noding/NodedSegmentString.h>
22 #include <noding/OrientedCoordinateArray.h>
23 #include <noding/Noder.h>
24 #include <geom/Geometry.h>
25 #include <geom/PrecisionModel.h>
26 #include <geom/CoordinateSequence.h>
27 #include <geom/GeometryFactory.h>
28 #include <geom/LineString.h>
30 #include <noding/IteratedNoder.h>
32 #include <algorithm/LineIntersector.h>
33 #include <noding/IntersectionAdder.h>
34 #include <noding/MCIndexNoder.h>
36 #include <noding/snapround/SimpleSnapRounder.h>
37 #include <noding/snapround/MCIndexSnapRounder.h>
39 #include <memory> // for auto_ptr
40 #include <iostream>
42 namespace geos {
43 namespace noding { // geos.noding
45 namespace {
47 /**
48 * Add every linear element in a geometry into SegmentString vector
50 class SegmentStringExtractor: public geom::GeometryComponentFilter {
51 public:
52 SegmentStringExtractor(SegmentString::NonConstVect& to)
53 : _to(to)
56 void filter_ro(const geom::Geometry * g) {
57 const geom::LineString *ls = dynamic_cast<const geom::LineString *>(g);
58 if ( ls ) {
59 geom::CoordinateSequence* coord = ls->getCoordinates();
60 // coord ownership transferred to SegmentString
61 SegmentString *ss = new NodedSegmentString(coord, 0);
62 _to.push_back(ss);
65 private:
66 SegmentString::NonConstVect& _to;
72 /* public static */
73 std::auto_ptr<geom::Geometry>
74 GeometryNoder::node(const geom::Geometry& geom)
76 GeometryNoder noder(geom);
77 return noder.getNoded();
80 /* public */
81 GeometryNoder::GeometryNoder(const geom::Geometry& g)
83 argGeom(g)
87 /* private */
88 std::auto_ptr<geom::Geometry>
89 GeometryNoder::toGeometry(SegmentString::NonConstVect& nodedEdges)
91 const geom::GeometryFactory *geomFact = argGeom.getFactory();
93 std::set< OrientedCoordinateArray > ocas;
95 // Create a geometry out of the noded substrings.
96 std::vector< geom::Geometry* >* lines = new std::vector< geom::Geometry * >();
97 lines->reserve(nodedEdges.size());
98 for ( unsigned int i = 0, n = nodedEdges.size(); i < n; ++i )
100 SegmentString* ss = nodedEdges [i];
102 const geom::CoordinateSequence* coords = ss->getCoordinates();
104 // Check if an equivalent edge is known
105 OrientedCoordinateArray oca1( *coords );
106 if ( ocas.insert(oca1).second ) {
107 geom::Geometry* tmp = geomFact->createLineString( coords->clone() );
108 lines->push_back( tmp );
112 std::auto_ptr<geom::Geometry> noded ( geomFact->createMultiLineString( lines ) );
114 return noded;
117 /* public */
118 std::auto_ptr<geom::Geometry>
119 GeometryNoder::getNoded()
121 SegmentString::NonConstVect lineList;
122 extractSegmentStrings(argGeom, lineList);
124 Noder& noder = getNoder();
125 SegmentString::NonConstVect* nodedEdges = 0;
127 try {
128 noder.computeNodes( &lineList );
129 nodedEdges = noder.getNodedSubstrings();
131 catch (const std::exception& ex)
133 for (size_t i=0, n=lineList.size(); i<n; ++i)
134 delete lineList[i];
135 throw ex;
138 std::auto_ptr<geom::Geometry> noded = toGeometry(*nodedEdges);
140 for ( unsigned int i = 0, n = nodedEdges->size(); i < n; ++i )
141 delete ( *nodedEdges )[i];
142 delete nodedEdges;
144 for (size_t i=0, n=lineList.size(); i<n; ++i)
145 delete lineList[i];
147 return noded;
150 /* private static */
151 void
152 GeometryNoder::extractSegmentStrings(const geom::Geometry& g,
153 SegmentString::NonConstVect& to)
155 SegmentStringExtractor ex(to);
156 g.apply_ro(&ex);
159 /* private */
160 Noder&
161 GeometryNoder::getNoder()
163 if ( ! noder.get() )
165 const geom::PrecisionModel *pm = argGeom.getFactory()->getPrecisionModel();
166 #if 0
167 using algorithm::LineIntersector;
168 LineIntersector li;
169 IntersectionAdder intersectionAdder(li);
170 noder.reset( new MCIndexNoder(&intersectionAdder) );
171 #else
173 IteratedNoder* in = new IteratedNoder(pm);
174 //in->setMaximumIterations(0);
175 noder.reset( in );
177 //using snapround::SimpleSnapRounder;
178 //noder.reset( new SimpleSnapRounder(*pm) );
180 //using snapround::MCIndexSnapRounder;
181 //noder.reset( new MCIndexSnapRounder(*pm) );
182 #endif
184 return *noder;
189 } // namespace geos.noding
190 } // namespace geos