1 /**********************************************************************
2  *
3  * GEOS - Geometry Engine Open Source
4  * http://geos.osgeo.org
5  *
6  * Copyright (C) 2011 Sandro Santilli <strk@kbt.io>
7  * Copyright (C) 2005-2006 Refractions Research Inc.
8  * Copyright (C) 2001-2002 Vivid Solutions Inc.
9  *
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.
14  *
15  **********************************************************************
16  *
17  * Last port: operation/linemerge/LineMergeGraph.java r378 (JTS-1.12)
18  *
19  **********************************************************************/
20 
21 #include <geos/operation/linemerge/LineMergeGraph.h>
22 #include <geos/operation/linemerge/LineMergeEdge.h>
23 #include <geos/operation/linemerge/LineMergeDirectedEdge.h>
24 #include <geos/operation/valid/RepeatedPointRemover.h>
25 #include <geos/planargraph/DirectedEdge.h>
26 #include <geos/planargraph/Node.h>
27 #include <geos/geom/CoordinateSequence.h>
28 #include <geos/geom/LineString.h>
29 #include <memory>
30 
31 #include <vector>
32 
33 #ifndef GEOS_DEBUG
34 #define GEOS_DEBUG 0
35 #endif
36 
37 #ifdef GEOS_DEBUG
38 #include <iostream>
39 #endif
40 
41 using namespace std;
42 //using namespace geos::planargraph;
43 using namespace geos::geom;
44 
45 namespace geos {
46 namespace operation { // geos.operation
47 namespace linemerge { // geos.operation.linemerge
48 
49 void
addEdge(const LineString * lineString)50 LineMergeGraph::addEdge(const LineString* lineString)
51 {
52     if(lineString->isEmpty()) {
53         return;
54     }
55 
56 #if GEOS_DEBUG
57     cerr << "Adding LineString " << lineString->toString() << endl;
58 #endif
59 
60     auto coordinates = valid::RepeatedPointRemover::removeRepeatedPoints(lineString->getCoordinatesRO());
61 
62     std::size_t nCoords = coordinates->size(); // virtual call..
63 
64     // don't add lines with all coordinates equal
65     if(nCoords <= 1) {
66         return;
67     }
68 
69     const Coordinate& startCoordinate = coordinates->getAt(0);
70     const Coordinate& endCoordinate = coordinates->getAt(nCoords - 1);
71 
72     planargraph::Node* startNode = getNode(startCoordinate);
73     planargraph::Node* endNode = getNode(endCoordinate);
74 #if GEOS_DEBUG
75     cerr << " startNode: " << *startNode << endl;
76     cerr << " endNode: " << *endNode << endl;
77 #endif
78 
79     planargraph::DirectedEdge* directedEdge0 = new LineMergeDirectedEdge(startNode,
80             endNode, coordinates->getAt(1),
81             true);
82     newDirEdges.push_back(directedEdge0);
83 
84     planargraph::DirectedEdge* directedEdge1 = new LineMergeDirectedEdge(endNode,
85             startNode, coordinates->getAt(nCoords - 2),
86             false);
87     newDirEdges.push_back(directedEdge1);
88 
89     planargraph::Edge* edge = new LineMergeEdge(lineString);
90     newEdges.push_back(edge);
91     edge->setDirectedEdges(directedEdge0, directedEdge1);
92 
93 #if GEOS_DEBUG
94     cerr << " planargraph::Edge: " << *edge << endl;
95 #endif
96 
97     add(edge);
98 
99 #if GEOS_DEBUG
100     cerr << " After addition to the graph:" << endl;
101     cerr << "  startNode: " << *startNode << endl;
102     cerr << "  endNode: " << *endNode << endl;
103 #endif
104 
105 }
106 
107 planargraph::Node*
getNode(const Coordinate & coordinate)108 LineMergeGraph::getNode(const Coordinate& coordinate)
109 {
110     planargraph::Node* node = findNode(coordinate);
111     if(node == nullptr) {
112         node = new planargraph::Node(coordinate);
113         newNodes.push_back(node);
114         add(node);
115     }
116     return node;
117 }
118 
~LineMergeGraph()119 LineMergeGraph::~LineMergeGraph()
120 {
121     unsigned int i;
122     for(i = 0; i < newNodes.size(); i++) {
123         delete newNodes[i];
124     }
125     for(i = 0; i < newEdges.size(); i++) {
126         delete newEdges[i];
127     }
128     for(i = 0; i < newDirEdges.size(); i++) {
129         delete newDirEdges[i];
130     }
131 }
132 
133 } // namespace geos.operation.linemerge
134 } // namespace geos.operation
135 } // namespace geos
136