Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libDwg / src / com / iver / cit / jdwglib / dwg / objects / DwgPolyline2D.java @ 23458

History | View | Annotate | Download (17.7 KB)

1
/* jdwglib. Java Library for reading Dwg files.
2
 *
3
 * Author: Jose Morell Rama (jose.morell@gmail.com).
4
 * Port from the Pythoncad Dwg library by Art Haas.
5
 *
6
 * Copyright (C) 2005 Jose Morell, IVER TI S.A. and Generalitat Valenciana
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 * Jose Morell (jose.morell@gmail.com)
25
 *
26
 * or
27
 *
28
 * IVER TI S.A.
29
 *  C/Salamanca, 50
30
 *  46005 Valencia
31
 *  Spain
32
 *  +34 963163400
33
 *  dac@iver.es
34
 */
35
package com.iver.cit.jdwglib.dwg.objects;
36

    
37
import java.awt.Shape;
38
import java.awt.geom.GeneralPath;
39
import java.awt.geom.Point2D;
40
import java.util.ArrayList;
41
import java.util.List;
42
import java.util.Map;
43

    
44
import org.apache.log4j.Logger;
45

    
46
import org.gvsig.fmap.geom.Geometry;
47
import org.gvsig.fmap.geom.GeometryFactory;
48
import org.gvsig.fmap.geom.GeometryManager;
49
import org.gvsig.fmap.geom.primitive.Curve2D;
50
import org.gvsig.fmap.geom.primitive.GeneralPathX;
51

    
52
import com.iver.cit.jdwglib.dwg.DwgFile;
53
import com.iver.cit.jdwglib.dwg.DwgHandleReference;
54
import com.iver.cit.jdwglib.dwg.DwgObject;
55
import com.iver.cit.jdwglib.dwg.IDwg2FMap;
56
import com.iver.cit.jdwglib.dwg.IDwg3DTestable;
57
import com.iver.cit.jdwglib.dwg.IDwgBlockMember;
58
import com.iver.cit.jdwglib.dwg.IDwgExtrusionable;
59
import com.iver.cit.jdwglib.dwg.IDwgPolyline;
60
import com.iver.cit.jdwglib.dwg.IDwgVertex;
61
import com.iver.cit.jdwglib.util.AcadExtrusionCalculator;
62
import com.iver.cit.jdwglib.util.FMapUtil;
63
import com.iver.cit.jdwglib.util.GisModelCurveCalculator;
64

    
65
/**
66
 * The DwgPolyline2D class represents a DWG Polyline2D
67
 *
68
 * @author jmorell
69
 */
70
public class DwgPolyline2D extends DwgObject
71
        implements IDwgPolyline, IDwgExtrusionable, IDwg3DTestable, IDwg2FMap, IDwgBlockMember{
72

    
73
        private static Logger logger = Logger.getLogger(DwgPolyline2D.class.getName());
74

    
75
        private int flags;
76
        private int curveType;
77
        private double initWidth;
78
        private double endWidth;
79
        private double thickness;
80
        private double elevation;
81
        private double[] extrusion;
82
        private DwgHandleReference firstVertexHandle = null;
83
        private DwgHandleReference lastVertexHandle = null;
84
        private DwgHandleReference seqendHandle = null;
85
        private List vertices;
86
        private double[] bulges;
87
        private ArrayList vertexHandles;
88

    
89
        public DwgPolyline2D(int index) {
90
                super(index);
91
                vertices = new ArrayList();
92
                vertexHandles = new ArrayList();
93
        }
94
        /**
95
         * @return Returns the firstVertexHandle.
96
         */
97
        public DwgHandleReference getFirstVertexHandle() {
98
                return firstVertexHandle;
99
        }
100
        /**
101
         * @param firstVertexHandle The firstVertexHandle to set.
102
         */
103
        public void setFirstVertexHandle(DwgHandleReference firstVertexHandle) {
104
                this.firstVertexHandle = firstVertexHandle;
105
        }
106
        /**
107
         * @return Returns the flags.
108
         */
109
        public int getFlags() {
110
                return flags;
111
        }
112
        /**
113
         * @param flags The flags to set.
114
         */
115
        public void setFlags(int flags) {
116
                this.flags = flags;
117
        }
118
        /**
119
         * @return Returns the lastVertexHandle.
120
         */
121
        public DwgHandleReference getLastVertexHandle() {
122
                return lastVertexHandle;
123
        }
124
        /**
125
         * @param lastVertexHandle The lastVertexHandle to set.
126
         */
127
        public void setLastVertexHandle(DwgHandleReference lastVertexHandle) {
128
                this.lastVertexHandle = lastVertexHandle;
129
        }
130
        /**
131
         * @return Returns the pts.
132
         */
133
        public List getPts() {
134
                return vertices;
135
        }
136
        /**
137
         * @param pts The pts to set.
138
         */
139
        public void setPts(List pts) {
140
                this.vertices = pts;
141
        }
142
        /**
143
         * @return Returns the bulges.
144
         */
145
        public double[] getBulges() {
146
                return bulges;
147
        }
148
        /**
149
         * @param bulges The bulges to set.
150
         */
151
        public void setBulges(double[] bulges) {
152
                this.bulges = bulges;
153
        }
154
        /**
155
         * @return Returns the initWidth.
156
         */
157
        public double getInitWidth() {
158
                return initWidth;
159
        }
160
        /**
161
         * @param initWidth The initWidth to set.
162
         */
163
        public void setInitWidth(double initWidth) {
164
                this.initWidth = initWidth;
165
        }
166
        /**
167
         * @return Returns the seqendHandle.
168
         */
169
        public DwgHandleReference getSeqendHandle() {
170
                return seqendHandle;
171
        }
172
        /**
173
         * @param seqendHandle The seqendHandle to set.
174
         */
175
        public void setSeqendHandle(DwgHandleReference seqendHandle) {
176
                this.seqendHandle = seqendHandle;
177
        }
178
        /**
179
         * @return Returns the thickness.
180
         */
181
        public double getThickness() {
182
                return thickness;
183
        }
184
        /**
185
         * @param thickness The thickness to set.
186
         */
187
        public void setThickness(double thickness) {
188
                this.thickness = thickness;
189
        }
190
        /**
191
         * @return Returns the curveType.
192
         */
193
        public int getCurveType() {
194
                return curveType;
195
        }
196
        /**
197
         * @param curveType The curveType to set.
198
         */
199
        public void setCurveType(int curveType) {
200
                this.curveType = curveType;
201
        }
202
        /**
203
         * @return Returns the elevation.
204
         */
205
        public double getElevation() {
206
                return elevation;
207
        }
208
        /**
209
         * @param elevation The elevation to set.
210
         */
211
        public void setElevation(double elevation) {
212
                this.elevation = elevation;
213
        }
214
        /**
215
         * @return Returns the endWidth.
216
         */
217
        public double getEndWidth() {
218
                return endWidth;
219
        }
220
        /**
221
         * @param endWidth The endWidth to set.
222
         */
223
        public void setEndWidth(double endWidth) {
224
                this.endWidth = endWidth;
225
        }
226
        /**
227
         * @return Returns the extrusion.
228
         */
229
        public double[] getExtrusion() {
230
                return extrusion;
231
        }
232
        /**
233
         * @param extrusion The extrusion to set.
234
         */
235
        public void setExtrusion(double[] extrusion) {
236
                this.extrusion = extrusion;
237
        }
238

    
239
        /**
240
         * @param Handles The vertexHandles to set.
241
         */
242
        public void setVertexHandles(ArrayList handles){
243
                this.vertexHandles = handles;
244
        }
245

    
246
        /**
247
         * @return Returns the vertexHandles.
248
         */
249
        public ArrayList getVertexHandles(){
250
                return this.vertexHandles;
251
        }
252
        /**
253
         * @param Handle The vertexHandles to add.
254
         */
255
        public void addVertexHandle(DwgHandleReference handle){
256
                this.vertexHandles.add(handle);
257
        }
258

    
259

    
260
        public void calculateGisModel(DwgFile dwgFile){
261
                int flags = getFlags();
262
//                En este metodo se mantiene el mecanismo anterior
263
//                al refactoring de los handles references.
264
//                TODO: Pensar si deberiamos coger el handle completo.
265
//                Tal vez deberiamos tomar el handle completo y evaluar
266
//                a donde apuntan (pueden haber 2 handles con codigo y offset
267
//                distintos y que, sin embargo apunten al mismo objeto).
268

    
269
                ArrayList pts = new ArrayList();
270
                ArrayList bulges = new ArrayList();
271
                double[] pt = new double[3];
272
                double bulge = 0d;
273

    
274
                if(dwgFile.getDwgVersion().equalsIgnoreCase("Autocad R2004, R2005, R2006")){
275
                        ArrayList vertexHandles = getVertexHandles();
276
                        DwgObject seqend = null;
277
                        for (int i=0; i<vertexHandles.size(); i++){
278
                                DwgHandleReference vertice = (DwgHandleReference)vertexHandles.get(i);
279
                                DwgObject objVertex = dwgFile.getDwgObjectFromHandle(vertice.getOffset());
280
                                if (objVertex != null){
281
                                        if (objVertex instanceof DwgVertex2D) {
282
                                                pts.add(((DwgVertex2D)objVertex).getPoint());
283
                                                bulge = ((DwgVertex2D)objVertex).getBulge();
284
                                                bulges.add(new Double(bulge));
285
                                        } else {
286
                                                logger.warn("Encontrado un "+objVertex.getClass().getName()+" " +
287
                                                                "con indice "+i+" en la lista de vertices de Polyline2D");
288
                                        }
289
                                } else {
290
                                        logger.warn("No se ha encontrado el vertice "+i+" de "+vertexHandles.size()
291
                                                        +" de la Polyline2D "+this.getIndex());
292
                                        if (i==0){
293
                                                seqend = dwgFile.getDwgObjectFromHandle(seqendHandle.getOffset());
294
                                        }
295
                                }
296
                        }
297
                        if(seqend != null){
298
                                if (seqend instanceof DwgVertex2D) {
299
                                        pts.add(((DwgVertex2D)seqend).getPoint());
300
                                        bulge = ((DwgVertex2D)seqend).getBulge();
301
                                        bulges.add(new Double(bulge));
302
                                } else {
303
                                        logger.warn("Encontrado un "+seqend.getClass().getName()+" en seqend de Polyline2D "+
304
                                                        this.getIndex()+" cuando debería ser un DwgVertex2D");
305
                                }
306
                        }
307

    
308
                } else {
309
                        DwgHandleReference firstHandle = getFirstVertexHandle();
310
                        DwgHandleReference lastHandle = getLastVertexHandle();
311

    
312

    
313
                        DwgObject first = dwgFile.getDwgObjectFromHandle(firstHandle.getOffset());
314
                        DwgObject last = dwgFile.getDwgObjectFromHandle(lastHandle.getOffset());
315
                        if(first == null || last == null){
316
                                logger.warn("Polyline2D con vertices inicial o final a null");
317
                                return;
318
                        }
319

    
320
                        if(!(first instanceof DwgVertex2D)){
321
                                logger.warn("El primer vertice de Polyline2D es "+
322
                                                first.getClass().getName());
323
                                return;
324
                        }
325

    
326
                        if(!(last instanceof DwgVertex2D)){
327
                                logger.warn("El primer vertice de Polyline2D es "+
328
                                                first.getClass().getName());
329
                                return;
330
                        }
331

    
332
                        int firstObjIdx = dwgFile.getIndexOf(first);
333
                        int lastObjIdx =  dwgFile.getIndexOf(last);
334
                        if(firstObjIdx == -1 || lastObjIdx == -1){
335
                                logger.warn("Calculate GIS Model: Problemas en la LinkedList: 1�="+firstObjIdx+",Ultimo="+lastObjIdx);
336
                                return;
337
                        }
338

    
339
//                        pt = ((DwgVertex2D)first).getPoint();
340
//                        pts.add(new Point2D.Double(pt[0], pt[1]));
341
//                        bulge = ((DwgVertex2D)first).getBulge();
342
//                        bulges.add(new Double(bulge));
343

    
344
                        for(int i = firstObjIdx; i <= lastObjIdx; i++){
345
                                DwgObject obj = dwgFile.getDwgObject(i);
346
                                if(obj instanceof DwgVertex2D){
347
                                        DwgVertex2D vertex = (DwgVertex2D) obj;
348
                                        pt = vertex.getPoint();
349
                                        pts.add(new Point2D.Double(pt[0], pt[1]));
350
                                        bulge = vertex.getBulge();
351
                                        bulges.add(new Double(bulge));
352
                                }else{
353
                                        logger.warn("Encontrado "+obj.getClass().getName()+" en la lista de vertices de Polyline2D");
354
                                }
355
                        }//for
356
                }
357

    
358
                if (pts.size()>0) {
359
                        List newPts = new ArrayList();
360
                        if ((flags & 0x1)==0x1) {
361
                                for (int j=0;j<pts.size();j++) {
362
                                        newPts.add(pts.get(j));
363
                                }
364
                                newPts.add(pts.get(0));
365
                                bulges.add(new Double(0));
366
                        } else {
367
                                for (int j=0;j<pts.size();j++) {
368
                                        newPts.add(pts.get(j));
369
                                }
370
                        }
371
                        double[] bs = new double[bulges.size()];
372
                        for (int j=0;j<bulges.size();j++) {
373
                                bs[j] = ((Double)bulges.get(j)).doubleValue();
374
                        }
375
                        setBulges(bs);
376
                        List points = GisModelCurveCalculator.
377
                        calculateGisModelBulge(newPts, bs);
378
                        setPts(points);
379
                } else {
380
                        logger.warn("Encontrada polilínea sin puntos ...");
381
                        // TODO: No se debe mandar nunca una polil�nea sin puntos, si esto
382
                        // ocurre es porque existe un error que hay que corregir ...
383
                }
384
        }
385
        //TODO Este metodo es antiguo y MUY INEFICIENTE
386
        //No obstante lo dejo porque hace referencia a SeqEnd y a un posible bug
387
        public void calculateGisModel(List dwgObjects) {
388
                int flags = getFlags();
389
//                En estas dos lineas de abajo y en el resto del metodo
390
//                se mantiene el mecanismo anterior al refactoring.
391
//                TODO: Pensar si deberiamos coger el handle completo.
392
//                Tal vez deberiamos tomar el handle completo y evaluar
393
//                a donde apuntan (pueden haber 2 handles con codigo y offset
394
//                distintos y que, sin embargo apunten al mismo objeto).
395
                int firstHandle = getFirstVertexHandle().getOffset();
396
                int lastHandle = getLastVertexHandle().getOffset();
397
                ArrayList pts = new ArrayList();
398
                ArrayList bulges = new ArrayList();
399
                double[] pt = new double[3];
400

    
401
                //TODO Esto cambiarlo. Es lento y poco elegante
402

    
403
                for (int j=0;j<dwgObjects.size();j++) {
404
                        DwgObject firstVertex = (DwgObject)dwgObjects.get(j);
405

    
406
                        if (firstVertex instanceof DwgVertex2D) {
407
                                int vertexHandle = firstVertex.getHandle().getOffset();
408
                                if (vertexHandle==firstHandle) {
409
                                        int k=0;
410
                                        while (true) {
411
                                                DwgObject vertex = (DwgObject)dwgObjects.get(j+k);
412
                                                int vHandle = vertex.getHandle().getOffset();
413
                                                if (vertex instanceof DwgVertex2D) {
414
                                                        pt = ((DwgVertex2D)vertex).getPoint();
415
                                                        pts.add(new Point2D.Double(pt[0], pt[1]));
416
                                                        double bulge = ((DwgVertex2D)vertex).getBulge();
417
                                                        bulges.add(new Double(bulge));
418
                                                        k++;
419
                                                        if (vHandle==lastHandle && vertex instanceof DwgVertex2D) {
420
                                                                break;
421
                                                        }
422
                                                } else if (vertex instanceof DwgSeqend) {
423
                            // 051116, jmorell: Polil�neas_ACAD2000.dwg tiene un DwgSeqend en mitad de
424
                            //una secuencia de v�rtices. Precauci�n con esto puesto que es posible que esta
425
                            // condici�n fuera requerida en la carga de otros DWGs.
426
                            //break;
427
                            k++;
428
                                                }
429
                                        }//while
430
                                }//if first handle
431
                        }//if
432
                }//for
433

    
434
                if (pts.size()>0) {
435
                        List newPts = new ArrayList();
436
                        if ((flags & 0x1)==0x1) {
437
                                for (int j=0;j<pts.size();j++) {
438
                                        newPts.add(pts.get(j));
439
                                }
440
                                newPts.add(pts.get(0));
441
                                bulges.add(new Double(0));
442
                        } else {
443
                                for (int j=0;j<pts.size();j++) {
444
                                        newPts.add(pts.get(j));
445
                                }
446
                        }
447
                        double[] bs = new double[bulges.size()];
448
                        for (int j=0;j<bulges.size();j++) {
449
                                bs[j] = ((Double)bulges.get(j)).doubleValue();
450
                        }
451
                        setBulges(bs);
452
                        List points = GisModelCurveCalculator.
453
                                        calculateGisModelBulge(newPts, bs);
454
                        setPts(points);
455
                } else {
456
//                        System.out.println("Encontrada polil�nea sin puntos ...");
457
                        // TODO: No se debe mandar nunca una polil�nea sin puntos, si esto
458
                        // ocurre es porque existe un error que hay que corregir ...
459
                }
460
        }
461
        /* (non-Javadoc)
462
         * @see com.iver.cit.jdwglib.dwg.IDwgExtrusionable#applyExtrussion()
463
         */
464
        public void applyExtrussion() {
465
                  if(getPts() == null)
466
                        return;
467
                  List vertices = getPts();
468
              double[] polyline2DExt = getExtrusion();
469
              double elev = getElevation();
470
              double[][] polylinePoints3D = new double[vertices.size()][3];
471
              for (int j = 0;j < vertices.size(); j++) {
472
                  polylinePoints3D[j][0] = ((double[])vertices.get(j))[0];
473
                  polylinePoints3D[j][1] = ((double[])vertices.get(j))[1];
474
                  polylinePoints3D[j][2] = elev;
475
                  polylinePoints3D[j] = AcadExtrusionCalculator.extrude2(polylinePoints3D[j], polyline2DExt);
476
              }
477
              setElevation(elev);
478
              for (int j=0;j<vertices.size();j++) {
479
                  vertices.add(new double[]{((double[])polylinePoints3D[j])[0], ((double[])polylinePoints3D[j])[1]});
480
              }
481
              setPts(vertices);
482
        }
483
        /* (non-Javadoc)
484
         * @see com.iver.cit.jdwglib.dwg.IDwg3DTestable#has3DData()
485
         */
486
        public boolean has3DData() {
487
                return (getElevation() != 0.0);
488
        }
489
        /* (non-Javadoc)
490
         * @see com.iver.cit.jdwglib.dwg.IDwg3DTestable#getZ()
491
         */
492
        public double getZ() {
493
                return getElevation();
494
        }
495
        /* (non-Javadoc)
496
         * @see com.iver.cit.jdwglib.dwg.IDwg2FMap#toFMapGeometry(boolean)
497
         */
498
        public Geometry toFMapGeometry(boolean is3DFile) {
499
                GeometryFactory gFactory = GeometryManager.getInstance().getGeometryFactory();
500
                List vertices = getPts();
501
                double elev = getElevation();
502

    
503
                if (vertices != null){
504
                        GeneralPathX gp = new GeneralPathX();
505
                        for (int i = 0; i < vertices.size(); i++) {
506
                                Object vertice = vertices.get(i);
507
                                if(i==0){
508
                                        if(vertice instanceof double[]){
509
                                                gp.moveTo(new Double(((double[])vertice)[0]).floatValue(),new Double(((double[])vertice)[1]).floatValue());
510
                                        } else if (vertice instanceof Point2D){
511
                                                gp.moveTo(new Double(((Point2D)vertice).getX()).floatValue(),
512
                                                                new Double(((Point2D)vertice).getY()).floatValue());
513
                                        }
514
                                } else {
515

    
516
                                        if(vertice instanceof double[]){
517
                                                gp.lineTo(new Double(((double[])vertice)[0]).floatValue(),new Double(((double[])vertice)[1]).floatValue());
518
                                        } else if (vertice instanceof Point2D){
519
                                                gp.lineTo(new Double(((Point2D)vertice).getX()).floatValue(),
520
                                                                new Double(((Point2D)vertice).getY()).floatValue());
521
                                        }
522
                                }
523
                        }
524
                        if (is3DFile) {
525
                                return gFactory.createPolyline3D(gp,new double[] {elev});
526
                        } else {
527
                                return gFactory.createPolyline2D(gp);
528
                        }
529
                } else {
530
                        return null;
531
                }
532
        }
533
        /* (non-Javadoc)
534
         * @see com.iver.cit.jdwglib.dwg.IDwg2FMap#toFMapString(boolean)
535
         */
536
        public String toFMapString(boolean is3DFile) {
537
                if(is3DFile)
538
                        return "FPolyline3D";
539
                else
540
                        return "FPolyline2D";
541
        }
542

    
543
        public String toString(){
544
                return "Polyline2D";
545
        }
546
        public void transform2Block(double[] bPoint, Point2D insPoint,
547
                        double[] scale, double rot,
548
                        List dwgObjectsWithoutBlocks,
549
                        Map handleObjWithoutBlocks, DwgFile callBack) {
550

    
551
                DwgPolyline2D transformedEntity = null;
552
                List vertices = this.getPts();
553

    
554
                if (vertices != null) {
555
                    List transformedVertices = new ArrayList();
556
                        for (int i=0;i < vertices.size();i++) {
557
                                double[] pointAux = null;
558
                            pointAux = new double[]{((double[]) vertices.get(i))[0] - bPoint[0],
559
                                            ((double[]) vertices.get(i))[1] - bPoint[1]};
560

    
561
                                double laX = insPoint.getX() + ((pointAux[0] * scale[0])*Math.cos(rot) + (pointAux[1]*scale[1])*(-1)*Math.sin(rot));
562
                                double laY = insPoint.getY() + ((pointAux[0]*scale[0])*Math.sin(rot) + (pointAux[1]*scale[1])*Math.cos(rot));
563
                                transformedVertices.add(new double[]{laX, laY});
564
                        }//for
565
                        transformedEntity = (DwgPolyline2D)this.clone();
566
                        transformedEntity.setPts(transformedVertices);
567
                        transformedEntity.setElevation((this.getElevation() * scale[2]));
568
                        dwgObjectsWithoutBlocks.add(transformedEntity);
569
                        handleObjWithoutBlocks.put(new Integer(transformedEntity.getHandle().getOffset()), transformedEntity);
570
                }
571
        }
572
        /* (non-Javadoc)
573
         * @see java.lang.Object#clone()
574
         */
575
        public Object clone(){
576
                DwgPolyline2D obj = new DwgPolyline2D(index);
577
                this.fill(obj);
578
                return obj;
579
        }
580

    
581
        protected void fill(DwgObject obj){
582
                super.fill(obj);
583
                DwgPolyline2D myObj = (DwgPolyline2D)obj;
584

    
585
                myObj.setBulges(bulges);
586
                myObj.setCurveType(curveType);
587
                myObj.setElevation(elevation);
588
                myObj.setEndWidth(endWidth);
589
                myObj.setExtrusion(extrusion);
590
                myObj.setFirstVertexHandle(firstVertexHandle);
591
                myObj.setFlags(flags);
592
                myObj.setInitWidth(initWidth);
593
                myObj.setLastVertexHandle(lastVertexHandle);
594
                myObj.setPts(vertices);
595
                myObj.setSeqendHandle(seqendHandle);
596
                myObj.setThickness(thickness);
597

    
598
        }
599
        public void addVertex(IDwgVertex vertex) {
600
                vertices.add(vertex.getPoint());
601
        }
602
}