Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.file / org.gvsig.fmap.dal.file.shp / src / main / java / org / gvsig / fmap / dal / store / shp / utils / SHPMultiLine.java @ 40435

History | View | Annotate | Download (12.6 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 org.gvsig.fmap.dal.store.shp.utils;
42

    
43
import java.awt.geom.PathIterator;
44
import java.nio.ByteBuffer;
45
import java.nio.MappedByteBuffer;
46
import java.util.ArrayList;
47
import java.util.List;
48

    
49
import org.gvsig.fmap.geom.Geometry;
50
import org.gvsig.fmap.geom.GeometryLocator;
51
import org.gvsig.fmap.geom.GeometryManager;
52
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
53
import org.gvsig.fmap.geom.Geometry.TYPES;
54
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
55
import org.gvsig.fmap.geom.exception.CreateGeometryException;
56
import org.gvsig.fmap.geom.primitive.Circle;
57
import org.gvsig.fmap.geom.primitive.Curve;
58
import org.gvsig.fmap.geom.primitive.Envelope;
59
import org.gvsig.fmap.geom.primitive.GeneralPathX;
60
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
61
import org.gvsig.fmap.geom.primitive.Point;
62
import org.gvsig.fmap.geom.primitive.Primitive;
63
import org.slf4j.Logger;
64
import org.slf4j.LoggerFactory;
65

    
66

    
67
/**
68
 * Elemento shape de tipo multil?nea.
69
 *
70
 * @author Vicente Caballero Navarro
71
 */
72
public class SHPMultiLine implements SHPShape {
73
        protected int m_type;
74
        protected int[] parts;
75
        protected Point[] points;
76
        protected double[] zs;
77
        //double flatness = 0.8; // Por ejemplo. Cuanto m?s peque?o, m?s segmentos necesitar? la curva
78
        private GeometryManager geomManager = GeometryLocator.getGeometryManager();
79
        private static final Logger logger = LoggerFactory.getLogger(SHPShape.class);
80

    
81
        /**
82
         * Crea un nuevo SHPMultiLine.
83
         */
84
        public SHPMultiLine() {
85
                m_type = SHP.POLYLINE2D;
86
        }
87

    
88
        /**
89
         * Crea un nuevo SHPMultiLine.
90
         *
91
         * @param type Tipo de multil?nea.
92
         *
93
         * @throws ShapefileException
94
         */
95
        public SHPMultiLine(int type) {
96
                if ((type != SHP.POLYLINE2D) &&
97
                                (type != SHP.POLYLINEM) &&
98
                                (type != SHP.POLYLINE3D)) {
99
//                        throw new ShapefileException("No es de tipo 3,13 ni 23");
100
                }
101

    
102
                m_type = type;
103
        }
104

    
105
        /**
106
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#getShapeType()
107
         */
108
        public int getShapeType() {
109
                return m_type;
110
        }
111

    
112
        /**
113
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#read(MappedByteBuffer, int)
114
         */
115
        public Geometry read(MappedByteBuffer buffer, int type) {
116
//                double minX = buffer.getDouble();
117
//                double minY = buffer.getDouble();
118
//                double maxX = buffer.getDouble();
119
//                double maxY = buffer.getDouble();
120
//                Rectangle2D rec = new Rectangle2D.Double(minX, minY, maxX - minX, maxY
121
//                                - maxY);
122

    
123
                int numParts = buffer.getInt();
124
                int numPoints = buffer.getInt(); //total number of points
125

    
126
                int[] partOffsets = new int[numParts];
127

    
128
                for (int i = 0; i < numParts; i++) {
129
                        partOffsets[i] = buffer.getInt();
130
                }
131

    
132
                Point[] points = new Point[numPoints];
133

    
134
                for (int t = 0; t < numPoints; t++) {
135
                        try {
136
                                points[t] = (Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM2D);
137
                                points[t].setX(buffer.getDouble());
138
                                points[t].setY(buffer.getDouble());
139
                        } catch (CreateGeometryException e) {
140
                                logger.error("Error creating a point",e);
141
                        }
142
                }
143

    
144
                /*   if (type == FConstant.SHAPE_TYPE_POLYLINEZ) {
145
                   //z min, max
146
                   buffer.position(buffer.position() + (2 * 8));
147
                   for (int t = 0; t < numPoints; t++) {
148
                       points[t].z = buffer.getDouble(); //z value
149
                   }
150
                   }
151
                 */
152
                Curve curve = null;
153
                try {
154
                        curve = (Curve)geomManager.create(TYPES.CURVE, SUBTYPES.GEOM2D);
155
                        curve.setGeneralPath(getGeneralPathX(points, partOffsets));
156
                } catch (CreateGeometryException e) {
157
                        logger.error("Error creating the curve",e);
158
                }
159
                return curve;
160
        }
161

    
162
        /**
163
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#write(ByteBuffer, IGeometry)
164
         */
165
        public void write(ByteBuffer buffer, Geometry geometry) {
166
                Envelope env = geometry.getEnvelope();
167

    
168
                buffer.putDouble(env.getMinimum(0));
169
                buffer.putDouble(env.getMinimum(1));
170
                buffer.putDouble(env.getMaximum(0));
171
                buffer.putDouble(env.getMaximum(1));
172
                int numParts = parts.length;
173
                int npoints = points.length;
174
                buffer.putInt(numParts);
175
                buffer.putInt(npoints);
176

    
177
                for (int i = 0; i < numParts; i++) {
178
                        buffer.putInt(parts[i]);
179
                }
180

    
181
                for (int t = 0; t < npoints; t++) {
182
                        buffer.putDouble(points[t].getX());
183
                        buffer.putDouble(points[t].getY());
184
                }
185

    
186
                  if (m_type == SHP.POLYLINE3D) {
187
                   double[] zExtreame = SHP.getZMinMax(zs);
188
                   if (Double.isNaN(zExtreame[0])) {
189
                       buffer.putDouble(0.0);
190
                       buffer.putDouble(0.0);
191
                   } else {
192
                       buffer.putDouble(zExtreame[0]);
193
                       buffer.putDouble(zExtreame[1]);
194
                   }
195
                   for (int t = 0; t < npoints; t++) {
196
                       double z = zs[t];
197
                       if (Double.isNaN(z)) {
198
                           buffer.putDouble(0.0);
199
                       } else {
200
                           buffer.putDouble(z);
201
                       }
202
                   }
203

    
204
                   }
205
                   if (m_type == SHP.POLYLINEM) {
206
                       buffer.putDouble(-10E40);
207
                       buffer.putDouble(-10E40);
208
                       for (int t = 0; t < npoints; t++) {
209
                           buffer.putDouble(-10E40);
210
                       }
211
                   }
212

    
213
        }
214

    
215
        /**
216
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#getLength(int)
217
         */
218
        public int getLength(Geometry fgeometry) {
219
                int numlines;
220
                int numpoints;
221
                int length;
222

    
223
                numlines = parts.length;
224
                numpoints = points.length;
225
                if (m_type == SHP.POLYLINE2D) {
226
                        length = 44 + (4 * numlines) + (numpoints * 16);
227
                } else if (m_type == SHP.POLYLINEM) {
228
                        length = 44 + (4 * numlines) + (numpoints * 16) +
229
                                (8 * numpoints) + 16;
230
                } else if (m_type == SHP.POLYLINE3D) {
231
                        length = 44 + (4 * numlines) + (numpoints * 16) +
232
                                (8 * numpoints) + 16;
233
                } else {
234
                        throw new IllegalStateException("Expected ShapeType of Arc, got " +
235
                                m_type);
236
                }
237

    
238
                return length;
239
        }
240

    
241
        /**
242
         * DOCUMENT ME!
243
         *
244
         * @param po DOCUMENT ME!
245
         * @param pa DOCUMENT ME!
246
         *
247
         * @return DOCUMENT ME!
248
         */
249
        protected GeneralPathX getGeneralPathX(Point[] po, int[] pa) {
250
                GeneralPathX gPX = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
251
                                po.length);
252
                int j = 0;
253

    
254
                for (int i = 0; i < po.length; i++) {
255
                        if (i == pa[j]) {
256
                                gPX.moveTo(po[i].getX(), po[i].getY());
257

    
258
                                if (j < (pa.length - 1)) {
259
                                        j++;
260
                                }
261
                        } else {
262
                                gPX.lineTo(po[i].getX(), po[i].getY());
263
                        }
264
                }
265

    
266
                return gPX;
267
        }
268

    
269
        /**
270
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#obtainsPoints(com.iver.cit.gvsig.fmap.core.GeneralPathXIterator)
271
         */
272
        public void obtainsPoints(Geometry g) {
273
                ArrayList arrayPoints = new ArrayList();
274
                ArrayList arrayParts = new ArrayList();
275
                ArrayList arrayZs = new ArrayList();
276
                
277
                boolean is3D = false;
278
                if ((SHP.POLYLINE3D == m_type) || (SHP.POLYGON3D == m_type)) {
279
                        if (g.getGeometryType().isTypeOf(Geometry.TYPES.AGGREGATE)) {
280
                                MultiPrimitive multiPrimitive = (MultiPrimitive)g;
281
                                int countVertex = 0;
282
                                for (int i = 0; i < multiPrimitive.getPrimitivesNumber(); i++) {
283
                                        OrientablePrimitive orientablePrimitive = (OrientablePrimitive)multiPrimitive.getPrimitiveAt(i);
284
                                        countVertex += orientablePrimitive.getNumVertices();
285
                                }
286
                                
287
                                zs = new double[countVertex];
288
                                int indexZS = 0;
289
                                for (int nPrimitive = 0; nPrimitive < multiPrimitive.getPrimitivesNumber(); nPrimitive++) {
290
                                        OrientablePrimitive orientablePrimitive = (OrientablePrimitive)multiPrimitive.getPrimitiveAt(nPrimitive);
291
                                        for (int nVertex = 0; nVertex < orientablePrimitive.getNumVertices(); nVertex++) {
292
                                                zs[indexZS] = orientablePrimitive.getCoordinateAt(nVertex, 2);
293
                                        }
294
                                }
295
                        } else {
296
                                OrientablePrimitive orientablePrimitive = (OrientablePrimitive)g;
297
                                zs = new double[orientablePrimitive.getNumVertices()];
298
                                for (int i = 0; i < zs.length; i++) {
299
                                        zs[i] = orientablePrimitive.getCoordinateAt(i, 2);
300
                                }
301
                        }
302
                        is3D = true;
303
                }
304

    
305
                
306
                if (g.getGeometryType().isTypeOf(Geometry.TYPES.AGGREGATE)) {
307
                    MultiPrimitive multiPrimitive = (MultiPrimitive)g;
308
                    int index = 0;
309
                    for (int i = 0; i < multiPrimitive.getPrimitivesNumber(); i++) {
310
                            index = obtainsPoints(
311
                                                    multiPrimitive.getPrimitiveAt(i), 
312
                                                    arrayPoints, 
313
                                                    arrayParts, 
314
                                                    arrayZs, 
315
                                                    is3D, 
316
                                                    index);
317
                    }
318
                }else{
319
                    obtainsPoints((Primitive)g, arrayPoints, arrayParts, arrayZs, is3D, 0);
320
                }        
321
                
322
                Integer[] integers = (Integer[]) arrayParts.toArray(new Integer[0]);
323
        parts = new int[integers.length];
324
        for (int i = 0; i < integers.length; i++) {
325
            parts[i] = integers[i].intValue();
326
        }
327
        if (arrayPoints == null) {
328
            points = new Point[0];
329
            return;
330
        }
331
        points = (Point[]) arrayPoints.toArray(new Point[0]);
332
        
333
        if (is3D) {
334
            Double[] doubleZs = (Double[])arrayZs.toArray(new Double[0]);
335
            zs = new double[doubleZs.length];
336
            for (int i = 0; i < doubleZs.length; i++){
337
                zs[i] = doubleZs[i].doubleValue();
338
            }
339
        }
340
        }
341
        
342
        private int obtainsPoints(Primitive primitive, List arrayPoints, List arrayParts, List arrayZs, boolean is3D, int index) {
343
                PathIterator theIterator = primitive.getPathIterator(null, geomManager.getFlatness());
344
                double[] theData = new double[6];
345
                java.awt.geom.Point2D pFirst = null;
346
                int pos = 0;
347
                                
348
                boolean first = true;
349
                
350
                Double firstZ = null;
351
                while (!theIterator.isDone()) {
352
                        int theType = theIterator.currentSegment(theData);
353
                        switch (theType) {
354
                                case PathIterator.SEG_MOVETO:
355
                                        if (first) {
356
                                                first = false;
357
                                        } else {
358
                                                if (m_type == SHP.POLYGON2D ||
359
                                                                m_type == SHP.POLYGON3D ||
360
                                                                m_type == SHP.POLYGONM) {
361
                                                        try {
362
                                                                Point point = geomManager.createPoint(pFirst.getX(), pFirst.getY(), SUBTYPES.GEOM2D);
363
                                                                if (!arrayPoints.get(arrayPoints.size()-1).equals(point)) {
364
                                                                        arrayPoints.add(point);
365
                                                                        if (is3D) {
366
                                                                                arrayZs.add(firstZ);
367
                                                                        }
368
                                                                }
369
                                                        } catch (CreateGeometryException e) {
370
                                                                logger.error("Error creating a point", e);
371
                                                        }
372
                                                }
373
                                        }
374
                                        arrayParts.add(new Integer(index));
375
                                        pFirst = new java.awt.geom.Point2D.Double(theData[0], theData[1]);
376
                                        try {
377
                                                arrayPoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
378
                                        } catch (CreateGeometryException e1) {
379
                                                logger.error("Error creating a point", e1);
380
                                        }
381
                                        if (is3D) {
382
                                                Double z = 0D;
383
                                                if(pos < zs.length)
384
                                                        z = new Double(zs[pos]);
385
                                                firstZ = z;
386
                                                arrayZs.add(z);
387
                                                pos++;
388
                                        }
389
                                        break;
390

    
391
                                case PathIterator.SEG_LINETO:
392
                                        try {
393
                                                arrayPoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
394
                                        } catch (CreateGeometryException e) {
395
                                                logger.error("Error creating a point", e);
396
                                        }
397
                                        if (is3D){
398
                                                Double z = 0D;
399
                                                if(pos < zs.length)
400
                                                        z = new Double(zs[pos]);
401
                                                arrayZs.add(z);
402
                                                pos++;
403
                                        }
404
                                        break;
405

    
406
                                case PathIterator.SEG_QUADTO:
407
                                        System.out.println("Not supported here");
408

    
409
                                        break;
410

    
411
                                case PathIterator.SEG_CUBICTO:
412
                                        System.out.println("Not supported here");
413

    
414
                                        break;
415

    
416
                                case PathIterator.SEG_CLOSE:
417
                                        try{
418
                                                Point point = geomManager.createPoint(pFirst.getX(), pFirst.getY(), SUBTYPES.GEOM2D);
419
                                                if (!arrayPoints.get(arrayPoints.size()-1).equals(point)) {
420
                                                        arrayPoints.add(point);
421
                                                        if (is3D) {
422
                                                                arrayZs.add(firstZ);
423
                                                        }
424
                                                        index++;
425
                                                }
426
                                        } catch (CreateGeometryException e) {
427
                                                logger.error("Error creating a point", e);
428
                                        }
429
                                        break;
430
                        } //end switch
431
                        if(theType != PathIterator.SEG_CLOSE)
432
                                index++;
433
                        theIterator.next();
434
                }
435
                return index;
436
        }
437
}