| 1 | /* |
|---|
| 2 | * OrbisGIS is a GIS application dedicated to scientific spatial simulation. |
|---|
| 3 | * This cross-platform GIS is developed at French IRSTV institute and is able |
|---|
| 4 | * to manipulate and create vector and raster spatial information. OrbisGIS |
|---|
| 5 | * is distributed under GPL 3 license. It is produced by the geo-informatic team of |
|---|
| 6 | * the IRSTV Institute <http://www.irstv.cnrs.fr/>, CNRS FR 2488: |
|---|
| 7 | * Erwan BOCHER, scientific researcher, |
|---|
| 8 | * Thomas LEDUC, scientific researcher, |
|---|
| 9 | * Fernando GONZALEZ CORTES, computer engineer. |
|---|
| 10 | * |
|---|
| 11 | * Copyright (C) 2007 Erwan BOCHER, Fernando GONZALEZ CORTES, Thomas LEDUC |
|---|
| 12 | * |
|---|
| 13 | * This file is part of OrbisGIS. |
|---|
| 14 | * |
|---|
| 15 | * OrbisGIS is free software: you can redistribute it and/or modify |
|---|
| 16 | * it under the terms of the GNU General Public License as published by |
|---|
| 17 | * the Free Software Foundation, either version 3 of the License, or |
|---|
| 18 | * (at your option) any later version. |
|---|
| 19 | * |
|---|
| 20 | * OrbisGIS is distributed in the hope that it will be useful, |
|---|
| 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 23 | * GNU General Public License for more details. |
|---|
| 24 | * |
|---|
| 25 | * You should have received a copy of the GNU General Public License |
|---|
| 26 | * along with OrbisGIS. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 27 | * |
|---|
| 28 | * For more information, please consult: |
|---|
| 29 | * <http://orbisgis.cerma.archi.fr/> |
|---|
| 30 | * <http://sourcesup.cru.fr/projects/orbisgis/> |
|---|
| 31 | * |
|---|
| 32 | * or contact directly: |
|---|
| 33 | * erwan.bocher _at_ ec-nantes.fr |
|---|
| 34 | * fergonco _at_ gmail.com |
|---|
| 35 | * thomas.leduc _at_ cerma.archi.fr |
|---|
| 36 | */ |
|---|
| 37 | /* |
|---|
| 38 | * GeoTools - OpenSource mapping toolkit |
|---|
| 39 | * http://geotools.org |
|---|
| 40 | * (C) 2004-2006, Geotools Project Managment Committee (PMC) |
|---|
| 41 | * |
|---|
| 42 | * This library is free software; you can redistribute it and/or |
|---|
| 43 | * modify it under the terms of the GNU Lesser General Public |
|---|
| 44 | * License as published by the Free Software Foundation; either |
|---|
| 45 | * version 2.1 of the License, or (at your option) any later version. |
|---|
| 46 | * |
|---|
| 47 | * This library is distributed in the hope that it will be useful, |
|---|
| 48 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 49 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 50 | * Lesser General Public License for more details. |
|---|
| 51 | */ |
|---|
| 52 | |
|---|
| 53 | package org.orbisgis.renderer.liteShape; |
|---|
| 54 | |
|---|
| 55 | import java.awt.geom.AffineTransform; |
|---|
| 56 | import java.awt.geom.PathIterator; |
|---|
| 57 | |
|---|
| 58 | import com.vividsolutions.jts.geom.Geometry; |
|---|
| 59 | import com.vividsolutions.jts.geom.GeometryCollection; |
|---|
| 60 | import com.vividsolutions.jts.geom.LineString; |
|---|
| 61 | import com.vividsolutions.jts.geom.LinearRing; |
|---|
| 62 | import com.vividsolutions.jts.geom.Point; |
|---|
| 63 | import com.vividsolutions.jts.geom.Polygon; |
|---|
| 64 | |
|---|
| 65 | /** |
|---|
| 66 | * A path iterator for the LiteShape class, specialized to iterate over a |
|---|
| 67 | * geometry collection. It can be seen as a composite, since uses in fact other, |
|---|
| 68 | * simpler iterator to carry on its duties. |
|---|
| 69 | * |
|---|
| 70 | * @author Andrea Aime |
|---|
| 71 | * @source $URL: |
|---|
| 72 | * http://svn.geotools.org/geotools/tags/2.3.1/module/render/src/org/geotools/renderer/lite/GeomCollectionIterator.java $ |
|---|
| 73 | * @version $Id: GeomCollectionIterator.java 20874 2006-08-07 10:00:01Z jgarnett $ |
|---|
| 74 | */ |
|---|
| 75 | public final class GeomCollectionIterator extends AbstractLiteIterator { |
|---|
| 76 | /** Transform applied on the coordinates during iteration */ |
|---|
| 77 | private AffineTransform at; |
|---|
| 78 | |
|---|
| 79 | /** The set of geometries that we will iterate over */ |
|---|
| 80 | private GeometryCollection gc; |
|---|
| 81 | |
|---|
| 82 | /** The current geometry */ |
|---|
| 83 | private int currentGeom; |
|---|
| 84 | |
|---|
| 85 | /** The current sub-iterator */ |
|---|
| 86 | private PathIterator currentIterator; |
|---|
| 87 | |
|---|
| 88 | /** True when the iterator is terminate */ |
|---|
| 89 | private boolean done = false; |
|---|
| 90 | |
|---|
| 91 | /** If true, apply simple distance based generalization */ |
|---|
| 92 | private boolean generalize = false; |
|---|
| 93 | |
|---|
| 94 | /** Maximum distance for point elision when generalizing */ |
|---|
| 95 | private double maxDistance = 1.0; |
|---|
| 96 | |
|---|
| 97 | private LineIterator lineIterator = new LineIterator(); |
|---|
| 98 | |
|---|
| 99 | public GeomCollectionIterator() { |
|---|
| 100 | |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | /** |
|---|
| 104 | * @param gc |
|---|
| 105 | * @param at |
|---|
| 106 | */ |
|---|
| 107 | public void init(GeometryCollection gc, AffineTransform at, |
|---|
| 108 | boolean generalize, double maxDistance) { |
|---|
| 109 | this.gc = gc; |
|---|
| 110 | this.at = at == null ? new AffineTransform() : at; |
|---|
| 111 | this.generalize = generalize; |
|---|
| 112 | this.maxDistance = maxDistance; |
|---|
| 113 | currentGeom = 0; |
|---|
| 114 | done = false; |
|---|
| 115 | currentIterator = getIterator(gc.getGeometryN(0)); |
|---|
| 116 | } |
|---|
| 117 | |
|---|
| 118 | /** |
|---|
| 119 | * Creates a new instance of GeomCollectionIterator |
|---|
| 120 | * |
|---|
| 121 | * @param gc |
|---|
| 122 | * The geometry collection the iterator will use |
|---|
| 123 | * @param at |
|---|
| 124 | * The affine transform applied to coordinates during iteration |
|---|
| 125 | * @param generalize |
|---|
| 126 | * if true apply simple distance based generalization |
|---|
| 127 | * @param maxDistance |
|---|
| 128 | * during iteration, a point will be skipped if it's distance |
|---|
| 129 | * from the previous is less than maxDistance |
|---|
| 130 | */ |
|---|
| 131 | public GeomCollectionIterator(GeometryCollection gc, AffineTransform at, |
|---|
| 132 | boolean generalize, double maxDistance) { |
|---|
| 133 | init(gc, at, generalize, maxDistance); |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | /** |
|---|
| 137 | * Sets the distance limit for point skipping during distance based |
|---|
| 138 | * generalization |
|---|
| 139 | * |
|---|
| 140 | * @param distance |
|---|
| 141 | * the maximum distance for point skipping |
|---|
| 142 | */ |
|---|
| 143 | public void setMaxDistance(double distance) { |
|---|
| 144 | maxDistance = distance; |
|---|
| 145 | } |
|---|
| 146 | |
|---|
| 147 | /** |
|---|
| 148 | * Returns the distance limit for point skipping during distance based |
|---|
| 149 | * generalization |
|---|
| 150 | * |
|---|
| 151 | * @return the maximum distance for distance based generalization |
|---|
| 152 | */ |
|---|
| 153 | public double getMaxDistance() { |
|---|
| 154 | return maxDistance; |
|---|
| 155 | } |
|---|
| 156 | |
|---|
| 157 | /** |
|---|
| 158 | * Returns the specific iterator for the geometry passed. |
|---|
| 159 | * |
|---|
| 160 | * @param g |
|---|
| 161 | * The geometry whole iterator is requested |
|---|
| 162 | * |
|---|
| 163 | * @return the specific iterator for the geometry passed. |
|---|
| 164 | */ |
|---|
| 165 | private AbstractLiteIterator getIterator(Geometry g) { |
|---|
| 166 | AbstractLiteIterator pi = null; |
|---|
| 167 | |
|---|
| 168 | if (g instanceof Polygon) { |
|---|
| 169 | Polygon p = (Polygon) g; |
|---|
| 170 | pi = new PolygonIterator(p, at, generalize, maxDistance); |
|---|
| 171 | } else if (g instanceof GeometryCollection) { |
|---|
| 172 | GeometryCollection gc = (GeometryCollection) g; |
|---|
| 173 | pi = new GeomCollectionIterator(gc, at, generalize, maxDistance); |
|---|
| 174 | } else if (g instanceof LineString) { |
|---|
| 175 | LineString ls = (LineString) g; |
|---|
| 176 | lineIterator.init(ls, at, generalize, (float) maxDistance); |
|---|
| 177 | pi = lineIterator; |
|---|
| 178 | } else if (g instanceof LinearRing) { |
|---|
| 179 | LinearRing lr = (LinearRing) g; |
|---|
| 180 | lineIterator.init(lr, at, generalize, (float) maxDistance); |
|---|
| 181 | pi = lineIterator; |
|---|
| 182 | } else if (g instanceof Point) { |
|---|
| 183 | Point p = (Point) g; |
|---|
| 184 | pi = new PointIterator(p, at); |
|---|
| 185 | } |
|---|
| 186 | |
|---|
| 187 | return pi; |
|---|
| 188 | } |
|---|
| 189 | |
|---|
| 190 | /** |
|---|
| 191 | * Returns the coordinates and type of the current path segment in the |
|---|
| 192 | * iteration. The return value is the path-segment type: SEG_MOVETO, |
|---|
| 193 | * SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE. A double array of |
|---|
| 194 | * length 6 must be passed in and can be used to store the coordinates of |
|---|
| 195 | * the point(s). Each point is stored as a pair of double x,y coordinates. |
|---|
| 196 | * SEG_MOVETO and SEG_LINETO types returns one point, SEG_QUADTO returns two |
|---|
| 197 | * points, SEG_CUBICTO returns 3 points and SEG_CLOSE does not return any |
|---|
| 198 | * points. |
|---|
| 199 | * |
|---|
| 200 | * @param coords |
|---|
| 201 | * an array that holds the data returned from this method |
|---|
| 202 | * |
|---|
| 203 | * @return the path-segment type of the current path segment. |
|---|
| 204 | * |
|---|
| 205 | * @see #SEG_MOVETO |
|---|
| 206 | * @see #SEG_LINETO |
|---|
| 207 | * @see #SEG_QUADTO |
|---|
| 208 | * @see #SEG_CUBICTO |
|---|
| 209 | * @see #SEG_CLOSE |
|---|
| 210 | */ |
|---|
| 211 | public int currentSegment(double[] coords) { |
|---|
| 212 | return currentIterator.currentSegment(coords); |
|---|
| 213 | } |
|---|
| 214 | |
|---|
| 215 | /** |
|---|
| 216 | * Returns the coordinates and type of the current path segment in the |
|---|
| 217 | * iteration. The return value is the path-segment type: SEG_MOVETO, |
|---|
| 218 | * SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE. A float array of |
|---|
| 219 | * length 6 must be passed in and can be used to store the coordinates of |
|---|
| 220 | * the point(s). Each point is stored as a pair of float x,y coordinates. |
|---|
| 221 | * SEG_MOVETO and SEG_LINETO types returns one point, SEG_QUADTO returns two |
|---|
| 222 | * points, SEG_CUBICTO returns 3 points and SEG_CLOSE does not return any |
|---|
| 223 | * points. |
|---|
| 224 | * |
|---|
| 225 | * @param coords |
|---|
| 226 | * an array that holds the data returned from this method |
|---|
| 227 | * |
|---|
| 228 | * @return the path-segment type of the current path segment. |
|---|
| 229 | * |
|---|
| 230 | * @see #SEG_MOVETO |
|---|
| 231 | * @see #SEG_LINETO |
|---|
| 232 | * @see #SEG_QUADTO |
|---|
| 233 | * @see #SEG_CUBICTO |
|---|
| 234 | * @see #SEG_CLOSE |
|---|
| 235 | */ |
|---|
| 236 | public int currentSegment(float[] coords) { |
|---|
| 237 | return currentIterator.currentSegment(coords); |
|---|
| 238 | } |
|---|
| 239 | |
|---|
| 240 | /** |
|---|
| 241 | * Returns the winding rule for determining the interior of the path. |
|---|
| 242 | * |
|---|
| 243 | * @return the winding rule. |
|---|
| 244 | * |
|---|
| 245 | * @see #WIND_EVEN_ODD |
|---|
| 246 | * @see #WIND_NON_ZERO |
|---|
| 247 | */ |
|---|
| 248 | public int getWindingRule() { |
|---|
| 249 | return WIND_EVEN_ODD; |
|---|
| 250 | } |
|---|
| 251 | |
|---|
| 252 | /** |
|---|
| 253 | * Tests if the iteration is complete. |
|---|
| 254 | * |
|---|
| 255 | * @return <code>true</code> if all the segments have been read; |
|---|
| 256 | * <code>false</code> otherwise. |
|---|
| 257 | */ |
|---|
| 258 | public boolean isDone() { |
|---|
| 259 | return done; |
|---|
| 260 | } |
|---|
| 261 | |
|---|
| 262 | /** |
|---|
| 263 | * Moves the iterator to the next segment of the path forwards along the |
|---|
| 264 | * primary direction of traversal as long as there are more points in that |
|---|
| 265 | * direction. |
|---|
| 266 | */ |
|---|
| 267 | public void next() { |
|---|
| 268 | if (currentIterator.isDone()) { |
|---|
| 269 | if (currentGeom < (gc.getNumGeometries() - 1)) { |
|---|
| 270 | currentGeom++; |
|---|
| 271 | currentIterator = getIterator(gc.getGeometryN(currentGeom)); |
|---|
| 272 | } else { |
|---|
| 273 | done = true; |
|---|
| 274 | } |
|---|
| 275 | } else { |
|---|
| 276 | currentIterator.next(); |
|---|
| 277 | } |
|---|
| 278 | } |
|---|
| 279 | |
|---|
| 280 | } |
|---|