Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_dalfile / src / org / gvsig / fmap / dal / store / shp / utils / SHPMultiLine.java @ 29041

History | View | Annotate | Download (10.9 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

    
48
import org.gvsig.fmap.geom.Geometry;
49
import org.gvsig.fmap.geom.GeometryLocator;
50
import org.gvsig.fmap.geom.GeometryManager;
51
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
52
import org.gvsig.fmap.geom.Geometry.TYPES;
53
import org.gvsig.fmap.geom.exception.CreateGeometryException;
54
import org.gvsig.fmap.geom.primitive.Curve;
55
import org.gvsig.fmap.geom.primitive.Envelope;
56
import org.gvsig.fmap.geom.primitive.GeneralPathX;
57
import org.gvsig.fmap.geom.primitive.Point;
58
import org.gvsig.fmap.geom.primitive.Surface;
59
import org.gvsig.fmap.geom.util.Converter;
60
import org.slf4j.Logger;
61
import org.slf4j.LoggerFactory;
62

    
63

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

    
78
        /**
79
         * Crea un nuevo SHPMultiLine.
80
         */
81
        public SHPMultiLine() {
82
                m_type = SHP.POLYLINE2D;
83
        }
84

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

    
99
                m_type = type;
100
        }
101

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

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

    
120
                int numParts = buffer.getInt();
121
                int numPoints = buffer.getInt(); //total number of points
122

    
123
                int[] partOffsets = new int[numParts];
124

    
125
                for (int i = 0; i < numParts; i++) {
126
                        partOffsets[i] = buffer.getInt();
127
                }
128

    
129
                Point[] points = new Point[numPoints];
130

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

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

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

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

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

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

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

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

    
211
        }
212

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

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

    
236
                return length;
237
        }
238

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

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

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

    
264
                return gPX;
265
        }
266

    
267
        /**
268
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#obtainsPoints(com.iver.cit.gvsig.fmap.core.GeneralPathXIterator)
269
         */
270
        public void obtainsPoints(Geometry g) {
271
                boolean is3D=false;
272
                if (SHP.POLYLINE3D == m_type){
273
                        Curve curve = (Curve)g;
274
                        zs = new double[curve.getNumVertices()];
275
                        for (int i=0 ; i<zs.length ; i++){
276
                                zs[i] = curve.getCoordinateAt(i, 2);
277
                        }
278
                        is3D=true;
279
                }else if (SHP.POLYGON3D == m_type){
280
                        Surface surface = (Surface)g;
281
                        zs = new double[surface.getNumVertices()];
282
                        for (int i=0 ; i<zs.length ; i++){
283
                                zs[i] = surface.getCoordinateAt(i, 2);
284
                        }
285
                        is3D=true;
286
                }
287
                ArrayList arrayPoints = null;
288
                ArrayList arrayParts = new ArrayList();
289
                PathIterator theIterator = g.getPathIterator(null, Converter.FLATNESS); //polyLine.getPathIterator(null, flatness);
290
                double[] theData = new double[6];
291
                int numParts = 0;
292
                java.awt.geom.Point2D pFirst=null;
293
                int pos=0;
294
                ArrayList arrayZs=new ArrayList();
295
                Double firstZ = null;
296
                while (!theIterator.isDone()) {
297
                        int theType = theIterator.currentSegment(theData);
298
                        switch (theType) {
299
                                case PathIterator.SEG_MOVETO:
300
                                        if (arrayPoints == null) {
301
                                                arrayPoints = new ArrayList();
302
                                                arrayParts.add(new Integer(0));
303
                                        } else {
304
                                                if (m_type==SHP.POLYGON2D ||
305
                                                                m_type==SHP.POLYGON3D ||
306
                                                                m_type==SHP.POLYGONM){
307
                                                        try {
308
                                                                Point point=geomManager.createPoint(pFirst.getX(), pFirst.getY(), SUBTYPES.GEOM2D);
309
                                                                if (!arrayPoints.get(arrayPoints.size()-1).equals(point)){
310
                                                                        arrayPoints.add(point);
311
                                                                        if (is3D){
312
                                                                                arrayZs.add(firstZ);
313
                                                                        }
314
                                                                }
315
                                                        } catch (CreateGeometryException e) {
316
                                                                logger.error("Error creating a point", e);
317
                                                        }
318
                                                }
319
                                                arrayParts.add(new Integer(arrayPoints.size()));
320
                                        }
321

    
322
                                        numParts++;
323
                                        pFirst=new java.awt.geom.Point2D.Double(theData[0], theData[1]);
324
                                        try {
325
                                                arrayPoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
326
                                        } catch (CreateGeometryException e1) {
327
                                                logger.error("Error creating a point", e1);
328
                                        }
329
                                        if (is3D){
330
                                                firstZ=new Double(zs[pos]);
331
                                                arrayZs.add(new Double(zs[pos]));
332
                                                pos++;
333
                                        }
334
                                        break;
335

    
336
                                case PathIterator.SEG_LINETO:
337
                                        try {
338
                                                arrayPoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
339
                                        } catch (CreateGeometryException e) {
340
                                                logger.error("Error creating a point", e);
341
                                        }
342
                                        if (is3D){
343
                                                arrayZs.add(new Double(zs[pos]));
344
                                                pos++;
345
                                        }
346
                                        break;
347

    
348
                                case PathIterator.SEG_QUADTO:
349
                                        System.out.println("Not supported here");
350

    
351
                                        break;
352

    
353
                                case PathIterator.SEG_CUBICTO:
354
                                        System.out.println("Not supported here");
355

    
356
                                        break;
357

    
358
                                case PathIterator.SEG_CLOSE:
359
                                        try{
360
                                                Point point=geomManager.createPoint(pFirst.getX(), pFirst.getY(), SUBTYPES.GEOM2D);
361
                                                if (!arrayPoints.get(arrayPoints.size()-1).equals(point)){
362
                                                        arrayPoints.add(point);
363
                                                        if (is3D){
364
                                                                arrayZs.add(firstZ);
365
                                                        }
366
                                                }
367
                                        } catch (CreateGeometryException e) {
368
                                                logger.error("Error creating a point", e);
369
                                        }
370
                                        break;
371
                        } //end switch
372
                        theIterator.next();
373
                }
374
                Integer[] integers = (Integer[]) arrayParts.toArray(new Integer[0]);
375
                parts = new int[integers.length];
376
                for (int i = 0; i < integers.length; i++) {
377
                        parts[i] = integers[i].intValue();
378
                }
379
                if (arrayPoints==null){
380
                        points=new Point[0];
381
                        return;
382
                }
383
                points = (Point[]) arrayPoints.toArray(new Point[0]);
384
                if (is3D){
385
                        Double[] doubleZs=(Double[])arrayZs.toArray(new Double[0]);
386
                        zs=new double[doubleZs.length];
387
                        for (int i=0;i<doubleZs.length;i++){
388
                                zs[i]=doubleZs[i].doubleValue();
389
                        }
390
                }
391
        }
392
}