/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2009, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.display2d.primitive.iso; import java.awt.geom.AffineTransform; import java.util.ArrayList; import java.util.List; import org.opengis.geometry.DirectPosition; import org.opengis.geometry.coordinate.PointArray; import org.opengis.geometry.coordinate.Polygon; import org.opengis.geometry.coordinate.PolyhedralSurface; import org.opengis.geometry.primitive.OrientableCurve; import org.opengis.geometry.primitive.Ring; import org.opengis.geometry.primitive.SurfaceBoundary; /** * Simple and efficient path iterator for ISO PolyhedralSurface. * * @author Johann Sorel (Geomatys) * @module */ public final class ISOPolyhedralSurfaceIterator extends ISOGeometryIterator<PolyhedralSurface> { /** The rings describing the polygon geometry */ private final List<OrientableCurve> curves; /** The current ring during iteration */ private int currentRing = 0; /** Current line coordinate */ private int currentCoord = 0; /** The array of coordinates that represents the line geometry */ private PointArray coordinate = null; /** True when the iteration is terminated */ private boolean done = false; /** if the geometry is empty */ private boolean empty = false; /** * Creates a new PolygonIterator object. * * @param p The polygon * @param trs The affine transform applied to coordinates during iteration */ public ISOPolyhedralSurfaceIterator(final PolyhedralSurface p, final AffineTransform trs) { super(p,trs); curves = new ArrayList<OrientableCurve>(); for(Polygon polygon : p.getPatches()){ SurfaceBoundary boundary = polygon.getBoundary(); curves.addAll(boundary.getExterior().getGenerators()); for(Ring r : boundary.getInteriors()){ curves.addAll(r.getGenerators()); } } reset(); } private void reset(){ currentRing = 0; currentCoord = 0; coordinate = curves.get(0).getPrimitive().asLineString(0, 0).getControlPoints(); empty = coordinate.isEmpty(); done = empty; } /** * {@inheritDoc } */ @Override public int currentSegment(final double[] coords) { if(empty) return 0; // first make sure we're not at the last element, this prevents us from exceptions // in the case where coords.size() == 0 if (currentCoord == this.coordinate.size()) { return SEG_CLOSE; } else if (currentCoord == 0) { DirectPosition pos = coordinate.get(0).getDirectPosition(); coords[0] = pos.getOrdinate(0); coords[1] = pos.getOrdinate(1); transform.transform(coords, 0, coords, 0, 1); return SEG_MOVETO; } else { DirectPosition pos = coordinate.get(currentCoord).getDirectPosition(); coords[0] = pos.getOrdinate(0); coords[1] = pos.getOrdinate(1); transform.transform(coords, 0, coords, 0, 1); return SEG_LINETO; } } /** * {@inheritDoc } */ @Override public int getWindingRule() { return (empty) ? WIND_NON_ZERO : WIND_EVEN_ODD; } /** * {@inheritDoc } */ @Override public boolean isDone() { if(done){ reset(); return true; }else{ return false; } } /** * {@inheritDoc } */ @Override public void next() { if (currentCoord == coordinate.size()) { if (currentRing < (curves.size() - 1)) { currentCoord = 0; currentRing++; coordinate = curves.get(currentRing).getPrimitive().asLineString(0, 0).getControlPoints(); } else { done = true; } } else { currentCoord++; } } }