//$HeadURL: https://svn.wald.intevation.org/svn/deegree/deegree3/trunk/deegree-core/deegree-core-geometry/src/main/java/org/deegree/geometry/io/WKBReader.java $ /*---------------------------------------------------------------------------- This file is part of deegree, http://deegree.org/ Copyright (C) 2001-2009 by: - Department of Geography, University of Bonn - and - lat/lon GmbH - 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 information: lat/lon GmbH Aennchenstr. 19, 53177 Bonn Germany http://lat-lon.de/ Department of Geography, University of Bonn Prof. Dr. Klaus Greve Postfach 1147, 53001 Bonn Germany http://www.geographie.uni-bonn.de/deegree/ e-mail: info@deegree.org ----------------------------------------------------------------------------*/ package nl.ipo.cds.deegree.persistence; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.deegree.cs.coordinatesystems.ICRS; import org.deegree.geometry.Geometry; import org.deegree.geometry.points.Points; import org.deegree.geometry.precision.PrecisionModel; import org.deegree.geometry.primitive.Curve; import org.deegree.geometry.primitive.LineString; import org.deegree.geometry.primitive.LinearRing; import org.deegree.geometry.primitive.Point; import org.deegree.geometry.primitive.Polygon; import org.deegree.geometry.primitive.Ring; import org.deegree.geometry.standard.AbstractDefaultGeometry; import org.deegree.geometry.standard.multi.DefaultMultiGeometry; import org.deegree.geometry.standard.multi.DefaultMultiLineString; import org.deegree.geometry.standard.multi.DefaultMultiPoint; import org.deegree.geometry.standard.multi.DefaultMultiPolygon; import org.deegree.geometry.standard.points.JTSPoints; import org.deegree.geometry.standard.primitive.DefaultLineString; import org.deegree.geometry.standard.primitive.DefaultLinearRing; import org.deegree.geometry.standard.primitive.DefaultPoint; import org.deegree.geometry.standard.primitive.DefaultPolygon; import com.vividsolutions.jts.geom.CoordinateSequence; import com.vividsolutions.jts.geom.impl.PackedCoordinateSequenceFactory; import com.vividsolutions.jts.io.InputStreamInStream; import com.vividsolutions.jts.io.ParseException; /** * Reads {@link Geometry} objects encoded as Well-Known Binary (WKB). * * TODO re-implement without delegating to JTS TODO add support for non-SFS geometries (e.g. non-linear curves) * * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a> * @author last edited by: $Author: mschneider $ * * @version $Revision: 31641 $, $Date: 2011-08-24 21:24:55 +0200 (wo, 24 aug 2011) $ */ public class ExtendedWKBReader { public static Geometry read( byte[] wkb, ICRS crs ) throws ParseException { return read( wkb, crs, false ); } public static Geometry read( byte[] wkb, ICRS crs, boolean swapAxis ) throws ParseException { // com.vividsolutions.jts.io.WKBReader() is not thread safe return createFromJTS( new com.vividsolutions.jts.io.WKBReader().read( wkb ), crs, swapAxis ); } public static Geometry read( InputStream is, ICRS crs ) throws IOException, ParseException { return read( is, crs, false ); } public static Geometry read( InputStream is, ICRS crs, boolean swapAxis ) throws IOException, ParseException { // com.vividsolutions.jts.io.WKBReader() is not thread safe return createFromJTS( new com.vividsolutions.jts.io.WKBReader().read( new InputStreamInStream( is ) ), crs, swapAxis ); } public static AbstractDefaultGeometry createFromJTS( com.vividsolutions.jts.geom.Geometry jtsGeom, ICRS crs ) { return createFromJTS( jtsGeom, crs, false ); } @SuppressWarnings("unchecked") public static AbstractDefaultGeometry createFromJTS( com.vividsolutions.jts.geom.Geometry jtsGeom, ICRS crs, boolean swapAxis ) { AbstractDefaultGeometry geom = null; PrecisionModel pm = null; if ( jtsGeom instanceof com.vividsolutions.jts.geom.Point ) { com.vividsolutions.jts.geom.Point jtsPoint = (com.vividsolutions.jts.geom.Point) jtsGeom; if ( Double.isNaN( jtsPoint.getCoordinate().z ) ) { if ( swapAxis ) { geom = new DefaultPoint( null, crs, pm , new double[] { jtsPoint.getY(), jtsPoint.getX() } ); } else { geom = new DefaultPoint( null, crs, pm, new double[] { jtsPoint.getX(), jtsPoint.getY() } ); } } else { if ( swapAxis ) { geom = new DefaultPoint( null, crs, pm, new double[] { jtsPoint.getY(), jtsPoint.getX(), jtsPoint.getCoordinate().z } ); } else { geom = new DefaultPoint( null, crs, pm, new double[] { jtsPoint.getX(), jtsPoint.getY(), jtsPoint.getCoordinate().z } ); } } } else if ( jtsGeom instanceof com.vividsolutions.jts.geom.LinearRing ) { com.vividsolutions.jts.geom.LinearRing jtsLinearRing = (com.vividsolutions.jts.geom.LinearRing) jtsGeom; geom = new DefaultLinearRing( null, crs, pm, getAsPoints( jtsLinearRing.getCoordinateSequence(), crs, swapAxis ) ); } else if ( jtsGeom instanceof com.vividsolutions.jts.geom.LineString ) { com.vividsolutions.jts.geom.LineString jtsLineString = (com.vividsolutions.jts.geom.LineString) jtsGeom; geom = new DefaultLineString( null, crs, pm, getAsPoints( jtsLineString.getCoordinateSequence(), crs, swapAxis ) ); } else if ( jtsGeom instanceof com.vividsolutions.jts.geom.Polygon ) { com.vividsolutions.jts.geom.Polygon jtsPolygon = (com.vividsolutions.jts.geom.Polygon) jtsGeom; Points exteriorPoints = getAsPoints( jtsPolygon.getExteriorRing().getCoordinateSequence(), crs, swapAxis ); LinearRing exteriorRing = new DefaultLinearRing( null, crs, pm, exteriorPoints ); List<Ring> interiorRings = new ArrayList<Ring>( jtsPolygon.getNumInteriorRing() ); for ( int i = 0; i < jtsPolygon.getNumInteriorRing(); i++ ) { Points interiorPoints = getAsPoints( jtsPolygon.getInteriorRingN( i ).getCoordinateSequence(), crs, swapAxis ); interiorRings.add( new DefaultLinearRing( null, crs, pm, interiorPoints ) ); } geom = new DefaultPolygon( null, crs, pm, exteriorRing, interiorRings ); } else if ( jtsGeom instanceof com.vividsolutions.jts.geom.MultiPoint ) { com.vividsolutions.jts.geom.MultiPoint jtsMultiPoint = (com.vividsolutions.jts.geom.MultiPoint) jtsGeom; if ( jtsMultiPoint.getNumGeometries() > 0 ) { List<Point> members = new ArrayList<Point>( jtsMultiPoint.getNumGeometries() ); for ( int i = 0; i < jtsMultiPoint.getNumGeometries(); i++ ) { members.add( (Point) createFromJTS( jtsMultiPoint.getGeometryN( i ), crs, swapAxis ) ); } geom = new DefaultMultiPoint( null, crs, pm, members ); } } else if ( jtsGeom instanceof com.vividsolutions.jts.geom.MultiLineString ) { com.vividsolutions.jts.geom.MultiLineString jtsMultiLineString = (com.vividsolutions.jts.geom.MultiLineString) jtsGeom; if ( jtsMultiLineString.getNumGeometries() > 0 ) { List<LineString> members = new ArrayList<LineString>( jtsMultiLineString.getNumGeometries() ); for ( int i = 0; i < jtsMultiLineString.getNumGeometries(); i++ ) { Curve curve = (Curve) createFromJTS( jtsMultiLineString.getGeometryN( i ), crs, swapAxis ); members.add( curve.getAsLineString() ); } geom = new DefaultMultiLineString( null, crs, pm, members ); } } else if ( jtsGeom instanceof com.vividsolutions.jts.geom.MultiPolygon ) { com.vividsolutions.jts.geom.MultiPolygon jtsMultiPolygon = (com.vividsolutions.jts.geom.MultiPolygon) jtsGeom; if ( jtsMultiPolygon.getNumGeometries() > 0 ) { List<Polygon> members = new ArrayList<Polygon>( jtsMultiPolygon.getNumGeometries() ); for ( int i = 0; i < jtsMultiPolygon.getNumGeometries(); i++ ) { members.add( (Polygon) createFromJTS( jtsMultiPolygon.getGeometryN( i ), crs, swapAxis ) ); } geom = new DefaultMultiPolygon( null, crs, pm, members ); } } else if ( jtsGeom instanceof com.vividsolutions.jts.geom.GeometryCollection ) { com.vividsolutions.jts.geom.GeometryCollection jtsGeometryCollection = (com.vividsolutions.jts.geom.GeometryCollection) jtsGeom; if ( jtsGeometryCollection.getNumGeometries() > 0 ) { List<Geometry> members = new ArrayList<Geometry>( jtsGeometryCollection.getNumGeometries() ); for ( int i = 0; i < jtsGeometryCollection.getNumGeometries(); i++ ) { members.add( createFromJTS( jtsGeometryCollection.getGeometryN( i ), crs, swapAxis ) ); } geom = new DefaultMultiGeometry( null, crs, pm, members ); } } else { throw new RuntimeException( "Internal error. Encountered unhandled JTS geometry type '" + jtsGeom.getClass().getName() + "'." ); } return geom; } private static Points getAsPoints( CoordinateSequence seq, ICRS crs, boolean swapAxis ) { int dim = seq.getDimension(); double[] coordinates = new double[ seq.size() * dim ]; int idx = 0; for(int i = 0; i < seq.size(); i++) { for(int j = 0; j < dim; j++) { if(swapAxis) { if(j == 0) { coordinates[idx++] = seq.getOrdinate(i, 1); } else if( j == 1) { coordinates[idx++] = seq.getOrdinate(i, 0); } else { coordinates[idx++] = seq.getOrdinate(i, j); } } else { coordinates[idx++] = seq.getOrdinate(i, j); } } } PackedCoordinateSequenceFactory factory = new PackedCoordinateSequenceFactory(); seq = factory.create(coordinates, dim); return new JTSPoints( crs, seq ); } }