Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / core / gt2 / GeomCollectionIterator.java @ 9284

History | View | Annotate | Download (8.4 KB)

1
/*
2
 * Created on 12-may-2005
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 * 
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 * 
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *  
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 * 
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
 *  
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 * 
34
 *    or
35
 * 
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 * 
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
package com.iver.cit.gvsig.fmap.core.gt2;
45

    
46
import java.awt.geom.AffineTransform;
47
import java.awt.geom.PathIterator;
48

    
49
import com.vividsolutions.jts.geom.Geometry;
50
import com.vividsolutions.jts.geom.GeometryCollection;
51
import com.vividsolutions.jts.geom.LineString;
52
import com.vividsolutions.jts.geom.LinearRing;
53
import com.vividsolutions.jts.geom.Point;
54
import com.vividsolutions.jts.geom.Polygon;
55

    
56

    
57
/**
58
 * A path iterator for the LiteShape class, specialized to iterate over a
59
 * geometry collection. It can be seen as a composite, since uses in fact
60
 * other, simpler iterator to carry on its duties.
61
 *
62
 * @author Andrea Aime
63
 * @version $Id: GeomCollectionIterator.java 2943 2005-09-22 11:27:52Z fjp $
64
 */
65
class GeomCollectionIterator extends AbstractLiteIterator {
66
    /** Transform applied on the coordinates during iteration */
67
    private AffineTransform at;
68

    
69
    /** The set of geometries that we will iterate over */
70
    private GeometryCollection gc;
71
    
72
    /** The current geometry */
73
    private int currentGeom;
74

    
75
    /** The current sub-iterator */
76
    private PathIterator currentIterator;
77

    
78
    /** True when the iterator is terminate */
79
    private boolean done = false;
80

    
81
    /** If true, apply simple distance based generalization */
82
    private boolean generalize = false;
83

    
84
    /** Maximum distance for point elision when generalizing */
85
    private double maxDistance = 1.0;
86
    
87
    private LineIterator lineIterator = new LineIterator();
88

    
89
    public GeomCollectionIterator()
90
    {
91
        
92
    }
93
    
94
    /**
95
     * @param gc
96
     * @param at
97
     */
98
    public void init(GeometryCollection gc, AffineTransform at, boolean generalize, double maxDistance) {
99
        int numGeometries = gc.getNumGeometries();
100
        
101
        
102
        this.gc = gc;
103

    
104
        if (at == null) {
105
            at = new AffineTransform();
106
        }
107

    
108
        this.at = at;
109
        this.generalize = generalize;
110
        this.maxDistance = maxDistance;
111
        currentGeom = 0;
112
        done = false;
113

    
114
        currentIterator = getIterator(gc.getGeometryN(0));
115
    }
116

    
117
    /**
118
     * Creates a new instance of GeomCollectionIterator
119
     *
120
     * @param gc The geometry collection the iterator will use
121
     * @param at The affine transform applied to coordinates during iteration
122
     * @param generalize if true apply simple distance based generalization
123
     * @param maxDistance during iteration, a point will be skipped if it's
124
     *        distance from the previous is less than maxDistance
125
     */
126
    public GeomCollectionIterator(
127
        GeometryCollection gc, AffineTransform at, boolean generalize,
128
        double maxDistance) {
129
        init(gc, at, generalize, maxDistance);
130
    }
131

    
132
    /**
133
     * Sets the distance limit for point skipping during distance based
134
     * generalization
135
     *
136
     * @param distance the maximum distance for point skipping
137
     */
138
    public void setMaxDistance(double distance) {
139
        maxDistance = distance;
140
    }
141

    
142
    /**
143
     * Returns the distance limit for point skipping during distance based
144
     * generalization
145
     *
146
     * @return the maximum distance for distance based generalization
147
     */
148
    public double getMaxDistance() {
149
        return maxDistance;
150
    }
151

    
152
    /**
153
     * Returns the specific iterator for the geometry passed.
154
     *
155
     * @param g The geometry whole iterator is requested
156
     *
157
     * @return the specific iterator for the geometry passed.
158
     */
159
    private AbstractLiteIterator getIterator(Geometry g) {
160
        AbstractLiteIterator pi = null;
161

    
162
        if (g instanceof Polygon) {
163
            Polygon p = (Polygon) g;
164
            pi = new PolygonIterator(p, at, generalize, maxDistance);
165
        } else if (g instanceof GeometryCollection) {
166
            GeometryCollection gc = (GeometryCollection) g;
167
            pi = new GeomCollectionIterator(gc, at, generalize, maxDistance);
168
        } else if (g instanceof LineString) {
169
            LineString ls = (LineString) g;
170
            lineIterator.init(ls, at, generalize, (float) maxDistance);
171
            pi = lineIterator;
172
        } else if (g instanceof LinearRing) {
173
            LinearRing lr = (LinearRing) g;
174
            lineIterator.init(lr, at, generalize, (float) maxDistance);
175
            pi = lineIterator;
176
        } else if (g instanceof Point) {
177
            Point p = (Point) g;
178
            pi = new PointIterator(p, at);
179
        }
180
        
181
        return pi;
182
    }
183

    
184
    /**
185
     * Returns the coordinates and type of the current path segment in the
186
     * iteration. The return value is the path-segment type: SEG_MOVETO,
187
     * SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE. A double array of
188
     * length 6 must be passed in and can be used to store the coordinates of
189
     * the point(s). Each point is stored as a pair of double x,y coordinates.
190
     * SEG_MOVETO and SEG_LINETO types returns one point, SEG_QUADTO returns
191
     * two points, SEG_CUBICTO returns 3 points and SEG_CLOSE does not return
192
     * any points.
193
     *
194
     * @param coords an array that holds the data returned from this method
195
     *
196
     * @return the path-segment type of the current path segment.
197
     *
198
     * @see #SEG_MOVETO
199
     * @see #SEG_LINETO
200
     * @see #SEG_QUADTO
201
     * @see #SEG_CUBICTO
202
     * @see #SEG_CLOSE
203
     */
204
    public int currentSegment(double[] coords) {
205
        return currentIterator.currentSegment(coords);
206
    }
207

    
208
    /**
209
     * Returns the coordinates and type of the current path segment in the
210
     * iteration. The return value is the path-segment type: SEG_MOVETO,
211
     * SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE. A float array of
212
     * length 6 must be passed in and can be used to store the coordinates of
213
     * the point(s). Each point is stored as a pair of float x,y coordinates.
214
     * SEG_MOVETO and SEG_LINETO types returns one point, SEG_QUADTO returns
215
     * two points, SEG_CUBICTO returns 3 points and SEG_CLOSE does not return
216
     * any points.
217
     *
218
     * @param coords an array that holds the data returned from this method
219
     *
220
     * @return the path-segment type of the current path segment.
221
     *
222
     * @see #SEG_MOVETO
223
     * @see #SEG_LINETO
224
     * @see #SEG_QUADTO
225
     * @see #SEG_CUBICTO
226
     * @see #SEG_CLOSE
227
     */
228
    public int currentSegment(float[] coords) {
229
        return currentIterator.currentSegment(coords);
230
    }
231

    
232
    /**
233
     * Returns the winding rule for determining the interior of the path.
234
     *
235
     * @return the winding rule.
236
     *
237
     * @see #WIND_EVEN_ODD
238
     * @see #WIND_NON_ZERO
239
     */
240
    public int getWindingRule() {
241
        return WIND_NON_ZERO;
242
    }
243

    
244
    /**
245
     * Tests if the iteration is complete.
246
     *
247
     * @return <code>true</code> if all the segments have been read;
248
     *         <code>false</code> otherwise.
249
     */
250
    public boolean isDone() {
251
        return done;
252
    }
253

    
254
    /**
255
     * Moves the iterator to the next segment of the path forwards along the
256
     * primary direction of traversal as long as there are more points in that
257
     * direction.
258
     */
259
    public void next() {
260
        if (currentIterator.isDone()) {
261
            if (currentGeom < (gc.getNumGeometries() - 1)) {
262
                currentGeom++;
263
                currentIterator = getIterator(gc.getGeometryN(currentGeom));
264
            } else {
265
                done = true;
266
            }
267
        } else {
268
            currentIterator.next();
269
        }
270
    }
271

    
272
}