Statistics
| Revision:

root / trunk / extensions / extGraph / src / org / gvsig / graph / core / writers / NetworkFileRedWriter.java @ 37909

History | View | Annotate | Download (13.2 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.writers;
42

    
43
import java.io.File;
44
import java.io.IOException;
45
import java.io.RandomAccessFile;
46
import java.nio.ByteOrder;
47
import java.sql.Types;
48
import java.util.ArrayList;
49
import java.util.Hashtable;
50

    
51
import javax.imageio.stream.FileImageOutputStream;
52

    
53
import org.cresques.cts.ICoordTrans;
54
import org.gvsig.exceptions.BaseException;
55
import org.gvsig.graph.core.GraphException;
56
import org.gvsig.graph.core.NodeGv;
57

    
58
import com.hardcode.gdbms.engine.instruction.IncompatibleTypesException;
59
import com.hardcode.gdbms.engine.values.BooleanValue;
60
import com.hardcode.gdbms.engine.values.NumericValue;
61
import com.hardcode.gdbms.engine.values.Value;
62
import com.hardcode.gdbms.engine.values.ValueFactory;
63
import com.iver.cit.gvsig.fmap.core.FShape;
64
import com.iver.cit.gvsig.fmap.core.IGeometry;
65
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
66
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
67
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
68
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
69
import com.iver.cit.gvsig.fmap.layers.VectorialAdapter;
70
import com.iver.cit.gvsig.util.SnappingCoordinateMap;
71
import com.iver.utiles.swing.threads.CancellableMonitorable;
72
import com.vividsolutions.jts.geom.Coordinate;
73
import com.vividsolutions.jts.geom.Geometry;
74

    
75
/**
76
 * @author fjp
77
 * 
78
 * 
79
 */
80
public class NetworkFileRedWriter extends AbstractNetworkWriter {
81
        File redFile;
82
        CancellableMonitorable cancel;
83
        private double snapTolerance = 0d;
84
        private double unitsFactor = 1.0; // 1.0->secs (no conversion). 60 ->
85
                                                                                // minutes, 3600 hours, etc.
86
        private String digitalizationDirection;
87
        private String reverseDigitalizationDirection;
88

    
89
        public NetworkFileRedWriter() {
90

    
91
                // Set up fields for table nodes
92
                nodeFields = new FieldDescription[3];
93
                FieldDescription fieldNodeId = new FieldDescription();
94
                fieldNodeId.setFieldName("NODEID");
95
                fieldNodeId.setFieldType(Types.INTEGER);
96

    
97
                FieldDescription fieldX = new FieldDescription();
98
                fieldX.setFieldName("X");
99
                fieldX.setFieldType(Types.DOUBLE);
100
                fieldX.setFieldDecimalCount(2);
101

    
102
                FieldDescription fieldY = new FieldDescription();
103
                fieldY.setFieldName("Y");
104
                fieldY.setFieldType(Types.DOUBLE);
105
                fieldY.setFieldDecimalCount(2);
106

    
107
                nodeFields[0] = fieldNodeId;
108
                nodeFields[1] = fieldX;
109
                nodeFields[2] = fieldY;
110

    
111
                // Set up fields for table edges
112
                edgeFields = new FieldDescription[7];
113

    
114
                // ID_TRAMO ORIGINAL!!!
115
                FieldDescription fieldArcID = new FieldDescription();
116
                fieldArcID.setFieldName("ArcID");
117
                fieldArcID.setFieldType(Types.INTEGER);
118

    
119
                FieldDescription fieldDirection = new FieldDescription();
120
                fieldDirection.setFieldName("Direction");
121
                fieldDirection.setFieldType(Types.SMALLINT);
122

    
123
                FieldDescription fieldNodeOrigin = new FieldDescription();
124
                fieldNodeOrigin.setFieldName("NodeOrigin");
125
                fieldNodeOrigin.setFieldType(Types.INTEGER);
126
                FieldDescription fieldNodeEnd = new FieldDescription();
127
                fieldNodeEnd.setFieldName("NodeEnd");
128
                fieldNodeEnd.setFieldType(Types.INTEGER);
129

    
130
                FieldDescription fieldType = new FieldDescription();
131
                fieldType.setFieldName("Type");
132
                fieldType.setFieldType(Types.SMALLINT);
133

    
134
                FieldDescription fieldDistanceDist = new FieldDescription();
135
                fieldDistanceDist.setFieldName("Dist");
136
                fieldDistanceDist.setFieldType(Types.DOUBLE);
137

    
138
                FieldDescription fieldDistanceCost = new FieldDescription();
139
                fieldDistanceCost.setFieldName("Cost");
140
                fieldDistanceCost.setFieldType(Types.DOUBLE);
141

    
142
                edgeFields[0] = fieldArcID;
143
                edgeFields[1] = fieldDirection;
144
                edgeFields[2] = fieldNodeOrigin;
145
                edgeFields[3] = fieldNodeEnd;
146
                edgeFields[4] = fieldType;
147
                edgeFields[5] = fieldDistanceDist;
148
                edgeFields[6] = fieldDistanceCost;
149
        }
150

    
151
        /*
152
         * (non-Javadoc)
153
         * 
154
         * @see org.gvsig.graph.core.INetworkWriter#writeNetwork(boolean)
155
         */
156
        public void writeNetwork() throws BaseException {
157
                // PRIMERO VAN EL NUMERO DE TRAMOS, LUEGO EL NUMERO DE ARCOS Y LUEGO
158
                // EL NUMERO DE NODOS, DESPUES
159
                // IDTRAMO-SENTIDO_DIGITALIZACION-IDNODOORIGEN-IDNODODESTINO-TIPOTRAMO-DISTANCIA
160
                // Y POR FIN
161
                // IDNODO-Xdouble-Ydouble
162

    
163
                // El campo sentido indica //3-> Doble sentido, 1-> seg?n viene, 2
164
                // -> al rev?s, cualquier otro valor-> No hay arco
165
                // TipoTamo va a ser un campo num?rico, entero.
166
                // 0-> Autopista.
167
                // 1-> Autov?a.
168
                // 2-> Nacional.
169
                // 3-> Nacional - Comarcal.
170
                // 4-> Comarcal.
171
                // 5-> Otras.
172
                // 6-> Ferry.
173
                // 7-> Conexiones
174
                // Los nombres son orientativos. Basta saber que puede haber hasta X
175
                // tipos distintos de tramos, cada uno
176
                // con su velocidad. Esa velocidad se fijar? en la funci?n
177
                // FijaVelocidades. OJO, empezar siempre desde el 0
178

    
179
                double distance, cost;
180
                short arcType;
181
                int direction;
182
                int i;
183
                int idNodo1, idNodo2, nodeCount, edgeCount;
184
                short sentidoDigit; // => 1 en esa direcci?n. 0=> Al contrario. SOLO
185
                // SE UTILIZA PARA LOS CALCULOS POR IDTRAMO Y
186
                // PORCENTAJE
187
                // PARA SABER SI EST? M?S CERCA DE UN NODO O DEL OTRO.
188
                Hashtable nodeHash = null;
189
                if (snapTolerance != 0d)
190
                        nodeHash = new SnappingCoordinateMap(snapTolerance);
191
                else
192
                        nodeHash = new Hashtable();
193
                ArrayList nodes = new ArrayList();
194

    
195
                try {
196
                        // if (lyr.getShapeType() != FShape.LINE) {
197
                        if ((lyr.getShapeType() & FShape.LINE) != FShape.LINE) {
198
                                return;
199
                        }
200
                        RandomAccessFile file = new RandomAccessFile(redFile.getPath(),
201
                                        "rw");
202
                        FileImageOutputStream output = new FileImageOutputStream(file);
203
                        // FileChannel channel = file.getChannel();
204
                        // MappedByteBuffer buf = channel.map(MapMode.READ_WRITE, 0,
205
                        // 16 * 1024);
206
                        // buf.order(ByteOrder.LITTLE_ENDIAN);
207
                        output.setByteOrder(ByteOrder.LITTLE_ENDIAN);
208

    
209
                        nodeCount = 0;
210
                        ReadableVectorial adapter = lyr.getSource();
211
                        adapter.start();
212
                        int numTramos;
213

    
214
                        ICoordTrans ct = lyr.getCoordTrans();
215

    
216
                        numTramos = adapter.getShapeCount();
217
                        // Cambiamos otra vez: Escribimos primero el n? de tramos. Luego va
218
                        // el n? de arcos y el de nodos.
219
                        // buf.putInt(numTramos);
220
                        output.writeInt(numTramos);
221
                        // /////// Cambiamos el formato: primero van los arcos y luego los
222
                        // nodos
223
                        // file.writeInt(0);
224
                        output.writeInt(0);
225
                        // OJO: El numero de arcos todav?a no lo sabemos, habr? que volver
226
                        // luego y escribir el numero correcto. Es por lo de los sentidos.
227
                        // Metemos 2 arcos si es doble sentido, y uno si es de un solo
228
                        // sentido
229

    
230
                        // Guardamos un long. Luego volveremos aqu? y grabaremos el n? de
231
                        // nodos
232
                        // file.writeInt(0);
233
                        output.writeInt(numTramos);
234
                        // AHORA METEMOS LOS NOMBRES DE LOS CAMPOS. EN EL CARGA RED LOS
235
                        // USAREMOS PARA LEER DEL DBF.
236

    
237
                        edgeCount = 0;
238

    
239
                        SelectableDataSource sds = lyr.getRecordset();
240
                        int senseFieldIndex = -1;
241
                        int distFieldIndex = -1;
242
                        int typeFieldIndex = -1;
243
                        int costFieldIndex = -1;
244

    
245
                        if (fieldSense != null)
246
                                senseFieldIndex = sds.getFieldIndexByName(fieldSense);
247
                        if (fieldDist != null)
248
                                distFieldIndex = sds.getFieldIndexByName(fieldDist);
249
                        if (fieldType != null)
250
                                typeFieldIndex = sds.getFieldIndexByName(fieldType);
251
                        if (fieldCost != null)
252
                                costFieldIndex = sds.getFieldIndexByName(fieldCost);
253

    
254
                        DriverAttributes attr = adapter.getDriverAttributes();
255
                        boolean bMustClone = false;
256
                        if (attr != null) {
257
                                if (attr.isLoadedInMemory()) {
258
                                        bMustClone = attr.isLoadedInMemory();
259
                                }
260
                        }
261

    
262
                        NumericValue valAux = null;
263
                        for (i = 0; i < numTramos; i++) {
264
                                IGeometry geom = adapter.getShape(i);
265
                                if (geom == null)
266
                                        continue;
267
                                if (ct != null) {
268
                                        if (bMustClone)
269
                                                geom = geom.cloneGeometry();
270
                                        geom.reProject(ct);
271

    
272
                                }
273
                                Geometry jtsGeom = geom.toJTSGeometry();
274
                                Coordinate[] coords = jtsGeom.getCoordinates();
275
                                Coordinate c1 = coords[0];
276
                                Coordinate c2 = coords[coords.length - 1];
277

    
278
                                NodeGv nodeAux;
279
                                if (!nodeHash.containsKey(c1)) // No est?.
280
                                {
281
                                        idNodo1 = nodeCount++;
282
                                        nodeAux = new NodeGv(c1, idNodo1);
283
                                        nodeHash.put(c1, nodeAux);
284
                                        nodes.add(nodeAux);
285
                                } else {
286
                                        nodeAux = (NodeGv) nodeHash.get(c1);
287
                                }
288
                                idNodo1 = nodeAux.getId().intValue();
289

    
290
                                if (!nodeHash.containsKey(c2)) // No est?.
291
                                {
292
                                        idNodo2 = nodeCount++;
293
                                        nodeAux = new NodeGv(c2, idNodo2);
294
                                        nodeHash.put(c2, nodeAux);
295
                                        nodes.add(nodeAux);
296

    
297
                                } else {
298
                                        nodeAux = (NodeGv) nodeHash.get(c2);
299
                                }
300
                                idNodo2 = nodeAux.getId().intValue();
301

    
302
                                if (typeFieldIndex != -1)
303
                                        valAux = (NumericValue) sds
304
                                                        .getFieldValue(i, typeFieldIndex);
305
                                else
306
                                        valAux = ValueFactory.createValue(0); // no hay tipo
307
                                arcType = valAux.shortValue();
308
                                // TipoTramo = DBFReadIntegerAttribute(hDBF, i, indiceCampo1);
309

    
310
                                if (distFieldIndex != -1)
311
                                        valAux = (NumericValue) sds
312
                                                        .getFieldValue(i, distFieldIndex);
313
                                else
314
                                        valAux = ValueFactory.createValue(jtsGeom.getLength());
315
                                distance = valAux.floatValue();
316
                                // Distancia = (float) DBFReadDoubleAttribute(hDBF, i,
317
                                // indiceCampo2);
318
                                if (costFieldIndex != -1) {
319
                                        valAux = (NumericValue) sds
320
                                                        .getFieldValue(i, costFieldIndex);
321
                                        cost = valAux.doubleValue() * unitsFactor;
322
                                } else
323
                                        cost = distance;
324

    
325
                                direction = -1;
326

    
327
                                if (senseFieldIndex == -1)
328
                                        direction = 3; // 3-> Doble sentido, 1-> seg?n viene, 2 ->
329
                                // al rev?s
330
                                else {
331
                                        Value aux = sds.getFieldValue(i, senseFieldIndex);
332
                                        String auxStr = aux.toString();
333
                                        direction = 3; // default
334
                                        if (auxStr.equals(digitalizationDirection))
335
                                                direction = 1;
336
                                        if (auxStr.equals(reverseDigitalizationDirection))
337
                                                direction = 2;
338

    
339
                                }
340

    
341
                                if (direction == 3) {
342
                                        sentidoDigit = 1; // En esa direcci?n
343
                                        writeEdge(output, i, sentidoDigit, idNodo1, idNodo2,
344
                                                        arcType, distance, cost);
345
                                        edgeCount++;
346

    
347
                                        sentidoDigit = 0;
348
                                        writeEdge(output, i, sentidoDigit, idNodo2, idNodo1,
349
                                                        arcType, distance, cost);
350
                                        edgeCount++;
351

    
352
                                }
353
                                if (direction == 1) {
354
                                        sentidoDigit = 1; // En esa direcci?n
355
                                        writeEdge(output, i, sentidoDigit, idNodo1, idNodo2,
356
                                                        arcType, distance, cost);
357
                                        edgeCount++;
358
                                }
359
                                if (direction == 2) {
360
                                        sentidoDigit = 0;
361
                                        writeEdge(output, i, sentidoDigit, idNodo2, idNodo1,
362
                                                        arcType, distance, cost);
363
                                        edgeCount++;
364

    
365
                                }
366

    
367
                                if (cancel != null) {
368
                                        cancel.reportStep();
369

    
370
                                }
371
                        }// for
372

    
373
                        for (int j = 0; j < nodes.size(); j++) {
374
                                NodeGv node = (NodeGv) nodes.get(j);
375
                                output.writeInt(node.getId().intValue());
376
                                output.writeDouble(node.getCoordinate().x);
377
                                output.writeDouble(node.getCoordinate().y);
378
                        }
379

    
380
                        output.seek(0);
381
                        // buf.position(0);
382
                        output.writeInt(numTramos);
383
                        output.writeInt(edgeCount);
384
                        output.writeInt(nodes.size());
385

    
386
                        // buf.force();
387
                        output.close();
388
                        file.close();
389

    
390
                        adapter.stop();
391

    
392
                        cancel.setCurrentStep(cancel.getFinalStep());
393

    
394
                        return;
395
                } catch (IOException e) {
396
                        e.printStackTrace();
397
                        throw new GraphException(e);
398
                }
399
                // } catch (ReadDriverException e) {
400
                // e.printStackTrace();
401
                // throw new IOException(e);
402
                // } catch (ExpansionFileReadException e) {
403
                // e.printStackTrace();
404
                // throw new IOException(e);
405
                // }
406
        }
407

    
408
        public void setCancellableMonitorable(CancellableMonitorable cancel) {
409
                this.cancel = cancel;
410

    
411
        }
412

    
413
        public void setRedFile(File redFile) {
414
                this.redFile = redFile;
415

    
416
        }
417

    
418
        private void writeEdge(FileImageOutputStream output, int id, short sense,
419
                        int idNodeOrig, int idNodeEnd, short tipoTramo, double dist,
420
                        double cost) throws IOException {
421
                output.writeInt(id);
422
                output.writeInt(sense);
423

    
424
                output.writeInt(idNodeOrig);
425
                output.writeInt(idNodeEnd);
426
                output.writeInt(tipoTramo);
427
                output.writeDouble(dist);
428
                output.writeDouble(cost);
429

    
430
        }
431

    
432
        public void setSnapTolerance(double snapTolerance) {
433
                this.snapTolerance = snapTolerance;
434
        }
435

    
436
        public double getUnitsFactor() {
437
                return unitsFactor;
438
        }
439

    
440
        public void setUnitsFactor(double unitsFactor) {
441
                this.unitsFactor = unitsFactor;
442
        }
443

    
444
        public String getDigitalizationDirection() {
445
                return digitalizationDirection;
446
        }
447

    
448
        public void setDigitalizationDirection(String digitalizationDirection) {
449
                this.digitalizationDirection = digitalizationDirection;
450
        }
451

    
452
        public String getReverseDigitalizationDirection() {
453
                return reverseDigitalizationDirection;
454
        }
455

    
456
        public void setReverseDigitalizationDirection(
457
                        String reverseDigitalizationDirection) {
458
                this.reverseDigitalizationDirection = reverseDigitalizationDirection;
459
        }
460

    
461
}