package com.revolsys.geometry.model.segment; import java.util.Iterator; import java.util.NoSuchElementException; import com.revolsys.geometry.model.Geometry; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.geometry.model.LineString; import com.revolsys.geometry.model.Lineal; import com.revolsys.geometry.model.impl.AbstractLineString; import com.revolsys.geometry.model.vertex.Vertex; public class MultiLineStringSegment extends AbstractLineString implements Iterator<Segment>, Segment { private static final long serialVersionUID = 1L; private final Lineal lineal; private int partIndex; private int segmentIndex; public MultiLineStringSegment(final Lineal lineal, final int partIndex, final int segmentIndex) { super(); this.lineal = lineal; this.partIndex = partIndex; this.segmentIndex = segmentIndex; } @Override public MultiLineStringSegment clone() { return (MultiLineStringSegment)super.clone(); } @Override public int getAxisCount() { return this.lineal.getAxisCount(); } @Override public double getCoordinate(final int vertexIndex, final int axisIndex) { if (vertexIndex < 0 || vertexIndex > 1) { return Double.NaN; } else { final LineString part = getPart(); if (part == null) { return Double.NaN; } else { return part.getCoordinate(this.segmentIndex + vertexIndex, axisIndex); } } } @Override public double[] getCoordinates() { final int axisCount = getAxisCount(); final double[] coordinates = new double[axisCount * 2]; for (int vertexIndex = 0; vertexIndex < 2; vertexIndex++) { for (int axisIndex = 0; axisIndex < axisCount; axisIndex++) { coordinates[vertexIndex * axisCount + axisIndex] = getCoordinate(vertexIndex, axisIndex); } } return coordinates; } @SuppressWarnings("unchecked") @Override public <V extends Geometry> V getGeometry() { return (V)this.lineal; } @Override public GeometryFactory getGeometryFactory() { return this.lineal.getGeometryFactory(); } @Override public Vertex getGeometryVertex(final int index) { final Lineal line = this.lineal; if (index == 0) { return line.getVertex(this.partIndex, this.segmentIndex); } else if (index == 1) { return line.getVertex(this.partIndex, this.segmentIndex + 1); } else { return null; } } public Lineal getLineal() { return this.lineal; } public LineString getPart() { final Lineal multiLine = this.lineal; if (multiLine == null) { return null; } else { return multiLine.getGeometry(this.partIndex); } } @Override public int getPartIndex() { return this.partIndex; } @Override public int[] getSegmentId() { return new int[] { this.partIndex, this.segmentIndex }; } @Override public int getSegmentIndex() { return this.segmentIndex; } @Override public double getX(final int vertexIndex) { if (vertexIndex < 0 || vertexIndex > 1) { return Double.NaN; } else { final LineString part = getPart(); if (part == null) { return Double.NaN; } else { return part.getX(this.segmentIndex + vertexIndex); } } } @Override public double getY(final int vertexIndex) { if (vertexIndex < 0 || vertexIndex > 1) { return Double.NaN; } else { final LineString part = getPart(); if (part == null) { return Double.NaN; } else { return part.getY(this.segmentIndex + vertexIndex); } } } @Override public double getZ(final int vertexIndex) { if (vertexIndex < 0 || vertexIndex > 1) { return Double.NaN; } else { final LineString part = getPart(); if (part == null) { return Double.NaN; } else { return part.getZ(this.segmentIndex + vertexIndex); } } } @Override public boolean hasNext() { if (getGeometry().isEmpty()) { return false; } else { final Lineal line = this.lineal; int partIndex = this.partIndex; int segmentIndex = this.segmentIndex + 1; final int geometryCount = line.getGeometryCount(); while (partIndex < geometryCount) { final LineString part = line.getGeometry(partIndex); final int segmentCount = part.getSegmentCount(); if (segmentIndex < segmentCount) { return true; } else { partIndex++; segmentIndex = 0; } } return false; } } @Override public boolean isLineClosed() { return getPart().isClosed(); } @Override public boolean isLineEnd() { final LineString line = getPart(); return this.segmentIndex == line.getSegmentCount() - 1; } @Override public boolean isLineStart() { return this.segmentIndex == 0; } @Override public Segment next() { final Lineal lineal = this.lineal; this.segmentIndex++; while (this.partIndex < lineal.getGeometryCount()) { final LineString part = getPart(); if (this.segmentIndex < part.getSegmentCount()) { return this; } else { this.partIndex++; this.segmentIndex = 0; } } throw new NoSuchElementException(); } @Override public void remove() { throw new UnsupportedOperationException("Removing segments not supported"); } @Override public void setSegmentId(final int... segmentId) { this.partIndex = segmentId[0]; this.segmentIndex = segmentId[1]; } }