|
|
|
svn_geotools
|
Author: jive
Date: 2009-10-25 02:32:17 -0400 (Sun, 25 Oct 2009) New Revision: 34237 Added: branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/DuplicateBuilder.java branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/SFGeometryBuilder.java Modified: branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/GeometryFactory.java Log: working on jts method compatible builder Added: branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/DuplicateBuilder.java =================================================================== --- branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/DuplicateBuilder.java (rev 0) +++ branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/DuplicateBuilder.java 2009-10-25 06:32:17 UTC (rev 34237) @@ -0,0 +1,39 @@ +package org.osgeo.geometry; + +import org.osgeo.geometry.Geometry.GeometryType; + +/** + * Provide a deep copy; used to duplicate a geometry or translate into an alternate implementation. + * @author Jody Garnett + */ +public class DuplicateBuilder { + private GeometryFactory factory; + + public DuplicateBuilder( GeometryFactory factory ){ + this.factory = factory; + } + + public Geometry copy( Geometry geometry){ + if( geometry == null ) { + return null; + } + switch( geometry.getGeometryType() ){ + case ENVELOPE: + return copy( (Envelope) geometry ); + + case PRIMITIVE_GEOMETRY: + + case COMPOSITE_GEOMETRY: + + case MULTI_GEOMETRY: + + default: + throw new IllegalStateException("Unexpected geometry type "+ geometry.getGeometryType() ); + } + } + + public Envelope copy( Envelope envelope ){ + return envelope; + } + +} Modified: branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/GeometryFactory.java =================================================================== --- branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/GeometryFactory.java 2009-10-25 05:02:38 UTC (rev 34236) +++ branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/GeometryFactory.java 2009-10-25 06:32:17 UTC (rev 34237) @@ -203,7 +203,7 @@ * @return created {@link MultiPoint} */ public MultiPoint multiPoint(String id, CRS crs, List<Point> members); - + /** * Creates a {@link MultiCurve} from a list of passed {@link LineString}s. * Added: branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/SFGeometryBuilder.java =================================================================== --- branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/SFGeometryBuilder.java (rev 0) +++ branches/geometry/spike/geometry/src/main/java/org/osgeo/geometry/SFGeometryBuilder.java 2009-10-25 06:32:17 UTC (rev 34237) @@ -0,0 +1,462 @@ +/* + * OSGeom -- Geometry Collab + * + * (C) 2009, Open Source Geospatial Foundation (OSGeo) + * (C) 2001, Vivid Solutions + * + * 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.osgeo.geometry; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.osgeo.commons.crs.CRS; +import org.osgeo.geometry.multi.MultiGeometry; +import org.osgeo.geometry.multi.MultiLineString; +import org.osgeo.geometry.multi.MultiPoint; +import org.osgeo.geometry.points.Points; +import org.osgeo.geometry.primitive.LineString; +import org.osgeo.geometry.primitive.LinearRing; +import org.osgeo.geometry.primitive.Point; +import org.osgeo.geometry.primitive.Polygon; +import org.osgeo.geometry.primitive.Ring; + +import com.vividsolutions.jts.geom.MultiPolygon; + +/** + * A method compatible builder with JTS Topology Suite GeometryFactory. + * <p> + * This factory captures the simple feature for SQL constructs represented by the JTS library. + * </p> + * + * @author Jody Garnett + * + */ +public class SFGeometryBuilder { + private GeometryFactory factory; + private CRS crs; + + public SFGeometryBuilder( GeometryFactory factory, CRS crs ){ + this.factory = factory; + this.crs = crs; + } + + /** + * Converts the <code>List</code> to an array. + * + *@param points + * the <code>List</code> of Points to convert + *@return the <code>List</code> in array format + */ + public Points toPointArray(Collection<Point> points) { + if( points == null){ + return null; + } + List<Point> list; + if( points instanceof List){ + list = (List<Point>) points; + } + else { + list = new ArrayList<Point>( points ); + } + return factory.points( list, crs ); + } + + /** + * Converts the <code>List</code> to an array. + * + *@param geometries + * the list of <code>Geometry's</code> to convert + *@return the <code>List</code> in array format + */ + public static Geometry[] toGeometryArray(Collection<Geometry> geometries) { + if (geometries == null){ + return null; + } + Geometry[] geometryArray = new Geometry[geometries.size()]; + return (Geometry[]) geometries.toArray(geometryArray); + } + + /** + * Converts the <code>List</code> to an array. + * + *@param linearRings + * the <code>List</code> of LinearRings to convert + *@return the <code>List</code> in array format + */ + public static LinearRing[] toLinearRingArray(Collection linearRings) { + LinearRing[] linearRingArray = new LinearRing[linearRings.size()]; + return (LinearRing[]) linearRings.toArray(linearRingArray); + } + + /** + * Converts the <code>List</code> to an array. + * + *@param lineStrings + * the <code>List</code> of LineStrings to convert + *@return the <code>List</code> in array format + */ + public static LineString[] toLineStringArray(Collection lineStrings) { + LineString[] lineStringArray = new LineString[lineStrings.size()]; + return (LineString[]) lineStrings.toArray(lineStringArray); + } + + /** + * Converts the <code>List</code> to an array. + * + *@param polygons + * the <code>List</code> of Polygons to convert + *@return the <code>List</code> in array format + */ + public static Polygon[] toPolygonArray(Collection polygons) { + Polygon[] polygonArray = new Polygon[polygons.size()]; + return (Polygon[]) polygons.toArray(polygonArray); + } + + /** + * Converts the <code>List</code> to an array. + * + *@param multiPolygons + * the <code>List</code> of MultiPolygons to convert + *@return the <code>List</code> in array format + */ + public static MultiPolygon[] toMultiPolygonArray(Collection multiPolygons) { + MultiPolygon[] multiPolygonArray = new MultiPolygon[multiPolygons.size()]; + return (MultiPolygon[]) multiPolygons.toArray(multiPolygonArray); + } + + /** + * Converts the <code>List</code> to an array. + * + *@param multiLineStrings + * the <code>List</code> of MultiLineStrings to convert + *@return the <code>List</code> in array format + */ + public static MultiLineString[] toMultiLineStringArray(Collection multiLineStrings) { + MultiLineString[] multiLineStringArray = new MultiLineString[multiLineStrings.size()]; + return (MultiLineString[]) multiLineStrings.toArray(multiLineStringArray); + } + + /** + * Converts the <code>List</code> to an array. + * + *@param multiPoints + * the <code>List</code> of MultiPoints to convert + *@return the <code>List</code> in array format + */ + public static MultiPoint[] toMultiPointArray(Collection multiPoints) { + MultiPoint[] multiPointArray = new MultiPoint[multiPoints.size()]; + return (MultiPoint[]) multiPoints.toArray(multiPointArray); + } + + /** + * Creates a {@link Geometry} with the same extent as the given envelope. The Geometry returned + * is guaranteed to be valid. To provide this behaviour, the following cases occur: + * <p> + * If the <code>Envelope</code> is: + * <ul> + * <li>null : returns an empty {@link Point} + * <li>a point : returns a non-empty {@link Point} + * <li>a line : returns a two-point {@link LineString} + * <li>a rectangle : returns a {@link Polygon}> whose points are (minx, miny), (minx, maxy), + * (maxx, maxy), (maxx, miny), (minx, miny). + * </ul> + * + *@param envelope + * the <code>Envelope</code> to convert + *@return an empty <code>Point</code> (for null <code>Envelope</code>s), a <code>Point</code> + * (when min x = max x and min y = max y) or a <code>Polygon</code> (in all other cases) + */ + public Geometry toGeometry(Envelope envelope) { + // null envelope - return empty point geometry + if (envelope == null ) { + return null; + } + + // point? + if (envelope.getMin().get0() == envelope.getMax().get0() && + envelope.getMin().get1() == envelope.getMax().get1()) { + double[] Points = envelope.getMin().getAsArray(); + return factory.point( null, Points, crs ); // does this return a copy? + } + + // vertical or horizontal line? + if (envelope.getMin().get0() == envelope.getMax*().get0() || envelope.getMinY() == envelope.getMaxY()) { + return createLineString(new Point[] { + new Point(envelope.getMin().get0(), envelope.getMin().get1()), + new Point(envelope.getMax*().get0(), envelope.getMaxY()) }); + } + + // create a CW ring for the polygon + return createPolygon(createLinearRing(new Point[] { + new Point(envelope.getMin().get0(), envelope.getMin().get1()), + new Point(envelope.getMin().get0(), envelope.getMax().get1()), + new Point(envelope.getMax().get0(), envelope.getMax().get1()), + new Point(envelope.getMax().get0(), envelope.getMin().get1()), + new Point(envelope.getMin().get0(), envelope.getMin().get1()) }), null); + } + + /** + * Creates a Point using the given Point; a null Point will create an empty Geometry. + */ + public Point createPoint( Point Point) { + double[] array = Point.getAsArray(); + return factory.point( null, array, crs ); + } + + /** + * Creates a Point using the given PointSequence; a null or empty PointSequence will + * create an empty Point. + */ + public Point createPoint(Points Points) { + return createPoint( Points.get(0) ); + } + + /** + * Creates a MultiLineString using the given LineStrings; a null or empty array will create an + * empty MultiLineString. + * + * @param lineStrings + * LineStrings, each of which may be empty but not null + */ + public MultiLineString createMultiLineString(LineString[] lineStrings) { + return factory.multiLineString(null,crs, Arrays.asList(lineStrings)); + } + + /** + * Creates a GeometryCollection using the given Geometries; a null or empty array will create an + * empty GeometryCollection. + * + * @param geometries + * Geometries, each of which may be empty but not null + */ + public MultiGeometry<Geometry> createGeometryCollection(Geometry[] geometries) { + return factory.multiGeometry(null,crs, Arrays.asList(geometries)); + } + + /** + * Creates a MultiPolygon using the given Polygons; a null or empty array will create an empty + * Polygon. The polygons must conform to the assertions specified in the <A + * HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple Features Specification for + * SQL</A>. + * + * @param polygons + * Polygons, each of which may be empty but not null + */ + public MultiPolygon createMultiPolygon(Polygon[] polygons) { + return new MultiPolygon(polygons, this); + } + + /** + * Creates a LinearRing using the given Points; a null or empty array will create an empty + * LinearRing. The points must form a closed and simple linestring. Consecutive points must not + * be equal. + * + * @param Points + * an array without null elements, or an empty array, or null + */ + public LinearRing createLinearRing(Point[] Points) { + return createLinearRing(Points != null ? getPointSequenceFactory().create( + Points) : null); + } + + /** + * Creates a LinearRing using the given PointSequence; a null or empty PointSequence + * will create an empty LinearRing. The points must form a closed and simple linestring. + * Consecutive points must not be equal. + * + * @param Points + * a PointSequence possibly empty, or null + */ + public LinearRing createLinearRing(PointSequence Points) { + return new LinearRing(Points, this); + } + + /** + * Creates a MultiPoint using the given Points. A null or empty array will create an empty + * MultiPoint. + * + * @param Points + * an array (without null elements), or an empty array, or <code>null</code> + * @return a MultiPoint object + */ + public MultiPoint createMultiPoint(Point[] points) { + return factory.multiPoint(null, crs, Arrays.asList(points)); + } + + /** + * Creates a {@link MultiPoint} using the given {@link Point}s. A null or empty array will + * create an empty MultiPoint. + * + * @param Points + * an array (without null elements), or an empty array, or <code>null</code> + * @return a MultiPoint object + * + public MultiPoint createMultiPoint(Point[] Points) { + if( Points == null ){ + return null; + } + return factory.multiPoint(null,crs, Arrays.asList( Points )); + }*/ + + /** + * Creates a MultiPoint using the given PointSequence. A a null or empty PointSequence + * will create an empty MultiPoint. + * + * @param Points + * a PointSequence (possibly empty), or <code>null</code> + * @return a MultiPoint object + */ + public MultiPoint createMultiPoint(Points Points) { + if (Points == null) { + return createMultiPoint(new Point[0]); + } + ArrayList<Point> points = new ArrayList<Point>(); + for( Point point : Points ){ + points.add( point ); + } + return factory.multiPoint(null, crs, points ); + } + + /** + * Constructs a <code>Polygon</code> with the given exterior boundary and interior boundaries. + * + * @param shell + * the outer boundary of the new <code>Polygon</code>, or <code>null</code> or an + * empty <code>LinearRing</code> if the empty geometry is to be created. + * @param holes + * the inner boundaries of the new <code>Polygon</code>, or <code>null</code> or + * empty <code>LinearRing</code> s if the empty geometry is to be created. + */ + public Polygon createPolygon(Ring shell, Ring[] holes) { + return factory.polygon(null,crs, shell, Arrays.asList(holes)); + } + + /** + * Build an appropriate <code>Geometry</code>, <code>MultiGeometry</code>, or + * <code>GeometryCollection</code> to contain the <code>Geometry</code>s in it. For example:<br> + * + * <ul> + * <li>If <code>geomList</code> contains a single <code>Polygon</code>, the <code>Polygon</code> + * is returned. + * <li>If <code>geomList</code> contains several <code>Polygon</code>s, a + * <code>MultiPolygon</code> is returned. + * <li>If <code>geomList</code> contains some <code>Polygon</code>s and some + * <code>LineString</code>s, a <code>GeometryCollection</code> is returned. + * <li>If <code>geomList</code> is empty, an empty <code>GeometryCollection</code> is returned + * </ul> + * + * Note that this method does not "flatten" Geometries in the input, and hence if any + * MultiGeometries are contained in the input a GeometryCollection containing them will be + * returned. + * + *@param geomList + * the <code>Geometry</code>s to combine + *@return a <code>Geometry</code> of the "smallest", "most type-specific" class that can + * contain the elements of <code>geomList</code> . + */ + public Geometry buildGeometry(Collection<Geometry> geomList) { + + /** + * Determine some facts about the geometries in the list + */ + Class geomClass = null; + boolean isHeterogeneous = false; + boolean hasGeometryCollection = false; + for (Geometry geom : geomList ) { + Class<?> partClass = geom.getClass(); + if (geomClass == null) { + geomClass = partClass; + } + if (partClass != geomClass) { + isHeterogeneous = true; + } + if (geom instanceof MultiGeometry<?>){ + hasGeometryCollection = true; + } + } + + /** + * Now construct an appropriate geometry to return + */ + // for the empty geometry, return an empty GeometryCollection + if (geomClass == null) { + return createGeometryCollection(null); + } + if (isHeterogeneous || hasGeometryCollection) { + return createGeometryCollection(toGeometryArray(geomList)); + } + // at this point we know the collection is hetereogenous. + // Determine the type of the result from the first Geometry in the list + // this should always return a geometry, since otherwise an empty collection would have + // already been returned + Geometry geom0 = (Geometry) geomList.iterator().next(); + boolean isCollection = geomList.size() > 1; + if (isCollection) { + if (geom0 instanceof Polygon) { + return createMultiPolygon(toPolygonArray(geomList)); + } else if (geom0 instanceof LineString) { + return createMultiLineString(toLineStringArray(geomList)); + } else if (geom0 instanceof Point) { + return createMultiPoint(toPointArray(geomList)); + } + throw new IllegalStateException("Unhandled class: " + geom0.getClass().getName()); + } + return geom0; + } + + /** + * Creates a LineString using the given Points; a null or empty array will create an empty + * LineString. Consecutive points must not be equal. + * + * @param Points + * an array without null elements, or an empty array, or null + */ + public LineString createLineString(Point[] Points) { + return createLineString(Points != null ? getPointSequenceFactory().create( + Points) : null); + } + + /** + * Creates a LineString using the given PointSequence; a null or empty PointSequence + * will create an empty LineString. Consecutive points must not be equal. + * + * @param Points + * a PointSequence possibly empty, or null + */ + public LineString createLineString(PointSequence Points) { + return new LineString(Points, this); + } + + /** + * @return a clone of g based on a PointSequence created by this GeometryFactory's + * PointSequenceFactory + */ + public Geometry createGeometry(Geometry g) { + // could this be cached to make this more efficient? Or maybe it isn't enough overhead to + // bother + DuplicateBuilder duplicate = new DuplicateBuilder( factory ); + return duplicate.copy( g ); + } + + public int getSRID() { + return SRID; + } + + private int SRID; + + public PointSequenceFactory getPointSequenceFactory() { + return PointSequenceFactory; + } +} ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ GeoTools-commits mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/geotools-commits |
||||||||||||||||
| Free Embeddable Forum Powered by Nabble | Help |