Statistics
| Revision:

root / trunk / extensions / extDwg / src / com / iver / cit / gvsig / drivers / dwg / DwgMemoryDriver.java @ 10823

History | View | Annotate | Download (16.4 KB)

1
/*
2
 * Created on 14-abr-2005
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 * DwgMemoryDriver 0.2. Driver del formato DWG para gvSIG
6
 *
7
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
22
 *
23
 * For more information, contact:
24
 *
25
 *  Generalitat Valenciana
26
 *   Conselleria d'Infraestructures i Transport
27
 *   Av. Blasco Ib??ez, 50
28
 *   46010 VALENCIA
29
 *   SPAIN
30
 *
31
 *      +34 963862235
32
 *   gvsig@gva.es
33
 *      www.gvsig.gva.es
34
 *
35
 *    or
36
 *
37
 *   IVER T.I. S.A
38
 *   Salamanca 50
39
 *   46005 Valencia
40
 *   Spain
41
 *
42
 *   +34 963163400
43
 *   dac@iver.es
44
 */
45
/* CVS MESSAGES:
46
 *
47
 * $Id: DwgMemoryDriver.java 10823 2007-03-20 20:21:19Z azabala $
48
 * $Log$
49
 * Revision 1.9  2007-03-20 20:21:19  azabala
50
 * added roi filtering, reordering of code
51
 *
52
 * Revision 1.7  2007/02/27 17:18:03  azabala
53
 * solved bug with text orientation
54
 *
55
 * Revision 1.6  2007/02/14 16:17:22  azabala
56
 * *** empty log message ***
57
 *
58
 * Revision 1.5  2007/01/20 18:30:37  azabala
59
 * refactoring of blocks
60
 *
61
 * Revision 1.4  2007/01/18 19:59:10  azabala
62
 * refactoring to optimize and simplify the code
63
 *
64
 * Revision 1.3  2007/01/18 13:36:42  azabala
65
 * Refactoring general para evitar dar tantas pasadas en la carga, y para incrementar
66
 * la legibilidad del codigo (demasiados if-else-if en vez de usar polimorfismo)
67
 *
68
 * Revision 1.2  2007/01/12 19:57:44  azabala
69
 * *** empty log message ***
70
 *
71
 * Revision 1.1  2007/01/11 20:31:05  azabala
72
 * *** empty log message ***
73
 *
74
 *
75
 */
76
package com.iver.cit.gvsig.drivers.dwg;
77

    
78
import java.awt.Color;
79
import java.awt.Font;
80
import java.awt.geom.Rectangle2D;
81
import java.io.File;
82
import java.io.IOException;
83
import java.util.ArrayList;
84
import java.util.List;
85

    
86
import com.hardcode.gdbms.engine.data.DataSourceFactory;
87
import com.hardcode.gdbms.driver.exceptions.InitializeDriverException;
88
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
89
import com.hardcode.gdbms.driver.exceptions.UnsupportedVersionDriverException;
90
import com.hardcode.gdbms.engine.data.driver.DriverException;
91
import com.hardcode.gdbms.engine.data.driver.ObjectDriver;
92
import com.hardcode.gdbms.engine.data.edition.DataWare;
93
import com.hardcode.gdbms.engine.values.IntValue;
94
import com.hardcode.gdbms.engine.values.Value;
95
import com.hardcode.gdbms.engine.values.ValueFactory;
96
import com.iver.cit.gvsig.fmap.core.FShape;
97
import com.iver.cit.gvsig.fmap.core.IGeometry;
98
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
99
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
100
import com.iver.cit.gvsig.fmap.drivers.AbstractCadMemoryDriver;
101
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
102
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
103
import com.iver.cit.gvsig.fmap.drivers.WithDefaultLegend;
104
import com.iver.cit.gvsig.fmap.rendering.Legend;
105
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
106
import com.iver.cit.gvsig.fmap.rendering.VectorialUniqueValueLegend;
107
import com.iver.cit.jdwglib.dwg.DwgFile;
108
import com.iver.cit.jdwglib.dwg.DwgObject;
109
import com.iver.cit.jdwglib.dwg.DwgVersionNotSupportedException;
110
import com.iver.cit.jdwglib.dwg.IDwg2FMap;
111
import com.iver.cit.jdwglib.dwg.IDwg3DTestable;
112
import com.iver.cit.jdwglib.dwg.objects.DwgMText;
113
import com.iver.cit.jdwglib.dwg.objects.DwgText;
114
import com.iver.cit.jdwglib.util.AcadColor;
115

    
116
/**
117
 * Driver that allows gvSIG to read files in DWG format Using this driver, a
118
 * gvSIG user can manipulate part of the information contained in a DWG file
119
 * This driver load the Dwg file in memory This driver uses jdwglib
120
 * 
121
 * @author jmorell
122
 */
123
public class DwgMemoryDriver extends AbstractCadMemoryDriver implements
124
                VectorialFileDriver, WithDefaultLegend {
125

    
126
        VectorialUniqueValueLegend defaultLegend;
127
        private File m_Fich;
128
        private String fileVersion;
129
        private DriverAttributes attr = new DriverAttributes();
130
        private boolean isInitialized = false;
131
        float heightText = 10;        
132
        
133
        
134
        private boolean debug = false;
135
        /**
136
         * entities of the dwg file (once applied many transformation,
137
         * including block insertion) that are IDwgToFMap.
138
         * */
139
        ArrayList entities = new ArrayList();
140
        
141
        /**
142
         * Saves an original DWG entity associated to a FMap entity
143
         * by their index.
144
         * Only available in debug mode (if debug is false, doesnt save anything)
145
         * */
146
        private void saveEntity(DwgObject entity) {
147
                if(debug)
148
                        entities.add(entity);
149
        }
150
        
151
        public DwgObject getEntity(int i){
152
                if(debug)
153
                        return (DwgObject) entities.get(i);
154
                else
155
                        return null;
156
        }
157

    
158
        /*
159
         * (non-Javadoc)
160
         * 
161
         * @see com.iver.cit.gvsig.fmap.drivers.MemoryDriver#open(java.io.File)
162
         */
163
        public void open(File f) throws IOException {
164
                m_Fich = f;
165
        }
166

    
167
        /**
168
         * Allows recovering of the DWG Drawing entity associated to the FMap
169
         * feature whose position is index.
170
         * If debug mode is false, it always returns null.
171
         * 
172
         * @param index
173
         *            position of the fmap feature whose dwg entity is required
174
         * 
175
         */
176
        public Object getCadSource(int index) {
177
                if(debug)
178
                        return getEntity(index);
179
                else
180
                        return null;
181
        }
182

    
183
        /**
184
         * This method load the DWG file in memory. First, it will be necessary to
185
         * create a DwgFile object with the DWG file path as the argument. Second,
186
         * the method read of DwgFile allows to read the objects inside the DWG
187
         * file. Third, it will be necessary to process some DWG objects like Layers
188
         * or Polylines Fourth, applyExtrusions() can change the location of the DWG
189
         * objects through the extrusion parameters. Fifth, the testDwg3D method
190
         * test if this DWG has elevation informacion. Sixth, we can extract the
191
         * objects contained inside the blocks through the blockManagement method.
192
         * And finally, we can read the objects Vector, and convert this objects to
193
         * the FMap object model.
194
         */
195
        public void initialize() throws InitializeDriverException {
196
                if (isInitialized)
197
                        return;
198
                else
199
                        isInitialized = true;
200
                attr.setLoadedInMemory(true);
201
                DwgFile dwg = new DwgFile(m_Fich.getAbsolutePath());
202

    
203
                try {
204
                        dwg.read();
205
                } catch (DwgVersionNotSupportedException e1) {
206

    
207
                        String autodeskUrl = "<a href=\"http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=7024151\">"
208
                                        + "http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=7024151</a>";
209
//                        throw new InitializeDriverException(
210
//                                        formatString(
211
//                                                        "La version (%s) del fichero DWG '%s' no esta soportada por gvSIG.\n%s\n%s\n%s",
212
//                                                        new String[] { e1.getDwgVersion().toString(),
213
//                                                                        m_Fich.getName(),
214
//                                                                        Messages.getText("Probe_to_convert"),
215
//                                                                        Messages.getText("Autodesk_converter"),
216
//                                                                        autodeskUrl }));
217
                        String description=formatString(
218
                                        "La version (%s) del fichero DWG '%s' no esta soportada por gvSIG.\n%s\n%s\n%s",
219
                                        new String[] { e1.getDwgVersion().toString(),
220
                                                        m_Fich.getName(),
221
                                                        Messages.getText("Probe_to_convert"),
222
                                                        Messages.getText("Autodesk_converter"),
223
                                                        autodeskUrl });
224
                        throw new UnsupportedVersionDriverException(getName(),e1,description);
225
                } catch (IOException e) {
226
                        throw new InitializeDriverException(getName(),e);
227
                }
228

    
229
                fileVersion = dwg.getDwgVersion();
230
                dwg.calculateGisModelDwgPolylines();
231
                dwg.blockManagement2();
232
                List dwgObjects = dwg.getDwgObjects();
233
                
234
                //Each dwg file has two headers vars, EXTMIN and EXTMAX
235
                //that marks bounds of the file.
236
                //Also, it could have spureus entities (deleted objects
237
                //dont removed from the DWG database)
238
                double[] extMin = (double[]) dwg.getHeader("MSPACE_EXTMIN");
239
                double[] extMax = (double[]) dwg.getHeader("MSPACE_EXTMAX");
240
                if(extMin != null && extMax != null){
241
                        if(extMin.length >= 2 && extMax.length >= 2){
242
                                double xmin = extMin[0];
243
                                double ymin = extMin[1];
244
                                double xmax = extMax[0];
245
                                double ymax = extMax[1];
246
                                Rectangle2D roi = new 
247
                                        Rectangle2D.Double(xmin-100, ymin-100, 
248
                                                        (xmax-xmin)+100, (ymax-ymin)+100);
249
                                addRegionOfInterest(roi);
250
                        }
251
                }
252
                // Campos de las MemoryLayer:
253
                Value[] auxRow = new Value[10];
254
                ArrayList arrayFields = new ArrayList();
255
                arrayFields.add("ID");
256
                arrayFields.add("FShape");
257
                arrayFields.add("Entity");
258
                arrayFields.add("Layer");
259
                arrayFields.add("Color");
260
                arrayFields.add("Elevation");
261
                arrayFields.add("Thickness");
262
                arrayFields.add("Text");
263
                arrayFields.add("HeightText");
264
                arrayFields.add("RotationText");
265
                getTableModel().setColumnIdentifiers(arrayFields.toArray());
266

    
267
                boolean is3dFile = dwg.isDwg3DFile();
268
                try {
269
                        for (int i = 0; i < dwgObjects.size(); i++) {
270
                                DwgObject entity = (DwgObject) dwgObjects.get(i);
271

    
272
                                if (entity instanceof IDwg2FMap) {
273
                                        IDwg2FMap dwgEnt = (IDwg2FMap) entity;
274
                                        IGeometry geometry = dwgEnt.toFMapGeometry(is3dFile);
275
                                        if (geometry == null)
276
                                                continue;
277
                                        //we check for Region of Interest of the CAD file
278
                                        if(! checkRois(geometry))
279
                                                continue;
280
                                        
281
                                        String fmapStr = dwgEnt.toFMapString(is3dFile);
282
                                        // nombre del tipo de geometria fmap
283
                                        auxRow[ID_FIELD_FSHAPE] = ValueFactory.createValue(fmapStr);
284
                                        
285
                                        // indice del registro
286
                                        auxRow[ID_FIELD_ID] = ValueFactory.createValue(i);
287
                                        
288
                                        // nombre de entidad dwg
289
                                        auxRow[ID_FIELD_ENTITY] = ValueFactory.createValue(dwgEnt
290
                                                        .toString());
291
                                        String layerName = dwg.getLayerName(entity);
292
                                        auxRow[ID_FIELD_LAYER] = ValueFactory
293
                                                        .createValue(layerName);
294
                                        int color = entity.getColor();
295
                                        int colorByLayer = dwg.getColorByLayer(entity);
296

    
297
                                        if (color == 256)
298
                                                color = colorByLayer;
299
                                        
300
                                        auxRow[ID_FIELD_COLOR] = ValueFactory.createValue(color);
301

    
302
                                        auxRow[ID_FIELD_HEIGHTTEXT] = ValueFactory.createValue(0.0);
303
                                        auxRow[ID_FIELD_ROTATIONTEXT] = ValueFactory
304
                                                        .createValue(0.0);
305
                                        auxRow[ID_FIELD_TEXT] = ValueFactory.createNullValue();
306
                                        auxRow[ID_FIELD_THICKNESS] = ValueFactory.createValue(0.0);
307

    
308
                                        if (entity instanceof IDwg3DTestable) {
309
                                                auxRow[ID_FIELD_ELEVATION] = ValueFactory
310
                                                                .createValue(((IDwg3DTestable) entity).getZ());
311
                                        }
312

    
313
                                        if (entity instanceof DwgMText) {
314
                                                DwgMText mtext = (DwgMText) entity;
315
                                                auxRow[ID_FIELD_TEXT] = ValueFactory.createValue(mtext
316
                                                                .getText());
317
                                                auxRow[ID_FIELD_HEIGHTTEXT] = ValueFactory
318
                                                                .createValue(mtext.getHeight());
319
                                        } else if (entity instanceof DwgText) {
320
                                                DwgText text = (DwgText) entity;
321
                                                auxRow[ID_FIELD_TEXT] = ValueFactory.createValue(text
322
                                                                .getText());
323
                                                auxRow[ID_FIELD_THICKNESS] = ValueFactory
324
                                                                .createValue(text.getThickness());
325
                                                auxRow[ID_FIELD_HEIGHTTEXT] = ValueFactory
326
                                                                .createValue(text.getHeight());
327
                                                auxRow[ID_FIELD_ROTATIONTEXT] = ValueFactory
328
                                                                .createValue(Math.toDegrees(text
329
                                                                                .getRotationAngle()));
330
                                        }// if-else
331
                                        addGeometry(geometry, auxRow);
332
                                        
333
                                        if(debug)
334
                                                saveEntity(entity);
335

    
336
                                }
337
                        }// for
338

    
339
                } catch (Throwable t) {
340
                        t.printStackTrace();
341
                }
342
                dwgObjects = null;
343
                dwg = null;
344
                if(! debug)
345
                        dwg = null;
346
                System.gc();
347
                setSymbols();
348
        }
349
        
350
        /**
351
         * Sets a symbol for each dwg entity's derived feature based in
352
         * the DWG symbology info.
353
         * */
354
        private void setSymbols() throws IOException{
355
                FSymbol myDefaultSymbol = new FSymbol(getShapeType());
356
                myDefaultSymbol.setShapeVisible(false);
357
                myDefaultSymbol.setFontSizeInPixels(false);
358
                myDefaultSymbol.setFont(new Font("SansSerif", Font.PLAIN, 9));
359
                myDefaultSymbol.setFontColor(Color.BLACK);
360
                myDefaultSymbol.setFontSize(heightText);
361
                myDefaultSymbol.setStyle(FConstant.SYMBOL_STYLE_DGNSPECIAL);
362
                myDefaultSymbol.setSize(3);
363
                myDefaultSymbol.setSizeInPixels(true);
364

    
365
                defaultLegend = LegendFactory
366
                                .createVectorialUniqueValueLegend(getShapeType());
367
                defaultLegend.setFieldName("Color");
368
                defaultLegend.setLabelField("Text");
369
                defaultLegend.setDefaultSymbol(myDefaultSymbol);
370
                defaultLegend.setLabelHeightField("HeightText");
371
                defaultLegend.setLabelRotationField("RotationText");
372

    
373
                ObjectDriver rs = this;
374
                IntValue clave;
375
                FSymbol theSymbol = null;
376
                try {
377
                        for (long j = 0; j < rs.getRowCount(); j++) {
378
                                clave = (IntValue) rs.getFieldValue(j, ID_FIELD_COLOR);
379
                                if (defaultLegend.getSymbolByValue(clave) == null) {
380
                                        theSymbol = new FSymbol(getShapeType());
381
                                        theSymbol.setDescription(clave.toString());
382
                                        theSymbol.setColor(AcadColor.getColor(clave.getValue()));
383
                                        // theSymbol.setFill(fillProv);
384
                                        // 050202, jmorell: Asigna los colores de Autocad a los
385
                                        // bordes
386
                                        // de los pol?gonos.
387
                                        theSymbol.setOutlineColor(AcadColor.getColor(clave
388
                                                        .getValue()));
389

    
390
                                        theSymbol.setStyle(FConstant.SYMBOL_STYLE_DGNSPECIAL);
391
                                        theSymbol.setSize(3);
392
                                        theSymbol.setSizeInPixels(true);
393
                                        defaultLegend.addSymbol(clave, theSymbol);
394
                                }// if
395
                        } // for
396
                } catch (ReadDriverException e) {
397
                        throw new InitializeDriverException(getName(),e);
398
                }
399
        }
400
        
401
        /**
402
         * checks if the given geometry intersects or its
403
         * contained in one of the driver regions of interest.
404
         * 
405
         * @param geometry feature geometry we want to check
406
         * against the drivers rois.
407
         * 
408
         *  @return true if feature is contained in any ROI.
409
         *  false if not.
410
         * */
411
        private boolean checkRois(IGeometry geometry){
412
                Rectangle2D rect = geometry.getBounds2D();
413
                int numRois = this.getNumOfRois();
414
                for(int i = 0; i < numRois; i++){
415
                        Rectangle2D roi = getRegionOfInterest(i);
416
                        if( checkIntersect(rect.getMinX(), rect.getMaxX(), rect.getMinY(), rect.getMaxY(),
417
                                        roi.getMinX(), roi.getMaxX(), roi.getMinY(),roi.getMaxY()) ||
418
                                checkContains(rect.getMinX(), rect.getMaxX(), rect.getMinY(), rect.getMaxY(),
419
                                                roi.getMinX(), roi.getMaxX(), roi.getMinY(),roi.getMaxY())
420
                        ){
421
                                return true;
422
                        }
423
//                        if(roi.intersects(rect) || roi.contains(rect))
424
//                                return true;
425
                }
426
                return false;
427
        }
428
        
429
        private boolean checkContains(double x1, double x2, double y1, double y2, 
430
                        double ax1, double ax2, double ay1, double ay2){
431
                 boolean solution = ( x1 >= ax1 &&
432
                x2 <= ax2 &&
433
                y1 >= ay1 &&
434
                y2 <= ay2);
435
                 return solution;
436
        }
437
        
438
        private boolean checkIntersect(double x1, double x2, double y1, double y2, 
439
                                                                double ax1, double ax2, double ay1, double ay2){
440
                
441
                 return !(x1 > ax2 ||
442
                        x2 < ax1 ||
443
                        y1 > ay2 ||
444
                        y2 < ay1);
445
                 
446
        }
447

    
448
        public String getFileVersion() {
449
                return fileVersion;
450
        }
451

    
452
        private String formatString(String fmt, String[] params) {
453
                String ret = fmt;
454
                for (int i = 0; i < params.length; i++) {
455
                        ret = ret.replaceFirst("%s", params[i]);
456
                }
457
                return ret;
458
        }
459

    
460
        
461
        /*
462
         * (non-Javadoc)
463
         * 
464
         * @see com.iver.cit.gvsig.fmap.drivers.MemoryDriver#accept(java.io.File)
465
         */
466
        public boolean accept(File f) {
467
                return f.getName().toUpperCase().endsWith("DWG");
468
        }
469

    
470
        /*
471
         * (non-Javadoc)
472
         * 
473
         * @see com.iver.cit.gvsig.fmap.drivers.MemoryDriver#getShapeType()
474
         */
475
        public int getShapeType() {
476
                return FShape.MULTI;
477
        }
478

    
479
        /*
480
         * (non-Javadoc)
481
         * 
482
         * @see com.iver.cit.gvsig.fmap.drivers.MemoryDriver#getName()
483
         */
484
        public String getName() {
485
                return "gvSIG DWG Memory Driver";
486
        }
487

    
488
        /*
489
         * (non-Javadoc)
490
         * 
491
         * @see com.iver.cit.gvsig.fmap.drivers.WithDefaultLegend#getDefaultLegend()
492
         */
493
        public Legend getDefaultLegend() {
494
                return defaultLegend;
495
        }
496

    
497
        /*
498
         * (non-Javadoc)
499
         * 
500
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getDriverAttributes()
501
         */
502
        public DriverAttributes getDriverAttributes() {
503
                return attr;
504
        }
505

    
506
        /*
507
         * (non-Javadoc)
508
         * 
509
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getPrimaryKeys()
510
         */
511
        public int[] getPrimaryKeys() throws DriverException {
512
                // TODO Auto-generated method stub
513
                return null;
514
        }
515

    
516
        /*
517
         * (non-Javadoc)
518
         * 
519
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#write(com.hardcode.gdbms.engine.data.edition.DataWare)
520
         */
521
        public void write(DataWare arg0) throws DriverException {
522
                // TODO Auto-generated method stub
523

    
524
        }
525

    
526
        public void setDataSourceFactory(DataSourceFactory arg0) {
527
                // TODO Auto-generated method stub
528

    
529
        }
530

    
531
        public void close() throws IOException {
532
                // TODO Auto-generated method stub
533

    
534
        }
535

    
536
        public File getFile() {
537
                return m_Fich;
538
        }
539

    
540
        public boolean isWritable() {
541
                return m_Fich.canWrite();
542
        }
543

    
544

    
545
        public boolean isDebug() {
546
                return debug;
547
        }
548

    
549

    
550
        public void setDebug(boolean debug) {
551
                this.debug = debug;
552
        }
553
}