root / trunk / extensions / extGraph / src / org / gvsig / graph / core / Network.java @ 37909
History | View | Annotate | Download (34.4 KB)
1 |
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|
2 |
*
|
3 |
* Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
|
4 |
*
|
5 |
* This program is free software; you can redistribute it and/or
|
6 |
* modify it under the terms of the GNU General Public License
|
7 |
* as published by the Free Software Foundation; either version 2
|
8 |
* of the License, or (at your option) any later version.
|
9 |
*
|
10 |
* This program is distributed in the hope that it will be useful,
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13 |
* GNU General Public License for more details.
|
14 |
*
|
15 |
* You should have received a copy of the GNU General Public License
|
16 |
* along with this program; if not, write to the Free Software
|
17 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
18 |
*
|
19 |
* For more information, contact:
|
20 |
*
|
21 |
* Generalitat Valenciana
|
22 |
* Conselleria d'Infraestructures i Transport
|
23 |
* Av. Blasco Ib??ez, 50
|
24 |
* 46010 VALENCIA
|
25 |
* SPAIN
|
26 |
*
|
27 |
* +34 963862235
|
28 |
* gvsig@gva.es
|
29 |
* www.gvsig.gva.es
|
30 |
*
|
31 |
* or
|
32 |
*
|
33 |
* IVER T.I. S.A
|
34 |
* Salamanca 50
|
35 |
* 46005 Valencia
|
36 |
* Spain
|
37 |
*
|
38 |
* +34 963163400
|
39 |
* dac@iver.es
|
40 |
*/
|
41 |
package org.gvsig.graph.core; |
42 |
|
43 |
import java.awt.geom.PathIterator; |
44 |
import java.awt.geom.Point2D; |
45 |
import java.util.ArrayList; |
46 |
import java.util.Hashtable; |
47 |
import java.util.Iterator; |
48 |
import java.util.Map; |
49 |
import java.util.TreeMap; |
50 |
|
51 |
import org.cresques.cts.IProjection; |
52 |
import org.gvsig.exceptions.BaseException; |
53 |
|
54 |
import com.iver.cit.gvsig.fmap.ViewPort; |
55 |
import com.iver.cit.gvsig.fmap.core.IGeometry; |
56 |
import com.iver.cit.gvsig.fmap.core.v02.FConverter; |
57 |
import com.iver.cit.gvsig.fmap.drivers.DriverIOException; |
58 |
import com.iver.cit.gvsig.fmap.layers.CancelationException; |
59 |
import com.iver.cit.gvsig.fmap.layers.FBitSet; |
60 |
import com.iver.cit.gvsig.fmap.layers.FLyrVect; |
61 |
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial; |
62 |
import com.iver.cit.gvsig.fmap.layers.VectorialAdapter; |
63 |
import com.vividsolutions.jts.geom.Coordinate; |
64 |
import com.vividsolutions.jts.geom.LineSegment; |
65 |
import com.vividsolutions.jts.geom.MultiLineString; |
66 |
|
67 |
public class Network { |
68 |
protected FLyrVect lyrVect;
|
69 |
|
70 |
protected IGraph graph;
|
71 |
|
72 |
protected ArrayList flags = new ArrayList(); |
73 |
|
74 |
protected int numOriginalEdges; |
75 |
|
76 |
protected int numOriginalNodes; |
77 |
|
78 |
private ArrayList modifiedCosts = new ArrayList(); |
79 |
private ArrayList flagListeners = new ArrayList(); |
80 |
private boolean dispatching = true; |
81 |
|
82 |
private Hashtable velocities = null; |
83 |
|
84 |
private ArrayList<GvTurn> turnCosts = new ArrayList(); |
85 |
|
86 |
private IFeatureExtractor featExtractor = null; |
87 |
|
88 |
public void reconstruyeTramo(int idArc) { |
89 |
GvNode pN1, pN2; |
90 |
int i;
|
91 |
|
92 |
// Si encontramos un enlace con idEdge >= numOriginalEdges, lo cambiamos.
|
93 |
// Y CON ESE IDarc!!
|
94 |
// Si hay varios, no pasa nada, volvemos a llamar a esta funci?n con IdTramo
|
95 |
|
96 |
EdgePair edgePair = graph.getEdgesByIdArc(idArc); |
97 |
if (edgePair.getIdEdge() != -1) |
98 |
{ |
99 |
// Restauramos los enlaces de los nodos de ese tramo.
|
100 |
// pN1 = &Nodos[Arcos[IndiceArcos[idTramo].idArco].idNodo1];
|
101 |
// pN2 = &Nodos[Arcos[IndiceArcos[idTramo].idArco].idNodo2];
|
102 |
GvEdge edge = graph.getEdgeByID(edgePair.getIdEdge()); |
103 |
pN1 = graph.getNodeByID(edge.getIdNodeOrig()); |
104 |
pN2 = graph.getNodeByID(edge.getIdNodeEnd()); |
105 |
|
106 |
// Metemos idArco en los enlaces de Nodo1
|
107 |
// for (i=0; i< pN1.getOutputLinks().size(); i++)
|
108 |
// {
|
109 |
// GvEdge auxEdge = (GvEdge) pN1.getOutputLinks().get(i);
|
110 |
// if (auxEdge.getIdArc() == idArc)
|
111 |
// {
|
112 |
// if (auxEdge.getIdEdge() >= numOriginalEdges)
|
113 |
// {
|
114 |
// pN1.getOutputLinks().set(i, graph.getEdgeByID(edgePair.getIdEdge()));
|
115 |
// break;
|
116 |
// }
|
117 |
// }
|
118 |
// }
|
119 |
restoreConnectors(edge); |
120 |
|
121 |
} |
122 |
|
123 |
if (edgePair.idInverseEdge != -1) |
124 |
{ |
125 |
// pN1 = &Nodos[Arcos[IndiceArcos[idTramo].idContraArco].idNodo1];
|
126 |
// pN2 = &Nodos[Arcos[IndiceArcos[idTramo].idContraArco].idNodo2];
|
127 |
GvEdge edge = graph.getEdgeByID(edgePair.getIdInverseEdge()); |
128 |
pN1 = graph.getNodeByID(edge.getIdNodeOrig()); |
129 |
|
130 |
// for (i=0; i< pN1.getOutputLinks().size(); i++)
|
131 |
// {
|
132 |
// if (edge.getIdArc() == idArc)
|
133 |
// {
|
134 |
// GvEdge auxEdge = (GvEdge) pN1.getOutputLinks().get(i);
|
135 |
// if (auxEdge.getIdEdge() >= numOriginalEdges)
|
136 |
// {
|
137 |
// pN1.getOutputLinks().set(i, graph.getEdgeByID(edgePair.getIdInverseEdge()));
|
138 |
// break;
|
139 |
// }
|
140 |
// }
|
141 |
// }
|
142 |
restoreConnectors(edge); |
143 |
} |
144 |
|
145 |
int numEdges = graph.numEdges();
|
146 |
int numNodes = graph.numVertices();
|
147 |
for (int idEdge = numEdges-1; idEdge >= numOriginalEdges; idEdge--) |
148 |
{ |
149 |
graph.removeEdge(idEdge); |
150 |
} |
151 |
for (int idNode = numNodes-1; idNode >= numOriginalNodes; idNode--) |
152 |
{ |
153 |
graph.removeNode(idNode); |
154 |
} |
155 |
|
156 |
} |
157 |
|
158 |
private void restoreConnectors(GvEdge edge) { |
159 |
GvNode pN1 = graph.getNodeByID(edge.getIdNodeOrig()); |
160 |
GvNode pN2 = graph.getNodeByID(edge.getIdNodeEnd()); |
161 |
for (int iCon = 0; iCon < pN1.getConnectors().size(); iCon++) { |
162 |
GvConnector c = pN1.getConnectors().get(iCon); |
163 |
if (c.getEdgeOut() != null) { |
164 |
if ((c.getEdgeOut().getIdEdge() >= numOriginalEdges) && (c.getEdgeOut().getIdArc() == edge.getIdArc())) {
|
165 |
c.setEdgeOut(edge); |
166 |
} |
167 |
} |
168 |
} |
169 |
for (int iCon = 0; iCon < pN2.getConnectors().size(); iCon++) { |
170 |
GvConnector c = pN2.getConnectors().get(iCon); |
171 |
if (c.getEdgeIn() != null) { |
172 |
if ((c.getEdgeIn().getIdEdge() >= numOriginalEdges) && (c.getEdgeIn().getIdArc() == edge.getIdArc())) {
|
173 |
c.setEdgeIn(edge); |
174 |
} |
175 |
} |
176 |
} |
177 |
} |
178 |
|
179 |
/**
|
180 |
* Closest ID to this point. -1 if out from tolerance.
|
181 |
* @param x
|
182 |
* @param y
|
183 |
* @param tolerance
|
184 |
* @param nearest. Point to receive the nearest point ON arc.
|
185 |
* @return
|
186 |
*/
|
187 |
public int findClosestArc(double x, double y, double tolerance, Point2D nearestPoint) { |
188 |
Point2D p = new Point2D.Double(x, y); |
189 |
|
190 |
if (featExtractor != null) |
191 |
{ |
192 |
if (! (featExtractor instanceof DefaultFeatureExtractor)) { |
193 |
return findClosestArcWithFeatExtractor(p, tolerance, nearestPoint);
|
194 |
} |
195 |
} |
196 |
FBitSet bitSet; |
197 |
try {
|
198 |
bitSet = lyrVect.queryByPoint(p, tolerance); |
199 |
ReadableVectorial va = lyrVect.getSource(); |
200 |
va.start(); |
201 |
double minDist = tolerance;
|
202 |
int foundGeom = -1; |
203 |
for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet |
204 |
.nextSetBit(i + 1)) {
|
205 |
IGeometry geom; |
206 |
geom = va.getShape(i); |
207 |
IProjection proj = lyrVect.getProjection(); |
208 |
if (proj != null) { |
209 |
if (!proj.getAbrev().equals(lyrVect.getMapContext().getViewPort().getProjection().getAbrev())){
|
210 |
geom.reProject(lyrVect.getCoordTrans()); |
211 |
} |
212 |
} |
213 |
|
214 |
Point2D nearest = getNearestPoint(p, geom, tolerance);
|
215 |
if (nearest != null) { |
216 |
double dist = nearest.distance(p);
|
217 |
if (dist < minDist) {
|
218 |
minDist = dist; |
219 |
foundGeom = i; |
220 |
nearestPoint.setLocation(nearest); |
221 |
} |
222 |
} |
223 |
} |
224 |
va.stop(); |
225 |
return foundGeom;
|
226 |
} catch (BaseException e1) {
|
227 |
// TODO Auto-generated catch block
|
228 |
e1.printStackTrace(); |
229 |
} |
230 |
return -1; |
231 |
|
232 |
} |
233 |
|
234 |
private int findClosestArcWithFeatExtractor(Point2D p, double tolerance, |
235 |
Point2D nearestPoint) {
|
236 |
double minDist = tolerance;
|
237 |
int foundGeom = -1; |
238 |
for (int i = 0; i < featExtractor.getNumFeatures(); i++) { |
239 |
IGeometry geom = featExtractor.getGeometry(i); |
240 |
Point2D nearest = getNearestPoint(p, geom, tolerance);
|
241 |
if (nearest != null) { |
242 |
double dist = nearest.distance(p);
|
243 |
if (dist < minDist) {
|
244 |
minDist = dist; |
245 |
foundGeom = i; |
246 |
nearestPoint.setLocation(nearest); |
247 |
} |
248 |
} |
249 |
} |
250 |
return foundGeom;
|
251 |
|
252 |
} |
253 |
|
254 |
protected Point2D getNearestPoint(Point2D point, IGeometry geom, |
255 |
double tolerance) {
|
256 |
Point2D resul = null; |
257 |
Coordinate c = new Coordinate(point.getX(), point.getY());
|
258 |
|
259 |
PathIterator theIterator = geom.getPathIterator(null, |
260 |
FConverter.FLATNESS); // polyLine.getPathIterator(null,
|
261 |
// flatness);
|
262 |
double[] theData = new double[6]; |
263 |
double minDist = tolerance;
|
264 |
Coordinate from = null, first = null; |
265 |
while (!theIterator.isDone()) {
|
266 |
// while not done
|
267 |
int theType = theIterator.currentSegment(theData);
|
268 |
|
269 |
switch (theType) {
|
270 |
case PathIterator.SEG_MOVETO: |
271 |
from = new Coordinate(theData[0], theData[1]); |
272 |
first = from; |
273 |
break;
|
274 |
|
275 |
case PathIterator.SEG_LINETO: |
276 |
|
277 |
// System.out.println("SEG_LINETO");
|
278 |
Coordinate to = new Coordinate(theData[0], theData[1]); |
279 |
LineSegment line = new LineSegment(from, to);
|
280 |
Coordinate closestPoint = line.closestPoint(c); |
281 |
double dist = c.distance(closestPoint);
|
282 |
if ((dist < minDist)) {
|
283 |
resul = new Point2D.Double(closestPoint.x, closestPoint.y); |
284 |
minDist = dist; |
285 |
} |
286 |
|
287 |
from = to; |
288 |
break;
|
289 |
case PathIterator.SEG_CLOSE: |
290 |
line = new LineSegment(from, first);
|
291 |
closestPoint = line.closestPoint(c); |
292 |
dist = c.distance(closestPoint); |
293 |
if ((dist < minDist)) {
|
294 |
resul = new Point2D.Double(closestPoint.x, closestPoint.y); |
295 |
minDist = dist; |
296 |
} |
297 |
|
298 |
from = first; |
299 |
break;
|
300 |
|
301 |
} // end switch
|
302 |
|
303 |
theIterator.next(); |
304 |
} |
305 |
|
306 |
return resul;
|
307 |
} |
308 |
|
309 |
/**
|
310 |
* TODO: POR TERMINAR!!!
|
311 |
*
|
312 |
* @param flag
|
313 |
* @return
|
314 |
*/
|
315 |
public int creaArcosVirtuales(GvFlag flag) { |
316 |
// Devuelve el idNodo del nodo virtual creado.
|
317 |
/*
|
318 |
* 0.- Creamos el nuevo Nodo virtual. 1.- Recorremos los arcos nuevos
|
319 |
* mirando su idTramo. 2.- Si existe ese idtramo=> Ya hemos partido
|
320 |
* antes ese idTramo. Buscamos el arco virtual que contiene ese nodo y
|
321 |
* lo partimos. Ojo, recorrer hasta el final los tramos para asegurarnos
|
322 |
* de que es el trozo m?s peque?o. 3.- Si NO existe, utilizamos el
|
323 |
* IndiceArcos para coger los arcos que toca y partirlos.
|
324 |
*
|
325 |
* 4.- OJO: Si el porcentaje es 0 ? 100, no partimos el arco, devolvemos
|
326 |
* el id del nodo que toca.
|
327 |
*/
|
328 |
// NUEVO: 20/7/2004:
|
329 |
// Cuando trabajamos con sentidos, al partir un arco no podemos insertar
|
330 |
// 2 nuevos sin mirar
|
331 |
// si es o no de un ?nico sentido.) (Mirar idArco. Si es -1, no partimos
|
332 |
// el arco).
|
333 |
// FIN NUEVO
|
334 |
int idNodo1, idNodo2;
|
335 |
int idArco, elIdArco, elIdContraArco;
|
336 |
boolean encontrado;
|
337 |
GvNode newNode; |
338 |
|
339 |
// Sacamos los idNodos del tramo
|
340 |
EdgePair edgePair = graph.getEdgesByIdArc(flag.getIdArc()); |
341 |
if (edgePair.getIdEdge() != -1) { |
342 |
// idNodo1 = Arcos[IndiceArcos[idTramo].idArco].idNodo1;
|
343 |
// idNodo2 = Arcos[IndiceArcos[idTramo].idArco].idNodo2;
|
344 |
idNodo1 = graph.getEdgeByID(edgePair.getIdEdge()).getIdNodeOrig(); |
345 |
idNodo2 = graph.getEdgeByID(edgePair.getIdEdge()).getIdNodeEnd(); |
346 |
|
347 |
} else {
|
348 |
// idNodo2 = Arcos[IndiceArcos[idTramo].idContraArco].idNodo1;
|
349 |
// idNodo1 = Arcos[IndiceArcos[idTramo].idContraArco].idNodo2;
|
350 |
idNodo2 = graph.getEdgeByID(edgePair.getIdInverseEdge()) |
351 |
.getIdNodeOrig(); |
352 |
idNodo1 = graph.getEdgeByID(edgePair.getIdInverseEdge()) |
353 |
.getIdNodeEnd(); |
354 |
|
355 |
} |
356 |
|
357 |
if (flag.getPct() == 0) |
358 |
return idNodo1;
|
359 |
if (flag.getPct() == 1) |
360 |
return idNodo2;
|
361 |
|
362 |
// Creamos el nodo de enmedio
|
363 |
|
364 |
// if (numNodos == maxNodos) // La jodimos, T?rtola, hay que usar
|
365 |
// reallocate
|
366 |
// {
|
367 |
// // NOTA: ESTO EN DEBUG HACE QUE FALLE AL USAR DESPUES EnlacesSTL. ES
|
368 |
// POR NO S? QU? HISTORIA
|
369 |
// // DEL HEAP. EN RELEASE NO FALLA. (TAMPOCO S? SI FASTIDIA ALGO).
|
370 |
// Nodos = (CNode *) realloc(Nodos,(numNodos + MAX_RESERVA_NODOS) *
|
371 |
// sizeof(CNode)); // Deber?amos chequear que devuelve algo correcto
|
372 |
// maxNodos = numNodos + MAX_RESERVA_NODOS;
|
373 |
// }
|
374 |
|
375 |
newNode = new GvNode();
|
376 |
// Nodo = &Nodos[numNodos];
|
377 |
|
378 |
// pNuevoNodo->idNodo = numNodos;
|
379 |
newNode.setIdNode(graph.numVertices()); |
380 |
|
381 |
// OJO: Las coordenadas estas puede que no tengan que ver con la
|
382 |
// realidad. Algo m?s correcto
|
383 |
// ser?a tener en cuenta el shape de verdad, pero creo que no influye en
|
384 |
// el resultado final.
|
385 |
// pNuevoNodo->x = Nodos[idNodo1].x + (Nodos[idNodo2].x -
|
386 |
// Nodos[idNodo1].x) * Porcentaje;
|
387 |
// pNuevoNodo->y = Nodos[idNodo1].y + (Nodos[idNodo2].y -
|
388 |
// Nodos[idNodo1].y) * Porcentaje;
|
389 |
GvNode node1 = graph.getNodeByID(idNodo1); |
390 |
GvNode node2 = graph.getNodeByID(idNodo2); |
391 |
newNode.setX(node1.getX() + (node2.getX() - node1.getX()) |
392 |
* flag.getPct()); |
393 |
newNode.setY(node1.getY() + (node2.getY() - node1.getY()) |
394 |
* flag.getPct()); |
395 |
graph.addNode(newNode); |
396 |
Coordinate newC = new Coordinate(newNode.getX(), newNode.getY());
|
397 |
|
398 |
encontrado = false;
|
399 |
|
400 |
elIdArco = -1;
|
401 |
elIdContraArco = -1;
|
402 |
|
403 |
boolean bIdTramoYaPartido = false; |
404 |
|
405 |
// TODO: POR AQUI VOY
|
406 |
for (idArco = numOriginalEdges; idArco < graph.numEdges(); idArco++) {
|
407 |
GvEdge addedEdge = graph.getEdgeByID(idArco); |
408 |
if (addedEdge.getIdArc() == flag.getIdArc()) {
|
409 |
bIdTramoYaPartido = true;
|
410 |
|
411 |
idNodo1 = addedEdge.getIdNodeOrig(); |
412 |
idNodo2 = addedEdge.getIdNodeEnd(); |
413 |
|
414 |
// Comprobamos si est? enmedio
|
415 |
GvNode n1 = graph.getNodeByID(idNodo1); |
416 |
GvNode n2 = graph.getNodeByID(idNodo2); |
417 |
Coordinate c1 = new Coordinate(n1.getX(), n1.getY());
|
418 |
Coordinate c2 = new Coordinate(n2.getX(), n2.getY());
|
419 |
LineSegment line = new LineSegment(c1, c2);
|
420 |
double t = line.projectionFactor(newC);
|
421 |
|
422 |
// Si la proyecci?n es positiva y menor que la magnitud d, est?
|
423 |
// en medio
|
424 |
if ((t >= 0) && (t <= 1)) { |
425 |
encontrado = true;
|
426 |
if (t == 0) |
427 |
return idNodo1; // No partimos |
428 |
if (t == 1) |
429 |
return idNodo2; // Tampoco partimos |
430 |
|
431 |
if (addedEdge.getDirec() == 1) |
432 |
elIdArco = idArco; |
433 |
else
|
434 |
elIdContraArco = idArco; |
435 |
|
436 |
} // if est? enmedio
|
437 |
} // if idTramo encontrado
|
438 |
} // for idArco
|
439 |
if (bIdTramoYaPartido && (!encontrado))
|
440 |
throw new RuntimeException( |
441 |
"Algo va mal con lo del producto escalar");
|
442 |
|
443 |
if (encontrado) {
|
444 |
// sprintf(Mensaje,"Voy a partir el idTramo= %ld (idArco
|
445 |
// %ld)",idTramo,elIdArco);
|
446 |
// MessageBox(NULL,Mensaje,"",MB_OK);
|
447 |
if (elIdArco != -1) |
448 |
PartirArco(elIdArco, newNode.getIdNode()); |
449 |
|
450 |
if (elIdContraArco != -1) |
451 |
PartirArco(elIdContraArco, newNode.getIdNode()); |
452 |
} else {
|
453 |
// Creamos 2 Arcos por cada arco que ten?amos antes.
|
454 |
if (edgePair.getIdEdge() != -1) |
455 |
PartirArco(edgePair.getIdEdge(), newNode.getIdNode()); |
456 |
|
457 |
if (edgePair.getIdInverseEdge() != -1) |
458 |
PartirArco(edgePair.getIdInverseEdge(), newNode.getIdNode()); |
459 |
|
460 |
} // else encontrado
|
461 |
|
462 |
return newNode.getIdNode();
|
463 |
|
464 |
} |
465 |
|
466 |
/**
|
467 |
* Cogemos el nodo m?s cercano y ponemos el pct a ese flag.
|
468 |
*
|
469 |
* @param flag
|
470 |
* @return
|
471 |
*/
|
472 |
public int getClosestIdNode(GvFlag flag) { |
473 |
EdgePair pair = graph.getEdgesByIdArc(flag.getIdArc()); |
474 |
if (pair.getIdEdge() != -1) { |
475 |
GvEdge edge = graph.getEdgeByID(pair.getIdEdge()); |
476 |
GvNode from = graph.getNodeByID(edge.getIdNodeOrig()); |
477 |
GvNode to = graph.getNodeByID(edge.getIdNodeEnd()); |
478 |
|
479 |
double dist1 = flag.getOriginalPoint().distance(from.getX(),
|
480 |
from.getY()); |
481 |
double dist2 = flag.getOriginalPoint().distance(to.getX(),
|
482 |
to.getY()); |
483 |
if (dist1 < dist2) {
|
484 |
flag.setPct(0);
|
485 |
return from.getIdNode();
|
486 |
} |
487 |
else
|
488 |
{ |
489 |
flag.setPct(1.0);
|
490 |
return to.getIdNode();
|
491 |
} |
492 |
} else {
|
493 |
GvEdge edge = graph.getEdgeByID(pair.getIdInverseEdge()); |
494 |
GvNode from = graph.getNodeByID(edge.getIdNodeOrig()); |
495 |
GvNode to = graph.getNodeByID(edge.getIdNodeEnd()); |
496 |
|
497 |
double dist1 = flag.getOriginalPoint().distance(from.getX(),
|
498 |
from.getY()); |
499 |
double dist2 = flag.getOriginalPoint().distance(to.getX(),
|
500 |
to.getY()); |
501 |
if (dist1 < dist2)
|
502 |
{ |
503 |
flag.setPct(0);
|
504 |
return from.getIdNode();
|
505 |
} |
506 |
else
|
507 |
{ |
508 |
flag.setPct(1.0);
|
509 |
return to.getIdNode();
|
510 |
} |
511 |
// if (flag.getPct() < 0.5)
|
512 |
// return to.getIdNode();
|
513 |
// else
|
514 |
// return from.getIdNode();
|
515 |
} |
516 |
} |
517 |
|
518 |
/**
|
519 |
* @param idArc
|
520 |
* @param x
|
521 |
* @param y
|
522 |
* @return entre 0.0 y 1.0
|
523 |
* @throws DriverIOException
|
524 |
*/
|
525 |
private double percentAlong(int idArc, double x, double y) |
526 |
throws BaseException {
|
527 |
// Le pasamos el idTramo, la coordenada X de donde hemos pulsado y la
|
528 |
// coordenada Y
|
529 |
// Primero calculamos la longitud total del shape.
|
530 |
// Luego calculamos el punto m?s cercano y su distancia para cada
|
531 |
// segmento del shape.
|
532 |
// Nos quedamos con el que est? m?s cerca y luego recorremos hasta ?l
|
533 |
// acumulando distancia.
|
534 |
// Finalmente, dividimos esa distancia por la longitud total.
|
535 |
// lyrVect.getSource().start();
|
536 |
// IGeometry geom = lyrVect.getSource().getShape(idArc);
|
537 |
IGeometry geom = featExtractor.getGeometry(idArc); |
538 |
MultiLineString jtsGeom = (MultiLineString) geom.toJTSGeometry(); |
539 |
|
540 |
Coordinate[] coords = jtsGeom.getCoordinates();
|
541 |
|
542 |
Coordinate userCoord = new Coordinate(x, y);
|
543 |
|
544 |
double longReal = 0; |
545 |
// Le pegamos una primera pasada para saber su longitud real.
|
546 |
// OJO, NO TRABAJAMOS CON SHAPES MULTIPARTE, NO TIENE SENTIDO CON LAS
|
547 |
// REDES (CREO)
|
548 |
// POR ESO SUPONEMOS UNA ?NICA PARTE (L?NEA CONT?NUA)
|
549 |
// A la vez calculamos el punto m?s cercano y su distancia para cada
|
550 |
// segmento.
|
551 |
double minDist = Double.MAX_VALUE; |
552 |
double distTo = 0; |
553 |
double dist = 0; |
554 |
Coordinate cOrig = null;
|
555 |
Coordinate closestPoint = null;
|
556 |
for (int j = 0; j < coords.length - 1; j++) { |
557 |
Coordinate c1 = coords[j]; |
558 |
Coordinate c2 = coords[j + 1];
|
559 |
LineSegment line = new LineSegment(c1, c2);
|
560 |
|
561 |
Coordinate auxPoint = line.closestPoint(userCoord); |
562 |
dist = userCoord.distance(auxPoint); |
563 |
if ((dist < minDist)) {
|
564 |
minDist = dist; |
565 |
cOrig = c1; |
566 |
closestPoint = auxPoint; |
567 |
distTo = longReal; |
568 |
} |
569 |
longReal += line.getLength(); |
570 |
} |
571 |
// lyrVect.getSource().stop();
|
572 |
dist = cOrig.distance(closestPoint); |
573 |
double longBuscada = distTo + dist;
|
574 |
|
575 |
double pct;
|
576 |
if (longReal > 0) |
577 |
pct = longBuscada / longReal; |
578 |
else
|
579 |
pct = 0.0;
|
580 |
|
581 |
return pct;
|
582 |
} |
583 |
|
584 |
/**
|
585 |
* Adds a flag on a network. flagDirection set if the flag must be on left
|
586 |
* or right edge.
|
587 |
*
|
588 |
* @param x
|
589 |
* @param y
|
590 |
* @param flagDirection
|
591 |
* @param tol
|
592 |
* tolerance in map units
|
593 |
* @return null if there is no place to add flag. You can increase the
|
594 |
* tolerance, then.
|
595 |
* @throws GraphException
|
596 |
*/
|
597 |
public GvFlag addFlag(double x, double y, int flagDirection, double tol) |
598 |
throws GraphException {
|
599 |
try {
|
600 |
Point2D nearestPoint = new Point2D.Double(); |
601 |
int idArc = findClosestArc(x, y, tol, nearestPoint);
|
602 |
if (idArc == -1) |
603 |
return null; |
604 |
GvFlag flag = new GvFlag(x, y);
|
605 |
flag.setIdArc(idArc); |
606 |
|
607 |
flag.setPct(percentAlong(idArc, x, y)); |
608 |
flag.setDirec(flagDirection); |
609 |
flag.setIdFlag(flags.size()); |
610 |
callFlagsChanged(IFlagListener.FLAG_ADDED); |
611 |
return flag;
|
612 |
} catch (BaseException e) {
|
613 |
e.printStackTrace(); |
614 |
throw new GraphException(e); |
615 |
} |
616 |
|
617 |
} |
618 |
|
619 |
/**
|
620 |
* Adds 2 flags on a network. (On both sides of an arc)
|
621 |
*
|
622 |
* @param x
|
623 |
* @param y
|
624 |
* @param tol
|
625 |
* tolerance in map units
|
626 |
* @return null if there is no place to add flag. You can increase the
|
627 |
* tolerance, then.
|
628 |
* @throws GraphException
|
629 |
*/
|
630 |
public GvFlag addFlag(double x, double y, double tol) throws GraphException { |
631 |
try {
|
632 |
Point2D nearestPoint = new Point2D.Double(); |
633 |
int idArc = findClosestArc(x, y, tol, nearestPoint);
|
634 |
if (idArc == -1) |
635 |
return null; |
636 |
|
637 |
GvFlag flag = new GvFlag(x, y);
|
638 |
flag.setIdArc(idArc); |
639 |
EdgePair edgePair = graph.getEdgesByIdArc(idArc); |
640 |
flag.setDirec(GvFlag.BOTH_DIRECTIONS); |
641 |
|
642 |
flag.setPct(percentAlong(idArc, x, y)); |
643 |
flag.setIdFlag(flags.size()); |
644 |
flags.add(flag); |
645 |
callFlagsChanged(IFlagListener.FLAG_ADDED); |
646 |
return flag;
|
647 |
} catch (BaseException e) {
|
648 |
e.printStackTrace(); |
649 |
throw new GraphException(e); |
650 |
} |
651 |
|
652 |
} |
653 |
|
654 |
/**
|
655 |
* Create a flag in both directions, but NOT add it to the Network.
|
656 |
* We use it on onetomany solver
|
657 |
* @param x
|
658 |
* @param y
|
659 |
* @param tol
|
660 |
* @return
|
661 |
* @throws GraphException
|
662 |
*/
|
663 |
public GvFlag createFlag(double x, double y, double tol) throws GraphException { |
664 |
try {
|
665 |
Point2D nearestPoint = new Point2D.Double(); |
666 |
int idArc = findClosestArc(x, y, tol, nearestPoint);
|
667 |
if (idArc == -1) |
668 |
return null; |
669 |
|
670 |
GvFlag flag = new GvFlag(x, y);
|
671 |
flag.setIdArc(idArc); |
672 |
// EdgePair edgePair = graph.getEdgesByIdArc(idArc);
|
673 |
flag.setDirec(GvFlag.BOTH_DIRECTIONS); |
674 |
|
675 |
flag.setPct(percentAlong(idArc, x, y)); |
676 |
flag.setIdFlag(flags.size()); |
677 |
return flag;
|
678 |
} catch (BaseException e) {
|
679 |
e.printStackTrace(); |
680 |
throw new GraphException(e); |
681 |
} |
682 |
|
683 |
} |
684 |
|
685 |
public GvFlag addFlagToNode(double x, double y, double tol) throws GraphException { |
686 |
Point2D nearestPoint = new Point2D.Double(); |
687 |
int idArc = findClosestArc(x, y, tol, nearestPoint);
|
688 |
if (idArc == -1) |
689 |
return null; |
690 |
|
691 |
GvFlag flag = new GvFlag(x, y);
|
692 |
flag.setIdArc(idArc); |
693 |
flag.setDirec(GvFlag.BOTH_DIRECTIONS); |
694 |
int idNode = getClosestIdNode(flag);
|
695 |
|
696 |
GvNode node = graph.getNodeByID(idNode); |
697 |
flag.setOriginalPoint(node.getX(), node.getY()); |
698 |
flag.setIdFlag(flags.size()); |
699 |
flags.add(flag); |
700 |
callFlagsChanged(IFlagListener.FLAG_ADDED); |
701 |
return flag;
|
702 |
|
703 |
} |
704 |
|
705 |
|
706 |
public void addFlag(GvFlag flag) { |
707 |
flags.add(flag); |
708 |
callFlagsChanged(IFlagListener.FLAG_ADDED); |
709 |
} |
710 |
|
711 |
public GvFlag[] getFlags() { |
712 |
ArrayList aux = new ArrayList(); |
713 |
for (int i=0; i < getOriginaFlags().size(); i++) |
714 |
{ |
715 |
GvFlag flag = (GvFlag) getOriginaFlags().get(i); |
716 |
if (flag.isEnabled()) aux.add(flag);
|
717 |
} |
718 |
|
719 |
return (GvFlag[]) aux.toArray(new GvFlag[0]); |
720 |
} |
721 |
|
722 |
public int getFlagsCount(){ |
723 |
return this.getOriginaFlags().size(); |
724 |
} |
725 |
|
726 |
/**
|
727 |
* Suitable to change directly the flags collection
|
728 |
* @return
|
729 |
*/
|
730 |
public ArrayList getOriginaFlags() { |
731 |
return flags;
|
732 |
} |
733 |
|
734 |
|
735 |
public void setFlags(ArrayList flags) { |
736 |
this.flags = flags;
|
737 |
} |
738 |
|
739 |
public IGraph getGraph() {
|
740 |
return graph;
|
741 |
} |
742 |
|
743 |
public void setGraph(IGraph graph) { |
744 |
this.graph = graph;
|
745 |
numOriginalEdges = graph.numEdges(); |
746 |
numOriginalNodes = graph.numVertices(); |
747 |
} |
748 |
|
749 |
public FLyrVect getLayer() {
|
750 |
return lyrVect;
|
751 |
} |
752 |
|
753 |
public void setLayer(FLyrVect lyr) { |
754 |
this.lyrVect = lyr;
|
755 |
this.featExtractor = new DefaultFeatureExtractor(lyr); |
756 |
// FJP: Workarround to avoid using SpatialIndex with reprojected layers
|
757 |
if (lyrVect.getCoordTrans() != null) { |
758 |
if (!lyrVect.getProjection().getAbrev().equals(lyrVect.getMapContext().getViewPort().getProjection().getAbrev()))
|
759 |
lyrVect.setISpatialIndex(null);
|
760 |
} |
761 |
|
762 |
// fin
|
763 |
|
764 |
} |
765 |
|
766 |
public void removeFlags() { |
767 |
flags = new ArrayList(); |
768 |
callFlagsChanged(IFlagListener.FLAG_REMOVED); |
769 |
} |
770 |
|
771 |
public void removeFlag(GvFlag flag){ |
772 |
flags.remove(flag); |
773 |
callFlagsChanged(IFlagListener.FLAG_REMOVED); |
774 |
} |
775 |
|
776 |
void PartirArco(int idEdge, int idNode) { |
777 |
// Se supone que el nuevo Nodo YA est? creado. Aqui dentro se coge el
|
778 |
// arco viejo y se le pega un tajo.
|
779 |
// (Se modifican los enlaces de los nodos de ese arco y se crean los
|
780 |
// arcos nuevos, fijando sus costes).
|
781 |
// Para sacar el porcentaje nos aprovechamos de que el nuevo nodo est?
|
782 |
// puesto en base a ese porcentaje
|
783 |
// en distancia de los extremos.
|
784 |
GvEdge oldEdge; |
785 |
GvNode pN1, pN2; |
786 |
double pct;
|
787 |
|
788 |
oldEdge = graph.getEdgeByID(idEdge); |
789 |
|
790 |
// OJO, controlando los ceros por si acaso la recta es horizontal o
|
791 |
// vertical (Y si mide cero???)
|
792 |
|
793 |
// pN1 = &Nodos[Arcos[idArco].idNodo1];
|
794 |
// pN2 = &Nodos[Arcos[idArco].idNodo2];
|
795 |
pN1 = graph.getNodeByID(graph.getEdgeByID(idEdge).getIdNodeOrig()); |
796 |
pN2 = graph.getNodeByID(graph.getEdgeByID(idEdge).getIdNodeEnd()); |
797 |
GvNode newNode = graph.getNodeByID(idNode); |
798 |
|
799 |
if (newNode.getX() != pN1.getX())
|
800 |
pct = Math.abs((newNode.getX() - pN1.getX())
|
801 |
/ (pN2.getX() - pN1.getX())); |
802 |
else
|
803 |
pct = Math.abs((newNode.getY() - pN1.getY())
|
804 |
/ (pN2.getY() - pN1.getY())); |
805 |
|
806 |
GvEdge first = new GvEdge();
|
807 |
first.setIdEdge(graph.numEdges()); |
808 |
first.setIdArc(oldEdge.getIdArc()); |
809 |
first.setDistance(oldEdge.getDistance() * pct); |
810 |
first.setWeight(oldEdge.getWeight() * pct); |
811 |
|
812 |
first.setDirec(oldEdge.getDirec()); |
813 |
first.setIdNodeOrig(oldEdge.getIdNodeOrig()); |
814 |
first.setType(oldEdge.getType()); |
815 |
first.setIdNodeEnd(idNode); |
816 |
graph.addEdge(first); |
817 |
|
818 |
GvEdge second = new GvEdge();
|
819 |
second.setIdEdge(graph.numEdges()); |
820 |
second.setDistance(oldEdge.getDistance() * (1.0 - pct));
|
821 |
second.setWeight(oldEdge.getWeight() * (1.0 - pct));
|
822 |
second.setIdArc(oldEdge.getIdArc()); |
823 |
second.setDirec(oldEdge.getDirec()); |
824 |
second.setType(oldEdge.getType()); |
825 |
second.setIdNodeOrig(idNode); |
826 |
second.setIdNodeEnd(oldEdge.getIdNodeEnd()); |
827 |
graph.addEdge(second); |
828 |
|
829 |
// ////////////////////////////////////////////////////
|
830 |
// Ahora retocamos los enlaces que salen de cada nodo
|
831 |
// ////////////////////////////////////////////////////
|
832 |
int i;
|
833 |
// boolean encontrado = false;
|
834 |
// for (i = 0; i < pN1.getOutputLinks().size(); i++) {
|
835 |
// GvEdge aux = (GvEdge) pN1.getOutputLinks().get(i);
|
836 |
// if (aux.getIdEdge() == idEdge) {
|
837 |
// pN1.getOutputLinks().set(i, first);
|
838 |
// // encontrado = true;
|
839 |
// break;
|
840 |
// }
|
841 |
// } // for
|
842 |
for (i = 0; i < pN1.getConnectors().size(); i++) { |
843 |
GvConnector c = pN1.getConnectors().get(i); |
844 |
if ((c.getEdgeOut() != null) && (c.getEdgeOut().getIdEdge()== idEdge)) { |
845 |
c.setEdgeOut(first); |
846 |
// encontrado = true;
|
847 |
break;
|
848 |
} |
849 |
} // for
|
850 |
|
851 |
// Conector de entrada
|
852 |
// GvConnector newCon = new GvConnector();
|
853 |
// newCon.setEdgeIn(first);
|
854 |
// newNode.getConnectors().add(newCon);
|
855 |
addInputLink(newNode, first); |
856 |
|
857 |
// Conector de salida
|
858 |
// GvConnector conOut = new GvConnector();
|
859 |
// conOut.setEdgeOut(second);
|
860 |
// newNode.getConnectors().add(conOut);
|
861 |
addOutputLink(newNode, second); |
862 |
|
863 |
// Y hacemos que el conector de entrada del idNodo2 tenga el arco nuevo
|
864 |
// log("Y hacemos que el conector de entrada del idNodo2 tenga el arco nuevo");
|
865 |
for (i = 0; i < pN2.getConnectors().size(); i++) { |
866 |
GvConnector c = pN2.getConnectors().get(i); |
867 |
if ((c.getEdgeIn() != null) && (c.getEdgeIn().getIdEdge()== idEdge)) { |
868 |
c.setEdgeIn(second); |
869 |
// encontrado = true;
|
870 |
break;
|
871 |
} |
872 |
} // for
|
873 |
} |
874 |
|
875 |
/**
|
876 |
* Add an edge out to this node. This function takes care of creating the needed connectors
|
877 |
* @param edge
|
878 |
*/
|
879 |
private void addOutputLink(GvNode n, GvEdge edge) { |
880 |
// outputLinks.add(edge);
|
881 |
// Create connectors
|
882 |
// First, search the connector if it is already created
|
883 |
GvConnector c; |
884 |
boolean bFound = false; |
885 |
GvConnector cFound = null;
|
886 |
for (int iConec=0; iConec< n.getConnectors().size(); iConec++) |
887 |
{ |
888 |
c = n.getConnectors().get(iConec); |
889 |
if ((c.getEdgeIn() != null) && (c.getEdgeIn().getIdNodeOrig() == edge.getIdNodeEnd()) |
890 |
&& (c.getEdgeIn().getIdNodeEnd() == edge.getIdNodeOrig())) { |
891 |
// Found. This connector has been originated before by the same edge
|
892 |
bFound = true;
|
893 |
cFound = c; |
894 |
break;
|
895 |
} |
896 |
} |
897 |
if (!bFound) {
|
898 |
GvConnector newCon = new GvConnector();
|
899 |
newCon.setEdgeOut(edge); |
900 |
n.getConnectors().add(newCon); |
901 |
} |
902 |
else
|
903 |
{ |
904 |
cFound.setEdgeOut(edge); |
905 |
} |
906 |
|
907 |
} |
908 |
|
909 |
/**
|
910 |
* Add an input edge to this node. This function takes care of creating the needed connectors
|
911 |
* @param edge
|
912 |
*/
|
913 |
private void addInputLink(GvNode n, GvEdge edge) { |
914 |
// inputLinks.add(edge);
|
915 |
// First, search the connector if it is already created
|
916 |
GvConnector c; |
917 |
boolean bFound = false; |
918 |
GvConnector cFound = null;
|
919 |
for (int iConec=0; iConec< n.getConnectors().size(); iConec++) |
920 |
{ |
921 |
c = n.getConnectors().get(iConec); |
922 |
if ((c.getEdgeOut() != null) && (c.getEdgeOut().getIdNodeOrig() == edge.getIdNodeEnd()) |
923 |
&& (c.getEdgeOut().getIdNodeEnd() == edge.getIdNodeOrig())) { |
924 |
// Found. This connector has been originated before by the same arc
|
925 |
bFound = true;
|
926 |
cFound = c; |
927 |
break;
|
928 |
} |
929 |
} |
930 |
if (!bFound) {
|
931 |
GvConnector newCon = new GvConnector();
|
932 |
newCon.setEdgeIn(edge); |
933 |
n.getConnectors().add(newCon); |
934 |
} |
935 |
else
|
936 |
{ |
937 |
cFound.setEdgeIn(edge); |
938 |
} |
939 |
|
940 |
} |
941 |
|
942 |
|
943 |
public ArrayList getModifiedCosts() { |
944 |
return modifiedCosts;
|
945 |
|
946 |
} |
947 |
|
948 |
private int[] BuscaNodosDeTramo(EdgePair pair) { |
949 |
int[] resul = new int[2]; |
950 |
if ((pair.idEdge == -1) && (pair.idInverseEdge == -1)) |
951 |
{ |
952 |
return null; // Error: No existen esos arcos. |
953 |
} |
954 |
|
955 |
if (pair.idEdge != -1) |
956 |
{ |
957 |
resul[0] = graph.getEdgeByID(pair.idEdge).getIdNodeOrig();
|
958 |
resul[1]= graph.getEdgeByID(pair.idEdge).getIdNodeEnd();
|
959 |
} |
960 |
else
|
961 |
{ |
962 |
resul[0] = graph.getEdgeByID(pair.idInverseEdge).getIdNodeOrig();
|
963 |
resul[1]= graph.getEdgeByID(pair.idInverseEdge).getIdNodeEnd();
|
964 |
} |
965 |
return resul;
|
966 |
|
967 |
} |
968 |
|
969 |
public GvTurn addTurnCost(int idArcOrigin, int idArcDestination, double newCost) { |
970 |
GvTurn turnCost = new GvTurn(idArcOrigin, idArcDestination, newCost);
|
971 |
EdgePair edgePairFrom = getGraph().getEdgesByIdArc(idArcOrigin); |
972 |
EdgePair edgePairTo = getGraph().getEdgesByIdArc(idArcDestination); |
973 |
|
974 |
// We found the node that connects these arcs,
|
975 |
// and add the new turnCost to its list of turnCosts.
|
976 |
GvNode searchedNode; |
977 |
int idNa1, idNa2, idNb1, idNb2, idNodoBuscado;
|
978 |
int[] A, B; |
979 |
|
980 |
A = BuscaNodosDeTramo(edgePairFrom); |
981 |
if (A == null) return null; // No existen arcos para ese idTramo |
982 |
|
983 |
|
984 |
B = BuscaNodosDeTramo(edgePairTo); |
985 |
if (B == null) return null; // No existen arcos para ese idTramo |
986 |
|
987 |
idNa1 = A[0]; idNa2 = A[1]; |
988 |
idNb1 = B[0]; idNb2 = B[1]; |
989 |
|
990 |
// Buscamos el nodo que est? entre fromIdTramo y toIdTramo
|
991 |
// y el arco. Al arco hay que cambiarle el destino
|
992 |
if (idNa1 == idNb1)
|
993 |
idNodoBuscado = idNa1; |
994 |
else
|
995 |
if (idNa1 == idNb2)
|
996 |
idNodoBuscado = idNa1; |
997 |
else
|
998 |
if (idNa2 == idNb1)
|
999 |
idNodoBuscado = idNa2; |
1000 |
else
|
1001 |
if (idNa2 == idNb2)
|
1002 |
idNodoBuscado = idNa2; |
1003 |
else // ERROR |
1004 |
return null; // esos tramos no conectan. |
1005 |
|
1006 |
// Podemos funcionar con idTramo en lugar de idArco porque cada CLink lleva dentro
|
1007 |
// el idTramo que lo origin?, y en el algoritmo podemos mirarlo.
|
1008 |
|
1009 |
searchedNode = graph.getNodeByID(idNodoBuscado); |
1010 |
searchedNode.addTurnCost(turnCost); |
1011 |
turnCosts.add(turnCost); //useful to remove them one by one without iterating the whole graph.
|
1012 |
|
1013 |
return turnCost; // everything is fine |
1014 |
} |
1015 |
/**
|
1016 |
* Create, add and apply a new modified cost to the graph.
|
1017 |
* @param idArc where the cost will be applied.
|
1018 |
* @param newCost. -1 if you want tu put a BARRIER.
|
1019 |
* @param direction. 1-> edge of digitalized direction. 2-> inverse edge. 3-> Both directions
|
1020 |
*/
|
1021 |
public GvModifiedCost addModifiedCost(int idArc, double newCost, int direction) { |
1022 |
GvModifiedCost modifiedCost = new GvModifiedCost(idArc, newCost, direction);
|
1023 |
EdgePair edgePair = getGraph().getEdgesByIdArc(idArc); |
1024 |
modifiedCost.setIdEdge(edgePair.idEdge); |
1025 |
modifiedCost.setIdInverseEdge(edgePair.idInverseEdge); |
1026 |
if (direction == 3) |
1027 |
{ |
1028 |
if (edgePair.getIdEdge() != -1) |
1029 |
{ |
1030 |
GvEdge edge = getGraph().getEdgeByID(edgePair.getIdEdge()); |
1031 |
modifiedCost.setOldCost(edge.getWeight()); |
1032 |
edge.setWeight(-1.0);
|
1033 |
} |
1034 |
if (edgePair.getIdInverseEdge() != -1) |
1035 |
{ |
1036 |
GvEdge inverseEdge = getGraph().getEdgeByID(edgePair.getIdInverseEdge()); |
1037 |
modifiedCost.setOldInverseCost(inverseEdge.getWeight()); |
1038 |
inverseEdge.setWeight(-1.0);
|
1039 |
} |
1040 |
} |
1041 |
if (direction == 1) |
1042 |
{ |
1043 |
if (edgePair.getIdEdge() != -1) |
1044 |
{ |
1045 |
GvEdge edge = getGraph().getEdgeByID(edgePair.getIdEdge()); |
1046 |
modifiedCost.setOldCost(edge.getWeight()); |
1047 |
edge.setWeight(-1.0);
|
1048 |
} |
1049 |
} |
1050 |
if (direction == 2) |
1051 |
{ |
1052 |
if (edgePair.getIdInverseEdge() != -1) |
1053 |
{ |
1054 |
GvEdge inverseEdge = getGraph().getEdgeByID(edgePair.getIdInverseEdge()); |
1055 |
modifiedCost.setOldInverseCost(inverseEdge.getWeight()); |
1056 |
inverseEdge.setWeight(-1.0);
|
1057 |
} |
1058 |
} |
1059 |
modifiedCosts.add(modifiedCost); |
1060 |
modifiedCost.setApplied(true);
|
1061 |
return modifiedCost;
|
1062 |
} |
1063 |
|
1064 |
/**
|
1065 |
* Remove ALL turn costs
|
1066 |
*/
|
1067 |
public void removeTurnCosts() { |
1068 |
for (int i=0; i < turnCosts.size(); i++) { |
1069 |
GvTurn turn = turnCosts.get(i); |
1070 |
// turn.getNode().getTurnCosts().remove(turn);
|
1071 |
if (turn.getNode() == null) |
1072 |
{ |
1073 |
System.err.println("El turnCost " + i + " no tiene nodo asociado."); |
1074 |
continue;
|
1075 |
} |
1076 |
turn.getNode().removeTurnCosts(); |
1077 |
} |
1078 |
turnCosts = new ArrayList<GvTurn>(); |
1079 |
} |
1080 |
|
1081 |
/**
|
1082 |
* Be careful about the ORDER!!!!
|
1083 |
* @param modifiedCost
|
1084 |
*/
|
1085 |
public boolean removeModifiedCost(GvModifiedCost modifiedCost) { |
1086 |
if (!modifiedCosts.remove(modifiedCost))
|
1087 |
return false; |
1088 |
int idArc = modifiedCost.getIdArc();
|
1089 |
int direction = modifiedCost.getDirection();
|
1090 |
EdgePair edgePair = getGraph().getEdgesByIdArc(idArc); |
1091 |
if (direction == 3) |
1092 |
{ |
1093 |
if (edgePair.getIdEdge() != -1) |
1094 |
{ |
1095 |
GvEdge edge = getGraph().getEdgeByID(edgePair.getIdEdge()); |
1096 |
edge.setWeight(modifiedCost.getOldCost()); |
1097 |
} |
1098 |
if (edgePair.getIdInverseEdge() != -1) |
1099 |
{ |
1100 |
GvEdge inverseEdge = getGraph().getEdgeByID(edgePair.getIdInverseEdge()); |
1101 |
inverseEdge.setWeight(modifiedCost.getOldInverseCost()); |
1102 |
} |
1103 |
} |
1104 |
if (direction == 1) |
1105 |
{ |
1106 |
if (edgePair.getIdEdge() != -1) |
1107 |
{ |
1108 |
GvEdge edge = getGraph().getEdgeByID(edgePair.getIdEdge()); |
1109 |
edge.setWeight(modifiedCost.getOldCost()); |
1110 |
} |
1111 |
} |
1112 |
if (direction == 2) |
1113 |
{ |
1114 |
if (edgePair.getIdInverseEdge() != -1) |
1115 |
{ |
1116 |
GvEdge inverseEdge = getGraph().getEdgeByID(edgePair.getIdInverseEdge()); |
1117 |
inverseEdge.setWeight(modifiedCost.getOldInverseCost()); |
1118 |
} |
1119 |
} |
1120 |
return true; |
1121 |
} |
1122 |
|
1123 |
public void addFlagListener(IFlagListener listener) { |
1124 |
if (!flagListeners.contains(listener)) {
|
1125 |
flagListeners.add(listener); |
1126 |
} |
1127 |
} |
1128 |
|
1129 |
public void removeFlagListener(IFlagListener listener){ |
1130 |
flagListeners.remove(listener); |
1131 |
} |
1132 |
|
1133 |
private void callFlagsChanged(int reason) { |
1134 |
if (dispatching) {
|
1135 |
for (int i=0; i < flagListeners.size(); i++) |
1136 |
{ |
1137 |
IFlagListener listener = (IFlagListener) flagListeners.get(i); |
1138 |
listener.flagsChanged(reason); |
1139 |
} |
1140 |
} |
1141 |
} |
1142 |
|
1143 |
/**
|
1144 |
* Useful to do batch modifies. (For example, add lot of flags
|
1145 |
* and when finished (endModifying), throw event.
|
1146 |
*/
|
1147 |
public void beginModifyingFlags() { |
1148 |
dispatching = false;
|
1149 |
} |
1150 |
|
1151 |
public void endModifyingFlags() { |
1152 |
dispatching = true;
|
1153 |
callFlagsChanged(IFlagListener.FLAG_MANY_CHANGES); |
1154 |
} |
1155 |
/**
|
1156 |
* Mueve un flag de la posici?n from a la posici?n to.
|
1157 |
*
|
1158 |
* @param from origen.
|
1159 |
* @param to destino.
|
1160 |
*
|
1161 |
*/
|
1162 |
public void moveTo(int from, int to) throws CancelationException { |
1163 |
int newfrom=flags.size()-from-1; |
1164 |
int newto=flags.size()-to-1; |
1165 |
if ( newfrom < 0 || newfrom >=flags.size() || newto < 0 || newto >= flags.size()) return; |
1166 |
GvFlag aux = (GvFlag) flags.get(newfrom); |
1167 |
flags.remove(newfrom); |
1168 |
flags.add(newto, aux); |
1169 |
callFlagsChanged(IFlagListener.FLAG_REORDER); |
1170 |
} |
1171 |
|
1172 |
public ArrayList getEdgeTypes() { |
1173 |
// TODO: Tener esto precalculado
|
1174 |
TreeMap map = new TreeMap(); |
1175 |
ArrayList ret = new ArrayList(); |
1176 |
for (int i = 0; i < graph.numEdges(); i++) |
1177 |
{ |
1178 |
GvEdge edge = graph.getEdgeByID(i); |
1179 |
Integer type = new Integer(edge.getType()); |
1180 |
if (!map.containsKey(type))
|
1181 |
{ |
1182 |
map.put(type, type); |
1183 |
} |
1184 |
} |
1185 |
Iterator it = map.entrySet().iterator();
|
1186 |
while (it.hasNext())
|
1187 |
{ |
1188 |
Map.Entry entry = (Map.Entry) it.next(); |
1189 |
Integer type = (Integer) entry.getKey(); |
1190 |
ret.add(type); |
1191 |
} |
1192 |
return ret;
|
1193 |
} |
1194 |
|
1195 |
public Hashtable getVelocities() { |
1196 |
return velocities ;
|
1197 |
} |
1198 |
|
1199 |
public void setVelocities(Hashtable veloMeters) { |
1200 |
for (int i=0; i < getGraph().numEdges(); i++) |
1201 |
{ |
1202 |
GvEdge edge = getGraph().getEdgeByID(i); |
1203 |
|
1204 |
Integer key = new Integer(edge.getType()); |
1205 |
Double vel = (Double) veloMeters.get(key); |
1206 |
edge.setWeight(edge.getDistance() / vel.doubleValue()); // segundos
|
1207 |
} |
1208 |
this.velocities = veloMeters;
|
1209 |
|
1210 |
|
1211 |
} |
1212 |
|
1213 |
public ArrayList<GvTurn> getTurnCosts() { |
1214 |
return turnCosts;
|
1215 |
} |
1216 |
|
1217 |
public IFeatureExtractor getFeatExtractor() {
|
1218 |
return featExtractor;
|
1219 |
} |
1220 |
|
1221 |
public void setFeatExtractor(IFeatureExtractor featExtractor) { |
1222 |
this.featExtractor = featExtractor;
|
1223 |
if (featExtractor instanceof DefaultFeatureExtractor) { |
1224 |
setLayer(((DefaultFeatureExtractor) featExtractor).getLyrVect()); |
1225 |
} |
1226 |
} |
1227 |
|
1228 |
} |