Statistics
| Revision:

root / tags / v2_0_0_Build_2051 / libraries / libFMap_dalfile / src / org / gvsig / fmap / dal / store / shp / utils / SHPMultiLine.java @ 38736

History | View | Annotate | Download (11.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.slf4j.Logger;
50
import org.slf4j.LoggerFactory;
51

    
52
import org.gvsig.fmap.geom.Geometry;
53
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
54
import org.gvsig.fmap.geom.Geometry.TYPES;
55
import org.gvsig.fmap.geom.GeometryLocator;
56
import org.gvsig.fmap.geom.GeometryManager;
57
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
58
import org.gvsig.fmap.geom.exception.CreateGeometryException;
59
import org.gvsig.fmap.geom.primitive.Curve;
60
import org.gvsig.fmap.geom.primitive.Envelope;
61
import org.gvsig.fmap.geom.primitive.GeneralPathX;
62
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
63
import org.gvsig.fmap.geom.primitive.Point;
64
import org.gvsig.fmap.geom.primitive.Primitive;
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] = (Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM2D);
138
                                points[t].setX(buffer.getDouble());
139
                                points[t].setY(buffer.getDouble());
140
                        } catch (CreateGeometryException e) {
141
                                logger.error("Error creating a point",e);
142
                        }
143
                }
144

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

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

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

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

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

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

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

    
214
        }
215

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

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

    
239
                return length;
240
        }
241

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

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

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

    
267
                return gPX;
268
        }
269

    
270
        /**
271
         * @see com.iver.cit.gvsig.fmap.shp.SHPShape#obtainsPoints(com.iver.cit.gvsig.fmap.core.GeneralPathXIterator)
272
         */
273
        public void obtainsPoints(Geometry g) {
274
                boolean is3D=false;
275
                if ((SHP.POLYLINE3D == m_type) || (SHP.POLYGON3D == m_type)){
276
                        OrientablePrimitive orientablePrimitive = (OrientablePrimitive)g;
277
                        zs = new double[orientablePrimitive.getNumVertices()];
278
                        for (int i=0 ; i<zs.length ; i++){
279
                                zs[i] = orientablePrimitive.getCoordinateAt(i, 2);
280
                        }
281
                        is3D=true;
282
                }
283
                ArrayList arrayPoints = new ArrayList();
284
                ArrayList arrayParts = new ArrayList();
285
                ArrayList arrayZs = new ArrayList();
286
                
287
                if (g.getGeometryType().isTypeOf(Geometry.TYPES.AGGREGATE)){
288
                    MultiPrimitive multiPrimitive = (MultiPrimitive)g;
289
                    int index = 0;
290
                    for (int i=0 ; i<multiPrimitive.getPrimitivesNumber() ; i++){
291
                        obtainsPoints(multiPrimitive.getPrimitiveAt(i), arrayPoints, arrayParts, arrayZs, is3D, index);
292
                        index += multiPrimitive.getPrimitiveAt(i).getGeneralPath().getNumCoords();
293
                    }
294
                }else{
295
                    obtainsPoints((Primitive)g, arrayPoints, arrayParts, arrayZs, is3D, 0);
296
                }        
297
                
298
                Integer[] integers = (Integer[]) arrayParts.toArray(new Integer[0]);
299
        parts = new int[integers.length];
300
        for (int i = 0; i < integers.length; i++) {
301
            parts[i] = integers[i].intValue();
302
        }
303
        if (arrayPoints==null){
304
            points = new Point[0];
305
            return;
306
        }
307
        points = (Point[]) arrayPoints.toArray(new Point[0]);
308
        if (is3D){
309
            Double[] doubleZs = (Double[])arrayZs.toArray(new Double[0]);
310
            zs = new double[doubleZs.length];
311
            for (int i=0;i<doubleZs.length;i++){
312
                zs[i]=doubleZs[i].doubleValue();
313
            }
314
        }
315
        }
316
        
317
        private void obtainsPoints(Primitive primitive, List arrayPoints, List arrayParts, List arrayZs, boolean is3D, int index) {                
318
                PathIterator theIterator = primitive.getPathIterator(null, geomManager.getFlatness()); 
319
                double[] theData = new double[6];
320
                java.awt.geom.Point2D pFirst = null;
321
                int pos=0;
322
                                
323
                boolean first = true;
324
                
325
                Double firstZ = null;
326
                while (!theIterator.isDone()) {
327
                        int theType = theIterator.currentSegment(theData);
328
                        switch (theType) {
329
                                case PathIterator.SEG_MOVETO:
330
                                        if (first) {
331
                                                first = false;
332
                                                arrayParts.add(new Integer(index));
333
                                        } else {
334
                                                if (m_type==SHP.POLYGON2D ||
335
                                                                m_type==SHP.POLYGON3D ||
336
                                                                m_type==SHP.POLYGONM){
337
                                                        try {
338
                                                                Point point = geomManager.createPoint(pFirst.getX(), pFirst.getY(), SUBTYPES.GEOM2D);
339
                                                                if (!arrayPoints.get(arrayPoints.size()-1).equals(point)){
340
                                                                        arrayPoints.add(point);
341
                                                                        if (is3D){
342
                                                                                arrayZs.add(firstZ);
343
                                                                        }
344
                                                                }
345
                                                                arrayParts.add(new Integer(arrayPoints.size()));
346
                                                        } catch (CreateGeometryException e) {
347
                                                                logger.error("Error creating a point", e);
348
                                                        }
349
                                                }
350
                                                
351
                                        }
352

    
353
                                        pFirst = new java.awt.geom.Point2D.Double(theData[0], theData[1]);
354
                                        try {
355
                                                arrayPoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
356
                                        } catch (CreateGeometryException e1) {
357
                                                logger.error("Error creating a point", e1);
358
                                        }
359
                                        if (is3D){
360
                                                firstZ=new Double(zs[pos]);
361
                                                arrayZs.add(new Double(zs[pos]));
362
                                                pos++;
363
                                        }
364
                                        break;
365

    
366
                                case PathIterator.SEG_LINETO:
367
                                        try {
368
                                                arrayPoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
369
                                        } catch (CreateGeometryException e) {
370
                                                logger.error("Error creating a point", e);
371
                                        }
372
                                        if (is3D){
373
                                                arrayZs.add(new Double(zs[pos]));
374
                                                pos++;
375
                                        }
376
                                        break;
377

    
378
                                case PathIterator.SEG_QUADTO:
379
                                        System.out.println("Not supported here");
380

    
381
                                        break;
382

    
383
                                case PathIterator.SEG_CUBICTO:
384
                                        System.out.println("Not supported here");
385

    
386
                                        break;
387

    
388
                                case PathIterator.SEG_CLOSE:
389
                                        try{
390
                                                Point point=geomManager.createPoint(pFirst.getX(), pFirst.getY(), SUBTYPES.GEOM2D);
391
                                                if (!arrayPoints.get(arrayPoints.size()-1).equals(point)){
392
                                                        arrayPoints.add(point);
393
                                                        if (is3D){
394
                                                                arrayZs.add(firstZ);
395
                                                        }
396
                                                }
397
                                        } catch (CreateGeometryException e) {
398
                                                logger.error("Error creating a point", e);
399
                                        }
400
                                        break;
401
                        } //end switch
402
                        index++;
403
                        theIterator.next();
404
                }                
405
        }
406
}