/* This program 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. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.opentripplanner.common.geometry; import java.io.Serializable; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.CoordinateSequence; import com.vividsolutions.jts.geom.Envelope; /** * 2D, supports only coordinates in range +/- 180. */ public class IntPackedCoordinateSequence implements CoordinateSequence, Cloneable, Serializable { private static final long serialVersionUID = 1L; int[] ordinates; private static final double TO_FIXED = Integer.MAX_VALUE / 180.0; private static final double FROM_FIXED = 180.0 / Integer.MAX_VALUE; private int toFixedInt(double latlon) { return (int) (latlon * TO_FIXED); } private double fromFixedInt(int fixed) { return (double) (fixed * FROM_FIXED); } public IntPackedCoordinateSequence(Coordinate[] coordinates) { int nc = coordinates.length; ordinates = new int[nc * 2]; int i = 0; for (Coordinate c : coordinates) { setOrdinate(i, 0, c.x); setOrdinate(i, 1, c.y); i++; } } @Override public int getDimension() { return 2; } @Override public Coordinate getCoordinate(int i) { return getCoordinateCopy(i); } @Override public Coordinate getCoordinateCopy(int i) { return new Coordinate(getX(i), getY(i)); } @Override public void getCoordinate(int index, Coordinate coord) { coord.x = getX(index); coord.y = getY(index); } @Override public double getX(int index) { return fromFixedInt(ordinates[2*index]); } @Override public double getY(int index) { return fromFixedInt(ordinates[2*index + 1]); } @Override public double getOrdinate(int index, int ordinateIndex) { return fromFixedInt(ordinates[2*index + ordinateIndex]); } @Override public int size() { return ordinates.length / 2; } @Override public void setOrdinate(int index, int ordinateIndex, double value) { ordinates[2*index + ordinateIndex] = toFixedInt(value); } @Override public Coordinate[] toCoordinateArray() { Coordinate[] ret = new Coordinate[this.size()]; for (int i = 0; i < this.size(); i++) { ret[i] = this.getCoordinate(i); } return ret; } @Override public Envelope expandEnvelope(Envelope env) { for (int i = 0; i < ordinates.length / 2; i++) { env.expandToInclude(getX(i), getY(i)); } return env; } @Override public IntPackedCoordinateSequence clone() { try { return (IntPackedCoordinateSequence) super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException("programming error.", e); } } }