/*
* This file is part of the GeoLatte project.
*
* GeoLatte 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, either version 3 of the License, or
* (at your option) any later version.
*
* GeoLatte 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GeoLatte. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2010 - 2011 and Ownership of code is shared by:
* Qmino bvba - Esperantolaan 4 - 3001 Heverlee (http://www.qmino.com)
* Geovise bvba - Generaal Eisenhowerlei 9 - 2140 Antwerpen (http://www.geovise.com)
*/
package org.geolatte.maprenderer.shape;
import com.vividsolutions.jts.geom.Coordinate;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
abstract public class GeometryPathIterator implements PathIterator {
protected final AffineTransform transform;
protected final AffineTransform worldToImageTransform;
private boolean done = false;
private double[] coordinateBuffer = new double[2];
private double[] pixelCoordinateBuffer = new double[2];
private Coordinate previousCoordinate = null;
private int[] previousPixelCoordinate = new int[2];
public GeometryPathIterator(AffineTransform worldToImageTransform, AffineTransform transform) {
this.worldToImageTransform = worldToImageTransform;
this.transform = transform;
}
public int getWindingRule() {
return WIND_EVEN_ODD;
}
public boolean isDone() {
return this.done;
}
public void next() {
do {
advance();
} while (!pixelDifferentFromPrevious() && !isDone());
}
abstract protected void advance();
abstract void setCurrentCoordinate(Coordinate coordinate);
abstract Coordinate getCurrentCoordinate();
protected void setIsDone() {
this.done = true;
}
/**
* Determines whether this pixel is actually different from the previous pixel
*
* @return
*/
private boolean pixelDifferentFromPrevious() {
if (previousCoordinate == null) {
return true;
}
coordinateBuffer[0] = getCurrentCoordinate().x;
coordinateBuffer[1] = getCurrentCoordinate().y;
worldToImageTransform.transform(coordinateBuffer, 0, pixelCoordinateBuffer, 0, 1);
if (previousPixelCoordinate[0] != (int) pixelCoordinateBuffer[0] || previousPixelCoordinate[1] != (int) pixelCoordinateBuffer[1]) {
previousPixelCoordinate[0] = (int) pixelCoordinateBuffer[0];
previousPixelCoordinate[1] = (int) pixelCoordinateBuffer[1];
return true;
}
return false;
}
public int currentSegment(float[] coords) {
int op = currentSegment(coordinateBuffer);
coords[0] = (float) coordinateBuffer[0];
coords[1] = (float) coordinateBuffer[1];
return op;
}
public int currentSegment(double[] coords) {
previousCoordinate = getCurrentCoordinate();
coords[0] = previousCoordinate.x;
coords[1] = previousCoordinate.y;
if (transform != null && !transform.isIdentity()) {
transform.transform(coords, 0, coords, 0, 1);
}
return determineOperation();
}
abstract protected int determineOperation();
}