Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGraph_predes / src / com / iver / cit / gvsig / graph / core / writers / NetworkFileRedWriter.java @ 8659

History | View | Annotate | Download (11.9 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 com.iver.cit.gvsig.graph.core.writers;
42

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

    
52
import javax.imageio.stream.FileImageOutputStream;
53

    
54
import com.hardcode.gdbms.engine.values.NumericValue;
55
import com.hardcode.gdbms.engine.values.ValueFactory;
56
import com.iver.cit.gvsig.fmap.DriverException;
57
import com.iver.cit.gvsig.fmap.core.FShape;
58
import com.iver.cit.gvsig.fmap.core.IGeometry;
59
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
60
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
61
import com.iver.cit.gvsig.fmap.edition.EditionException;
62
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
63
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
64
import com.iver.cit.gvsig.fmap.layers.VectorialAdapter;
65
import com.iver.cit.gvsig.graph.core.NodeGv;
66
import com.iver.cit.gvsig.util.SnappingCoordinateMap;
67
import com.iver.utiles.swing.threads.CancellableMonitorable;
68
import com.vividsolutions.jts.geom.Coordinate;
69
import com.vividsolutions.jts.geom.Geometry;
70

    
71
/**
72
 * @author fjp
73
 *
74
 * 
75
 */
76
public class NetworkFileRedWriter extends AbstractNetworkWriter {
77
        File redFile;
78
        CancellableMonitorable cancel;
79
        private double snapTolerance = 0d;
80
        public NetworkFileRedWriter() {
81
                
82
                // Set up fields for table nodes
83
                nodeFields = new FieldDescription[3];
84
                FieldDescription fieldNodeId = new FieldDescription();
85
                fieldNodeId.setFieldName("NODEID");
86
                fieldNodeId.setFieldType(Types.INTEGER);
87

    
88
                FieldDescription fieldX = new FieldDescription();
89
                fieldX.setFieldName("X");
90
                fieldX.setFieldType(Types.DOUBLE);
91
                fieldX.setFieldDecimalCount(2);
92

    
93
                FieldDescription fieldY = new FieldDescription();
94
                fieldY.setFieldName("Y");
95
                fieldY.setFieldType(Types.DOUBLE);
96
                fieldY.setFieldDecimalCount(2);
97
                
98
                nodeFields[0] = fieldNodeId;
99
                nodeFields[1] = fieldX;
100
                nodeFields[2] = fieldY;
101

    
102
                
103
                // Set up fields for table edges
104
                edgeFields = new FieldDescription[7];
105

    
106
                // ID_TRAMO ORIGINAL!!!
107
                FieldDescription fieldArcID = new FieldDescription();
108
                fieldArcID.setFieldName("ArcID");
109
                fieldArcID.setFieldType(Types.INTEGER);
110

    
111
                FieldDescription fieldDirection = new FieldDescription();
112
                fieldDirection.setFieldName("Direction");
113
                fieldDirection.setFieldType(Types.SMALLINT);
114
                
115
                FieldDescription fieldNodeOrigin = new FieldDescription();
116
                fieldNodeOrigin.setFieldName("NodeOrigin");
117
                fieldNodeOrigin.setFieldType(Types.INTEGER);
118
                FieldDescription fieldNodeEnd = new FieldDescription();
119
                fieldNodeEnd.setFieldName("NodeEnd");
120
                fieldNodeEnd.setFieldType(Types.INTEGER);
121

    
122
                FieldDescription fieldType = new FieldDescription();
123
                fieldType.setFieldName("Type");
124
                fieldType.setFieldType(Types.SMALLINT);
125

    
126
                FieldDescription fieldDistanceDist = new FieldDescription();
127
                fieldDistanceDist.setFieldName("Dist");
128
                fieldDistanceDist.setFieldType(Types.DOUBLE);
129
                
130
                FieldDescription fieldDistanceCost = new FieldDescription();
131
                fieldDistanceCost.setFieldName("Cost");
132
                fieldDistanceCost.setFieldType(Types.DOUBLE);
133
                
134
                edgeFields[0] = fieldArcID;
135
                edgeFields[1] = fieldDirection;
136
                edgeFields[2] = fieldNodeOrigin;
137
                edgeFields[3] = fieldNodeEnd;
138
                edgeFields[4] = fieldType;
139
                edgeFields[5] = fieldDistanceDist;
140
                edgeFields[6] = fieldDistanceCost;
141
        }
142

    
143
        /* (non-Javadoc)
144
         * @see com.iver.cit.gvsig.graph.core.INetworkWriter#writeNetwork(boolean)
145
         */
146
        public void writeNetwork() throws EditionException {
147
                // PRIMERO VAN EL NUMERO DE TRAMOS, LUEGO EL NUMERO DE ARCOS Y LUEGO
148
                // EL NUMERO DE NODOS, DESPUES
149
                // IDTRAMO-SENTIDO_DIGITALIZACION-IDNODOORIGEN-IDNODODESTINO-TIPOTRAMO-DISTANCIA
150
                // Y POR FIN
151
                // IDNODO-Xdouble-Ydouble
152

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

    
169
                double distance, cost;
170
                short arcType;
171
                int direction;
172
                int i;
173
                int idNodo1, idNodo2, nodeCount, edgeCount;
174
                short sentidoDigit; // => 1 en esa direcci?n. 0=> Al contrario. SOLO
175
                // SE UTILIZA PARA LOS CALCULOS POR IDTRAMO Y
176
                // PORCENTAJE
177
                // PARA SABER SI EST? M?S CERCA DE UN NODO O DEL OTRO.
178
                Hashtable nodeHash = null;
179
                if(snapTolerance != 0d)
180
                        nodeHash = new SnappingCoordinateMap(snapTolerance);
181
                else
182
                        nodeHash = new Hashtable();
183
                ArrayList nodes = new ArrayList();
184

    
185
                try {
186
                        if (lyr.getShapeType() != FShape.LINE) {
187
                                return;
188
                        }
189
                        RandomAccessFile file = new RandomAccessFile(redFile.getPath(),
190
                                        "rw");
191
                        FileImageOutputStream output = new FileImageOutputStream(file);
192
//                        FileChannel channel = file.getChannel();
193
//                        MappedByteBuffer buf = channel.map(MapMode.READ_WRITE, 0,
194
//                                        16 * 1024);
195
//                        buf.order(ByteOrder.LITTLE_ENDIAN);
196
                        output.setByteOrder(ByteOrder.LITTLE_ENDIAN);
197

    
198
                        nodeCount = 0;
199
                        VectorialAdapter adapter = (VectorialAdapter) lyr.getSource();
200
                        int numTramos;
201

    
202
                        numTramos = adapter.getShapeCount();
203
                        // Cambiamos otra vez: Escribimos primero el n? de tramos. Luego va
204
                        // el n? de arcos y el de nodos.
205
                        // buf.putInt(numTramos);
206
                        output.writeInt(numTramos);
207
                        // /////// Cambiamos el formato: primero van los arcos y luego los
208
                        // nodos
209
                        // file.writeInt(0);
210
                        output.writeInt(0);
211
                        // OJO: El numero de arcos todav?a no lo sabemos, habr? que volver
212
                        // luego y escribir el numero correcto. Es por lo de los sentidos.
213
                        // Metemos 2 arcos si es doble sentido, y uno si es de un solo
214
                        // sentido
215

    
216
                        // Guardamos un long. Luego volveremos aqu? y grabaremos el n? de
217
                        // nodos
218
                        // file.writeInt(0);
219
                        output.writeInt(numTramos);
220
                        // AHORA METEMOS LOS NOMBRES DE LOS CAMPOS. EN EL CARGA RED LOS
221
                        // USAREMOS PARA LEER DEL DBF.
222

    
223
                        edgeCount = 0;
224

    
225
                        SelectableDataSource sds = lyr.getRecordset();
226
                        int senseFieldIndex = -1;
227
                        int distFieldIndex = -1;
228
                        int typeFieldIndex = -1;
229
                        int costFieldIndex = -1;
230
                        
231
                        if (fieldSense != null)
232
                                senseFieldIndex = sds.getFieldIndexByName(fieldSense);
233
                        if (fieldDist != null)
234
                                distFieldIndex = sds.getFieldIndexByName(fieldDist);
235
                        if (fieldType != null)
236
                                typeFieldIndex = sds.getFieldIndexByName(fieldType);
237
                        if (fieldCost != null)
238
                                costFieldIndex = sds.getFieldIndexByName(fieldCost);
239

    
240
                        NumericValue valAux = null;
241
                        for (i = 0; i < numTramos; i++) {
242
                                IGeometry geom = adapter.getShape(i);
243
                                Geometry jtsGeom = geom.toJTSGeometry();
244
                                Coordinate[] coords = jtsGeom.getCoordinates();
245
                                Coordinate c1 = coords[0];
246
                                Coordinate c2 = coords[coords.length - 1];
247
                                
248
                                if(cancel != null)
249
                                        cancel.reportStep();
250

    
251
                                NodeGv nodeAux;
252
                                if (!nodeHash.containsKey(c1)) // No est?.
253
                                {
254
                                        idNodo1 = nodeCount++;
255
                                        nodeAux = new NodeGv(c1, idNodo1);
256
                                        nodeHash.put(c1, nodeAux);
257
                                        nodes.add(nodeAux);
258
                                } else {
259
                                        nodeAux = (NodeGv) nodeHash.get(c1);
260
                                }
261
                                idNodo1 = nodeAux.getId().intValue();
262

    
263
                                if (!nodeHash.containsKey(c2)) // No est?.
264
                                {
265
                                        idNodo2 = nodeCount++;
266
                                        nodeAux = new NodeGv(c2, idNodo2);
267
                                        nodeHash.put(c2, nodeAux);
268
                                        nodes.add(nodeAux);
269

    
270
                                } else {
271
                                        nodeAux = (NodeGv) nodeHash.get(c2);
272
                                }
273
                                idNodo2 = nodeAux.getId().intValue();
274

    
275
                                if (typeFieldIndex != -1)
276
                                        valAux = (NumericValue) sds.getFieldValue(i, typeFieldIndex);
277
                                else
278
                                        valAux = ValueFactory.createValue(0); // no hay tipo
279
                                arcType = valAux.shortValue();
280
                                // TipoTramo = DBFReadIntegerAttribute(hDBF, i, indiceCampo1);
281
                                
282
                                if (distFieldIndex != -1)
283
                                        valAux = (NumericValue) sds.getFieldValue(i, distFieldIndex);
284
                                else
285
                                        valAux = ValueFactory.createValue(jtsGeom.getLength());
286
                                distance = valAux.floatValue();
287
                                // Distancia = (float) DBFReadDoubleAttribute(hDBF, i,
288
                                // indiceCampo2);
289
                                if (costFieldIndex != -1)
290
                                {
291
                                        valAux = (NumericValue) sds.getFieldValue(i, costFieldIndex);
292
                                        cost = valAux.doubleValue();
293
                                }
294
                                else
295
                                        cost = distance;
296
                                
297
                                
298

    
299
                                direction = -1;
300

    
301
                                if (senseFieldIndex == -1)
302
                                        direction = 3; // 3-> Doble sentido, 1-> seg?n viene, 2 ->
303
                                // al rev?s, cualquier otro valor-> No hay
304
                                // arco
305
                                else {
306
                                        valAux = (NumericValue) sds.getFieldValue(i,
307
                                                        senseFieldIndex);
308
                                        direction = valAux.shortValue();
309
                                }
310

    
311
                                if (direction == 3) {
312
                                        sentidoDigit = 1; // En esa direcci?n
313
                                        writeEdge(output, i, sentidoDigit, idNodo1, idNodo2, arcType,
314
                                                        distance, cost);
315
                                        edgeCount++;
316

    
317
                                        sentidoDigit = 0;
318
                                        writeEdge(output, i, sentidoDigit, idNodo2, idNodo1, arcType,
319
                                                        distance, cost);
320
                                        edgeCount++;
321

    
322
                                }
323
                                if (direction == 1) {
324
                                        sentidoDigit = 1; // En esa direcci?n
325
                                        writeEdge(output, i, sentidoDigit, idNodo1, idNodo2, arcType,
326
                                                        distance, cost);
327
                                        edgeCount++;
328
                                }
329
                                if (direction == 2) {
330
                                        sentidoDigit = 0;
331
                                        writeEdge(output, i, sentidoDigit, idNodo2, idNodo1, arcType,
332
                                                        distance, cost);
333
                                        edgeCount++;
334

    
335
                                }
336
                                
337
                                if(cancel != null){
338
                                        cancel.reportStep();
339
                                        
340
                                }
341
                        }//for
342

    
343

    
344
                        for (int j=0; j < nodes.size(); j++) {
345
                                NodeGv node = (NodeGv) nodes.get(j);
346
                                output.writeInt(node.getId().intValue());
347
                                output.writeDouble(node.getCoordinate().x);
348
                                output.writeDouble(node.getCoordinate().y);
349
                        }
350

    
351
                        output.seek(0);
352
                        // buf.position(0);
353
                        output.writeInt(numTramos);
354
                        output.writeInt(edgeCount);
355
                        output.writeInt(nodes.size());
356

    
357
                        // buf.force();
358
                        output.close();
359
                        file.close();
360

    
361
                        return ;
362
                } catch (DriverIOException e) {
363
                        e.printStackTrace();
364
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
365
                        e.printStackTrace();
366
                        throw new EditionException(e);
367
                } catch (FileNotFoundException e) {
368
                        e.printStackTrace();
369
                        throw new EditionException(e);
370
                } catch (IOException e) {
371
                        e.printStackTrace();
372
                        throw new EditionException(e);
373
                } catch (DriverException e) {                
374
                        e.printStackTrace();
375
                        throw new EditionException(e);
376
                }
377
        }
378

    
379

    
380
        public void setCancellableMonitorable(CancellableMonitorable cancel) {
381
                this.cancel = cancel;
382
                
383
        }
384

    
385
        public void setRedFile(File redFile) {
386
                this.redFile = redFile;
387
                
388
        }
389

    
390
        private void writeEdge(FileImageOutputStream output, int id, short sense,
391
                        int idNodeOrig, int idNodeEnd, short tipoTramo, double dist, double cost)
392
                        throws IOException {
393
                output.writeInt(id);
394
                output.writeInt(sense);
395

    
396
                output.writeInt(idNodeOrig);
397
                output.writeInt(idNodeEnd);
398
                output.writeInt(tipoTramo);
399
                output.writeDouble(dist);
400
                output.writeDouble(cost);
401

    
402
        }
403

    
404
        public void setSnapTolerance(double snapTolerance) {
405
                this.snapTolerance = snapTolerance;
406
        }
407

    
408
}