1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2005-2006 Refractions Research Inc.
7 * Copyright (C) 2001-2002 Vivid Solutions Inc.
9 * This is free software; you can redistribute and/or modify it under
10 * the terms of the GNU Lesser General Public Licence as published
11 * by the Free Software Foundation.
12 * See the COPYING file for more information.
14 **********************************************************************
16 * Last port: geomgraph/PlanarGraph.java r428 (JTS-1.12+)
18 **********************************************************************/
20 #include <geos/geom/Coordinate.h>
21 #include <geos/geom/CoordinateSequence.h>
22 #include <geos/geom/Location.h>
24 #include <geos/geomgraph/PlanarGraph.h>
25 #include <geos/geomgraph/Node.h>
26 #include <geos/geomgraph/NodeFactory.h>
27 #include <geos/geomgraph/Edge.h>
28 #include <geos/geomgraph/EdgeEndStar.h>
29 #include <geos/geomgraph/DirectedEdge.h>
30 #include <geos/geomgraph/DirectedEdgeStar.h>
31 #include <geos/geomgraph/NodeMap.h>
32 #include <geos/geomgraph/Quadrant.h>
34 #include <geos/algorithm/CGAlgorithms.h>
47 using namespace geos::algorithm
;
48 using namespace geos::geom
;
51 namespace geomgraph
{ // geos.geomgraph
54 PlanarGraph::PlanarGraph(const NodeFactory
&nodeFact
)
56 edges(new vector
<Edge
*>()),
57 nodes(new NodeMap(nodeFact
)),
58 edgeEndList(new vector
<EdgeEnd
*>())
63 PlanarGraph::PlanarGraph()
65 edges(new vector
<Edge
*>()),
66 nodes(new NodeMap(NodeFactory::instance())),
67 edgeEndList(new vector
<EdgeEnd
*>())
72 PlanarGraph::~PlanarGraph()
75 #if 1 // FIXME: PlanarGraph should *not* own edges!
76 for(size_t i
=0, n
=edges
->size(); i
<n
; i
++) {
82 for(size_t i
=0, n
=edgeEndList
->size(); i
<n
; i
++) {
83 delete (*edgeEndList
)[i
];
89 vector
<Edge
*>::iterator
90 PlanarGraph::getEdgeIterator()
93 return edges
->begin();
98 PlanarGraph::getEdgeEnds()
105 PlanarGraph::isBoundaryNode(int geomIndex
, const Coordinate
& coord
)
109 Node
*node
=nodes
->find(coord
);
110 if (node
==NULL
) return false;
112 const Label
& label
= node
->getLabel();
113 if (! label
.isNull() && label
.getLocation(geomIndex
)==Location::BOUNDARY
)
121 PlanarGraph::insertEdge(Edge
*e
)
130 PlanarGraph::add(EdgeEnd
* e
)
138 edgeEndList
->push_back(e
);
143 PlanarGraph::getNodeIterator()
146 return nodes
->begin();
151 PlanarGraph::getNodes(vector
<Node
*>& values
)
154 NodeMap::iterator it
=nodes
->nodeMap
.begin();
155 while(it
!=nodes
->nodeMap
.end()) {
157 values
.push_back(it
->second
);
162 // arg cannot be const, NodeMap::addNode will
163 // occasionally label-merge first arg.
166 PlanarGraph::addNode(Node
*node
)
170 cerr
<< "PlanarGraph::addNode(Node * " << *node
173 return nodes
->addNode(node
);
178 PlanarGraph::addNode(const Coordinate
& coord
)
181 cerr
<< "PlanarGraph::addNode(Coordinate& "
182 << coord
<< ")" << endl
;
184 return nodes
->addNode(coord
);
189 PlanarGraph::find(Coordinate
& coord
)
192 return nodes
->find(coord
);
197 PlanarGraph::addEdges(const vector
<Edge
*>& edgesToAdd
)
199 // create all the nodes for the edges
200 for (vector
<Edge
*>::const_iterator it
=edgesToAdd
.begin(),
201 endIt
=edgesToAdd
.end(); it
!=endIt
; ++it
)
207 // PlanarGraph destructor will delete all DirectedEdges
208 // in edgeEndList, which is where these are added
209 // by the ::add(EdgeEnd) call
210 DirectedEdge
*de1
=new DirectedEdge(e
, true);
211 DirectedEdge
*de2
=new DirectedEdge(e
, false);
222 PlanarGraph::linkResultDirectedEdges()
225 cerr
<<"PlanarGraph::linkResultDirectedEdges called"<<endl
;
227 NodeMap::iterator nodeit
=nodes
->nodeMap
.begin();
228 for (;nodeit
!=nodes
->nodeMap
.end();nodeit
++) {
229 Node
*node
=nodeit
->second
;
232 EdgeEndStar
* ees
=node
->getEdges();
234 assert(dynamic_cast<DirectedEdgeStar
*>(ees
));
235 DirectedEdgeStar
* des
= static_cast<DirectedEdgeStar
*>(ees
);
237 // this might throw an exception
238 des
->linkResultDirectedEdges();
243 * Link the DirectedEdges at the nodes of the graph.
244 * This allows clients to link only a subset of nodes in the graph, for
245 * efficiency (because they know that only a subset is of interest).
248 PlanarGraph::linkAllDirectedEdges()
251 cerr
<<"PlanarGraph::linkAllDirectedEdges called"<<endl
;
253 NodeMap::iterator nodeit
=nodes
->nodeMap
.begin();
254 for (;nodeit
!=nodes
->nodeMap
.end();nodeit
++)
256 Node
*node
=nodeit
->second
;
259 EdgeEndStar
*ees
=node
->getEdges();
262 // Unespected non-DirectedEdgeStar in node
263 assert(dynamic_cast<DirectedEdgeStar
*>(ees
));
264 DirectedEdgeStar
*des
=static_cast<DirectedEdgeStar
*>(ees
);
266 des
->linkAllDirectedEdges();
272 PlanarGraph::findEdgeEnd(Edge
*e
)
274 vector
<EdgeEnd
*>* eev
=getEdgeEnds();
277 for (vector
<EdgeEnd
*>::iterator i
=eev
->begin(), iEnd
=eev
->end();
284 // should test using values rather then pointers ?
285 if (ee
->getEdge()==e
) return ee
;
292 PlanarGraph::findEdge(const Coordinate
& p0
, const Coordinate
& p1
)
294 for (size_t i
=0, n
=edges
->size(); i
<n
; ++i
)
299 const CoordinateSequence
* eCoord
=e
->getCoordinates();
302 if (p0
==eCoord
->getAt(0) && p1
==eCoord
->getAt(1))
310 PlanarGraph::findEdgeInSameDirection(const Coordinate
& p0
,
311 const Coordinate
& p1
)
313 for(size_t i
=0, n
=edges
->size(); i
<n
; i
++)
318 const CoordinateSequence
* eCoord
=e
->getCoordinates();
321 size_t nCoords
=eCoord
->size();
324 if (matchInSameDirection(p0
, p1
,
331 if (matchInSameDirection(p0
, p1
,
332 eCoord
->getAt(nCoords
-1),
333 eCoord
->getAt(nCoords
-2)))
344 PlanarGraph::matchInSameDirection(const Coordinate
& p0
, const Coordinate
& p1
,
345 const Coordinate
& ep0
, const Coordinate
& ep1
)
350 if (CGAlgorithms::computeOrientation(p0
,p1
,ep1
)==CGAlgorithms::COLLINEAR
351 && Quadrant::quadrant(p0
,p1
)==Quadrant::quadrant(ep0
,ep1
))
357 PlanarGraph::printEdges()
360 std::ostringstream oss
;
362 for(size_t i
=0, n
=edges
->size(); i
<n
; ++i
)
365 oss
<< "edge " << i
<< ":\n" << e
->print() << e
->eiList
.print();
371 PlanarGraph::getNodeMap()
376 } // namespace geos.geomgraph