Package org.geotools.geometry.iso.complex

Source Code of org.geotools.geometry.iso.complex.CompositeCurveImpl

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*   
*    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
*   
*    This library 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;
*    version 2.1 of the License.
*
*    This library 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.
*/
package org.geotools.geometry.iso.complex;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.geotools.geometry.iso.coordinate.DirectPositionImpl;
import org.geotools.geometry.iso.coordinate.EnvelopeImpl;
import org.geotools.geometry.iso.coordinate.LineStringImpl;
import org.geotools.geometry.iso.io.GeometryToString;
import org.geotools.geometry.iso.primitive.CurveBoundaryImpl;
import org.geotools.geometry.iso.primitive.CurveImpl;
import org.geotools.geometry.iso.primitive.OrientableCurveImpl;
import org.geotools.geometry.iso.primitive.PointImpl;
import org.geotools.geometry.iso.util.DoubleOperation;
import org.opengis.geometry.DirectPosition;
import org.opengis.geometry.Envelope;
import org.opengis.geometry.complex.Complex;
import org.opengis.geometry.complex.CompositeCurve;
import org.opengis.geometry.primitive.Curve;
import org.opengis.geometry.primitive.CurveBoundary;
import org.opengis.geometry.primitive.OrientableCurve;
import org.opengis.geometry.primitive.OrientablePrimitive;
import org.opengis.geometry.primitive.Primitive;

/**
*
* A composite curve, CompositeCurve shall be a Composite with all the geometric
* properties of a curve. These properties are instantiated in the operation
* "curve". Essentially, a composite curve is a list of orientable curves
* (OrientableCurve) agreeing in orientation in a manner such that each curve
* (except the first) begins where the previous one ends.
*
* @author Jackson Roehrig & Sanjay Jena
*
*
*
*
* @source $URL$
*/
public class CompositeCurveImpl extends CompositeImpl<OrientableCurveImpl>
    implements CompositeCurve {
    private static final long serialVersionUID = -5774107742557426260L;
    protected EnvelopeImpl envelope = null;

  /**
   * The association role Composition::generator associates this
   * CompositeCurve to the primitive Curves and OrientableCurves in its
   * generating set, the curves that form the core of this complex.
   * CompositeCurve::generator : Sequence<OrientableCurve> -- the start point
   * of each orientable curve in the generator is the -- end point of the
   * previous one CompositeCurve: forAll (1 < j < generator.count - 1)?
   * generator[j].endPoint = generator[j+1].startPoint;
   *
   * NOTE To get a full representation of the elements in the Complex, the
   * Points on the boundary of the generator set of Curve would be added to
   * the curves in the generator list.
   *
   * The generator elements will be passed through the super constructor. The
   * plausibility of the Curves will be checked within the constructor of the
   * CompositeCurve
   *
   * Constructs a Composite Curve
   * @param generator
   */
  public CompositeCurveImpl(List<OrientableCurve> generator) {
    /* Pass elements to super constructor */
    super(generator);
    this.checkConsistency();
  }

  /**
   * - Check plausibility, if all curve elements are continuous
   * - Build Envelope
   */
  private void checkConsistency() {
    /* Check plausibility, if all curve elements are continuous */
    Iterator<? extends Primitive> ci = this.elements.iterator();
    if (!ci.hasNext())
      throw new IllegalArgumentException("Curve has no elements."); //$NON-NLS-1$
    CurveImpl c0 = (CurveImpl) ci.next();
    ;
    //this.envelope = new EnvelopeImpl(c0.getEnvelope());
    this.envelope = new EnvelopeImpl(c0.getEnvelope());
    while (ci.hasNext()) {
      CurveImpl c1 = (CurveImpl) ci.next();
      this.envelope.expand(c1.getEnvelope());
     
      DirectPosition startPoint = c1.getStartPoint();
      DirectPosition endPoint = c0.getEndPoint();
      if (!endPoint.equals(startPoint)){
        throw new IllegalArgumentException(
            "Curve elements are not continous. The end point of a curve has to accord to the start point of the following curve."); //$NON-NLS-1$
      }
      c0 = c1;
    }

  }

  /* (non-Javadoc)
   * @see org.geotools.geometry.featgeom.complex.ComplexImpl#getElements()
   */
  public List<Primitive> getElements() {
    // Override to return a List
    return (List<Primitive>) super.getElements();
  }

  /* (non-Javadoc)
   * @see org.geotools.geometry.featgeom.complex.ComplexImpl#createBoundary()
   */
  public Set<Complex> createBoundary() {
    /*
     * used after construction, when the generators were already defined.
     * derived classes (e.g. Ring) may overwrite these method
     */
    List<Primitive> generator = this.getElements();
    if (generator == null)
      throw new IllegalArgumentException(
          "Could not create the boundary of CompositeCurve."); //$NON-NLS-1$
    HashSet<Complex> result = new HashSet<Complex>();
    result.add( new CurveBoundaryImpl( getCoordinateReferenceSystem(),
        new PointImpl( ((CurveImpl) generator
            .get(0)).getStartPoint()), new PointImpl( ((CurveImpl) generator
                .get(0)).getEndPoint()) ) );

    return result;
  }

  /* (non-Javadoc)
   * @see org.geotools.geometry.featgeom.complex.CompositeImpl#getGeneratorClass()
   */
  public Class getGeneratorClass() {
    return OrientableCurveImpl.class;
  }

  /**
   * Returns all control points of the Ring as one LineString
   *
   * @return Returns all control points of the Ring as one LineString
   */
  // public LineString asLineString() {
  // int len = 0;
  // /* All Curves of the CompositeCurve */
  // OrientableCurve tmpCurves[] = this.getGenerators();
  // /* Two dimensional array with all LineSegments for each curve */
  // LineSegment tmpLineSegments[][] = new LineSegment[tmpCurves.length][];
  // /* Copy LineSegments into array and count number of segments */
  // for (int i=0; i<tmpCurves.length; i++) {
  // tmpLineSegments[i] = tmpCurves[i].asLineString(0, 0).asLineSegment();
  // len += tmpLineSegments[i].length;
  // }
  // /* Array of Position - one position for each point of the LineSegments */
  // Position tmpPositions[] = new Position[len];
  // /* First Point */
  // tmpPositions[0] = new Position(tmpLineSegments[0][0].startPoint());
  // int index = 1;
  // /* Copy all following end points into the array of the positions */
  // for (int i=0; i<tmpLineSegments.length; i++) {
  // for (int j=0; j<tmpLineSegments[i].length; j++) {
  // tmpPositions[index] = new Position(tmpLineSegments[i][j].endPoint());
  // index++;
  // }
  // }
  // /* Return new LineString, created by the array of Positions of all curves
  // */
  // return new LineString(tmpPositions);
  // }

  /***************************************************************************
   * ********************************************************* * Method
   * implementation of Interface Object **
   * *********************************************************
   **************************************************************************/

  /**
   * The method <code>dimension</code> returns the inherent dimension of
   * this Object, which is less than or equal to the coordinate dimension. The
   * dimension of a collection of geometric objects is the largest dimension
   * of any of its pieces. Points are 0-dimensional, curves are 1-dimensional,
   * surfaces are 2-dimensional, and solids are 3-dimensional. Locally, the
   * dimension of a geometric object at a point is the dimension of a local
   * neighborhood of the point - that is the dimension of any coordinate
   * neighborhood of the point. Dimension is unambiguously defined only for
   * DirectPositions interior to this Object. If the passed DirectPosition2D
   * is NULL, then the method returns the largest possible dimension for any
   * DirectPosition2D in this Object.
   *
   * @param point
   *            a <code>DirectPosition2D</code> value
   * @return an <code>int</code> value
   */
  public int getDimension(@SuppressWarnings("unused")
  final DirectPositionImpl point) {
    return 1;
  }


  /* (non-Javadoc)
   * @see org.geotools.geometry.featgeom.root.GeometryImpl#getEnvelope()
   */
  public Envelope getEnvelope() {
    return this.envelope;
  }


  /* (non-Javadoc)
   * @see org.geotools.geometry.featgeom.root.GeometryImpl#getBoundary()
   */
  public CurveBoundary getBoundary() {
    // Return start and end point
    DirectPosition start = ((Curve)this.getGenerators().get(0)).getStartPoint();
    DirectPosition end = ((Curve)this.getGenerators().get(this.elements.size())).getEndPoint();
    // Compare start point with end point
    if (start.equals(end))
      // the boundary is null if the composite curve is closed
      return null;
    else
      return new CurveBoundaryImpl(getCoordinateReferenceSystem(),
          new PointImpl(start),
          new PointImpl(end));
      //return this.getFeatGeometryFactory().getPrimitiveFactory().createCurveBoundary(start, end);
  }

  /**
   * @return LineStringImpl
   */
  public LineStringImpl asLineString() {
    return this.asLineString(0.0, 0.0);
  }

  /**
   * @param maxSpacing
   * @param maxOffset
   * @return LineStringImpl
   */
  public LineStringImpl asLineString(double maxSpacing, double maxOffset) {
    // The function "asLineString" constructs a line string (sequence of
    // line segments) where the control points (ends of
    // the segments) lie on this curve. If "maxSpacing" is given (not zero),
    // then the distance between control points along
    // the generated curve shall be not more than "maxSpacing". If
    // "maxOffset" is given (not zero), the distance between
    // generated curve at any point and the original curve shall not be more
    // than the "maxOffset". If both parameters are
    // set, then both criteria shall be met. If the original control points
    // of the curve lie on the curve, then they shall be
    // included in the returned LineString's controlPoints. If both
    // parameters are set to zero, then the line string
    // returned shall be constructed from the control points of the original
    // curve.
    // GenericCurve::asLineString(spacing : Distance = 0, offset : Distance
    // = 0)
    // : LineString
    // NOTE This function is useful in creating linear approximations of the
    // curve for simple actions such as display. It is often
    // referred to as a "stroked curve". For this purpose, the "maxOffset"
    // version is useful in maintaining a minimal representation of
    // the curve appropriate for the display device being targeted. This
    // function is also useful in preparing to transform a curve from
    // one coordinate reference system to another by transforming its
    // control points. In this case, the "maxSpacing" version is more
    // appropriate. Allowing both parameters to default to zero does not
    // seem to have any useful geographic nor geometric
    // interpretation unless further information is known about how the
    // curves were constructed.

    List<Primitive> primitives = this.getElements();
    if (primitives == null || primitives.isEmpty())
      return null;
    // JR error: parameter maxSpacing and maxOffset were not passed
    LineStringImpl result = ((CurveImpl) primitives.get(0)).asLineString(
        maxSpacing, maxOffset);
    for (int i = 1; i < primitives.size(); ++i) {
      CurveImpl curve = ((CurveImpl) primitives.get(i));
      result = result.merge(curve.asLineString(maxSpacing, maxOffset));
    }
    return result;

  }

  /**
   * @return length
   */
  public double getLength() {
    List<OrientableCurve> tmpCurves = this.getGenerators();
    if (tmpCurves.isEmpty())
      return 0.0;

    double length = 0.0;
    /* Add envelopes of the other Curves */
    for (int i = 1; i < tmpCurves.size(); ++i) {
      length = DoubleOperation.add(length, ((CurveImpl) tmpCurves.get(i)).length());
      //length += ((CurveImpl) tmpCurves.get(i)).length();
    }
    return length;
  }

  /**
   * @param distance
   */
  public void split(double distance) {
    for (Primitive primitive : this.getElements()) {
      ((CurveImpl) primitive).split(distance);
    }
  }

  /* (non-Javadoc)
   * @see org.geotools.geometry.featgeom.root.GeometryImpl#clone()
   */
  public CompositeCurveImpl clone() throws CloneNotSupportedException {
    // TODO Test
    Iterator<Curve> elementIter = (Iterator<Curve>) this.elements.iterator();
    List<OrientableCurve> newElements = new ArrayList<OrientableCurve>();
    while (elementIter.hasNext()) {
      newElements.add((Curve) elementIter.next().clone());
    }
    return (CompositeCurveImpl) new CompositeCurveImpl(newElements);
    //return (CompositeCurveImpl) this.getFeatGeometryFactory().getComplexFactory().createCompositeCurve(newElements);
  }

  /* (non-Javadoc)
   * @see org.opengis.geometry.coordinate.root.Geometry#isSimple()
   */
  public boolean isSimple() {
    // TODO semantic SJ, JR
    // TODO implementation
    // TODO test
    // TODO documentation
    return false;
  }
  

  /* (non-Javadoc)
   * @see org.opengis.geometry.primitive.OrientableCurve#getComposite()
   */
  public CompositeCurve getComposite() {
    // TODO semantic SJ, JR
    // TODO implementation
    // TODO test
    // TODO documentation
    return null;
  }

  /* (non-Javadoc)
   * @see org.opengis.geometry.primitive.OrientablePrimitive#getOrientation()
   */
  public int getOrientation() {
    // TODO semantic SJ, JR
    // TODO implementation
    // TODO test
    // TODO documentation
    return 0;
  }

  /* (non-Javadoc)
   * @see org.opengis.geometry.primitive.OrientablePrimitive#getPrimitive()
   */
  public Curve getPrimitive() {
    // TODO semantic SJ, JR
    // TODO implementation
    // TODO test
    // TODO documentation
    return null;
  }

  /* (non-Javadoc)
   * @see org.opengis.geometry.primitive.Primitive#getContainedPrimitives()
   */
  public Set getContainedPrimitives() {
    // TODO semantic SJ, JR
    // TODO implementation
    // TODO test
    // TODO documentation
    return null;
  }

  /* (non-Javadoc)
   * @see org.opengis.geometry.primitive.Primitive#getContainingPrimitives()
   */
  public Set getContainingPrimitives() {
    // TODO semantic SJ, JR
    // TODO implementation
    // TODO test
    // TODO documentation
    return null;
  }

  /* (non-Javadoc)
   * @see org.opengis.geometry.primitive.Primitive#getComplexes()
   */
  public Set getComplexes() {
    // TODO semantic SJ, JR
    // TODO implementation
    // TODO test
    // TODO documentation
    return null;
  }

  /* (non-Javadoc)
   * @see org.opengis.geometry.primitive.Primitive#getProxy()
   */
  public OrientablePrimitive[] getProxy() {
    // TODO semantic SJ, JR
    // TODO implementation
    // TODO test
    // TODO documentation
    return null;
  }

  /* (non-Javadoc)
   * @see org.opengis.geometry.complex.Composite#getGenerators()
   */
  public List<OrientableCurve> getGenerators() {
    // ok
    // Return the curves which define this CompositeCurve
    return (List<OrientableCurve>) this.elements;
  }

  /* (non-Javadoc)
   * @see org.geotools.geometry.featgeom.root.GeometryImpl#getDimension(org.opengis.geometry.coordinate.DirectPosition)
   */
  public int getDimension(DirectPosition point) {
    // TODO documentation
    return 1;
  }

  /* (non-Javadoc)
   * @see org.geotools.geometry.featgeom.root.GeometryImpl#getRepresentativePoint()
   */
  public DirectPosition getRepresentativePoint() {
    // Use representative point of the first curve of the generator list
    return this.elements.get(0).getRepresentativePoint();
  }
 
  /* (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  public String toString() {
    return GeometryToString.getString(this);
  }

  @Override
  public int hashCode() {
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + ((envelope == null) ? 0 : envelope.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    final CompositeCurveImpl other = (CompositeCurveImpl) obj;
    if (envelope == null) {
      if (other.envelope != null)
        return false;
    } else if (!envelope.equals(other.envelope))
      return false;
    return true;
  }

}
TOP

Related Classes of org.geotools.geometry.iso.complex.CompositeCurveImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.