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 @ 40559

History | View | Annotate | Download (12.3 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.dal.store.shp.utils;
25

    
26
import java.awt.geom.PathIterator;
27
import java.nio.ByteBuffer;
28
import java.nio.MappedByteBuffer;
29
import java.util.ArrayList;
30
import java.util.List;
31

    
32
import org.gvsig.fmap.geom.Geometry;
33
import org.gvsig.fmap.geom.GeometryLocator;
34
import org.gvsig.fmap.geom.GeometryManager;
35
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
36
import org.gvsig.fmap.geom.Geometry.TYPES;
37
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
38
import org.gvsig.fmap.geom.exception.CreateGeometryException;
39
import org.gvsig.fmap.geom.primitive.Circle;
40
import org.gvsig.fmap.geom.primitive.Curve;
41
import org.gvsig.fmap.geom.primitive.Envelope;
42
import org.gvsig.fmap.geom.primitive.GeneralPathX;
43
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
44
import org.gvsig.fmap.geom.primitive.Point;
45
import org.gvsig.fmap.geom.primitive.Primitive;
46
import org.slf4j.Logger;
47
import org.slf4j.LoggerFactory;
48

    
49

    
50
/**
51
 * Elemento shape de tipo multil?nea.
52
 *
53
 * @author Vicente Caballero Navarro
54
 */
55
public class SHPMultiLine implements SHPShape {
56
        protected int m_type;
57
        protected int[] parts;
58
        protected Point[] points;
59
        protected double[] zs;
60
        //double flatness = 0.8; // Por ejemplo. Cuanto m?s peque?o, m?s segmentos necesitar? la curva
61
        private GeometryManager geomManager = GeometryLocator.getGeometryManager();
62
        private static final Logger logger = LoggerFactory.getLogger(SHPShape.class);
63

    
64
        /**
65
         * Crea un nuevo SHPMultiLine.
66
         */
67
        public SHPMultiLine() {
68
                m_type = SHP.POLYLINE2D;
69
        }
70

    
71
        /**
72
         * Crea un nuevo SHPMultiLine.
73
         *
74
         * @param type Tipo de multil?nea.
75
         *
76
         * @throws ShapefileException
77
         */
78
        public SHPMultiLine(int type) {
79
                if ((type != SHP.POLYLINE2D) &&
80
                                (type != SHP.POLYLINEM) &&
81
                                (type != SHP.POLYLINE3D)) {
82
//                        throw new ShapefileException("No es de tipo 3,13 ni 23");
83
                }
84

    
85
                m_type = type;
86
        }
87

    
88
        /**
89
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#getShapeType()
90
         */
91
        public int getShapeType() {
92
                return m_type;
93
        }
94

    
95
        /**
96
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#read(MappedByteBuffer, int)
97
         */
98
        public Geometry read(MappedByteBuffer buffer, int type) {
99
//                double minX = buffer.getDouble();
100
//                double minY = buffer.getDouble();
101
//                double maxX = buffer.getDouble();
102
//                double maxY = buffer.getDouble();
103
//                Rectangle2D rec = new Rectangle2D.Double(minX, minY, maxX - minX, maxY
104
//                                - maxY);
105

    
106
                int numParts = buffer.getInt();
107
                int numPoints = buffer.getInt(); //total number of points
108

    
109
                int[] partOffsets = new int[numParts];
110

    
111
                for (int i = 0; i < numParts; i++) {
112
                        partOffsets[i] = buffer.getInt();
113
                }
114

    
115
                Point[] points = new Point[numPoints];
116

    
117
                for (int t = 0; t < numPoints; t++) {
118
                        try {
119
                                points[t] = (Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM2D);
120
                                points[t].setX(buffer.getDouble());
121
                                points[t].setY(buffer.getDouble());
122
                        } catch (CreateGeometryException e) {
123
                                logger.error("Error creating a point",e);
124
                        }
125
                }
126

    
127
                /*   if (type == FConstant.SHAPE_TYPE_POLYLINEZ) {
128
                   //z min, max
129
                   buffer.position(buffer.position() + (2 * 8));
130
                   for (int t = 0; t < numPoints; t++) {
131
                       points[t].z = buffer.getDouble(); //z value
132
                   }
133
                   }
134
                 */
135
                Curve curve = null;
136
                try {
137
                        curve = (Curve)geomManager.create(TYPES.CURVE, SUBTYPES.GEOM2D);
138
                        curve.setGeneralPath(getGeneralPathX(points, partOffsets));
139
                } catch (CreateGeometryException e) {
140
                        logger.error("Error creating the curve",e);
141
                }
142
                return curve;
143
        }
144

    
145
        /**
146
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#write(ByteBuffer, IGeometry)
147
         */
148
        public void write(ByteBuffer buffer, Geometry geometry) {
149
                Envelope env = geometry.getEnvelope();
150

    
151
                buffer.putDouble(env.getMinimum(0));
152
                buffer.putDouble(env.getMinimum(1));
153
                buffer.putDouble(env.getMaximum(0));
154
                buffer.putDouble(env.getMaximum(1));
155
                int numParts = parts.length;
156
                int npoints = points.length;
157
                buffer.putInt(numParts);
158
                buffer.putInt(npoints);
159

    
160
                for (int i = 0; i < numParts; i++) {
161
                        buffer.putInt(parts[i]);
162
                }
163

    
164
                for (int t = 0; t < npoints; t++) {
165
                        buffer.putDouble(points[t].getX());
166
                        buffer.putDouble(points[t].getY());
167
                }
168

    
169
                  if (m_type == SHP.POLYLINE3D) {
170
                   double[] zExtreame = SHP.getZMinMax(zs);
171
                   if (Double.isNaN(zExtreame[0])) {
172
                       buffer.putDouble(0.0);
173
                       buffer.putDouble(0.0);
174
                   } else {
175
                       buffer.putDouble(zExtreame[0]);
176
                       buffer.putDouble(zExtreame[1]);
177
                   }
178
                   for (int t = 0; t < npoints; t++) {
179
                       double z = zs[t];
180
                       if (Double.isNaN(z)) {
181
                           buffer.putDouble(0.0);
182
                       } else {
183
                           buffer.putDouble(z);
184
                       }
185
                   }
186

    
187
                   }
188
                   if (m_type == SHP.POLYLINEM) {
189
                       buffer.putDouble(-10E40);
190
                       buffer.putDouble(-10E40);
191
                       for (int t = 0; t < npoints; t++) {
192
                           buffer.putDouble(-10E40);
193
                       }
194
                   }
195

    
196
        }
197

    
198
        /**
199
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#getLength(int)
200
         */
201
        public int getLength(Geometry fgeometry) {
202
                int numlines;
203
                int numpoints;
204
                int length;
205

    
206
                numlines = parts.length;
207
                numpoints = points.length;
208
                if (m_type == SHP.POLYLINE2D) {
209
                        length = 44 + (4 * numlines) + (numpoints * 16);
210
                } else if (m_type == SHP.POLYLINEM) {
211
                        length = 44 + (4 * numlines) + (numpoints * 16) +
212
                                (8 * numpoints) + 16;
213
                } else if (m_type == SHP.POLYLINE3D) {
214
                        length = 44 + (4 * numlines) + (numpoints * 16) +
215
                                (8 * numpoints) + 16;
216
                } else {
217
                        throw new IllegalStateException("Expected ShapeType of Arc, got " +
218
                                m_type);
219
                }
220

    
221
                return length;
222
        }
223

    
224
        /**
225
         * DOCUMENT ME!
226
         *
227
         * @param po DOCUMENT ME!
228
         * @param pa DOCUMENT ME!
229
         *
230
         * @return DOCUMENT ME!
231
         */
232
        protected GeneralPathX getGeneralPathX(Point[] po, int[] pa) {
233
                GeneralPathX gPX = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
234
                                po.length);
235
                int j = 0;
236

    
237
                for (int i = 0; i < po.length; i++) {
238
                        if (i == pa[j]) {
239
                                gPX.moveTo(po[i].getX(), po[i].getY());
240

    
241
                                if (j < (pa.length - 1)) {
242
                                        j++;
243
                                }
244
                        } else {
245
                                gPX.lineTo(po[i].getX(), po[i].getY());
246
                        }
247
                }
248

    
249
                return gPX;
250
        }
251

    
252
        /**
253
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#obtainsPoints(com.iver.cit.gvsig.fmap.core.GeneralPathXIterator)
254
         */
255
        public void obtainsPoints(Geometry g) {
256
                ArrayList arrayPoints = new ArrayList();
257
                ArrayList arrayParts = new ArrayList();
258
                ArrayList arrayZs = new ArrayList();
259
                
260
                boolean is3D = false;
261
                if ((SHP.POLYLINE3D == m_type) || (SHP.POLYGON3D == m_type)) {
262
                        if (g.getGeometryType().isTypeOf(Geometry.TYPES.AGGREGATE)) {
263
                                MultiPrimitive multiPrimitive = (MultiPrimitive)g;
264
                                int countVertex = 0;
265
                                for (int i = 0; i < multiPrimitive.getPrimitivesNumber(); i++) {
266
                                        OrientablePrimitive orientablePrimitive = (OrientablePrimitive)multiPrimitive.getPrimitiveAt(i);
267
                                        countVertex += orientablePrimitive.getNumVertices();
268
                                }
269
                                
270
                                zs = new double[countVertex];
271
                                int indexZS = 0;
272
                                for (int nPrimitive = 0; nPrimitive < multiPrimitive.getPrimitivesNumber(); nPrimitive++) {
273
                                        OrientablePrimitive orientablePrimitive = (OrientablePrimitive)multiPrimitive.getPrimitiveAt(nPrimitive);
274
                                        for (int nVertex = 0; nVertex < orientablePrimitive.getNumVertices(); nVertex++) {
275
                                                zs[indexZS] = orientablePrimitive.getCoordinateAt(nVertex, 2);
276
                                        }
277
                                }
278
                        } else {
279
                                OrientablePrimitive orientablePrimitive = (OrientablePrimitive)g;
280
                                zs = new double[orientablePrimitive.getNumVertices()];
281
                                for (int i = 0; i < zs.length; i++) {
282
                                        zs[i] = orientablePrimitive.getCoordinateAt(i, 2);
283
                                }
284
                        }
285
                        is3D = true;
286
                }
287

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

    
374
                                case PathIterator.SEG_LINETO:
375
                                        try {
376
                                                arrayPoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
377
                                        } catch (CreateGeometryException e) {
378
                                                logger.error("Error creating a point", e);
379
                                        }
380
                                        if (is3D){
381
                                                Double z = 0D;
382
                                                if(pos < zs.length)
383
                                                        z = new Double(zs[pos]);
384
                                                arrayZs.add(z);
385
                                                pos++;
386
                                        }
387
                                        break;
388

    
389
                                case PathIterator.SEG_QUADTO:
390
                                        System.out.println("Not supported here");
391

    
392
                                        break;
393

    
394
                                case PathIterator.SEG_CUBICTO:
395
                                        System.out.println("Not supported here");
396

    
397
                                        break;
398

    
399
                                case PathIterator.SEG_CLOSE:
400
                                        try{
401
                                                Point point = geomManager.createPoint(pFirst.getX(), pFirst.getY(), SUBTYPES.GEOM2D);
402
                                                if (!arrayPoints.get(arrayPoints.size()-1).equals(point)) {
403
                                                        arrayPoints.add(point);
404
                                                        if (is3D) {
405
                                                                arrayZs.add(firstZ);
406
                                                        }
407
                                                        index++;
408
                                                }
409
                                        } catch (CreateGeometryException e) {
410
                                                logger.error("Error creating a point", e);
411
                                        }
412
                                        break;
413
                        } //end switch
414
                        if(theType != PathIterator.SEG_CLOSE)
415
                                index++;
416
                        theIterator.next();
417
                }
418
                return index;
419
        }
420
}