Revision 8261 trunk/extensions/extGraph_predes/src/com/iver/cit/gvsig/graph/core/Network.java
Network.java | ||
---|---|---|
45 | 45 |
import java.util.ArrayList; |
46 | 46 |
|
47 | 47 |
import com.iver.cit.gvsig.fmap.DriverException; |
48 |
import com.iver.cit.gvsig.fmap.core.IFeature; |
|
48 | 49 |
import com.iver.cit.gvsig.fmap.core.IGeometry; |
49 | 50 |
import com.iver.cit.gvsig.fmap.core.v02.FConverter; |
50 | 51 |
import com.iver.cit.gvsig.fmap.drivers.DriverIOException; |
51 | 52 |
import com.iver.cit.gvsig.fmap.layers.FBitSet; |
52 | 53 |
import com.iver.cit.gvsig.fmap.layers.FLyrVect; |
53 | 54 |
import com.iver.cit.gvsig.fmap.layers.VectorialAdapter; |
55 |
import com.iver.cit.gvsig.graph.GraphException; |
|
54 | 56 |
import com.vividsolutions.jts.geom.Coordinate; |
57 |
import com.vividsolutions.jts.geom.Geometry; |
|
55 | 58 |
import com.vividsolutions.jts.geom.LineSegment; |
59 |
import com.vividsolutions.jts.geom.MultiLineString; |
|
56 | 60 |
|
57 | 61 |
public class Network { |
58 | 62 |
protected FLyrVect lyrVect; |
63 |
|
|
59 | 64 |
protected IGraph graph; |
65 |
|
|
60 | 66 |
protected ArrayList flags = new ArrayList(); |
61 |
|
|
67 |
|
|
68 |
protected int numOriginalEdges; |
|
69 |
|
|
70 |
protected int numOriginalNodes; |
|
71 |
|
|
62 | 72 |
public void reconstruyeTramo(int idArc) { |
63 | 73 |
// TODO Auto-generated method stub |
64 |
|
|
74 |
|
|
65 | 75 |
} |
66 | 76 |
|
67 |
|
|
68 |
private int findClosestArc(double x, double y, double tolerance) |
|
69 |
{ |
|
77 |
private int findClosestArc(double x, double y, double tolerance) { |
|
70 | 78 |
Point2D p = new Point2D.Double(x, y); |
71 | 79 |
FBitSet bitSet; |
72 | 80 |
try { |
73 | 81 |
bitSet = lyrVect.queryByPoint(p, tolerance); |
74 | 82 |
VectorialAdapter va = (VectorialAdapter) lyrVect.getSource(); |
75 |
int counter = 0; |
|
76 | 83 |
double minDist = tolerance; |
77 | 84 |
int foundGeom = -1; |
78 | 85 |
for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet |
... | ... | |
80 | 87 |
IGeometry geom; |
81 | 88 |
geom = va.getShape(i); |
82 | 89 |
Point2D nearest = getNearestPoint(p, geom, tolerance); |
83 |
if (nearest != null) |
|
84 |
{ |
|
90 |
if (nearest != null) { |
|
85 | 91 |
double dist = nearest.distance(p); |
86 |
if (dist < minDist) |
|
87 |
{ |
|
92 |
if (dist < minDist) { |
|
88 | 93 |
minDist = dist; |
89 | 94 |
foundGeom = i; |
90 | 95 |
} |
... | ... | |
99 | 104 |
e.printStackTrace(); |
100 | 105 |
} |
101 | 106 |
return -1; |
102 |
|
|
103 |
|
|
107 |
|
|
104 | 108 |
} |
105 |
|
|
106 |
protected Point2D getNearestPoint(Point2D point, IGeometry geom, double tolerance) { |
|
109 |
|
|
110 |
protected Point2D getNearestPoint(Point2D point, IGeometry geom, |
|
111 |
double tolerance) { |
|
107 | 112 |
Point2D resul = null; |
108 | 113 |
Coordinate c = new Coordinate(point.getX(), point.getY()); |
109 |
|
|
110 |
PathIterator theIterator = geom.getPathIterator(null, FConverter.FLATNESS); //polyLine.getPathIterator(null, flatness); |
|
114 |
|
|
115 |
PathIterator theIterator = geom.getPathIterator(null, |
|
116 |
FConverter.FLATNESS); // polyLine.getPathIterator(null, |
|
117 |
// flatness); |
|
111 | 118 |
double[] theData = new double[6]; |
112 | 119 |
double minDist = tolerance; |
113 | 120 |
Coordinate from = null, first = null; |
114 | 121 |
while (!theIterator.isDone()) { |
115 |
//while not done |
|
122 |
// while not done
|
|
116 | 123 |
int theType = theIterator.currentSegment(theData); |
117 | 124 |
|
118 | 125 |
switch (theType) { |
119 |
case PathIterator.SEG_MOVETO:
|
|
120 |
from = new Coordinate(theData[0], theData[1]);
|
|
121 |
first = from;
|
|
122 |
break;
|
|
126 |
case PathIterator.SEG_MOVETO: |
|
127 |
from = new Coordinate(theData[0], theData[1]); |
|
128 |
first = from; |
|
129 |
break; |
|
123 | 130 |
|
124 |
case PathIterator.SEG_LINETO:
|
|
131 |
case PathIterator.SEG_LINETO: |
|
125 | 132 |
|
126 |
// System.out.println("SEG_LINETO"); |
|
127 |
Coordinate to = new Coordinate(theData[0], theData[1]); |
|
128 |
LineSegment line = new LineSegment(from, to); |
|
129 |
Coordinate closestPoint = line.closestPoint(c); |
|
130 |
double dist = c.distance(closestPoint); |
|
131 |
if ((dist < minDist)) { |
|
132 |
resul = new Point2D.Double(closestPoint.x, closestPoint.y); |
|
133 |
minDist = dist; |
|
134 |
} |
|
135 |
|
|
136 |
from = to; |
|
137 |
break; |
|
138 |
case PathIterator.SEG_CLOSE: |
|
139 |
line = new LineSegment(from, first); |
|
140 |
closestPoint = line.closestPoint(c); |
|
141 |
dist = c.distance(closestPoint); |
|
142 |
if ((dist < minDist)) { |
|
143 |
resul = new Point2D.Double(closestPoint.x, closestPoint.y); |
|
144 |
minDist = dist; |
|
145 |
} |
|
146 |
|
|
147 |
from = first; |
|
148 |
break; |
|
149 |
|
|
133 |
// System.out.println("SEG_LINETO"); |
|
134 |
Coordinate to = new Coordinate(theData[0], theData[1]); |
|
135 |
LineSegment line = new LineSegment(from, to); |
|
136 |
Coordinate closestPoint = line.closestPoint(c); |
|
137 |
double dist = c.distance(closestPoint); |
|
138 |
if ((dist < minDist)) { |
|
139 |
resul = new Point2D.Double(closestPoint.x, closestPoint.y); |
|
140 |
minDist = dist; |
|
141 |
} |
|
150 | 142 |
|
151 |
} //end switch |
|
143 |
from = to; |
|
144 |
break; |
|
145 |
case PathIterator.SEG_CLOSE: |
|
146 |
line = new LineSegment(from, first); |
|
147 |
closestPoint = line.closestPoint(c); |
|
148 |
dist = c.distance(closestPoint); |
|
149 |
if ((dist < minDist)) { |
|
150 |
resul = new Point2D.Double(closestPoint.x, closestPoint.y); |
|
151 |
minDist = dist; |
|
152 |
} |
|
152 | 153 |
|
154 |
from = first; |
|
155 |
break; |
|
156 |
|
|
157 |
} // end switch |
|
158 |
|
|
153 | 159 |
theIterator.next(); |
154 | 160 |
} |
155 | 161 |
|
156 | 162 |
return resul; |
157 | 163 |
} |
158 |
|
|
164 |
|
|
159 | 165 |
/** |
160 | 166 |
* TODO: POR TERMINAR!!! |
167 |
* |
|
161 | 168 |
* @param flag |
162 | 169 |
* @return |
163 | 170 |
*/ |
164 |
public int creaArcosVirtualesComplejo(GvFlag flag) { |
|
165 |
// Devuelve el idNodo del nodo virtual creado. |
|
166 |
/* 0.- Creamos el nuevo Nodo virtual. |
|
167 |
1.- Recorremos los arcos nuevos mirando su idTramo. |
|
168 |
2.- Si existe ese idtramo=> Ya hemos partido antes ese idTramo. Buscamos el arco virtual que contiene |
|
169 |
ese nodo y lo partimos. Ojo, recorrer hasta el final los tramos para asegurarnos de que es el trozo |
|
170 |
m?s peque?o. |
|
171 |
3.- Si NO existe, utilizamos el IndiceArcos para coger los arcos que toca y partirlos. |
|
171 |
public int creaArcosVirtuales(GvFlag flag) { |
|
172 |
// Devuelve el idNodo del nodo virtual creado. |
|
173 |
/* |
|
174 |
* 0.- Creamos el nuevo Nodo virtual. 1.- Recorremos los arcos nuevos |
|
175 |
* mirando su idTramo. 2.- Si existe ese idtramo=> Ya hemos partido |
|
176 |
* antes ese idTramo. Buscamos el arco virtual que contiene ese nodo y |
|
177 |
* lo partimos. Ojo, recorrer hasta el final los tramos para asegurarnos |
|
178 |
* de que es el trozo m?s peque?o. 3.- Si NO existe, utilizamos el |
|
179 |
* IndiceArcos para coger los arcos que toca y partirlos. |
|
180 |
* |
|
181 |
* 4.- OJO: Si el porcentaje es 0 ? 100, no partimos el arco, devolvemos |
|
182 |
* el id del nodo que toca. |
|
183 |
*/ |
|
184 |
// NUEVO: 20/7/2004: |
|
185 |
// Cuando trabajamos con sentidos, al partir un arco no podemos insertar |
|
186 |
// 2 nuevos sin mirar |
|
187 |
// si es o no de un ?nico sentido.) (Mirar idArco. Si es -1, no partimos |
|
188 |
// el arco). |
|
189 |
// FIN NUEVO |
|
190 |
int idNodo1, idNodo2; |
|
191 |
int idArco, elIdArco, elIdContraArco; |
|
192 |
boolean encontrado; |
|
193 |
GvNode newNode; |
|
172 | 194 |
|
173 |
4.- OJO: Si el porcentaje es 0 ? 100, no partimos el arco, devolvemos el id del nodo que toca. |
|
174 |
*/ |
|
175 |
// NUEVO: 20/7/2004: |
|
176 |
// Cuando trabajamos con sentidos, al partir un arco no podemos insertar 2 nuevos sin mirar |
|
177 |
// si es o no de un ?nico sentido.) (Mirar idArco. Si es -1, no partimos el arco). |
|
178 |
// FIN NUEVO |
|
195 |
// Sacamos los idNodos del tramo |
|
196 |
EdgePair edgePair = graph.getEdgesByIdArc(flag.getIdArc()); |
|
197 |
if (edgePair.getIdEdge() != -1) { |
|
198 |
// idNodo1 = Arcos[IndiceArcos[idTramo].idArco].idNodo1; |
|
199 |
// idNodo2 = Arcos[IndiceArcos[idTramo].idArco].idNodo2; |
|
200 |
idNodo1 = graph.getEdgeByID(edgePair.getIdEdge()).getIdNodeOrig(); |
|
201 |
idNodo2 = graph.getEdgeByID(edgePair.getIdEdge()).getIdNodeEnd(); |
|
179 | 202 |
|
180 |
int idNodo1, idNodo2; |
|
181 |
int idArco, elIdArco, elIdContraArco; |
|
182 |
boolean encontrado; |
|
183 |
GvNode newNode; |
|
203 |
} else { |
|
204 |
// idNodo2 = Arcos[IndiceArcos[idTramo].idContraArco].idNodo1; |
|
205 |
// idNodo1 = Arcos[IndiceArcos[idTramo].idContraArco].idNodo2; |
|
206 |
idNodo2 = graph.getEdgeByID(edgePair.getIdInverseEdge()) |
|
207 |
.getIdNodeOrig(); |
|
208 |
idNodo1 = graph.getEdgeByID(edgePair.getIdInverseEdge()) |
|
209 |
.getIdNodeEnd(); |
|
184 | 210 |
|
185 |
// Sacamos los idNodos del tramo |
|
186 |
EdgePair edgePair = graph.getEdgesByIdArc(flag.getIdArc()); |
|
187 |
if (edgePair.getIdEdge() != -1) |
|
188 |
{ |
|
189 |
// idNodo1 = Arcos[IndiceArcos[idTramo].idArco].idNodo1; |
|
190 |
// idNodo2 = Arcos[IndiceArcos[idTramo].idArco].idNodo2; |
|
191 |
idNodo1 = graph.getEdgeByID(edgePair.getIdEdge()).getIdNodeOrig(); |
|
192 |
idNodo2 = graph.getEdgeByID(edgePair.getIdEdge()).getIdNodeEnd(); |
|
193 |
|
|
194 |
} |
|
195 |
else |
|
196 |
{ |
|
197 |
// idNodo2 = Arcos[IndiceArcos[idTramo].idContraArco].idNodo1; |
|
198 |
// idNodo1 = Arcos[IndiceArcos[idTramo].idContraArco].idNodo2; |
|
199 |
idNodo2 = graph.getEdgeByID(edgePair.getIdInverseEdge()).getIdNodeOrig(); |
|
200 |
idNodo1 = graph.getEdgeByID(edgePair.getIdInverseEdge()).getIdNodeEnd(); |
|
201 |
|
|
202 |
} |
|
211 |
} |
|
203 | 212 |
|
204 |
if (flag.getPct() == 0)
|
|
205 |
return idNodo1;
|
|
206 |
if (flag.getPct() == 1)
|
|
207 |
return idNodo2;
|
|
213 |
if (flag.getPct() == 0) |
|
214 |
return idNodo1; |
|
215 |
if (flag.getPct() == 1)
|
|
216 |
return idNodo2; |
|
208 | 217 |
|
209 |
// Creamos el nodo de enmedio
|
|
218 |
// Creamos el nodo de enmedio |
|
210 | 219 |
|
211 |
// if (numNodos == maxNodos) // La jodimos, T?rtola, hay que usar reallocate |
|
212 |
// { |
|
213 |
// // NOTA: ESTO EN DEBUG HACE QUE FALLE AL USAR DESPUES EnlacesSTL. ES POR NO S? QU? HISTORIA |
|
214 |
// // DEL HEAP. EN RELEASE NO FALLA. (TAMPOCO S? SI FASTIDIA ALGO). |
|
215 |
// Nodos = (CNode *) realloc(Nodos,(numNodos + MAX_RESERVA_NODOS) * sizeof(CNode)); // Deber?amos chequear que devuelve algo correcto |
|
216 |
// maxNodos = numNodos + MAX_RESERVA_NODOS; |
|
217 |
// } |
|
218 |
|
|
219 |
newNode = new GvNode(); |
|
220 |
// Nodo = &Nodos[numNodos]; |
|
221 |
|
|
222 |
// pNuevoNodo->idNodo = numNodos; |
|
223 |
newNode.setIdNode(graph.numVertices()); |
|
220 |
// if (numNodos == maxNodos) // La jodimos, T?rtola, hay que usar |
|
221 |
// reallocate |
|
222 |
// { |
|
223 |
// // NOTA: ESTO EN DEBUG HACE QUE FALLE AL USAR DESPUES EnlacesSTL. ES |
|
224 |
// POR NO S? QU? HISTORIA |
|
225 |
// // DEL HEAP. EN RELEASE NO FALLA. (TAMPOCO S? SI FASTIDIA ALGO). |
|
226 |
// Nodos = (CNode *) realloc(Nodos,(numNodos + MAX_RESERVA_NODOS) * |
|
227 |
// sizeof(CNode)); // Deber?amos chequear que devuelve algo correcto |
|
228 |
// maxNodos = numNodos + MAX_RESERVA_NODOS; |
|
229 |
// } |
|
224 | 230 |
|
225 |
|
|
231 |
newNode = new GvNode(); |
|
232 |
// Nodo = &Nodos[numNodos]; |
|
226 | 233 |
|
227 |
// OJO: Las coordenadas estas puede que no tengan que ver con la realidad. Algo m?s correcto |
|
228 |
// ser?a tener en cuenta el shape de verdad, pero creo que no influye en el resultado final. |
|
229 |
// pNuevoNodo->x = Nodos[idNodo1].x + (Nodos[idNodo2].x - Nodos[idNodo1].x) * Porcentaje; |
|
230 |
// pNuevoNodo->y = Nodos[idNodo1].y + (Nodos[idNodo2].y - Nodos[idNodo1].y) * Porcentaje; |
|
231 |
GvNode node1 = graph.getNodeByID(idNodo1); |
|
232 |
GvNode node2 = graph.getNodeByID(idNodo2); |
|
233 |
newNode.setX(node1.getX() + (node2.getX() - node1.getX()) * flag.getPct()); |
|
234 |
newNode.setY(node1.getY() + (node2.getY() - node1.getY()) * flag.getPct()); |
|
234 |
// pNuevoNodo->idNodo = numNodos; |
|
235 |
newNode.setIdNode(graph.numVertices()); |
|
235 | 236 |
|
236 |
encontrado = false; |
|
237 |
// OJO: Las coordenadas estas puede que no tengan que ver con la |
|
238 |
// realidad. Algo m?s correcto |
|
239 |
// ser?a tener en cuenta el shape de verdad, pero creo que no influye en |
|
240 |
// el resultado final. |
|
241 |
// pNuevoNodo->x = Nodos[idNodo1].x + (Nodos[idNodo2].x - |
|
242 |
// Nodos[idNodo1].x) * Porcentaje; |
|
243 |
// pNuevoNodo->y = Nodos[idNodo1].y + (Nodos[idNodo2].y - |
|
244 |
// Nodos[idNodo1].y) * Porcentaje; |
|
245 |
GvNode node1 = graph.getNodeByID(idNodo1); |
|
246 |
GvNode node2 = graph.getNodeByID(idNodo2); |
|
247 |
newNode.setX(node1.getX() + (node2.getX() - node1.getX()) |
|
248 |
* flag.getPct()); |
|
249 |
newNode.setY(node1.getY() + (node2.getY() - node1.getY()) |
|
250 |
* flag.getPct()); |
|
251 |
graph.addNode(newNode); |
|
252 |
Coordinate newC = new Coordinate(newNode.getX(), newNode.getY()); |
|
237 | 253 |
|
238 |
elIdArco = -1; |
|
239 |
elIdContraArco = -1; |
|
254 |
encontrado = false; |
|
240 | 255 |
|
241 |
boolean bIdTramoYaPartido = false; |
|
256 |
elIdArco = -1; |
|
257 |
elIdContraArco = -1; |
|
242 | 258 |
|
243 |
// TODO: POR AQUI VOY |
|
244 |
/* for (idArco = numArcosOriginal; idArco < numArcos; idArco++) |
|
245 |
{ |
|
246 |
if (Arcos[idArco].idTramo == idTramo) |
|
247 |
{ |
|
248 |
bIdTramoYaPartido = true; |
|
259 |
boolean bIdTramoYaPartido = false; |
|
249 | 260 |
|
250 |
idNodo1 = Arcos[idArco].idNodo1; |
|
251 |
idNodo2 = Arcos[idArco].idNodo2; |
|
261 |
// TODO: POR AQUI VOY |
|
262 |
for (idArco = numOriginalEdges; idArco < graph.numEdges(); idArco++) { |
|
263 |
GvEdge addedEdge = graph.getEdgeByID(idArco); |
|
264 |
if (addedEdge.getIdArc() == flag.getIdArc()) { |
|
265 |
bIdTramoYaPartido = true; |
|
252 | 266 |
|
253 |
// Comprobamos si est? enmedio |
|
254 |
|
|
255 |
CVector2 vA(Nodos[idNodo1].x, Nodos[idNodo1].y); |
|
256 |
CVector2 vB(Nodos[idNodo2].x, Nodos[idNodo2].y); |
|
257 |
CVector2 vPoint(pNuevoNodo->x, pNuevoNodo->y); |
|
267 |
idNodo1 = addedEdge.getIdNodeOrig(); |
|
268 |
idNodo2 = addedEdge.getIdNodeEnd(); |
|
258 | 269 |
|
259 |
CVector2 vVector1 = vPoint - vA; |
|
270 |
// Comprobamos si est? enmedio |
|
271 |
GvNode n1 = graph.getNodeByID(idNodo1); |
|
272 |
GvNode n2 = graph.getNodeByID(idNodo2); |
|
273 |
Coordinate c1 = new Coordinate(n1.getX(), n1.getY()); |
|
274 |
Coordinate c2 = new Coordinate(n2.getX(), n2.getY()); |
|
275 |
LineSegment line = new LineSegment(c1, c2); |
|
276 |
double t = line.projectionFactor(newC); |
|
260 | 277 |
|
261 |
// Create a normalized direction vector from end point vA to end point vB |
|
262 |
CVector2 vVector2 = Normalize(vB - vA); |
|
278 |
// Si la proyecci?n es positiva y menor que la magnitud d, est? |
|
279 |
// en medio |
|
280 |
if ((t >= 0) && (t <= 1)) { |
|
281 |
encontrado = true; |
|
282 |
if (t == 0) |
|
283 |
return idNodo1; // No partimos |
|
284 |
if (t == 1) |
|
285 |
return idNodo2; // Tampoco partimos |
|
263 | 286 |
|
264 |
// Use the distance formula to find the distance of the line segment (or magnitude) |
|
265 |
double d = Distance(vA, vB); |
|
287 |
if (addedEdge.getDirec() == 1) |
|
288 |
elIdArco = idArco; |
|
289 |
else |
|
290 |
elIdContraArco = idArco; |
|
266 | 291 |
|
267 |
// Using the dot product, we project the vVector1 onto the vector vVector2. |
|
268 |
// This essentially gives us the distance from our projected vector from vA. |
|
269 |
double t = Dot(vVector2, vVector1); |
|
292 |
} // if est? enmedio |
|
293 |
} // if idTramo encontrado |
|
294 |
} // for idArco |
|
295 |
if (bIdTramoYaPartido && (!encontrado)) |
|
296 |
throw new RuntimeException( |
|
297 |
"Algo va mal con lo del producto escalar"); |
|
270 | 298 |
|
271 |
// Si la proyecci?n es positiva y menor que la magnitud d, est? en medio
|
|
272 |
if ((t >= 0) && (t <= d))
|
|
273 |
{
|
|
274 |
encontrado = true;
|
|
275 |
if (t==0) return idNodo1; // No partimos
|
|
276 |
if (t==d) return idNodo2; // Tampoco partimos
|
|
299 |
if (encontrado) {
|
|
300 |
// sprintf(Mensaje,"Voy a partir el idTramo= %ld (idArco
|
|
301 |
// %ld)",idTramo,elIdArco);
|
|
302 |
// MessageBox(NULL,Mensaje,"",MB_OK);
|
|
303 |
if (elIdArco != -1)
|
|
304 |
PartirArco(elIdArco, newNode.getIdNode());
|
|
277 | 305 |
|
278 |
if (Arcos[idArco].sentido) |
|
279 |
elIdArco = idArco; |
|
280 |
else |
|
281 |
elIdContraArco = idArco; |
|
306 |
if (elIdContraArco != -1) |
|
307 |
PartirArco(elIdContraArco, newNode.getIdNode()); |
|
308 |
} else { |
|
309 |
// Creamos 2 Arcos por cada arco que ten?amos antes. |
|
310 |
if (edgePair.getIdEdge() != -1) |
|
311 |
PartirArco(edgePair.getIdEdge(), newNode.getIdNode()); |
|
282 | 312 |
|
283 |
} // if est? enmedio |
|
284 |
} // if idTramo encontrado |
|
285 |
} // for idArco |
|
286 |
if (bIdTramoYaPartido && (! encontrado)) |
|
287 |
MessageBox(NULL,"Algo va mal con lo del producto escalar","",MB_OK); |
|
313 |
if (edgePair.getIdInverseEdge() != -1) |
|
314 |
PartirArco(edgePair.getIdInverseEdge(), newNode.getIdNode()); |
|
288 | 315 |
|
316 |
} // else encontrado |
|
289 | 317 |
|
290 |
if (encontrado) |
|
291 |
{ |
|
292 |
// sprintf(Mensaje,"Voy a partir el idTramo= %ld (idArco %ld)",idTramo,elIdArco); |
|
293 |
// MessageBox(NULL,Mensaje,"",MB_OK); |
|
294 |
if (elIdArco != -1) |
|
295 |
PartirArco(elIdArco, numNodos); |
|
318 |
return newNode.getIdNode(); |
|
296 | 319 |
|
297 |
if (elIdContraArco != -1) |
|
298 |
PartirArco(elIdContraArco, numNodos); |
|
299 |
} |
|
300 |
else |
|
301 |
{ |
|
302 |
// Creamos 2 Arcos por cada arco que ten?amos antes. |
|
303 |
if (IndiceArcos[idTramo].idArco != -1) |
|
304 |
PartirArco(IndiceArcos[idTramo].idArco, numNodos); |
|
305 |
|
|
306 |
if (IndiceArcos[idTramo].idContraArco != -1) |
|
307 |
PartirArco(IndiceArcos[idTramo].idContraArco, numNodos); |
|
308 |
|
|
309 |
} // else encontrado |
|
310 |
|
|
311 |
numNodos++; |
|
312 |
return (numNodos -1); */ |
|
313 |
return graph.numVertices(); |
|
314 |
|
|
315 | 320 |
} |
316 | 321 |
|
317 | 322 |
/** |
318 |
* TODO: Por ahora, cogemos el nodo m?s cercano. Lo correcto |
|
319 |
* es a?adir un nuevo nodo que divida el arco, y devolver el
|
|
320 |
* id de ese nodo.
|
|
323 |
* TODO: Por ahora, cogemos el nodo m?s cercano. Lo correcto es a?adir un
|
|
324 |
* nuevo nodo que divida el arco, y devolver el id de ese nodo.
|
|
325 |
* |
|
321 | 326 |
* @param flag |
322 | 327 |
* @return |
323 | 328 |
*/ |
324 |
public int creaArcosVirtuales(GvFlag flag) { |
|
329 |
public int creaArcosVirtualesSimple(GvFlag flag) {
|
|
325 | 330 |
EdgePair pair = graph.getEdgesByIdArc(flag.getIdArc()); |
326 |
if (pair.getIdEdge() != -1) |
|
327 |
{ |
|
331 |
if (pair.getIdEdge() != -1) { |
|
328 | 332 |
GvEdge edge = graph.getEdgeByID(pair.getIdEdge()); |
329 | 333 |
GvNode from = graph.getNodeByID(edge.getIdNodeOrig()); |
330 | 334 |
GvNode to = graph.getNodeByID(edge.getIdNodeEnd()); |
331 |
|
|
332 |
double dist1 = flag.getOriginalPoint().distance(from.getX(), from.getY()); |
|
333 |
double dist2 = flag.getOriginalPoint().distance(to.getX(), to.getY()); |
|
335 |
|
|
336 |
double dist1 = flag.getOriginalPoint().distance(from.getX(), |
|
337 |
from.getY()); |
|
338 |
double dist2 = flag.getOriginalPoint().distance(to.getX(), |
|
339 |
to.getY()); |
|
334 | 340 |
if (dist1 < dist2) |
335 | 341 |
return from.getIdNode(); |
336 | 342 |
else |
337 | 343 |
return to.getIdNode(); |
338 |
// if (flag.getPct() > 0.5) |
|
339 |
// return to.getIdNode(); |
|
340 |
// else |
|
341 |
// return from.getIdNode(); |
|
342 |
} |
|
343 |
else |
|
344 |
{ |
|
344 |
// if (flag.getPct() > 0.5) |
|
345 |
// return to.getIdNode(); |
|
346 |
// else |
|
347 |
// return from.getIdNode(); |
|
348 |
} else { |
|
345 | 349 |
GvEdge edge = graph.getEdgeByID(pair.getIdInverseEdge()); |
346 | 350 |
GvNode from = graph.getNodeByID(edge.getIdNodeOrig()); |
347 | 351 |
GvNode to = graph.getNodeByID(edge.getIdNodeEnd()); |
348 | 352 |
|
349 |
double dist1 = flag.getOriginalPoint().distance(from.getX(), from.getY()); |
|
350 |
double dist2 = flag.getOriginalPoint().distance(to.getX(), to.getY()); |
|
353 |
double dist1 = flag.getOriginalPoint().distance(from.getX(), |
|
354 |
from.getY()); |
|
355 |
double dist2 = flag.getOriginalPoint().distance(to.getX(), |
|
356 |
to.getY()); |
|
351 | 357 |
if (dist1 < dist2) |
352 | 358 |
return from.getIdNode(); |
353 | 359 |
else |
354 | 360 |
return to.getIdNode(); |
355 | 361 |
|
356 |
// if (flag.getPct() < 0.5)
|
|
357 |
// return to.getIdNode();
|
|
358 |
// else
|
|
359 |
// return from.getIdNode();
|
|
362 |
// if (flag.getPct() < 0.5)
|
|
363 |
// return to.getIdNode();
|
|
364 |
// else
|
|
365 |
// return from.getIdNode();
|
|
360 | 366 |
} |
361 | 367 |
} |
362 |
|
|
368 |
|
|
363 | 369 |
/** |
364 | 370 |
* @param idArc |
365 | 371 |
* @param x |
366 | 372 |
* @param y |
367 | 373 |
* @return entre 0.0 y 1.0 |
374 |
* @throws DriverIOException |
|
368 | 375 |
*/ |
369 |
private double percentAlong(long idArc, double x, double y) |
|
370 |
{ |
|
371 |
return 0; |
|
376 |
private double percentAlong(int idArc, double x, double y) |
|
377 |
throws DriverIOException { |
|
378 |
// Le pasamos el idTramo, la coordenada X de donde hemos pulsado y la |
|
379 |
// coordenada Y |
|
380 |
// Primero calculamos la longitud total del shape. |
|
381 |
// Luego calculamos el punto m?s cercano y su distancia para cada |
|
382 |
// segmento del shape. |
|
383 |
// Nos quedamos con el que est? m?s cerca y luego recorremos hasta ?l |
|
384 |
// acumulando distancia. |
|
385 |
// Finalmente, dividimos esa distancia por la longitud total. |
|
386 |
IGeometry geom = lyrVect.getSource().getShape(idArc); |
|
387 |
MultiLineString jtsGeom = (MultiLineString) geom.toJTSGeometry(); |
|
388 |
|
|
389 |
Coordinate[] coords = jtsGeom.getCoordinates(); |
|
390 |
|
|
391 |
Coordinate userCoord = new Coordinate(x, y); |
|
392 |
|
|
393 |
double longReal = 0; |
|
394 |
// Le pegamos una primera pasada para saber su longitud real. |
|
395 |
// OJO, NO TRABAJAMOS CON SHAPES MULTIPARTE, NO TIENE SENTIDO CON LAS |
|
396 |
// REDES (CREO) |
|
397 |
// POR ESO SUPONEMOS UNA ?NICA PARTE (L?NEA CONT?NUA) |
|
398 |
// A la vez calculamos el punto m?s cercano y su distancia para cada |
|
399 |
// segmento. |
|
400 |
double minDist = Double.MAX_VALUE; |
|
401 |
double distTo = 0; |
|
402 |
double dist = 0; |
|
403 |
Coordinate cOrig = null; |
|
404 |
Coordinate closestPoint = null; |
|
405 |
for (int j = 0; j < coords.length - 1; j++) { |
|
406 |
Coordinate c1 = coords[j]; |
|
407 |
Coordinate c2 = coords[j + 1]; |
|
408 |
LineSegment line = new LineSegment(c1, c2); |
|
409 |
|
|
410 |
Coordinate auxPoint = line.closestPoint(userCoord); |
|
411 |
dist = userCoord.distance(auxPoint); |
|
412 |
if ((dist < minDist)) { |
|
413 |
minDist = dist; |
|
414 |
cOrig = c1; |
|
415 |
closestPoint = auxPoint; |
|
416 |
distTo = longReal; |
|
417 |
} |
|
418 |
longReal += line.getLength(); |
|
419 |
} |
|
420 |
|
|
421 |
dist = cOrig.distance(closestPoint); |
|
422 |
double longBuscada = distTo + dist; |
|
423 |
|
|
424 |
double pct; |
|
425 |
if (longReal > 0) |
|
426 |
pct = longBuscada / longReal; |
|
427 |
else |
|
428 |
pct = 0.0; |
|
429 |
|
|
430 |
return pct; |
|
372 | 431 |
} |
373 |
|
|
432 |
|
|
374 | 433 |
/** |
375 |
* Adds a flag on a network. flagDirection set if the flag |
|
376 |
* must be on left or right edge. |
|
434 |
* Adds a flag on a network. flagDirection set if the flag must be on left |
|
435 |
* or right edge. |
|
436 |
* |
|
377 | 437 |
* @param x |
378 | 438 |
* @param y |
379 | 439 |
* @param flagDirection |
380 |
* @param tol tolerance in map units |
|
381 |
* @return null if there is no place to add flag. |
|
382 |
* You can increase the tolerance, then. |
|
440 |
* @param tol |
|
441 |
* tolerance in map units |
|
442 |
* @return null if there is no place to add flag. You can increase the |
|
443 |
* tolerance, then. |
|
444 |
* @throws GraphException |
|
383 | 445 |
*/ |
384 | 446 |
public GvFlag addFlag(double x, double y, int flagDirection, double tol) |
385 |
{ |
|
386 |
int idArc = findClosestArc(x, y, tol); |
|
387 |
if (idArc == -1) |
|
388 |
return null; |
|
389 |
GvFlag flag = new GvFlag(x,y); |
|
390 |
flag.setIdArc(idArc); |
|
391 |
flag.setPct(percentAlong(idArc, x, y)); |
|
392 |
flag.setDirec(flagDirection); |
|
393 |
flag.setIdFlag(flags.size()); |
|
394 |
return flag; |
|
447 |
throws GraphException { |
|
448 |
try { |
|
449 |
int idArc = findClosestArc(x, y, tol); |
|
450 |
if (idArc == -1) |
|
451 |
return null; |
|
452 |
GvFlag flag = new GvFlag(x, y); |
|
453 |
flag.setIdArc(idArc); |
|
454 |
|
|
455 |
flag.setPct(percentAlong(idArc, x, y)); |
|
456 |
flag.setDirec(flagDirection); |
|
457 |
flag.setIdFlag(flags.size()); |
|
458 |
return flag; |
|
459 |
} catch (DriverIOException e) { |
|
460 |
e.printStackTrace(); |
|
461 |
throw new GraphException(e); |
|
462 |
} |
|
463 |
|
|
395 | 464 |
} |
396 | 465 |
|
397 | 466 |
/** |
398 | 467 |
* Adds 2 flags on a network. (On both sides of an arc) |
468 |
* |
|
399 | 469 |
* @param x |
400 | 470 |
* @param y |
401 |
* @param tol tolerance in map units |
|
402 |
* @return null if there is no place to add flag. |
|
403 |
* You can increase the tolerance, then. |
|
404 |
*/ |
|
405 |
public GvFlag addFlag(double x, double y, double tol) |
|
406 |
{ |
|
407 |
int idArc = findClosestArc(x, y, tol); |
|
408 |
if (idArc == -1) |
|
409 |
return null; |
|
410 |
|
|
411 |
GvFlag flag = new GvFlag(x, y); |
|
412 |
flag.setIdArc(idArc); |
|
413 |
flag.setDirec(GvFlag.BOTH_DIRECTIONS); |
|
414 |
flag.setPct(percentAlong(idArc, x, y)); |
|
415 |
flag.setIdFlag(flags.size()); |
|
416 |
flags.add(flag); |
|
417 |
return flag; |
|
471 |
* @param tol |
|
472 |
* tolerance in map units |
|
473 |
* @return null if there is no place to add flag. You can increase the |
|
474 |
* tolerance, then. |
|
475 |
* @throws GraphException |
|
476 |
*/ |
|
477 |
public GvFlag addFlag(double x, double y, double tol) throws GraphException { |
|
478 |
try { |
|
479 |
int idArc = findClosestArc(x, y, tol); |
|
480 |
if (idArc == -1) |
|
481 |
return null; |
|
482 |
|
|
483 |
GvFlag flag = new GvFlag(x, y); |
|
484 |
flag.setIdArc(idArc); |
|
485 |
flag.setDirec(GvFlag.BOTH_DIRECTIONS); |
|
486 |
|
|
487 |
flag.setPct(percentAlong(idArc, x, y)); |
|
488 |
flag.setIdFlag(flags.size()); |
|
489 |
flags.add(flag); |
|
490 |
return flag; |
|
491 |
} catch (DriverIOException e) { |
|
492 |
e.printStackTrace(); |
|
493 |
throw new GraphException(e); |
|
494 |
} |
|
495 |
|
|
418 | 496 |
} |
419 | 497 |
|
420 |
|
|
421 | 498 |
public void addFlag(GvFlag flag) { |
422 | 499 |
flags.add(flag); |
423 | 500 |
} |
501 |
|
|
424 | 502 |
public GvFlag[] getFlags() { |
425 | 503 |
return (GvFlag[]) flags.toArray(new GvFlag[0]); |
426 | 504 |
} |
505 |
|
|
427 | 506 |
public void setFlags(ArrayList flags) { |
428 | 507 |
this.flags = flags; |
429 | 508 |
} |
509 |
|
|
430 | 510 |
public IGraph getGraph() { |
431 | 511 |
return graph; |
432 | 512 |
} |
513 |
|
|
433 | 514 |
public void setGraph(IGraph graph) { |
434 | 515 |
this.graph = graph; |
516 |
numOriginalEdges = graph.numEdges(); |
|
517 |
numOriginalNodes = graph.numVertices(); |
|
435 | 518 |
} |
519 |
|
|
436 | 520 |
public FLyrVect getLayer() { |
437 | 521 |
return lyrVect; |
438 | 522 |
} |
523 |
|
|
439 | 524 |
public void setLayer(FLyrVect lyr) { |
440 | 525 |
this.lyrVect = lyr; |
441 | 526 |
} |
442 | 527 |
|
443 |
|
|
444 | 528 |
public void removeFlags() { |
445 |
flags = new ArrayList();
|
|
529 |
flags = new ArrayList(); |
|
446 | 530 |
} |
447 |
|
|
448 |
void PartirArco(int idEdge, int idNode) |
|
449 |
{ |
|
450 |
// Se supone que el nuevo Nodo YA est? creado. Aqui dentro se coge el arco viejo y se le pega un tajo. |
|
451 |
// (Se modifican los enlaces de los nodos de ese arco y se crean los arcos nuevos, fijando sus costes). |
|
452 |
// Para sacar el porcentaje nos aprovechamos de que el nuevo nodo est? puesto en base a ese porcentaje |
|
531 |
|
|
532 |
void PartirArco(int idEdge, int idNode) { |
|
533 |
// Se supone que el nuevo Nodo YA est? creado. Aqui dentro se coge el |
|
534 |
// arco viejo y se le pega un tajo. |
|
535 |
// (Se modifican los enlaces de los nodos de ese arco y se crean los |
|
536 |
// arcos nuevos, fijando sus costes). |
|
537 |
// Para sacar el porcentaje nos aprovechamos de que el nuevo nodo est? |
|
538 |
// puesto en base a ese porcentaje |
|
453 | 539 |
// en distancia de los extremos. |
454 |
GvEdge newEdge; |
|
455 | 540 |
GvEdge oldEdge; |
456 | 541 |
GvNode pN1, pN2; |
457 | 542 |
double pct; |
458 |
|
|
459 |
oldEdge = graph.getEdgeByID(idEdge); |
|
460 | 543 |
|
461 |
// OJO, controlando los ceros por si acaso la recta es horizontal o vertical (Y si mide cero???)
|
|
544 |
oldEdge = graph.getEdgeByID(idEdge);
|
|
462 | 545 |
|
463 |
// pN1 = &Nodos[Arcos[idArco].idNodo1]; |
|
464 |
// pN2 = &Nodos[Arcos[idArco].idNodo2]; |
|
465 |
pN1 = graph.getNodeByID(graph.getEdgeByID(idEdge).getIdNodeOrig()); |
|
466 |
pN2 = graph.getNodeByID(graph.getEdgeByID(idEdge).getIdNodeEnd()); |
|
467 |
GvNode newNode = graph.getNodeByID(idNode); |
|
468 |
|
|
469 |
if (newNode.getX() != pN1.getX()) |
|
470 |
pct = Math.abs((newNode.getX() - pN1.getX())/(pN2.getX()-pN1.getX())); |
|
471 |
else |
|
472 |
pct = Math.abs((newNode.getY() - pN1.getY())/(pN2.getY()-pN1.getY())); |
|
546 |
// OJO, controlando los ceros por si acaso la recta es horizontal o |
|
547 |
// vertical (Y si mide cero???) |
|
473 | 548 |
|
549 |
// pN1 = &Nodos[Arcos[idArco].idNodo1]; |
|
550 |
// pN2 = &Nodos[Arcos[idArco].idNodo2]; |
|
551 |
pN1 = graph.getNodeByID(graph.getEdgeByID(idEdge).getIdNodeOrig()); |
|
552 |
pN2 = graph.getNodeByID(graph.getEdgeByID(idEdge).getIdNodeEnd()); |
|
553 |
GvNode newNode = graph.getNodeByID(idNode); |
|
474 | 554 |
|
555 |
if (newNode.getX() != pN1.getX()) |
|
556 |
pct = Math.abs((newNode.getX() - pN1.getX()) |
|
557 |
/ (pN2.getX() - pN1.getX())); |
|
558 |
else |
|
559 |
pct = Math.abs((newNode.getY() - pN1.getY()) |
|
560 |
/ (pN2.getY() - pN1.getY())); |
|
475 | 561 |
|
476 |
GvEdge first = new GvEdge();
|
|
477 |
first.setIdEdge(graph.numEdges());
|
|
478 |
first.setIdArc(oldEdge.getIdArc());
|
|
479 |
first.setDistance(oldEdge.getDistance() * pct);
|
|
480 |
first.setWeight(oldEdge.getWeight() * pct);
|
|
562 |
GvEdge first = new GvEdge(); |
|
563 |
first.setIdEdge(graph.numEdges()); |
|
564 |
first.setIdArc(oldEdge.getIdArc()); |
|
565 |
first.setDistance(oldEdge.getDistance() * pct); |
|
566 |
first.setWeight(oldEdge.getWeight() * pct); |
|
481 | 567 |
|
482 |
first.setDirec(oldEdge.getDirec());
|
|
483 |
first.setIdNodeOrig(oldEdge.getIdNodeOrig());
|
|
484 |
first.setType(oldEdge.getType());
|
|
485 |
first.setIdNodeEnd(idNode);
|
|
486 |
graph.addEdge(first);
|
|
568 |
first.setDirec(oldEdge.getDirec()); |
|
569 |
first.setIdNodeOrig(oldEdge.getIdNodeOrig()); |
|
570 |
first.setType(oldEdge.getType()); |
|
571 |
first.setIdNodeEnd(idNode); |
|
572 |
graph.addEdge(first); |
|
487 | 573 |
|
488 |
GvEdge second = new GvEdge();
|
|
489 |
second.setIdEdge(graph.numEdges());
|
|
490 |
second.setDistance(oldEdge.getDistance()*(1.0-pct));
|
|
491 |
second.setWeight(oldEdge.getWeight()*(1.0-pct));
|
|
492 |
second.setIdArc(oldEdge.getIdArc());
|
|
493 |
second.setDirec(oldEdge.getDirec());
|
|
494 |
second.setType(oldEdge.getType());
|
|
495 |
second.setIdNodeOrig(idNode);
|
|
496 |
second.setIdNodeEnd(oldEdge.getIdNodeEnd());
|
|
497 |
graph.addEdge(second);
|
|
574 |
GvEdge second = new GvEdge(); |
|
575 |
second.setIdEdge(graph.numEdges()); |
|
576 |
second.setDistance(oldEdge.getDistance() * (1.0 - pct));
|
|
577 |
second.setWeight(oldEdge.getWeight() * (1.0 - pct));
|
|
578 |
second.setIdArc(oldEdge.getIdArc()); |
|
579 |
second.setDirec(oldEdge.getDirec()); |
|
580 |
second.setType(oldEdge.getType()); |
|
581 |
second.setIdNodeOrig(idNode); |
|
582 |
second.setIdNodeEnd(oldEdge.getIdNodeEnd()); |
|
583 |
graph.addEdge(second); |
|
498 | 584 |
|
585 |
// //////////////////////////////////////////////////// |
|
586 |
// Ahora retocamos los enlaces que salen de cada nodo |
|
587 |
// //////////////////////////////////////////////////// |
|
588 |
int i; |
|
589 |
// boolean encontrado = false; |
|
590 |
for (i = 0; i < pN1.getEnlaces().size(); i++) { |
|
591 |
GvEdge aux = (GvEdge) pN1.getEnlaces().get(i); |
|
592 |
if (aux.getIdEdge() == idEdge) { |
|
593 |
pN1.getEnlaces().set(i, first); |
|
594 |
// encontrado = true; |
|
595 |
break; |
|
596 |
} |
|
597 |
} // for |
|
499 | 598 |
|
500 |
////////////////////////////////////////////////////// |
|
501 |
// Ahora retocamos los enlaces que salen de cada nodo |
|
502 |
////////////////////////////////////////////////////// |
|
503 |
int i; |
|
504 |
boolean encontrado = false; |
|
505 |
for (i=0; i<pN1.getEnlaces().size(); i++) |
|
506 |
{ |
|
507 |
GvEdge aux = (GvEdge) pN1.getEnlaces().get(i); |
|
508 |
if (aux.getIdEdge() == idEdge) |
|
509 |
{ |
|
510 |
pN1.getEnlaces().set(i, first); |
|
511 |
encontrado = true; |
|
512 |
break; |
|
513 |
} |
|
514 |
} // for |
|
599 |
newNode.getEnlaces().add(second); |
|
515 | 600 |
|
516 |
newNode.getEnlaces().add(second); |
|
517 |
|
|
518 | 601 |
} |
519 | 602 |
|
520 | 603 |
} |
521 |
|
|
522 |
|
Also available in: Unified diff