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
43 namespace noding
{ // geos.noding
48 * Add every linear element in a geometry into SegmentString vector
50 class SegmentStringExtractor
: public geom::GeometryComponentFilter
{
52 SegmentStringExtractor(SegmentString::NonConstVect
& to
)
56 void filter_ro(const geom::Geometry
* g
) {
57 const geom::LineString
*ls
= dynamic_cast<const geom::LineString
*>(g
);
59 geom::CoordinateSequence
* coord
= ls
->getCoordinates();
60 // coord ownership transferred to SegmentString
61 SegmentString
*ss
= new NodedSegmentString(coord
, 0);
66 SegmentString::NonConstVect
& _to
;
73 std::auto_ptr
<geom::Geometry
>
74 GeometryNoder::node(const geom::Geometry
& geom
)
76 GeometryNoder
noder(geom
);
77 return noder
.getNoded();
81 GeometryNoder::GeometryNoder(const geom::Geometry
& g
)
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
) );
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;
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
)
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
];
144 for (size_t i
=0, n
=lineList
.size(); i
<n
; ++i
)
152 GeometryNoder::extractSegmentStrings(const geom::Geometry
& g
,
153 SegmentString::NonConstVect
& to
)
155 SegmentStringExtractor
ex(to
);
161 GeometryNoder::getNoder()
165 const geom::PrecisionModel
*pm
= argGeom
.getFactory()->getPrecisionModel();
167 using algorithm::LineIntersector
;
169 IntersectionAdder
intersectionAdder(li
);
170 noder
.reset( new MCIndexNoder(&intersectionAdder
) );
173 IteratedNoder
* in
= new IteratedNoder(pm
);
174 //in->setMaximumIterations(0);
177 //using snapround::SimpleSnapRounder;
178 //noder.reset( new SimpleSnapRounder(*pm) );
180 //using snapround::MCIndexSnapRounder;
181 //noder.reset( new MCIndexSnapRounder(*pm) );
189 } // namespace geos.noding