Package org.geotools.geometry

Source Code of org.geotools.geometry.GeometryBuilder

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2002-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;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import org.geotools.factory.GeoTools;
import org.geotools.factory.Hints;
import org.geotools.referencing.CRS;
import org.opengis.geometry.DirectPosition;
import org.opengis.geometry.Envelope;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.geometry.MismatchedReferenceSystemException;
import org.opengis.geometry.PositionFactory;
import org.opengis.geometry.Precision;
import org.opengis.geometry.aggregate.AggregateFactory;
import org.opengis.geometry.aggregate.MultiCurve;
import org.opengis.geometry.aggregate.MultiPoint;
import org.opengis.geometry.aggregate.MultiPrimitive;
import org.opengis.geometry.aggregate.MultiSurface;
import org.opengis.geometry.complex.ComplexFactory;
import org.opengis.geometry.complex.CompositeCurve;
import org.opengis.geometry.complex.CompositePoint;
import org.opengis.geometry.complex.CompositeSurface;
import org.opengis.geometry.coordinate.GeometryFactory;
import org.opengis.geometry.coordinate.LineSegment;
import org.opengis.geometry.coordinate.LineString;
import org.opengis.geometry.coordinate.PointArray;
import org.opengis.geometry.coordinate.Polygon;
import org.opengis.geometry.coordinate.PolyhedralSurface;
import org.opengis.geometry.coordinate.Position;
import org.opengis.geometry.coordinate.Tin;
import org.opengis.geometry.primitive.Curve;
import org.opengis.geometry.primitive.OrientableCurve;
import org.opengis.geometry.primitive.Point;
import org.opengis.geometry.primitive.Primitive;
import org.opengis.geometry.primitive.PrimitiveFactory;
import org.opengis.geometry.primitive.Ring;
import org.opengis.geometry.primitive.Solid;
import org.opengis.geometry.primitive.SolidBoundary;
import org.opengis.geometry.primitive.Surface;
import org.opengis.geometry.primitive.SurfaceBoundary;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.cs.AxisDirection;
import org.opengis.referencing.cs.CoordinateSystemAxis;

/**
* A Builder to help with Geometry creation.
* <p>
* The factory interfaces provided by GeoAPI are hard to use in isolation (they
* are even hard to collect a matched set in order to work on the same problem).
* The main advantage a "builder" has over a factory is that it does not have to
* be thread safe and can hold state in order to make your job easier.
* <p>
* @author Jody Garnett
*
*
*
*
* @source $URL$
*/
public class GeometryBuilder {
    /**
     * Hints used for the duration of this GeometryBuilder.
     */
    private Hints hints;
   
    /**
     * CoordinateReferenceSystem used to construct the next geometry artifact.
     * <p>
     * This forms the core state of our builds, all other factories are created
     * with this CoordinateReferenceSystem in mind.
     */
    private CoordinateReferenceSystem crs;
   
    private PositionFactory positionFactory;
    private PrimitiveFactory primitiveFactory;
    private AggregateFactory aggregateFactory;
    private ComplexFactory complexFactory;
    private GeometryFactory geometryFactory;
   
    public GeometryBuilder( CoordinateReferenceSystem crs ){
        this.crs = crs;
        this.hints = GeoTools.getDefaultHints();
        hints.put( Hints.CRS, crs );
        hints.put( Hints.GEOMETRY_VALIDATE, true );
    }
   
    public GeometryBuilder( String code ) throws NoSuchAuthorityCodeException, FactoryException{
        this( CRS.decode( code ));
    }
   
    public GeometryBuilder( Hints hints ){
        this.crs = (CoordinateReferenceSystem) hints.get( Hints.CRS );
        this.hints = hints;
        getPositionFactory();
        getPrecision();
        getPrimitiveFactory();
        getAggregateFactory();
        getGeometryFactory();
        getComplexFactory();
    }
   
    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
        return crs;
    }

    public void setCoordianteReferenceSystem( CoordinateReferenceSystem crs ) {
        if( this.crs != crs ){
            hints.remove(Hints.CRS);
            hints.put( Hints.CRS, crs );
            this.crs = crs;
            positionFactory = null;
            primitiveFactory = null;
            aggregateFactory = null;
            complexFactory = null;
            geometryFactory = null;
            getPositionFactory();
            getPrecision();
            getPrimitiveFactory();
            getAggregateFactory();
            getGeometryFactory();
            getComplexFactory();
        }
    }

    public Precision getPrecision() {
        return getPositionFactory().getPrecision();
    }
   
    public PositionFactory getPositionFactory() {
        if( positionFactory == null ){
            if( hints.containsKey(Hints.POSITION_FACTORY)){
                // check the hints for something explicit
                Object factory = hints.get(Hints.POSITION_FACTORY);
                if( factory instanceof PositionFactory){
                    positionFactory = (PositionFactory) factory;
                    return positionFactory;
                }
            }
            positionFactory = GeometryFactoryFinder.getPositionFactory( hints);
        }
        return positionFactory;
    }

    public PrimitiveFactory getPrimitiveFactory() {
        if( primitiveFactory == null ){
            if( hints.containsKey(Hints.PRIMITIVE_FACTORY)){
                // check the hints for something explicit
                Object factory = hints.get(Hints.PRIMITIVE_FACTORY);
                if( factory instanceof PrimitiveFactory){
                    primitiveFactory = (PrimitiveFactory) factory;
                    return primitiveFactory;
                }
            }
            primitiveFactory = GeometryFactoryFinder.getPrimitiveFactoryhints);
        }
        return primitiveFactory;
    }
   
    public AggregateFactory getAggregateFactory() {
        if( aggregateFactory == null ){
            if( hints.containsKey(Hints.AGGREGATE_FACTORY)){
                // check the hints for something explicit
                Object factory = hints.get(Hints.AGGREGATE_FACTORY);
                if( factory instanceof AggregateFactory){
                    aggregateFactory = (AggregateFactory) factory;
                    return aggregateFactory;
                }
            }           
          aggregateFactory = GeometryFactoryFinder.getAggregateFactory( hints);
        }
        return aggregateFactory;
    }
   
    public GeometryFactory getGeometryFactory() {
        if( geometryFactory == null ){
            if( hints.containsKey(Hints.GEOMETRY_FACTORY)){
                // check the hints for something explicit
                Object factory = hints.get(Hints.GEOMETRY_FACTORY);
                if( factory instanceof GeometryFactory){
                    geometryFactory = (GeometryFactory) factory;
                    return geometryFactory;
                }
            }           
            geometryFactory = GeometryFactoryFinder.getGeometryFactoryhints);
        }
        return geometryFactory;
    }
   
    public ComplexFactory getComplexFactory() {
        if( complexFactory == null ){
            if( hints.containsKey(Hints.COMPLEX_FACTORY)){
                // check the hints for something explicit
                Object factory = hints.get(Hints.COMPLEX_FACTORY);
                if( factory instanceof ComplexFactory){
                    complexFactory = (ComplexFactory) factory;
                    return complexFactory;
                }
            }
          complexFactory = GeometryFactoryFinder.getComplexFactoryhints);
        }
        return complexFactory;
    }   
   
    public DirectPosition createDirectPosition( double[] ordinates ) {
        return getPositionFactory().createDirectPosition( ordinates );
    }

    public Position createPosition( Position position ) {
        return getPositionFactory().createPosition( position );
    }

    public PointArray createPointArray() {
        return getPositionFactory().createPointArray();
    }

    public PointArray createPointArray( double[] array ) {
        return getPositionFactory().createPointArray(array, 0, array.length / crs.getCoordinateSystem().getDimension() );
    }
    public PointArray createPointArray( double[] array, int start, int end ) {
        return getPositionFactory().createPointArray(array, start, end );
    }

    public PointArray createPositionList( float[] array, int start, int end ) {
        return getPositionFactory().createPointArray(array, start, end );
    }

  public Curve createCurve(List segments) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    if (segments == null)
      throw new NullPointerException("Segments are required to create a curve");

    // A curve will be created
    // - The curve will be set as parent curves for the Curve segments
    // - Start and end params for the CurveSegments will be set
    return getPrimitiveFactory().createCurve(segments);
  }
    public Curve createCurve(PointArray points) throws MismatchedReferenceSystemException, MismatchedDimensionException {
        if (points == null)
            throw new NullPointerException("Points are required to create a curve");

        // A curve will be created
        // - The curve will be set as parent curves for the Curve segments
        // - Start and end params for the CurveSegments will be set
        List/*<LineSegment>*/ segmentList = new ArrayList/*<LineSegment>*/();
        for( int i=0; i<points.size();i++){
            int start = i;
            int end = (i+1)%points.size();
            DirectPosition point1 = points.getDirectPosition( start, null );
            DirectPosition point2 = points.getDirectPosition( end, null );
            LineSegment segment = createLineSegment( point1, point2 );
            segmentList.add( segment );
        }
        return getPrimitiveFactory().createCurve( segmentList );
    }

  /**
   * Create a point with the provided ordinates.
   * @param ord1
   * @param ord2
   * @return createPoint( new double[]{ ord1, ord2})
   */
  public Point createPoint( double ord1, double ord2 ){
      return createPoint( new double[]{ ord1, ord2});
  }
  /**
   * Create a point with the provided ordinates.
   * @param ord1
   * @param ord2
   * @param ord3
   * @return createPoint( new double[]{ ord1, ord2, ord3 })
   */
  public Point createPoint( double ord1, double ord2, double ord3 ){
        return createPoint( new double[]{ ord1, ord2, ord3 });
    }
  /**
   * Create a point with the provided ordinates
   * @param ordinates
   * @return getPrimitiveFactory().createPoint(coordinates)
   * @throws MismatchedDimensionException
   */
  public Point createPoint(double[] ordinates) throws MismatchedDimensionException {
    if (ordinates == null)
      throw new NullPointerException("Ordinates required to create a point");
    int dimension = this.getCoordinateReferenceSystem().getCoordinateSystem().getDimension();
        if (ordinates.length != dimension)
      throw new MismatchedDimensionException("Create point requires "+dimension+" ordinates ("+ordinates.length+" provided");

    return getPrimitiveFactory().createPoint(ordinates);
  }

  public Point createPoint(Position position) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    if (position == null) {
      throw new NullPointerException();
    }
    setCoordianteReferenceSystem(position.getDirectPosition().getCoordinateReferenceSystem());
    DirectPosition copy = (DirectPosition) getPositionFactory().createDirectPosition(position.getDirectPosition().getCoordinate());
    return getPrimitiveFactory().createPoint(copy);
  }

  public Primitive createPrimitive(Envelope envelope) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    LineSegment segment = processBoundsToSegment(envelope);   
    setCoordianteReferenceSystem(envelope.getCoordinateReferenceSystem());
    return processSegmentToPrimitive( envelope, segment, 1 )
  }
 
  private Primitive processSegmentToPrimitive(Envelope bounds, LineSegment segment, int dimension) {
    CoordinateSystemAxis axis = crs.getCoordinateSystem().getAxis( dimension );
   
    if( axis.getDirection() == AxisDirection.OTHER ){
      return processSegmentToPrimitive( bounds, segment, dimension+1 );
    }
    Ring ring = processBoundsToRing( bounds, segment, dimension );
    return processRingToPrimitive( bounds, ring, dimension+1 );       
  }
 
  private Ring processBoundsToRing( Envelope bounds, LineSegment segment, final int D ){
    DirectPosition one =  getPositionFactory().createDirectPosition(segment.getStartPoint().getCoordinate());
    one.setOrdinate( D, bounds.getMinimum(D) );
   
    DirectPosition two =  getPositionFactory().createDirectPosition(segment.getEndPoint().getCoordinate());
    two.setOrdinate( D, bounds.getMinimum(D) );
   
    DirectPosition three =  getPositionFactory().createDirectPosition(two.getCoordinate());
    three.setOrdinate( D, bounds.getMaximum(D) );
   
    DirectPosition four =  getPositionFactory().createDirectPosition(one.getCoordinate());
    four.setOrdinate( D, bounds.getMaximum(D) );
   
    LineSegment edge1 = getGeometryFactory().createLineSegment(one, two);
    LineSegment edge2 = getGeometryFactory().createLineSegment(two, three);
    LineSegment edge3 = getGeometryFactory().createLineSegment(three, four);
    LineSegment edge4 = getGeometryFactory().createLineSegment(four, one);
   
    List<OrientableCurve> edges = new ArrayList<OrientableCurve>();
    edges.add( createCurve( Arrays.asList(edge1) ));
    edges.add( createCurve( Arrays.asList(edge2) ));
    edges.add( createCurve( Arrays.asList(edge3) ));
    edges.add( createCurve( Arrays.asList(edge4) ));
    return createRing( edges );
  }
 
  private Primitive processRingToPrimitive(Envelope bounds, Ring ring, int dimension) {
    int D = crs.getCoordinateSystem().getDimension();
    if( dimension == D ){ // create Surface from ring and return     
      SurfaceBoundary boundary = createSurfaceBoundary( ring, Collections.EMPTY_LIST );
      return createSurface( boundary );
    }   
    CoordinateSystemAxis axis = crs.getCoordinateSystem().getAxis( dimension );
    if( axis.getDirection() == AxisDirection.OTHER ){
      return processRingToPrimitive( bounds, ring, dimension+1 );
    }
    return processRingToVolumne( bounds, ring, dimension+1 );
  }
 
  private Primitive processRingToVolumne(Envelope bounds, Ring ring, int i) {
    // go into a volume
    throw new UnsupportedOperationException("Not yet 3D");
  }
 
  private LineSegment processBoundsToSegment( Envelope bounds ) {
    final int D=0;
    CoordinateReferenceSystem crs = bounds.getCoordinateReferenceSystem();
    CoordinateSystemAxis axis = crs.getCoordinateSystem().getAxis( D );
   
    DirectPosition positionA = getPositionFactory().createDirectPosition(null);
    DirectPosition positionB = getPositionFactory().createDirectPosition(null)
    if( axis.getDirection() != AxisDirection.OTHER ){
      positionA.setOrdinate(D, bounds.getMinimum(D) );
      positionB.setOrdinate(D, bounds.getMaximum(D) );
    }   
    return getGeometryFactory().createLineSegment(positionA, positionB);
  }
 
  public Ring createRing(List<OrientableCurve> orientableCurves)
    throws MismatchedReferenceSystemException, MismatchedDimensionException {
    /**
     * Creates a Ring from triple Array of DirectPositions (Array of arrays,
     * which each represent a future Curve. Each array contain an array of
     * positions, which each represent a future lineString)
     */
    return getPrimitiveFactory().createRing(orientableCurves);
  }

  public Solid createSolid(SolidBoundary boundary) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    return getPrimitiveFactory().createSolid(boundary);
  }

    public SurfaceBoundary createSurfaceBoundary(PointArray points ) throws MismatchedReferenceSystemException, MismatchedDimensionException {
        Curve curve = createCurve( points );
        return createSurfaceBoundary( curve);
    }
  public Surface createSurface(List surfaces) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    return getPrimitiveFactory().createSurface(surfaces);
  }

  public Surface createSurface(SurfaceBoundary boundary) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    return getPrimitiveFactory().createSurface(boundary);
  }

  public SurfaceBoundary createSurfaceBoundary(Ring exterior, List interiors) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    return getPrimitiveFactory().createSurfaceBoundary(exterior, interiors);
  }
 
  public SurfaceBoundary createSurfaceBoundary(Ring exterior) throws MismatchedReferenceSystemException, MismatchedDimensionException {
        return createSurfaceBoundary( exterior, new ArrayList<Ring>() );
    }

  public SurfaceBoundary createSurfaceBoundary(OrientableCurve curve) throws MismatchedReferenceSystemException, MismatchedDimensionException {
      List<OrientableCurve> exterior = new ArrayList<OrientableCurve>(1);
      exterior.add( curve );
      Ring ring = createRing( exterior );
        return createSurfaceBoundary( ring );
    }
 
  /* not implemented in GeometryFactory yet
  public Arc createArc(Position startPoint, Position midPoint, Position endPoint) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    // TODO Auto-generated method stub
    return null;
  }

  public Arc createArc(Position startPoint, Position endPoint, double bulge, double[] normal) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    // TODO Auto-generated method stub
    return null;
  }

  public ArcByBulge createArcByBulge(Position startPoint, Position endPoint, double bulge, double[] normal) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    // TODO Auto-generated method stub
    return null;
  }

  public ArcString createArcString(List points) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    // TODO Auto-generated method stub
    return null;
  }

  public ArcStringByBulge createArcStringByBulge(List points, double[] bulges, List normals) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    // TODO Auto-generated method stub
    return null;
  }

  public BSplineCurve createBSplineCurve(int degree, PointArray points, List knots, KnotType knotSpec) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    // TODO Auto-generated method stub
    return null;
  }

  public BSplineSurface createBSplineSurface(List points, int[] degree, List[] knots, KnotType knotSpec) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    // TODO Auto-generated method stub
    return null;
  }
 
  public Geodesic createGeodesic(Position startPoint, Position endPoint) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    // TODO Auto-generated method stub
    return null;
  }

  public GeodesicString createGeodesicString(List points) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    // TODO Auto-generated method stub
    return null;
  }
  */

  public DirectPosition createDirectPosition() {
    return createDirectPosition(null);
  }

  public Envelope createEnvelope(DirectPosition lowerCorner, DirectPosition upperCorner) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    return getGeometryFactory().createEnvelope(lowerCorner, upperCorner);
  }

  public LineSegment createLineSegment(Position startPoint, Position endPoint) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    return getGeometryFactory().createLineSegment(startPoint, endPoint);
  }

  public LineString createLineString(List points) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    return getGeometryFactory().createLineString(points);
  }
  public LineString createLineString(PointArray points) throws MismatchedReferenceSystemException, MismatchedDimensionException {
      return getGeometryFactory().createLineString(points);
    }
  public LineSegment createLineSegment( DirectPosition from, DirectPosition to ) {
        return getGeometryFactory().createLineSegment( from, to );
    }
  public MultiPrimitive createMultiPrimitive() {
    return getGeometryFactory().createMultiPrimitive();
  }

  public Polygon createPolygon(SurfaceBoundary boundary) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    return getGeometryFactory().createPolygon(boundary);
  }

  public Polygon createPolygon(SurfaceBoundary boundary, Surface spanSurface) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    return getGeometryFactory().createPolygon(boundary, spanSurface);
  }

  public PolyhedralSurface createPolyhedralSurface(List tiles) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    return getGeometryFactory().createPolyhedralSurface(tiles);
  }

  public Tin createTin(Set post, Set stopLines, Set breakLines, double maxLength) throws MismatchedReferenceSystemException, MismatchedDimensionException {
    return getGeometryFactory().createTin(post, stopLines, breakLines, maxLength);
  }

  public CompositeCurve createCompositeCurve(List generator) {
    return getComplexFactory().createCompositeCurve(generator);
  }

  public CompositePoint createCompositePoint(Point generator) {
    return getComplexFactory().createCompositePoint(generator);
  }

  public CompositeSurface createCompositeSurface(List generator) {
    return getComplexFactory().createCompositeSurface(generator);
  }

  public MultiCurve createMultiCurve(Set curves) {
    return getAggregateFactory().createMultiCurve(curves);
  }

  public MultiPoint createMultiPoint(Set points) {
    return getAggregateFactory().createMultiPoint(points);
  }

  public MultiPrimitive createMultiPrimitive(Set primitives) {
    return getAggregateFactory().createMultiPrimitive(primitives);
  }

  public MultiSurface createMultiSurface(Set surfaces) {
    return getAggregateFactory().createMultiSurface(surfaces);
  }

}
TOP

Related Classes of org.geotools.geometry.GeometryBuilder

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.