package com.revolsys.geometry.model.impl; import java.util.Arrays; import java.util.Collection; import java.util.List; import com.revolsys.geometry.cs.projection.CoordinatesOperation; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.geometry.model.LineString; import com.revolsys.geometry.model.Point; import com.revolsys.geometry.model.coordinates.list.CoordinatesListUtil; import com.revolsys.util.MathUtil; public class LineStringDouble extends AbstractLineString { private static final long serialVersionUID = 7579865828939708871L; private static final double[] EMPTY_COORDINATES = new double[0]; public static LineStringDouble newLineStringDouble(final int axisCount, final int vertexCount, final double... coordinates) { if (coordinates == null || coordinates.length == 0) { return new LineStringDouble(axisCount); } else { assert axisCount >= 2; final int coordinateCount = vertexCount * axisCount; if (coordinates.length % axisCount != 0) { throw new IllegalArgumentException("coordinates.length=" + coordinates.length + " must be a multiple of axisCount=" + axisCount); } else if (coordinateCount == coordinates.length) { return new LineStringDouble(axisCount, vertexCount, coordinates); } else if (coordinateCount > coordinates.length) { throw new IllegalArgumentException("axisCount=" + axisCount + " * vertexCount=" + vertexCount + " > coordinates.length=" + coordinates.length); } else { final double[] copyCoordinates = new double[coordinateCount]; System.arraycopy(coordinates, 0, copyCoordinates, 0, coordinateCount); return new LineStringDouble(axisCount, vertexCount, copyCoordinates); } } } protected final int axisCount; protected final int vertexCount; protected double[] coordinates; public LineStringDouble(final int axisCount) { this.axisCount = axisCount; this.vertexCount = 0; this.coordinates = EMPTY_COORDINATES; } public LineStringDouble(final int axisCount, final Collection<Point> points) { this(points.size(), axisCount); int i = 0; for (final Point point : points) { CoordinatesListUtil.setCoordinates(this.coordinates, axisCount, i++, point); } } public LineStringDouble(final int axisCount, final double... coordinates) { if (coordinates == null || coordinates.length == 0) { this.axisCount = 2; this.coordinates = EMPTY_COORDINATES; this.vertexCount = 0; } else { assert axisCount >= 2; this.axisCount = axisCount; this.coordinates = coordinates; this.vertexCount = coordinates.length / axisCount; } } protected LineStringDouble(final int size, final int axisCount) { assert axisCount >= 2; assert size >= 0; this.coordinates = new double[size * axisCount]; this.axisCount = axisCount; this.vertexCount = this.coordinates.length / axisCount; } public LineStringDouble(final int axisCount, final int vertexCount, final double... coordinates) { this.axisCount = axisCount; this.vertexCount = vertexCount; this.coordinates = coordinates; } public LineStringDouble(final int axisCount, final LineString points) { this(points.getVertexCount(), axisCount); CoordinatesListUtil.setCoordinates(this.coordinates, axisCount, 0, points, 0, points.getVertexCount()); } public LineStringDouble(final int axisCount, final List<? extends Number> coordinates) { this(axisCount, MathUtil.toDoubleArray(coordinates)); } public LineStringDouble(final int axisCount, final Point... points) { this(axisCount, Arrays.asList(points)); } public LineStringDouble(final LineString coordinatesList) { this(coordinatesList.getAxisCount(), coordinatesList); } public LineStringDouble(final Point... coordinates) { this(3, coordinates); } @Override public LineStringDouble clone() { final LineStringDouble clone = (LineStringDouble)super.clone(); clone.coordinates = this.coordinates.clone(); return clone; } @Override protected double[] convertCoordinates(GeometryFactory geometryFactory) { final GeometryFactory sourceGeometryFactory = getGeometryFactory(); if (isEmpty()) { return this.coordinates; } else { geometryFactory = getNonZeroGeometryFactory(geometryFactory); double[] targetCoordinates; final CoordinatesOperation coordinatesOperation = sourceGeometryFactory .getCoordinatesOperation(geometryFactory); if (coordinatesOperation == null) { return this.coordinates; } else { targetCoordinates = new double[this.axisCount * this.vertexCount]; coordinatesOperation.perform(this.axisCount, this.coordinates, this.axisCount, targetCoordinates); return targetCoordinates; } } } @Override public int getAxisCount() { return this.axisCount; } @Override public double getCoordinate(int vertexIndex, final int axisIndex) { final int axisCount = this.axisCount; if (axisIndex < axisCount) { final int vertexCount = getVertexCount(); if (vertexIndex < vertexCount) { while (vertexIndex < 0) { vertexIndex += vertexCount; } return this.coordinates[vertexIndex * axisCount + axisIndex]; } } return Double.NaN; } @Override public double getCoordinateFast(final int vertexIndex, final int axisIndex) { final int axisCount = getAxisCount(); if (axisIndex < axisCount) { return this.coordinates[vertexIndex * axisCount + axisIndex]; } else { return Double.NaN; } } @Override public double[] getCoordinates() { return this.coordinates.clone(); } @Override public GeometryFactory getGeometryFactory() { final int axisCount = this.axisCount; if (axisCount == 2) { return GeometryFactory.DEFAULT_2D; } else if (axisCount == 2) { return GeometryFactory.DEFAULT_3D; } else { return GeometryFactory.floating(0, this.axisCount); } } @Override public int getSegmentCount() { final int vertexCount = this.vertexCount; if (vertexCount == 0) { return 0; } else { return vertexCount - 1; } } @Override public int getVertexCount() { return this.vertexCount; } @Override public double getX(final int vertexIndex) { return this.coordinates[vertexIndex * this.axisCount]; } @Override public double getY(final int vertexIndex) { return this.coordinates[vertexIndex * this.axisCount + 1]; } @Override public double getZ(final int vertexIndex) { final int axisCount = this.axisCount; if (axisCount > 2) { return this.coordinates[vertexIndex * axisCount + 2]; } else { return Double.NaN; } } @Override public boolean isEmpty() { return this.vertexCount == 0; } }