/*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de 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; either version 2.1 of the License, or (at your option) any later version. 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. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53115 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.model.spatialschema; import java.util.ArrayList; import org.deegree.framework.util.StringTools; import org.deegree.model.crs.CoordinateSystem; /** * Factory to create geometry instances. * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> * @version $Revision: 1.17 $, $Date: 2006/11/23 09:17:39 $ * */ public final class GeometryFactory { private GeometryFactory() { //Hidden default constructor. } /** * creates a Envelope object out from two corner coordinates * @param minx lower x-axis coordinate * @param miny lower y-axis coordinate * @param maxx upper x-axis coordinate * @param maxy upper y-axis coordinate * @param crs The coordinate system * @return an Envelope with given parameters */ public static Envelope createEnvelope( double minx, double miny, double maxx, double maxy, CoordinateSystem crs) { Position min = createPosition( minx, miny ); Position max = createPosition( maxx, maxy ); return new EnvelopeImpl( min, max, crs ); } /** * creates a Envelope object out from two corner coordinates * @param min lower point * @param max upper point * @param crs The coordinate system * @return an Envelope with given parameters */ public static Envelope createEnvelope( Position min, Position max, CoordinateSystem crs) { return new EnvelopeImpl( min, max, crs ); } /** * creates an Envelope from a comma seperated String; e.g.: 10,34,15,48 * @param bbox the boundingbox of the created Envelope * @param crs The coordinate system * @return an Envelope with given parameters */ public static Envelope createEnvelope(String bbox, CoordinateSystem crs) { double[] d = StringTools.toArrayDouble( bbox, "," ); return createEnvelope( d[0], d[1], d[2], d[3], crs ); } /** * creates a Position from two coordinates. * @param x coordinate on the x-axis * @param y coordinate on the y-axis * @return a Position defining position x, y */ public static Position createPosition( double x, double y ) { return new PositionImpl( x, y ); } /** * creates a Position from three coordinates. * @param x coordinate on the x-axis * @param y coordinate on the y-axis * @param z coordinate on the z-axis * @return a Position defining position x, y, z */ public static Position createPosition(double x, double y, double z) { return new PositionImpl(new double[] { x, y, z}); } /** * creates a Position from an array of double. * * @param p * list of points * @return the Position defined by the array. */ public static Position createPosition( double[] p ) { return new PositionImpl( p ); } /** * creates a Point from two coordinates. * @param x x coordinate * @param y y coordinate * @param crs spatial reference system of the point geometry * @return a Position defining position x, y in the given CRS */ public static Point createPoint( double x, double y, CoordinateSystem crs ) { return new PointImpl( x, y, crs ); } /** * creates a Point from two coordinates. * @param x x coordinate * @param y y coordinate * @param z coordinate on the z-axis * @param crs spatial reference system of the point geometry * @return a Position defining position x, y, z in the given CRS */ public static Point createPoint( double x, double y, double z, CoordinateSystem crs ) { return new PointImpl( x, y, z, crs ); } /** * creates a Point from a position. * @param position position * @param crs spatial reference system of the point geometry * @return the Position defined by the array in the given CRS */ public static Point createPoint( Position position, CoordinateSystem crs ) { return new PointImpl( position, crs ); } /** * creates a Point from a wkb. * @param wkb geometry in Well-Known Binary (WKB) format * @param srs spatial reference system of the geometry * @return the Position defined by the WKB and the given CRS * @throws GeometryException if the wkb is not known or invalid */ public static Point createPoint( byte[] wkb, CoordinateSystem srs ) throws GeometryException { int wkbType = -1; double x = 0; double y = 0; byte byteorder = wkb[0]; if ( byteorder == 0 ) { wkbType = ByteUtils.readBEInt( wkb, 1 ); } else { wkbType = ByteUtils.readLEInt( wkb, 1 ); } if ( wkbType != 1 ) { throw new GeometryException( "invalid byte stream" ); } if ( byteorder == 0 ) { x = ByteUtils.readBEDouble( wkb, 5 ); y = ByteUtils.readBEDouble( wkb, 13 ); } else { x = ByteUtils.readLEDouble( wkb, 5 ); y = ByteUtils.readLEDouble( wkb, 13 ); } return new PointImpl( x, y, srs ); } /** * creates a CurveSegment from an array of points. * * @param points array of Point * @param crs CS_CoordinateSystem spatial reference system of the curve * @return A curve defined by the given Points in the CRS. * @throws GeometryException if the point array is empty */ public static CurveSegment createCurveSegment( Position[] points, CoordinateSystem crs ) throws GeometryException { return new LineStringImpl( points, crs ); } /** * creates a Curve from an array of Positions. * * @param positions positions * @param crs spatial reference system of the geometry * @return A curve defined by the given Points in the CRS. * @throws GeometryException if the point array is empty */ public static Curve createCurve( Position[] positions, CoordinateSystem crs ) throws GeometryException { CurveSegment[] cs = new CurveSegment[1]; cs[0] = createCurveSegment( positions, crs ); return new CurveImpl( cs ); } /** * creates a Curve from one curve segment. * * @param segment CurveSegments * @return a new CurveSegment * @throws GeometryException if the segment is null */ public static Curve createCurve( CurveSegment segment ) throws GeometryException { return new CurveImpl( new CurveSegment[] { segment } ); } /** * creates a Curve from an array of curve segments. * * @param segments array of CurveSegments * @return a new CurveSegment * @throws GeometryException if the segment is null or has no values */ public static Curve createCurve( CurveSegment[] segments ) throws GeometryException { return new CurveImpl( segments ); } /** * creates a GM_Curve from an array of ordinates * * TODO: If resources are available, think about good programming style. * @param ord the ordinates * @param dim the dimension of the ordinates * @param crs the spatial reference system of the geometry * * @return the Curve defined by the given parameters * @throws GeometryException if the ord array is empty */ public static Curve createCurve( double[] ord, int dim, CoordinateSystem crs ) throws GeometryException { Position[] pos = new Position[ord.length/dim]; int i = 0; while (i < ord.length) { double[] o = new double[dim]; for (int j = 0; j < dim; j++) { o[j] = ord[i++]; } pos[i/dim -1] = GeometryFactory.createPosition( o ); } return GeometryFactory.createCurve( pos, crs ); } /** * creates a SurfacePatch from array(s) of Position * * @param exteriorRing exterior ring of the patch * @param interiorRings interior rings of the patch * @param si SurfaceInterpolation * @param crs CS_CoordinateSystem spatial reference system of the surface patch * @return a Surfacepatch defined by the given Parameters * @throws GeometryException */ public static SurfacePatch createSurfacePatch( Position[] exteriorRing, Position[][] interiorRings, SurfaceInterpolation si, CoordinateSystem crs ) throws GeometryException { return new PolygonImpl( si, exteriorRing, interiorRings, crs ); } /** * creates a Curve from a wkb. * * @param wkb byte stream that contains the wkb information * @param crs CS_CoordinateSystem spatial reference system of the curve * @return the Curve defined by the WKB and the given CRS * @throws GeometryException if the wkb is not known or invalid * */ public static Curve createCurve( byte[] wkb, CoordinateSystem crs ) throws GeometryException { int wkbType = -1; int numPoints = -1; Position[] points = null; double x = 0; double y = 0; byte byteorder = wkb[0]; if ( byteorder == 0 ) { wkbType = ByteUtils.readBEInt( wkb, 1 ); } else { wkbType = ByteUtils.readLEInt( wkb, 1 ); } // check if it's realy a linestrin/curve if ( wkbType != 2 ) { throw new GeometryException( "invalid byte stream for Curve" ); } // read number of points if ( byteorder == 0 ) { numPoints = ByteUtils.readBEInt( wkb, 5 ); } else { numPoints = ByteUtils.readLEInt( wkb, 5 ); } int offset = 9; points = new Position[numPoints]; // read the i-th point depending on the byteorde if ( byteorder == 0 ) { for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readBEDouble( wkb, offset ); offset += 8; y = ByteUtils.readBEDouble( wkb, offset ); offset += 8; points[i] = new PositionImpl( x, y ); } } else { for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readLEDouble( wkb, offset ); offset += 8; y = ByteUtils.readLEDouble( wkb, offset ); offset += 8; points[i] = new PositionImpl( x, y ); } } CurveSegment[] segment = new CurveSegment[1]; segment[0] = createCurveSegment( points, crs ); return createCurve( segment ); } /** * creates a Surface composed of one SurfacePatch from array(s) * of Position * * @param exteriorRing exterior ring of the patch * @param interiorRings interior rings of the patch * @param si SurfaceInterpolation * @param crs CS_CoordinateSystem spatial reference system of the surface patch * @return a Surface composed of one SurfacePatch from array(s) * of Position * @throws GeometryException if the implicite orientation is not '+' or '-', or the rings aren't closed */ public static Surface createSurface( Position[] exteriorRing, Position[][] interiorRings, SurfaceInterpolation si, CoordinateSystem crs ) throws GeometryException { SurfacePatch sp = new PolygonImpl( si, exteriorRing, interiorRings, crs ); return createSurface( sp ); } /** * creates a Surface from an array of SurfacePatch. * * @param patch patches that build the surface * @return a Surface from an array of SurfacePatch. * @throws GeometryException if implicite the orientation is not '+' or '-' */ public static Surface createSurface( SurfacePatch patch ) throws GeometryException { return new SurfaceImpl( patch ); } /** * creates a Surface from an array of SurfacePatch. * @param patches patches that build the surface * * @return a Surface from an array of SurfacePatch. * @throws GeometryException if implicite the orientation is not '+' or '-' */ public static Surface createSurface( SurfacePatch[] patches ) throws GeometryException { return new SurfaceImpl( patches ); } /** * creates a Surface from a wkb. * * @param wkb byte stream that contains the wkb information * @param crs CS_CoordinateSystem spatial reference system of the curve * @param si SurfaceInterpolation * @return a Surface from a wkb. * @throws GeometryException if the implicite orientation is not '+' or '-' or the wkb is not known or invalid */ public static Surface createSurface( byte[] wkb, CoordinateSystem crs, SurfaceInterpolation si ) throws GeometryException { int wkbtype = -1; int numRings = 0; int numPoints = 0; int offset = 0; double x = 0; double y = 0; Position[] externalBoundary = null; Position[][] internalBoundaries = null; byte byteorder = wkb[offset++]; if ( byteorder == 0 ) { wkbtype = ByteUtils.readBEInt( wkb, offset ); } else { wkbtype = ByteUtils.readLEInt( wkb, offset ); } offset += 4; if ( wkbtype == 6 ) { return null; } // is the geometry respresented by wkb a polygon? if ( wkbtype != 3 ) { throw new GeometryException( "invalid byte stream for Surface " + wkbtype ); } // read number of rings of the polygon if ( byteorder == 0 ) { numRings = ByteUtils.readBEInt( wkb, offset ); } else { numRings = ByteUtils.readLEInt( wkb, offset ); } offset += 4; // read number of points of the external ring if ( byteorder == 0 ) { numPoints = ByteUtils.readBEInt( wkb, offset ); } else { numPoints = ByteUtils.readLEInt( wkb, offset ); } offset += 4; // allocate memory for the external boundary externalBoundary = new Position[numPoints]; if ( byteorder == 0 ) { // read points of the external boundary from the byte[] for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readBEDouble( wkb, offset ); offset += 8; y = ByteUtils.readBEDouble( wkb, offset ); offset += 8; externalBoundary[i] = new PositionImpl( x, y ); } } else { // read points of the external boundary from the byte[] for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readLEDouble( wkb, offset ); offset += 8; y = ByteUtils.readLEDouble( wkb, offset ); offset += 8; externalBoundary[i] = new PositionImpl( x, y ); } } // only if numRings is larger then one there internal rings if ( numRings > 1 ) { internalBoundaries = new Position[numRings - 1][]; } if ( byteorder == 0 ) { for ( int j = 1; j < numRings; j++ ) { // read number of points of the j-th internal ring numPoints = ByteUtils.readBEInt( wkb, offset ); offset += 4; // allocate memory for the j-th internal boundary internalBoundaries[j - 1] = new Position[numPoints]; // read points of the external boundary from the byte[] for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readBEDouble( wkb, offset ); offset += 8; y = ByteUtils.readBEDouble( wkb, offset ); offset += 8; internalBoundaries[j - 1][i] = new PositionImpl( x, y ); } } } else { for ( int j = 1; j < numRings; j++ ) { // read number of points of the j-th internal ring numPoints = ByteUtils.readLEInt( wkb, offset ); offset += 4; // allocate memory for the j-th internal boundary internalBoundaries[j - 1] = new Position[numPoints]; // read points of the external boundary from the byte[] for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readLEDouble( wkb, offset ); offset += 8; y = ByteUtils.readLEDouble( wkb, offset ); offset += 8; internalBoundaries[j - 1][i] = new PositionImpl( x, y ); } } } SurfacePatch patch = createSurfacePatch( externalBoundary, internalBoundaries, si, crs ); return createSurface( patch ); } /** * Creates a <tt>Surface</tt> from a <tt>Envelope</tt>. * <p> * @param bbox envelope to be converted * @param crs spatial reference system of the surface * @return corresponding surface * * @throws GeometryException if the implicite orientation is not '+' or '-' */ public static Surface createSurface (Envelope bbox, CoordinateSystem crs) throws GeometryException { Position min = bbox.getMin (); Position max = bbox.getMax (); Position [] exteriorRing = null; if ( min.getCoordinateDimension() == 2 ) { exteriorRing = new Position [] { min, new PositionImpl (min.getX(), max.getY()), max, new PositionImpl (max.getX(), min.getY()), min }; } else { exteriorRing = new Position [] { min, new PositionImpl (min.getX(), max.getY(), min.getZ()+((max.getZ() - min.getZ())*0.5) ), max, new PositionImpl (max.getX(), min.getY(), min.getZ()+((max.getZ() - min.getZ())*0.5)), min }; } return createSurface (exteriorRing, null, new SurfaceInterpolationImpl (), crs); } /** * Creates a <tt>GM_Surface</tt> from the ordinates of the exterior ring * and the the interior rings * <p> * @param exterior ring * @param interior ring * @param dim of the surface * @param crs spatial reference system of the surface * @return corresponding surface * @throws GeometryException if the implicite orientation is not '+' or '-' * */ public static Surface createSurface (double[] exterior, double[][] interior, int dim, CoordinateSystem crs) throws GeometryException { // get exterior ring Position[] ext = new Position[exterior.length/dim]; int i = 0; int k = 0; while (i < exterior.length-1) { double[] o = new double[dim]; for (int j = 0; j < dim; j++) { o[j] = exterior[i++]; } ext[k++] = GeometryFactory.createPosition( o ); } // get interior rings if available Position[][] in = null; if ( interior != null && interior.length > 0 ) { in = new Position[interior.length][]; for (int j = 0; j < in.length; j++) { in[j] = new Position[interior[j].length/dim]; i = 0; while (i < interior[j].length) { double[] o = new double[dim]; for (int z = 0; z < dim; z++) { o[z] = interior[j][i++]; } in[j][i/dim-1] = GeometryFactory.createPosition( o ); } } } // default - linear - interpolation SurfaceInterpolation si = new SurfaceInterpolationImpl(); return GeometryFactory.createSurface( ext, in, si, crs ); } /** * creates a MultiPoint from an array of Point. * * @param points array of Points * @return a MultiPoint from an array of Point. * */ public static MultiPoint createMultiPoint( Point[] points ) { return new MultiPointImpl( points ); } /** * creates a MultiPoint from a wkb. * * @param wkb byte stream that contains the wkb information * @param crs CS_CoordinateSystem spatial reference system of the curve * @return the MultiPoint defined by the WKB and the given CRS * @throws GeometryException if the wkb is not known or invalid * */ public static MultiPoint createMultiPoint( byte[] wkb, CoordinateSystem crs ) throws GeometryException { Point[] points = null; int wkbType = -1; int numPoints = -1; double x = 0; double y = 0; byte byteorder = wkb[0]; // read wkbType if ( byteorder == 0 ) { wkbType = ByteUtils.readBEInt( wkb, 1 ); } else { wkbType = ByteUtils.readLEInt( wkb, 1 ); } // if the geometry isn't a multipoint throw exception if ( wkbType != 4 ) { throw new GeometryException( "Invalid byte stream for MultiPoint" ); } // read number of points if ( byteorder == 0 ) { numPoints = ByteUtils.readBEInt( wkb, 5 ); } else { numPoints = ByteUtils.readLEInt( wkb, 5 ); } points = new Point[numPoints]; int offset = 9; Object[] o = new Object[3]; o[2] = crs; // read all points for ( int i = 0; i < numPoints; i++ ) { // byteorder of the i-th point byteorder = wkb[offset]; // wkbType of the i-th geometry if ( byteorder == 0 ) { wkbType = ByteUtils.readBEInt( wkb, offset + 1 ); } else { wkbType = ByteUtils.readLEInt( wkb, offset + 1 ); } // if the geometry isn't a point throw exception if ( wkbType != 1 ) { throw new GeometryException( "Invalid byte stream for Point as " + "part of a multi point" ); } // read the i-th point depending on the byteorde if ( byteorder == 0 ) { x = ByteUtils.readBEDouble( wkb, offset + 5 ); y = ByteUtils.readBEDouble( wkb, offset + 13 ); } else { x = ByteUtils.readLEDouble( wkb, offset + 5 ); y = ByteUtils.readLEDouble( wkb, offset + 13 ); } offset += 21; points[i] = new PointImpl( x, y, crs ); } return createMultiPoint( points ); } /** * creates a MultiCurve from an array of Curves. * * @param curves * @return a MultiCurve from an array of Curves. */ public static MultiCurve createMultiCurve( Curve[] curves ) { return new MultiCurveImpl( curves ); } /** * creates a MultiCurve from a wkb. * * @param wkb byte stream that contains the wkb information * @param crs CS_CoordinateSystem spatial reference system of the curve * @return the MultiCurve defined by the WKB and the given CRS * @throws GeometryException if the wkb is not known or invalid */ public static MultiCurve createMultiCurve( byte[] wkb, CoordinateSystem crs ) throws GeometryException { int wkbType = -1; int numPoints = -1; int numParts = -1; double x = 0; double y = 0; Position[][] points = null; int offset = 0; byte byteorder = wkb[offset++]; if ( byteorder == 0 ) { wkbType = ByteUtils.readBEInt( wkb, offset ); } else { wkbType = ByteUtils.readLEInt( wkb, offset ); } offset += 4; // check if it's realy a linestring if ( wkbType != 5 ) { throw new GeometryException( "Invalid byte stream for MultiCurve" ); } // read number of linestrings if ( byteorder == 0 ) { numParts = ByteUtils.readBEInt( wkb, offset ); } else { numParts = ByteUtils.readLEInt( wkb, offset ); } offset += 4; points = new Position[numParts][]; // for every linestring for ( int j = 0; j < numParts; j++ ) { byteorder = wkb[offset++]; if ( byteorder == 0 ) { wkbType = ByteUtils.readBEInt( wkb, offset ); } else { wkbType = ByteUtils.readLEInt( wkb, offset ); } offset += 4; // check if it's realy a linestring if ( wkbType != 2 ) { throw new GeometryException( "Invalid byte stream for Curve as " + " part of a MultiCurve." ); } // read number of points if ( byteorder == 0 ) { numPoints = ByteUtils.readBEInt( wkb, offset ); } else { numPoints = ByteUtils.readLEInt( wkb, offset ); } offset += 4; points[j] = new Position[numPoints]; // read the i-th point depending on the byteorde if ( byteorder == 0 ) { for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readBEDouble( wkb, offset ); offset += 8; y = ByteUtils.readBEDouble( wkb, offset ); offset += 8; points[j][i] = new PositionImpl( x, y ); } } else { for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readLEDouble( wkb, offset ); offset += 8; y = ByteUtils.readLEDouble( wkb, offset ); offset += 8; points[j][i] = new PositionImpl( x, y ); } } } CurveSegment[] segment = new CurveSegment[1]; Curve[] curves = new Curve[numParts]; for ( int i = 0; i < numParts; i++ ) { segment[0] = createCurveSegment( points[i], crs ); curves[i] = createCurve( segment ); } return createMultiCurve( curves ); } /** * creates a MultiSurface from an array of surfaces * @param surfaces * @return a MultiSurface from an array of surfaces */ public static MultiSurface createMultiSurface( Surface[] surfaces ) { return new MultiSurfaceImpl( surfaces ); } /** * creates a MultiSurface from a wkb * @param wkb geometry in Well-Known Binary (WKB) format * @param crs spatial reference system of the geometry * @param si surface interpolation * @return the MultiSurface defined by the WKB and the given CRS * @throws GeometryException if the wkb is not known or invalid */ public static MultiSurface createMultiSurface( byte[] wkb, CoordinateSystem crs, SurfaceInterpolation si ) throws GeometryException { int wkbtype = -1; int numPoly = 0; int numRings = 0; int numPoints = 0; int offset = 0; double x = 0; double y = 0; Position[] externalBoundary = null; Position[][] internalBoundaries = null; byte byteorder = wkb[offset++]; if ( byteorder == 0 ) { wkbtype = ByteUtils.readBEInt( wkb, offset ); } else { wkbtype = ByteUtils.readLEInt( wkb, offset ); } offset += 4; // is the wkbmetry a multipolygon? if ( wkbtype != 6 ) { throw new GeometryException( "Invalid byte stream for MultiSurface" ); } // read number of polygons on the byte[] if ( byteorder == 0 ) { numPoly = ByteUtils.readBEInt( wkb, offset ); } else { numPoly = ByteUtils.readLEInt( wkb, offset ); } offset += 4; ArrayList<Surface> list = new ArrayList<Surface>( numPoly ); for ( int ip = 0; ip < numPoly; ip++ ) { byteorder = wkb[offset]; offset++; if ( byteorder == 0 ) { wkbtype = ByteUtils.readBEInt( wkb, offset ); } else { wkbtype = ByteUtils.readLEInt( wkb, offset ); } offset += 4; // is the geometry respresented by wkb a polygon? if ( wkbtype != 3 ) { throw new GeometryException( "invalid byte stream for Surface " + wkbtype ); } // read number of rings of the polygon if ( byteorder == 0 ) { numRings = ByteUtils.readBEInt( wkb, offset ); } else { numRings = ByteUtils.readLEInt( wkb, offset ); } offset += 4; // read number of points of the external ring if ( byteorder == 0 ) { numPoints = ByteUtils.readBEInt( wkb, offset ); } else { numPoints = ByteUtils.readLEInt( wkb, offset ); } offset += 4; // allocate memory for the external boundary externalBoundary = new Position[numPoints]; if ( byteorder == 0 ) { // read points of the external boundary from the byte[] for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readBEDouble( wkb, offset ); offset += 8; y = ByteUtils.readBEDouble( wkb, offset ); offset += 8; externalBoundary[i] = new PositionImpl( x, y ); } } else { // read points of the external boundary from the byte[] for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readLEDouble( wkb, offset ); offset += 8; y = ByteUtils.readLEDouble( wkb, offset ); offset += 8; externalBoundary[i] = new PositionImpl( x, y ); } } // only if numRings is larger then one there internal rings if ( numRings > 1 ) { internalBoundaries = new Position[numRings - 1][]; } if ( byteorder == 0 ) { for ( int j = 1; j < numRings; j++ ) { // read number of points of the j-th internal ring numPoints = ByteUtils.readBEInt( wkb, offset ); offset += 4; // allocate memory for the j-th internal boundary internalBoundaries[j - 1] = new Position[numPoints]; // read points of the external boundary from the byte[] for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readBEDouble( wkb, offset ); offset += 8; y = ByteUtils.readBEDouble( wkb, offset ); offset += 8; internalBoundaries[j - 1][i] = new PositionImpl( x, y ); } } } else { for ( int j = 1; j < numRings; j++ ) { // read number of points of the j-th internal ring numPoints = ByteUtils.readLEInt( wkb, offset ); offset += 4; // allocate memory for the j-th internal boundary internalBoundaries[j - 1] = new Position[numPoints]; // read points of the external boundary from the byte[] for ( int i = 0; i < numPoints; i++ ) { x = ByteUtils.readLEDouble( wkb, offset ); offset += 8; y = ByteUtils.readLEDouble( wkb, offset ); offset += 8; internalBoundaries[j - 1][i] = new PositionImpl( x, y ); } } } SurfacePatch patch = createSurfacePatch( externalBoundary, internalBoundaries, si, crs ); list.add( createSurface( patch ) ); } MultiSurface multisurface = new MultiSurfaceImpl( crs ); for ( int i = 0; i < list.size(); i++ ) { multisurface.addSurface( list.get( i ) ); } return multisurface; } }/* ******************************************************************** Changes to this class. What the people have been up to: $Log: GeometryFactory.java,v $ Revision 1.17 2006/11/23 09:17:39 bezema the middled z-values should be added to the min.getZ() value in create surface from envelope Revision 1.16 2006/11/03 14:16:22 poth bug fix - creating a surface from an envelope Revision 1.15 2006/09/19 07:23:03 bezema fixed documentation Revision 1.14 2006/09/18 14:10:28 bezema added documentation Revision 1.13 2006/07/12 14:46:15 poth comment footer added ********************************************************************** */