Statistics
| Revision:

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

History | View | Annotate | Download (10.3 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.primitive.impl.Point2D;
60
import org.gvsig.fmap.geom.util.Converter;
61
import org.slf4j.Logger;
62
import org.slf4j.LoggerFactory;
63

    
64

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

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

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

    
100
                m_type = type;
101
        }
102

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
212
        }
213

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

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

    
237
                return length;
238
        }
239

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

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

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

    
265
                return gPX;
266
        }
267

    
268
        /**
269
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#obtainsPoints(com.iver.cit.gvsig.fmap.core.GeneralPathXIterator)
270
         */
271
        public void obtainsPoints(Geometry g) {
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
                }else if (SHP.POLYGON3D == m_type){
279
                        Surface surface = (Surface)g;
280
                        zs = new double[surface.getNumVertices()];
281
                        for (int i=0 ; i<zs.length ; i++){
282
                                zs[i] = surface.getCoordinateAt(i, 2);
283
                        }
284
                }
285

    
286
                ArrayList arrayPoints = null;
287
                ArrayList arrayParts = new ArrayList();
288
                PathIterator theIterator = g.getPathIterator(null, Converter.FLATNESS); //polyLine.getPathIterator(null, flatness);
289
                double[] theData = new double[6];
290
                int numParts = 0;
291
                Point2D pFirst=null;
292
                while (!theIterator.isDone()) {
293
                        //while not done
294
                        int theType = theIterator.currentSegment(theData);
295

    
296
                        //Populate a segment of the new
297
                        // GeneralPathX object.
298
                        //Process the current segment to populate a new
299
                        // segment of the new GeneralPathX object.
300

    
301
                        switch (theType) {
302
                                case PathIterator.SEG_MOVETO:
303

    
304
                                        // System.out.println("SEG_MOVETO");
305
                                        if (arrayPoints == null) {
306
                                                arrayPoints = new ArrayList();
307
                                                arrayParts.add(new Integer(0));
308
                                        } else {
309
                                                if (m_type==SHP.POLYGON2D ||
310
                                                                m_type==SHP.POLYGON3D ||
311
                                                                m_type==SHP.POLYGONM)
312
                                                        arrayPoints.add(new Point2D(pFirst.getX(),
313
                                                                        pFirst.getY()));
314
                                                arrayParts.add(new Integer(arrayPoints.size()));
315
                                        }
316

    
317
                                        numParts++;
318
                                        pFirst=new Point2D(theData[0], theData[1]);
319
                                        try {
320
                                                arrayPoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
321
                                        } catch (CreateGeometryException e1) {
322
                                                logger.error("Error creating a point", e1);
323
                                        }
324

    
325
                                        break;
326

    
327
                                case PathIterator.SEG_LINETO:
328

    
329
                                        // System.out.println("SEG_LINETO");
330
                                        try {
331
                                                arrayPoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
332
                                        } catch (CreateGeometryException e) {
333
                                                logger.error("Error creating a point", e);
334
                                        }
335

    
336
                                        break;
337

    
338
                                case PathIterator.SEG_QUADTO:
339
                                        System.out.println("Not supported here");
340

    
341
                                        break;
342

    
343
                                case PathIterator.SEG_CUBICTO:
344
                                        System.out.println("Not supported here");
345

    
346
                                        break;
347

    
348
                                case PathIterator.SEG_CLOSE:
349
//                                        System.out.println("SEG_CLOSE");
350

    
351
                                        // A?adimos el primer punto para cerrar.
352
                                        arrayPoints.add(new Point2D(pFirst.getX(),
353
                                                        pFirst.getY()));
354

    
355
                                        break;
356
                        } //end switch
357

    
358
                        theIterator.next();
359
                }
360

    
361
                Integer[] integers = (Integer[]) arrayParts.toArray(new Integer[0]);
362
                parts = new int[integers.length];
363
                for (int i = 0; i < integers.length; i++) {
364
                        parts[i] = integers[i].intValue();
365
                }
366
                if (arrayPoints==null){
367
                        points=new Point[0];
368
                        return;
369
                }
370
                points = (Point[]) arrayPoints.toArray(new Point[0]);
371

    
372
        }
373

    
374
//        public void setFlatness(double flatness) {
375
//                this.flatness=flatness;
376
//        }
377
}