Statistics
| Revision:

svn-gvsig-desktop / tags / PilotoRedes_Build_3 / extensions / extGraph_predes / src / com / iver / cit / gvsig / graph / core / writers / NetworkFileRedWriter.java @ 11678

History | View | Annotate | Download (12.5 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 org.cresques.cts.ICoordTrans;
55

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

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

    
91
                FieldDescription fieldX = new FieldDescription();
92
                fieldX.setFieldName("X");
93
                fieldX.setFieldType(Types.DOUBLE);
94
                fieldX.setFieldDecimalCount(2);
95

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

    
105
                
106
                // Set up fields for table edges
107
                edgeFields = new FieldDescription[7];
108

    
109
                // ID_TRAMO ORIGINAL!!!
110
                FieldDescription fieldArcID = new FieldDescription();
111
                fieldArcID.setFieldName("ArcID");
112
                fieldArcID.setFieldType(Types.INTEGER);
113

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

    
125
                FieldDescription fieldType = new FieldDescription();
126
                fieldType.setFieldName("Type");
127
                fieldType.setFieldType(Types.SMALLINT);
128

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

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

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

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

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

    
201
                        nodeCount = 0;
202
                        VectorialAdapter adapter = (VectorialAdapter) lyr.getSource();
203
                        adapter.start();
204
                        int numTramos;
205
                        
206
                        ICoordTrans ct = lyr.getCoordTrans();
207

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

    
222
                        // Guardamos un long. Luego volveremos aqu? y grabaremos el n? de
223
                        // nodos
224
                        // file.writeInt(0);
225
                        output.writeInt(numTramos);
226
                        // AHORA METEMOS LOS NOMBRES DE LOS CAMPOS. EN EL CARGA RED LOS
227
                        // USAREMOS PARA LEER DEL DBF.
228

    
229
                        edgeCount = 0;
230

    
231
                        SelectableDataSource sds = lyr.getRecordset();
232
                        int senseFieldIndex = -1;
233
                        int distFieldIndex = -1;
234
                        int typeFieldIndex = -1;
235
                        int costFieldIndex = -1;
236
                        
237
                        if (fieldSense != null)
238
                                senseFieldIndex = sds.getFieldIndexByName(fieldSense);
239
                        if (fieldDist != null)
240
                                distFieldIndex = sds.getFieldIndexByName(fieldDist);
241
                        if (fieldType != null)
242
                                typeFieldIndex = sds.getFieldIndexByName(fieldType);
243
                        if (fieldCost != null)
244
                                costFieldIndex = sds.getFieldIndexByName(fieldCost);
245

    
246
                DriverAttributes attr = adapter.getDriverAttributes();
247
                boolean bMustClone = false;
248
                if (attr != null)
249
                {
250
                    if (attr.isLoadedInMemory())
251
                    {
252
                        bMustClone = attr.isLoadedInMemory();               
253
                    }
254
                }
255

    
256
                        
257
                        NumericValue valAux = null;
258
                        for (i = 0; i < numTramos; i++) {
259
                                IGeometry geom = adapter.getShape(i);
260
                                if (ct != null)
261
                                {
262
                        if (bMustClone)
263
                            geom = geom.cloneGeometry();
264
                        geom.reProject(ct);
265

    
266
                                }
267
                                Geometry jtsGeom = geom.toJTSGeometry();
268
                                Coordinate[] coords = jtsGeom.getCoordinates();
269
                                Coordinate c1 = coords[0];
270
                                Coordinate c2 = coords[coords.length - 1];
271
                                
272
                                NodeGv nodeAux;
273
                                if (!nodeHash.containsKey(c1)) // No est?.
274
                                {
275
                                        idNodo1 = nodeCount++;
276
                                        nodeAux = new NodeGv(c1, idNodo1);
277
                                        nodeHash.put(c1, nodeAux);
278
                                        nodes.add(nodeAux);
279
                                } else {
280
                                        nodeAux = (NodeGv) nodeHash.get(c1);
281
                                }
282
                                idNodo1 = nodeAux.getId().intValue();
283

    
284
                                if (!nodeHash.containsKey(c2)) // No est?.
285
                                {
286
                                        idNodo2 = nodeCount++;
287
                                        nodeAux = new NodeGv(c2, idNodo2);
288
                                        nodeHash.put(c2, nodeAux);
289
                                        nodes.add(nodeAux);
290

    
291
                                } else {
292
                                        nodeAux = (NodeGv) nodeHash.get(c2);
293
                                }
294
                                idNodo2 = nodeAux.getId().intValue();
295

    
296
                                if (typeFieldIndex != -1)
297
                                        valAux = (NumericValue) sds.getFieldValue(i, typeFieldIndex);
298
                                else
299
                                        valAux = ValueFactory.createValue(0); // no hay tipo
300
                                arcType = valAux.shortValue();
301
                                // TipoTramo = DBFReadIntegerAttribute(hDBF, i, indiceCampo1);
302
                                
303
                                if (distFieldIndex != -1)
304
                                        valAux = (NumericValue) sds.getFieldValue(i, distFieldIndex);
305
                                else
306
                                        valAux = ValueFactory.createValue(jtsGeom.getLength());
307
                                distance = valAux.floatValue();
308
                                // Distancia = (float) DBFReadDoubleAttribute(hDBF, i,
309
                                // indiceCampo2);
310
                                if (costFieldIndex != -1)
311
                                {
312
                                        valAux = (NumericValue) sds.getFieldValue(i, costFieldIndex);
313
                                        cost = valAux.doubleValue();
314
                                }
315
                                else
316
                                        cost = distance;
317
                                
318
                                
319

    
320
                                direction = -1;
321

    
322
                                if (senseFieldIndex == -1)
323
                                        direction = 3; // 3-> Doble sentido, 1-> seg?n viene, 2 ->
324
                                // al rev?s, cualquier otro valor-> No hay
325
                                // arco
326
                                else {
327
                                        valAux = (NumericValue) sds.getFieldValue(i,
328
                                                        senseFieldIndex);
329
                                        direction = valAux.shortValue();
330
                                }
331

    
332
                                if (direction == 3) {
333
                                        sentidoDigit = 1; // En esa direcci?n
334
                                        writeEdge(output, i, sentidoDigit, idNodo1, idNodo2, arcType,
335
                                                        distance, cost);
336
                                        edgeCount++;
337

    
338
                                        sentidoDigit = 0;
339
                                        writeEdge(output, i, sentidoDigit, idNodo2, idNodo1, arcType,
340
                                                        distance, cost);
341
                                        edgeCount++;
342

    
343
                                }
344
                                if (direction == 1) {
345
                                        sentidoDigit = 1; // En esa direcci?n
346
                                        writeEdge(output, i, sentidoDigit, idNodo1, idNodo2, arcType,
347
                                                        distance, cost);
348
                                        edgeCount++;
349
                                }
350
                                if (direction == 2) {
351
                                        sentidoDigit = 0;
352
                                        writeEdge(output, i, sentidoDigit, idNodo2, idNodo1, arcType,
353
                                                        distance, cost);
354
                                        edgeCount++;
355

    
356
                                }
357
                                
358
                                if(cancel != null){
359
                                        cancel.reportStep();
360
                                        
361
                                }
362
                        }//for
363

    
364

    
365
                        for (int j=0; j < nodes.size(); j++) {
366
                                NodeGv node = (NodeGv) nodes.get(j);
367
                                output.writeInt(node.getId().intValue());
368
                                output.writeDouble(node.getCoordinate().x);
369
                                output.writeDouble(node.getCoordinate().y);
370
                        }
371

    
372
                        output.seek(0);
373
                        // buf.position(0);
374
                        output.writeInt(numTramos);
375
                        output.writeInt(edgeCount);
376
                        output.writeInt(nodes.size());
377

    
378
                        // buf.force();
379
                        output.close();
380
                        file.close();
381
                        
382
                        adapter.stop();
383
                        
384
                        cancel.setCurrentStep(cancel.getFinalStep());
385

    
386
                        return ;
387
                } catch (DriverIOException e) {
388
                        e.printStackTrace();
389
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
390
                        e.printStackTrace();
391
                        throw new EditionException(e);
392
                } catch (FileNotFoundException e) {
393
                        e.printStackTrace();
394
                        throw new EditionException(e);
395
                } catch (IOException e) {
396
                        e.printStackTrace();
397
                        throw new EditionException(e);
398
                } catch (DriverException e) {                
399
                        e.printStackTrace();
400
                        throw new EditionException(e);
401
                }
402
        }
403

    
404

    
405
        public void setCancellableMonitorable(CancellableMonitorable cancel) {
406
                this.cancel = cancel;
407
                
408
        }
409

    
410
        public void setRedFile(File redFile) {
411
                this.redFile = redFile;
412
                
413
        }
414

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

    
421
                output.writeInt(idNodeOrig);
422
                output.writeInt(idNodeEnd);
423
                output.writeInt(tipoTramo);
424
                output.writeDouble(dist);
425
                output.writeDouble(cost);
426

    
427
        }
428

    
429
        public void setSnapTolerance(double snapTolerance) {
430
                this.snapTolerance = snapTolerance;
431
        }
432

    
433
}