Revision 20099 tags/v1_1_2_Build_1044/prototypes/VectorialAvanzado/extensions/extGraph/src/com/iver/cit/gvsig/graph/solvers/ShortestPathSolverAStar.java
ShortestPathSolverAStar.java | ||
---|---|---|
49 | 49 |
import com.iver.cit.gvsig.fmap.core.v02.FConverter; |
50 | 50 |
import com.iver.cit.gvsig.fmap.drivers.DriverIOException; |
51 | 51 |
import com.iver.cit.gvsig.fmap.layers.VectorialAdapter; |
52 |
import com.iver.cit.gvsig.graph.GraphException; |
|
53 | 52 |
import com.iver.cit.gvsig.graph.core.AbstractNetSolver; |
53 |
import com.iver.cit.gvsig.graph.core.GraphException; |
|
54 | 54 |
import com.iver.cit.gvsig.graph.core.GvEdge; |
55 | 55 |
import com.iver.cit.gvsig.graph.core.GvFlag; |
56 | 56 |
import com.iver.cit.gvsig.graph.core.GvNode; |
57 | 57 |
import com.iver.cit.gvsig.graph.core.GvTurn; |
58 | 58 |
import com.iver.cit.gvsig.graph.core.IGraph; |
59 |
import com.iver.cit.gvsig.graph.core.NetworkUtils; |
|
59 | 60 |
import com.vividsolutions.jts.geom.Coordinate; |
60 | 61 |
import com.vividsolutions.jts.geom.Geometry; |
61 | 62 |
import com.vividsolutions.jts.geom.GeometryFactory; |
... | ... | |
190 | 191 |
System.out.println("Salgo con node = " + node.getIdNode()); |
191 | 192 |
} |
192 | 193 |
|
193 |
private void populateRoute(GvFlag origin, GvFlag dest, int idStart, int idEnd) throws DriverException { |
|
194 |
private void populateRoute(GvFlag origin, GvFlag dest, int idStart, |
|
195 |
int idEnd) throws DriverException { |
|
194 | 196 |
int idEnlace; |
195 | 197 |
GvNode node; |
196 | 198 |
GvEdge link; |
197 | 199 |
double costeEntrada; |
198 | 200 |
|
199 |
// Trazar el camino desde idEnd hasta idStart hacia atr?s marcando los Enlaces |
|
200 |
|
|
201 |
// Trazar el camino desde idEnd hasta idStart hacia atr?s marcando los |
|
202 |
// Enlaces |
|
203 |
|
|
201 | 204 |
if (idStart == idEnd) |
202 | 205 |
return; |
203 | 206 |
IGraph graph = net.getGraph(); |
... | ... | |
206 | 209 |
VectorialAdapter va = (VectorialAdapter) net.getLayer().getSource(); |
207 | 210 |
try { |
208 | 211 |
va.start(); |
209 |
/* Miramos los nodos de los tramos inicio y final, y cogemos el nodo que tenga el from_link rellenado. E IGUAL A NUMSOLUCGLOBAL!!!! |
|
210 |
A partir de ah?, recorremos hacia atr?s y tenemos el cuerpo principal del shape. Luego, para |
|
211 |
las puntas hay que tener en cuenta los porcentajes, viendo el trozo que est? pegando a los nodos |
|
212 |
que sabemos que est?n en el path |
|
213 |
*/ |
|
212 |
/* |
|
213 |
* Miramos los nodos de los tramos inicio y final, y cogemos el nodo |
|
214 |
* que tenga el from_link rellenado. E IGUAL A NUMSOLUCGLOBAL!!!! A |
|
215 |
* partir de ah?, recorremos hacia atr?s y tenemos el cuerpo |
|
216 |
* principal del shape. Luego, para las puntas hay que tener en |
|
217 |
* cuenta los porcentajes, viendo el trozo que est? pegando a los |
|
218 |
* nodos que sabemos que est?n en el path |
|
219 |
*/ |
|
214 | 220 |
|
215 |
/* 22/9/2003 Corregimos el fallo que hab?a de escribir el shape de atr?s adelante. |
|
216 |
* Guardamos lo que necesitamos en listaShapes y recorremos esa lista guardando los tramos |
|
217 |
* con el sentido adecuado. |
|
218 |
*/ |
|
221 |
/* |
|
222 |
* 22/9/2003 Corregimos el fallo que hab?a de escribir el shape de |
|
223 |
* atr?s adelante. Guardamos lo que necesitamos en listaShapes y |
|
224 |
* recorremos esa lista guardando los tramos con el sentido |
|
225 |
* adecuado. |
|
226 |
*/ |
|
219 | 227 |
|
220 |
/* 3/Febrero/2005 Limpieza de c?digo superfluo y correci?n de un fallo raro. Ahora es m?s simple y parece |
|
221 |
* que no falla. A ver si dura. IDEA: quiz?s se necesite meter el porcentaje en los arcos partidos. |
|
222 |
*/ |
|
228 |
/* |
|
229 |
* 3/Febrero/2005 Limpieza de c?digo superfluo y correci?n de un |
|
230 |
* fallo raro. Ahora es m?s simple y parece que no falla. A ver si |
|
231 |
* dura. IDEA: quiz?s se necesite meter el porcentaje en los arcos |
|
232 |
* partidos. |
|
233 |
*/ |
|
223 | 234 |
|
224 |
// Define a template class for a vector of IDs. |
|
225 |
InfoShp infoShp; |
|
226 |
Stack pilaShapes = new Stack(); |
|
227 |
// typedef stack<CInfoShp> PILAINFO;
|
|
228 |
// PILAINFO pilaShapes;
|
|
235 |
// Define a template class for a vector of IDs.
|
|
236 |
InfoShp infoShp;
|
|
237 |
Stack pilaShapes = new Stack();
|
|
238 |
// typedef stack<CInfoShp> PILAINFO;
|
|
239 |
// PILAINFO pilaShapes;
|
|
229 | 240 |
|
230 |
double costeTramoFinal=-1;
|
|
231 |
GvNode nodeEnd = graph.getNodeByID(idEnd); |
|
232 |
GvEdge finalEdge = graph.getEdgeByID(nodeEnd.getFromLink()); |
|
233 |
costeTramoFinal = finalEdge.getWeight(); |
|
241 |
double costeTramoFinal = -1;
|
|
242 |
GvNode nodeEnd = graph.getNodeByID(idEnd);
|
|
243 |
GvEdge finalEdge = graph.getEdgeByID(nodeEnd.getFromLink());
|
|
244 |
costeTramoFinal = finalEdge.getWeight();
|
|
234 | 245 |
|
235 |
GvNode pNodo; |
|
236 |
GvEdge pEnlace; |
|
237 |
|
|
238 |
boolean bFlipearShape = false; |
|
246 |
GvNode pNodo; |
|
247 |
GvEdge pEnlace; |
|
239 | 248 |
|
240 |
double pctMax, pctMin;
|
|
249 |
boolean bFlipearShape = false;
|
|
241 | 250 |
|
251 |
double pctMax, pctMin; |
|
242 | 252 |
|
253 |
// //////////////////////////////////////////////////////////////////////////////////// |
|
254 |
// Trozo del final |
|
255 |
// El shape va de idStop1 a idStop2, y el porcentaje viene en ese |
|
256 |
// sentido. |
|
257 |
// Si el idEnd es idStop1, quiere decir que el tramo que falta va en |
|
258 |
// ese sentido tambi?n, |
|
259 |
// as? que recorremos ese shape desde idStop1 hasta que rebasemos o |
|
260 |
// igualemos ese porcentaje. |
|
261 |
// Si no, hemos pasado por idStop2 y la parte que hay que meter es |
|
262 |
// desde el pto interior a idStop2 |
|
263 |
// ///////////////////////////////////////////////////////////////////////////////////// |
|
264 |
IFeature feat = va.getFeature(finalEdge.getIdArc()); |
|
265 |
MultiLineString jtsGeom = (MultiLineString) feat.getGeometry() |
|
266 |
.toJTSGeometry(); |
|
267 |
// CoordinateFilter removeDuplicates = new |
|
268 |
// UniqueCoordinateArrayFilter(); |
|
269 |
// jtsGeom.apply(removeDuplicates); |
|
270 |
// jtsGeom.geometryChanged(); |
|
243 | 271 |
|
244 |
////////////////////////////////////////////////////////////////////////////////////// |
|
245 |
// Trozo del final |
|
246 |
// El shape va de idStop1 a idStop2, y el porcentaje viene en ese sentido. |
|
247 |
// Si el idEnd es idStop1, quiere decir que el tramo que falta va en ese sentido tambi?n, |
|
248 |
// as? que recorremos ese shape desde idStop1 hasta que rebasemos o igualemos ese porcentaje. |
|
249 |
// Si no, hemos pasado por idStop2 y la parte que hay que meter es desde el pto interior a idStop2 |
|
250 |
/////////////////////////////////////////////////////////////////////////////////////// |
|
251 |
IFeature feat = va.getFeature(finalEdge.getIdArc()); |
|
252 |
MultiLineString jtsGeom = (MultiLineString) feat.getGeometry().toJTSGeometry(); |
|
253 |
// CoordinateFilter removeDuplicates = new UniqueCoordinateArrayFilter(); |
|
254 |
// jtsGeom.apply(removeDuplicates); |
|
255 |
// jtsGeom.geometryChanged(); |
|
256 |
|
|
257 |
|
|
258 |
|
|
259 |
// SI ESTAMOS SOBRE EL MISMO TRAMO, CASO PARTICULAR |
|
260 |
// y el sentido de circulaci?n es correcto |
|
261 |
if ((origin.getIdArc() == dest.getIdArc()) && (nodeEnd.getBestCost() <= costeTramoFinal)) |
|
262 |
{ |
|
263 |
if (dest.getPct() > origin.getPct()) |
|
264 |
{ |
|
265 |
pctMax = dest.getPct(); |
|
266 |
pctMin = origin.getPct(); |
|
267 |
} |
|
268 |
else |
|
269 |
{ |
|
270 |
pctMax = origin.getPct(); |
|
271 |
pctMin = dest.getPct(); |
|
272 |
bFlipearShape = true; |
|
273 |
} |
|
272 |
// SI ESTAMOS SOBRE EL MISMO TRAMO, CASO PARTICULAR |
|
273 |
// y el sentido de circulaci?n es correcto |
|
274 |
if ((origin.getIdArc() == dest.getIdArc()) |
|
275 |
&& (nodeEnd.getBestCost() <= costeTramoFinal)) { |
|
276 |
if (dest.getPct() > origin.getPct()) { |
|
277 |
pctMax = dest.getPct(); |
|
278 |
pctMin = origin.getPct(); |
|
279 |
} else { |
|
280 |
pctMax = origin.getPct(); |
|
281 |
pctMin = dest.getPct(); |
|
282 |
bFlipearShape = true; |
|
283 |
} |
|
274 | 284 |
|
275 |
LineString line = SituaSobreTramo(jtsGeom,dest.getIdArc(), dest.getPct(),1); |
|
276 |
|
|
277 |
pctMin = pctMin / pctMax; // Porque ha cambiado la longitud del shape |
|
285 |
LineString line = NetworkUtils.getPartialLineString(jtsGeom, |
|
286 |
pctMax, 1); |
|
278 | 287 |
|
279 |
line = SituaSobreTramo(line,dest.getIdArc(), pctMin,0); |
|
288 |
pctMin = pctMin / pctMax; // Porque ha cambiado la longitud |
|
289 |
// del shape |
|
280 | 290 |
|
281 |
if (bFlipearShape) |
|
282 |
line = line.reverse(); |
|
283 |
|
|
284 |
IGeometry geom = FConverter.jts_to_igeometry(line); |
|
285 |
// TODO: Calcular bien el length de este arco, |
|
286 |
// basandonos en el porcentaje costeTramoFinal / costeOriginal |
|
287 |
route.addRouteFeature(geom, origin.getIdArc(), |
|
288 |
costeTramoFinal, line.getLength(), feat.getAttribute(getFieldIndexStreetName()).toString()); |
|
291 |
line = NetworkUtils.getPartialLineString(line, pctMin, 0); |
|
289 | 292 |
|
293 |
if (bFlipearShape) |
|
294 |
line = line.reverse(); |
|
290 | 295 |
|
291 |
return ; // Deber?a sacar el coste |
|
292 |
} |
|
296 |
IGeometry geom = FConverter.jts_to_igeometry(line); |
|
297 |
// TODO: Calcular bien el length de este arco, |
|
298 |
// basandonos en el porcentaje costeTramoFinal / costeOriginal |
|
299 |
route.addRouteFeature(geom, origin.getIdArc(), costeTramoFinal, |
|
300 |
line.getLength(), feat.getAttribute( |
|
301 |
getFieldIndexStreetName()).toString()); |
|
293 | 302 |
|
294 |
|
|
303 |
return; // Deber?a sacar el coste |
|
304 |
} |
|
295 | 305 |
|
296 |
// Trazar el camino desde idEnd hasta idStart hacia atr?s marcando los Enlaces |
|
297 |
pNodo = graph.getNodeByID(idEnd); |
|
306 |
// Trazar el camino desde idEnd hasta idStart hacia atr?s marcando |
|
307 |
// los Enlaces |
|
308 |
pNodo = graph.getNodeByID(idEnd); |
|
298 | 309 |
|
299 |
while ((pNodo.getIdNode() != idStart)) |
|
300 |
{ |
|
301 |
idEnlace = pNodo.getFromLink(); |
|
302 |
pEnlace = graph.getEdgeByID(idEnlace); |
|
310 |
while ((pNodo.getIdNode() != idStart)) { |
|
311 |
idEnlace = pNodo.getFromLink(); |
|
312 |
pEnlace = graph.getEdgeByID(idEnlace); |
|
303 | 313 |
|
304 |
pNodo = graph.getNodeByID(pEnlace.getIdNodeOrig()); |
|
305 |
|
|
306 |
infoShp = new InfoShp(); |
|
307 |
infoShp.distance = pEnlace.getDistance(); |
|
308 |
infoShp.cost = pEnlace.getWeight(); |
|
314 |
pNodo = graph.getNodeByID(pEnlace.getIdNodeOrig()); |
|
309 | 315 |
|
310 |
if ((pEnlace.getIdArc() == origin.getIdArc()) || (pEnlace.getIdArc() == dest.getIdArc())) |
|
311 |
{ |
|
312 |
if (pEnlace.getIdArc() == origin.getIdArc()) |
|
313 |
{ |
|
314 |
infoShp.pct = origin.getPct(); |
|
315 |
infoShp.idArc = origin.getIdArc(); |
|
316 |
if (pEnlace.getDirec() == 0) |
|
317 |
{ |
|
318 |
infoShp.direction = 1; |
|
319 |
infoShp.bFlip = true; |
|
316 |
infoShp = new InfoShp(); |
|
317 |
infoShp.distance = pEnlace.getDistance(); |
|
318 |
infoShp.cost = pEnlace.getWeight(); |
|
319 |
|
|
320 |
if ((pEnlace.getIdArc() == origin.getIdArc()) |
|
321 |
|| (pEnlace.getIdArc() == dest.getIdArc())) { |
|
322 |
if (pEnlace.getIdArc() == origin.getIdArc()) { |
|
323 |
infoShp.pct = origin.getPct(); |
|
324 |
infoShp.idArc = origin.getIdArc(); |
|
325 |
if (pEnlace.getDirec() == 0) { |
|
326 |
infoShp.direction = 1; |
|
327 |
infoShp.bFlip = true; |
|
328 |
} else // Hemos pasado por el 2 |
|
329 |
{ |
|
330 |
infoShp.direction = 0; |
|
331 |
infoShp.bFlip = false; |
|
332 |
} // if else */ |
|
333 |
} else { |
|
334 |
infoShp.pct = dest.getPct(); |
|
335 |
infoShp.idArc = dest.getIdArc(); |
|
336 |
if (pEnlace.getDirec() == 0) { |
|
337 |
infoShp.direction = 0; |
|
338 |
infoShp.bFlip = true; |
|
339 |
} else { |
|
340 |
infoShp.direction = 1; |
|
341 |
infoShp.bFlip = false; |
|
342 |
} // if else */ |
|
320 | 343 |
} |
321 |
else // Hemos pasado por el 2 |
|
322 |
{ |
|
323 |
infoShp.direction = 0; |
|
344 |
} else { |
|
345 |
infoShp.pct = 1.0; |
|
346 |
infoShp.idArc = pEnlace.getIdArc(); |
|
347 |
|
|
348 |
infoShp.direction = 1; |
|
349 |
if (pEnlace.getDirec() == 1) |
|
324 | 350 |
infoShp.bFlip = false; |
325 |
} // if else */ |
|
326 |
} |
|
327 |
else |
|
328 |
{ |
|
329 |
infoShp.pct = dest.getPct(); |
|
330 |
infoShp.idArc = dest.getIdArc(); |
|
331 |
if (pEnlace.getDirec() == 0) |
|
332 |
{ |
|
333 |
infoShp.direction = 0; |
|
334 |
infoShp.bFlip = true; |
|
335 |
} |
|
336 | 351 |
else |
337 |
{ |
|
338 |
infoShp.direction = 1; |
|
339 |
infoShp.bFlip = false; |
|
340 |
} // if else */ |
|
352 |
infoShp.bFlip = true; |
|
341 | 353 |
} |
354 |
|
|
355 |
pilaShapes.push(infoShp); |
|
342 | 356 |
} |
343 |
else |
|
344 |
{ |
|
345 |
infoShp.pct = 1.0; |
|
346 |
infoShp.idArc = pEnlace.getIdArc(); |
|
347 |
|
|
348 |
infoShp.direction =1; |
|
349 |
if (pEnlace.getDirec() == 1) |
|
350 |
infoShp.bFlip = false; |
|
351 |
else |
|
352 |
infoShp.bFlip = true; |
|
353 |
} |
|
354 | 357 |
|
355 |
pilaShapes.push(infoShp); |
|
356 |
} |
|
358 |
// Y ahora recorremos hacia atr?s el vector y escribimos los shapes. |
|
359 |
// VECTORINFO::iterator theIterator; |
|
360 |
int auxC = 0; |
|
357 | 361 |
|
358 |
// Y ahora recorremos hacia atr?s el vector y escribimos los shapes. |
|
359 |
// VECTORINFO::iterator theIterator; |
|
360 |
int auxC = 0; |
|
361 |
|
|
362 |
while (!pilaShapes.empty()) |
|
363 |
{ |
|
364 |
infoShp = (InfoShp) pilaShapes.peek(); |
|
365 |
feat = va.getFeature(infoShp.idArc); |
|
366 |
MultiLineString line = (MultiLineString) feat.getGeometry().toJTSGeometry(); |
|
367 |
// line.apply(removeDuplicates); |
|
368 |
// line.geometryChanged(); |
|
369 |
|
|
370 |
LineString aux = null; |
|
371 |
if (infoShp.pct < 1.0) |
|
372 |
aux = SituaSobreTramo(line,infoShp.idArc, infoShp.pct, infoShp.direction); |
|
362 |
while (!pilaShapes.empty()) { |
|
363 |
infoShp = (InfoShp) pilaShapes.peek(); |
|
364 |
feat = va.getFeature(infoShp.idArc); |
|
365 |
MultiLineString line = (MultiLineString) feat.getGeometry() |
|
366 |
.toJTSGeometry(); |
|
367 |
// line.apply(removeDuplicates); |
|
368 |
// line.geometryChanged(); |
|
373 | 369 |
|
374 |
IGeometry geom = null; |
|
375 |
if (aux == null) |
|
376 |
{ |
|
377 |
if (infoShp.bFlip) |
|
378 |
line = line.reverse(); |
|
379 |
geom = FConverter.jts_to_igeometry(line); |
|
380 |
} |
|
381 |
else |
|
382 |
{ |
|
383 |
if (infoShp.bFlip) |
|
384 |
aux = aux.reverse(); |
|
385 |
geom = FConverter.jts_to_igeometry(aux); |
|
386 |
} |
|
370 |
LineString aux = null; |
|
371 |
if (infoShp.pct < 1.0) |
|
372 |
aux = NetworkUtils.getPartialLineString(line, infoShp.pct, |
|
373 |
infoShp.direction); |
|
387 | 374 |
|
375 |
IGeometry geom = null; |
|
376 |
if (aux == null) { |
|
377 |
if (infoShp.bFlip) |
|
378 |
line = line.reverse(); |
|
379 |
geom = FConverter.jts_to_igeometry(line); |
|
380 |
} else { |
|
381 |
if (infoShp.bFlip) |
|
382 |
aux = aux.reverse(); |
|
383 |
geom = FConverter.jts_to_igeometry(aux); |
|
384 |
} |
|
388 | 385 |
|
389 |
route.addRouteFeature(geom, infoShp.idArc, |
|
390 |
infoShp.cost, infoShp.distance, feat.getAttribute(getFieldIndexStreetName()).toString()); |
|
386 |
route.addRouteFeature(geom, infoShp.idArc, infoShp.cost, |
|
387 |
infoShp.distance, feat.getAttribute( |
|
388 |
getFieldIndexStreetName()).toString()); |
|
391 | 389 |
|
390 |
pilaShapes.pop(); |
|
391 |
auxC++; |
|
392 | 392 |
|
393 |
pilaShapes.pop(); |
|
394 |
auxC++; |
|
395 |
|
|
396 |
} |
|
397 |
va.stop(); |
|
398 |
} catch (DriverIOException e) { |
|
393 |
} |
|
394 |
va.stop(); |
|
395 |
} catch (Exception e) { |
|
399 | 396 |
// TODO Auto-generated catch block |
400 | 397 |
e.printStackTrace(); |
401 | 398 |
} |
402 | 399 |
|
403 | 400 |
return; |
404 | 401 |
|
405 |
|
|
406 | 402 |
} |
407 | 403 |
|
408 | 404 |
LineString SituaSobreTramo(Geometry geom, int idArc, double pct, int parte) |
Also available in: Unified diff