Revision 8261 trunk/extensions/extGraph_predes/src/com/iver/cit/gvsig/graph/core/Network.java

View differences:

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