Statistics
| Revision:

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

History | View | Annotate | Download (17 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 10860 2007-03-22 19:56:12Z azabala $
48
 * $Log$
49
 * Revision 1.10  2007-03-22 19:56:12  azabala
50
 * changes in exceptinos api
51
 *
52
 * Revision 1.9  2007/03/20 20:21:19  azabala
53
 * added roi filtering, reordering of code
54
 *
55
 * Revision 1.7  2007/02/27 17:18:03  azabala
56
 * solved bug with text orientation
57
 *
58
 * Revision 1.6  2007/02/14 16:17:22  azabala
59
 * *** empty log message ***
60
 *
61
 * Revision 1.5  2007/01/20 18:30:37  azabala
62
 * refactoring of blocks
63
 *
64
 * Revision 1.4  2007/01/18 19:59:10  azabala
65
 * refactoring to optimize and simplify the code
66
 *
67
 * Revision 1.3  2007/01/18 13:36:42  azabala
68
 * Refactoring general para evitar dar tantas pasadas en la carga, y para incrementar
69
 * la legibilidad del codigo (demasiados if-else-if en vez de usar polimorfismo)
70
 *
71
 * Revision 1.2  2007/01/12 19:57:44  azabala
72
 * *** empty log message ***
73
 *
74
 * Revision 1.1  2007/01/11 20:31:05  azabala
75
 * *** empty log message ***
76
 *
77
 *
78
 */
79
package com.iver.cit.gvsig.drivers.dwg;
80

    
81
import java.awt.Color;
82
import java.awt.Font;
83
import java.awt.geom.Rectangle2D;
84
import java.io.File;
85
import java.io.IOException;
86
import java.util.ArrayList;
87
import java.util.List;
88

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

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

    
130
        VectorialUniqueValueLegend defaultLegend;
131
        private File m_Fich;
132
        private String fileVersion;
133
        private DriverAttributes attr = new DriverAttributes();
134
        private boolean isInitialized = false;
135
        float heightText = 10;        
136
        
137
        //new WithDefaultLegend API
138
        private AttrInTableLabeling labeling;
139

    
140
        
141
        
142
        
143
        
144
        private boolean debug = false;
145
        /**
146
         * entities of the dwg file (once applied many transformation,
147
         * including block insertion) that are IDwgToFMap.
148
         * */
149
        ArrayList entities = new ArrayList();
150
        
151
        /**
152
         * Saves an original DWG entity associated to a FMap entity
153
         * by their index.
154
         * Only available in debug mode (if debug is false, doesnt save anything)
155
         * */
156
        private void saveEntity(DwgObject entity) {
157
                if(debug)
158
                        entities.add(entity);
159
        }
160
        
161
        public DwgObject getEntity(int i){
162
                if(debug)
163
                        return (DwgObject) entities.get(i);
164
                else
165
                        return null;
166
        }
167

    
168
        /*
169
         * (non-Javadoc)
170
         * 
171
         * @see com.iver.cit.gvsig.fmap.drivers.MemoryDriver#open(java.io.File)
172
         */
173
        public void open(File f) {
174
                m_Fich = f;
175
        }
176

    
177
        /**
178
         * Allows recovering of the DWG Drawing entity associated to the FMap
179
         * feature whose position is index.
180
         * If debug mode is false, it always returns null.
181
         * 
182
         * @param index
183
         *            position of the fmap feature whose dwg entity is required
184
         * 
185
         */
186
        public Object getCadSource(int index) {
187
                if(debug)
188
                        return getEntity(index);
189
                else
190
                        return null;
191
        }
192

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

    
213
                try {
214
                        dwg.read();
215
                } catch (DwgVersionNotSupportedException e1) {
216

    
217
                        String autodeskUrl = "<a href=\"http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=7024151\">"
218
                                        + "http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=7024151</a>";
219
//                        throw new InitializeDriverException(
220
//                                        formatString(
221
//                                                        "La version (%s) del fichero DWG '%s' no esta soportada por gvSIG.\n%s\n%s\n%s",
222
//                                                        new String[] { e1.getDwgVersion().toString(),
223
//                                                                        m_Fich.getName(),
224
//                                                                        Messages.getText("Probe_to_convert"),
225
//                                                                        Messages.getText("Autodesk_converter"),
226
//                                                                        autodeskUrl }));
227
                        String description=formatString(
228
                                        "La version (%s) del fichero DWG '%s' no esta soportada por gvSIG.\n%s\n%s\n%s",
229
                                        new String[] { e1.getDwgVersion().toString(),
230
                                                        m_Fich.getName(),
231
                                                        Messages.getText("Probe_to_convert"),
232
                                                        Messages.getText("Autodesk_converter"),
233
                                                        autodeskUrl });
234
                        throw new UnsupportedVersionDriverException(getName(),e1,description);
235
                } catch (IOException e) {
236
                        throw new InitializeDriverException(getName(),e);
237
                }
238

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

    
282
                
283
                boolean is3dFile = dwg.isDwg3DFile();
284
                try {
285
                        for (int i = 0; i < dwgObjects.size(); i++) {
286
                                DwgObject entity = (DwgObject) dwgObjects.get(i);
287

    
288
                                if (entity instanceof IDwg2FMap) {
289
                                        IDwg2FMap dwgEnt = (IDwg2FMap) entity;
290
                                        IGeometry geometry = dwgEnt.toFMapGeometry(is3dFile);
291
                                        if (geometry == null)
292
                                                continue;
293
                                        //we check for Region of Interest of the CAD file
294
                                        if(! checkRois(geometry))
295
                                                continue;
296
                                        
297
                                        String fmapStr = dwgEnt.toFMapString(is3dFile);
298
                                        // nombre del tipo de geometria fmap
299
                                        auxRow[ID_FIELD_FSHAPE] = ValueFactory.createValue(fmapStr);
300
                                        
301
                                        // indice del registro
302
                                        auxRow[ID_FIELD_ID] = ValueFactory.createValue(i);
303
                                        
304
                                        // nombre de entidad dwg
305
                                        auxRow[ID_FIELD_ENTITY] = ValueFactory.createValue(dwgEnt
306
                                                        .toString());
307
                                        String layerName = dwg.getLayerName(entity);
308
                                        auxRow[ID_FIELD_LAYER] = ValueFactory
309
                                                        .createValue(layerName);
310
                                        int colorByLayer = dwg.getColorByLayer(entity);
311
                                        
312
                                        int color = entity.getColor();
313
                                        if(color < 0)
314
                                                color = Math.abs(color);
315
                                        if(color > 255)
316
                                                color = colorByLayer;                                        
317
                                        auxRow[ID_FIELD_COLOR] = ValueFactory.createValue(color);
318

    
319
                                        auxRow[ID_FIELD_HEIGHTTEXT] = ValueFactory.createValue(0.0);
320
                                        auxRow[ID_FIELD_ROTATIONTEXT] = ValueFactory
321
                                                        .createValue(0.0);
322
                                        auxRow[ID_FIELD_TEXT] = ValueFactory.createNullValue();
323
                                        auxRow[ID_FIELD_THICKNESS] = ValueFactory.createValue(0.0);
324

    
325
                                        if (entity instanceof IDwg3DTestable) {
326
                                                auxRow[ID_FIELD_ELEVATION] = ValueFactory
327
                                                                .createValue(((IDwg3DTestable) entity).getZ());
328
                                        }
329

    
330
                                        if (entity instanceof DwgMText) {
331
                                                DwgMText mtext = (DwgMText) entity;
332
                                                auxRow[ID_FIELD_TEXT] = ValueFactory.createValue(mtext
333
                                                                .getText());
334
                                                auxRow[ID_FIELD_HEIGHTTEXT] = ValueFactory
335
                                                                .createValue(mtext.getHeight());
336
                                        } else if (entity instanceof DwgText) {
337
                                                DwgText text = (DwgText) entity;
338
                                                auxRow[ID_FIELD_TEXT] = ValueFactory.createValue(text
339
                                                                .getText());
340
                                                auxRow[ID_FIELD_THICKNESS] = ValueFactory
341
                                                                .createValue(text.getThickness());
342
                                                auxRow[ID_FIELD_HEIGHTTEXT] = ValueFactory
343
                                                                .createValue(text.getHeight());
344
                                                auxRow[ID_FIELD_ROTATIONTEXT] = ValueFactory
345
                                                                .createValue(Math.toDegrees(text
346
                                                                                .getRotationAngle()));
347
                                        }// if-else
348
                                        addGeometry(geometry, auxRow);
349
                                        
350
                                        if(debug)
351
                                                saveEntity(entity);
352

    
353
                                }
354
                        }// for
355

    
356
                } catch (Throwable t) {
357
                        t.printStackTrace();
358
                }
359
                dwgObjects = null;
360
                dwg = null;
361
                if(! debug)
362
                        dwg = null;
363
                System.gc();
364
                setSymbols();
365
        }
366
        
367
        /**
368
         * Sets a symbol for each dwg entity's derived feature based in
369
         * the DWG symbology info.
370
         * */
371
        private void setSymbols() throws InitializeDriverException{
372
                FSymbol myDefaultSymbol = new FSymbol(getShapeType());
373
                myDefaultSymbol.setShapeVisible(false);
374
                myDefaultSymbol.setFontSizeInPixels(false);
375
                myDefaultSymbol.setFont(new Font("SansSerif", Font.PLAIN, 9));
376
                myDefaultSymbol.setFontColor(Color.BLACK);
377
                myDefaultSymbol.setFontSize(heightText);
378
                myDefaultSymbol.setStyle(FConstant.SYMBOL_STYLE_DGNSPECIAL);
379
                myDefaultSymbol.setSize(3);
380
                myDefaultSymbol.setSizeInPixels(true);
381

    
382
                defaultLegend = LegendFactory
383
                                .createVectorialUniqueValueLegend(getShapeType());
384
                defaultLegend.setFieldName("Color");
385
                defaultLegend.setLabelField("Text");
386
                defaultLegend.setDefaultSymbol(myDefaultSymbol);
387
                defaultLegend.setLabelHeightField("HeightText");
388
                defaultLegend.setLabelRotationField("RotationText");
389

    
390
                ObjectDriver rs = this;
391
                IntValue clave;
392
                FSymbol theSymbol = null;
393
                try {
394
                        for (long j = 0; j < rs.getRowCount(); j++) {
395
                                clave = (IntValue) rs.getFieldValue(j, ID_FIELD_COLOR);
396
                                if (defaultLegend.getSymbolByValue(clave) == null) {
397
                                        theSymbol = new FSymbol(getShapeType());
398
                                        theSymbol.setDescription(clave.toString());
399
                                        theSymbol.setColor(AcadColor.getColor(clave.getValue()));
400
                                        // theSymbol.setFill(fillProv);
401
                                        // 050202, jmorell: Asigna los colores de Autocad a los
402
                                        // bordes
403
                                        // de los pol?gonos.
404
                                        theSymbol.setOutlineColor(AcadColor.getColor(clave
405
                                                        .getValue()));
406

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

    
465
        public String getFileVersion() {
466
                return fileVersion;
467
        }
468

    
469
        private String formatString(String fmt, String[] params) {
470
                String ret = fmt;
471
                for (int i = 0; i < params.length; i++) {
472
                        ret = ret.replaceFirst("%s", params[i]);
473
                }
474
                return ret;
475
        }
476

    
477
        
478
        /*
479
         * (non-Javadoc)
480
         * 
481
         * @see com.iver.cit.gvsig.fmap.drivers.MemoryDriver#accept(java.io.File)
482
         */
483
        public boolean accept(File f) {
484
                return f.getName().toUpperCase().endsWith("DWG");
485
        }
486

    
487
        /*
488
         * (non-Javadoc)
489
         * 
490
         * @see com.iver.cit.gvsig.fmap.drivers.MemoryDriver#getShapeType()
491
         */
492
        public int getShapeType() {
493
                return FShape.MULTI;
494
        }
495

    
496
        /*
497
         * (non-Javadoc)
498
         * 
499
         * @see com.iver.cit.gvsig.fmap.drivers.MemoryDriver#getName()
500
         */
501
        public String getName() {
502
                return "gvSIG DWG Memory Driver";
503
        }
504

    
505
        /*
506
         * (non-Javadoc)
507
         * 
508
         * @see com.iver.cit.gvsig.fmap.drivers.WithDefaultLegend#getDefaultLegend()
509
         */
510
        public Legend getDefaultLegend() {
511
                return defaultLegend;
512
        }
513

    
514
        /*
515
         * (non-Javadoc)
516
         * 
517
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getDriverAttributes()
518
         */
519
        public DriverAttributes getDriverAttributes() {
520
                return attr;
521
        }
522

    
523
        /*
524
         * (non-Javadoc)
525
         * 
526
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getPrimaryKeys()
527
         */
528
        public int[] getPrimaryKeys() {
529
                // TODO Auto-generated method stub
530
                return null;
531
        }
532

    
533
        /*
534
         * (non-Javadoc)
535
         * 
536
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#write(com.hardcode.gdbms.engine.data.edition.DataWare)
537
         */
538
        public void write(DataWare arg0)  {
539
                // TODO Auto-generated method stub
540

    
541
        }
542

    
543
        public void setDataSourceFactory(DataSourceFactory arg0) {
544
                // TODO Auto-generated method stub
545

    
546
        }
547

    
548
        public void close()  {
549
                // TODO Auto-generated method stub
550

    
551
        }
552

    
553
        public File getFile() {
554
                return m_Fich;
555
        }
556

    
557
        public boolean isWritable() {
558
                return m_Fich.canWrite();
559
        }
560

    
561

    
562
        public boolean isDebug() {
563
                return debug;
564
        }
565

    
566

    
567
        public void setDebug(boolean debug) {
568
                this.debug = debug;
569
        }
570
        
571
        public ILabelingStrategy getDefaultLabelingStrategy() {
572
                return labeling;
573
        }
574
}