All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.anwiba.spatial.coordinate.MulitSegmentCoordinateSequence Maven / Gradle / Ivy

There is a newer version: 1.2.50
Show newest version
/*
 * #%L
 * anwiba spatial
 * %%
 * Copyright (C) 2007 - 2019 Andreas Bartels
 * %%
 * 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 2.1 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 Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */
// Copyright (c) 2006 by Andreas W. Bartels
package net.anwiba.spatial.coordinate;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import net.anwiba.commons.lang.object.ObjectPair;
import net.anwiba.commons.lang.optional.Optional;
import net.anwiba.commons.lang.stream.Streams;
import net.anwiba.commons.utilities.interval.IntegerInterval;

public class MulitSegmentCoordinateSequence implements ICoordinateSequence {

  private static final long serialVersionUID = 1L;
  private final List segments;
  private final List> indexIntervalsAndSegments = new ArrayList<>();
  private IEnvelope envelope;
  boolean isEmpty;
  int numberOfCoordinates;
  private final boolean isMeasured;
  private final int dimension;

  public MulitSegmentCoordinateSequence(final List segments) {
    this.segments = segments;
    @SuppressWarnings("hiding")
    boolean isEmpty = true;
    @SuppressWarnings("hiding")
    int numberOfCoordinates = 0;
    @SuppressWarnings("hiding")
    boolean isMeasured = segments.isEmpty() ? false : true;
    @SuppressWarnings("hiding")
    int dimension = segments.isEmpty() ? 2 : Integer.MAX_VALUE;
    for (final ICoordinateSequenceSegment segment : this.segments) {
      isMeasured = isMeasured && segment.isMeasured();
      isEmpty = isEmpty && segment.isEmpty();
      final IntegerInterval interval = new IntegerInterval(
          numberOfCoordinates,
          numberOfCoordinates + segment.getNumberOfCoordinates());

      this.indexIntervalsAndSegments.add(new ObjectPair<>(interval, segment));

      numberOfCoordinates = interval.getMaxValue();
      dimension = Math.min(dimension, segment.getDimension());
    }
    this.isEmpty = isEmpty;
    this.numberOfCoordinates = numberOfCoordinates;
    this.isMeasured = isMeasured;
    this.dimension = dimension;
  }

  @Override
  public double getXValue(final int index) {
    return getCoordinateN(index).getXValue();
  }

  @Override
  public double getYValue(final int index) {
    return getCoordinateN(index).getYValue();
  }

  @Override
  public double getZValue(final int index) {
    return getCoordinateN(index).getZValue();
  }

  @Override
  public double[] getXValues() {
    return getOrdinates(ICoordinate.X);
  }

  private double[] getOrdinates(final int index) {
    final double[] result = new double[this.numberOfCoordinates];
    for (final ObjectPair objectPair : this.indexIntervalsAndSegments) {
      final double[] values = objectPair.getSecondObject().getValues()[index];
      System.arraycopy(values, 0, result, objectPair.getFirstObject().getMinValue(), values.length);
    }
    return result;
  }

  @Override
  public double[] getYValues() {
    return getOrdinates(ICoordinate.Y);
  }

  @Override
  public double[] getZValues() {
    return getOrdinates(ICoordinate.Z);
  }

  @Override
  public int getDimension() {
    return this.dimension;
  }

  @Override
  public boolean isMeasured() {
    return this.isMeasured;
  }

  @Override
  public double getMeasuredValue(final int index) {
    return getCoordinateN(index).getMeasuredValue();
  }

  @Override
  public double[] getMeasuredValues() {
    if (!this.isMeasured) {
      throw new IllegalArgumentException("Coordinatesequence has no measured values"); //$NON-NLS-1$
    }
    return getOrdinates(this.dimension);
  }

  @Override
  public ICoordinate getCoordinateN(final int index) {
    for (final ObjectPair objectPair : this.indexIntervalsAndSegments) {
      if (objectPair.getFirstObject().interact(index)) {
        return objectPair.getSecondObject().getCoordinateN(index - objectPair.getFirstObject().getMinValue());
      }
    }
    throw new ArrayIndexOutOfBoundsException(index);
  }

  @Override
  public int getNumberOfCoordinates() {
    return this.numberOfCoordinates;
  }

  @Override
  public double[][] getValues() {
    final double[][] result = new double[this.segments.iterator().next().getValues().length][this.numberOfCoordinates];
    for (final ObjectPair objectPair : this.indexIntervalsAndSegments) {
      final double[][] values = objectPair.getSecondObject().getValues();
      for (int i = 0; i < values.length; i++) {
        System.arraycopy(values[i], 0, result[i], objectPair.getFirstObject().getMinValue(), values[0].length);
      }
    }
    return result;
  }

  @Override
  public String toString() {
    final StringBuffer buffer = new StringBuffer();
    buffer.append("["); //$NON-NLS-1$
    boolean cordinateFlag = false;
    boolean ordinateFlag = false;
    for (final ICoordinate coordinate : getCoordinates()) {
      if (cordinateFlag) {
        buffer.append("; "); //$NON-NLS-1$
      }
      cordinateFlag = true;
      final double[] values = coordinate.getValues();
      ordinateFlag = false;
      for (final double value : values) {
        if (ordinateFlag) {
          buffer.append(", "); //$NON-NLS-1$
        }
        ordinateFlag = true;
        buffer.append(value);
      }
    }
    buffer.append("]"); //$NON-NLS-1$
    return buffer.toString();
  }

  @Override
  public Iterable getCoordinates() {
    return new Iterable() {

      @Override
      public Iterator iterator() {
        return new Iterator() {

          ICoordinate coordinate = null;
          Iterator coordinateIterator;
          Iterator segmentsIterator = MulitSegmentCoordinateSequence.this.segments
              .iterator();

          @Override
          public void remove() {
            throw new UnsupportedOperationException();
          }

          @Override
          public ICoordinate next() {
            try {
              if (hasNext()) {
                return this.coordinate;
              }
              throw new NoSuchElementException();
            } finally {
              this.coordinate = null;
            }
          }

          @Override
          public boolean hasNext() {
            if (this.coordinate != null) {
              return true;
            }
            if (this.coordinateIterator == null || !this.coordinateIterator.hasNext()) {
              if (!this.segmentsIterator.hasNext()) {
                return false;
              }
              this.coordinateIterator = this.segmentsIterator.next().getCoordinates().iterator();
              if (!this.coordinateIterator.hasNext()) {
                return false;
              }
            }
            this.coordinate = this.coordinateIterator.next();
            return true;
          }
        };
      }
    };
  }

  @Override
  public boolean isClosed() {
    if (getNumberOfCoordinates() < 3) {
      return false;
    }
    return getCoordinateN(0).equals(getCoordinateN(getNumberOfCoordinates() - 1));
  }

  @Override
  public Iterable getCoordinateSequenceSegments() {
    return this.segments;
  }

  @Override
  public IEnvelope getEnvelope() {
    this.envelope = Optional.of(this.envelope).getOr(
        () -> Streams
            .of(this.segments)
            .convert(s -> s.getEnvelope())
            .aggregate(Envelope.NULL_ENVELOPE, (i, e) -> i.concat(e))
            .getOr(() -> Envelope.NULL_ENVELOPE));
    return this.envelope;
  }

  @Override
  public boolean isEmpty() {
    return this.isEmpty;
  }

  @Override
  public boolean isCompouned() {
    return this.segments.size() > 1;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy