/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2003-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.geotoolkit.data.shapefile.shp; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.geom.MultiPoint; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; import org.geotoolkit.geometry.jts.JTS; import org.apache.sis.storage.DataStoreException; /** * A collection of utility methods for use with JTS and the shapefile package. * * @author aaime * @author Ian Schneider * @module */ public final class JTSUtilities { static final GeometryFactory FACTORY = new GeometryFactory(); private JTSUtilities() { } /** * Returns: <br> * 2 for 2d (default) <br> * 4 for 3d - one of the oordinates has a non-NaN z value <br> * (3 is for x,y,m but thats not supported yet) <br> * * @param cs The array of Coordinates to search. * @return The dimension. */ public static int guessCoorinateDims(final Coordinate[] cs) { for(final Coordinate c : cs) { if (!(Double.isNaN(c.z))) { return 4; } } return 2; } public static Geometry convertToCollection(final Geometry geom, final ShapeType type) { Geometry retVal = null; if(type == ShapeType.NULL){ Point[] pNull = null; retVal = FACTORY.createMultiPoint(pNull); } else if (type.isPointType()) { if (geom instanceof Point) { retVal = geom; } else { Point[] pNull = null; retVal = FACTORY.createMultiPoint(pNull); } } else if (type.isLineType()) { if (geom instanceof LineString) { retVal = FACTORY.createMultiLineString(new LineString[] { (LineString) geom }); } else if (geom instanceof MultiLineString) { retVal = geom; } else { retVal = FACTORY.createMultiLineString(null); } } else if (type.isPolygonType()) { if (geom instanceof Polygon ) { final Polygon p = JTS.ensureClockWise((Polygon) geom); retVal = FACTORY.createMultiPolygon(new Polygon[] { p }); } else if (geom instanceof MultiPolygon) { retVal = JTS.ensureClockWise((MultiPolygon) geom); } else { retVal = FACTORY.createMultiPolygon(null); } } else if (type.isMultiPointType()) { if (geom instanceof Point) { retVal = FACTORY.createMultiPoint(new Point[] { (Point) geom }); } else if (geom instanceof MultiPoint) { retVal = geom; } else { Point[] pNull = null; retVal = FACTORY.createMultiPoint(pNull); } } else { throw new RuntimeException("Could not convert " + geom.getClass()+ " to " + type); } return retVal; } /** * Determine the best ShapeType for a geometry with the given dimension. * * @param geom * The Geometry to examine. * @param shapeFileDimentions * The dimension 2,3 or 4. * @throws ShapefileException * If theres a problem, like a bogus Geometry. * @return The best ShapeType. */ public static ShapeType getShapeType(final Geometry geom, final int shapeFileDimentions) throws DataStoreException { ShapeType type = null; if (geom == null) { type = ShapeType.NULL; } else if (geom instanceof Point) { switch (shapeFileDimentions) { case 2: type = ShapeType.POINT; break; case 3: type = ShapeType.POINTM; break; case 4: type = ShapeType.POINTZ; break; default: throw new DataStoreException("Too many dimensions for shapefile : "+ shapeFileDimentions); } } else if (geom instanceof MultiPoint) { switch (shapeFileDimentions) { case 2: type = ShapeType.MULTIPOINT; break; case 3: type = ShapeType.MULTIPOINTM; break; case 4: type = ShapeType.MULTIPOINTZ; break; default: throw new DataStoreException("Too many dimensions for shapefile : "+ shapeFileDimentions); } } else if ((geom instanceof Polygon) || (geom instanceof MultiPolygon)) { switch (shapeFileDimentions) { case 2: type = ShapeType.POLYGON; break; case 3: type = ShapeType.POLYGONM; break; case 4: type = ShapeType.POLYGONZ; break; default: throw new DataStoreException("Too many dimensions for shapefile : "+ shapeFileDimentions); } } else if ((geom instanceof LineString) || (geom instanceof MultiLineString)) { switch (shapeFileDimentions) { case 2: type = ShapeType.ARC; break; case 3: type = ShapeType.ARCM; break; case 4: type = ShapeType.ARCZ; break; default: throw new DataStoreException("Too many dimensions for shapefile : "+ shapeFileDimentions); } } if (type == null) { throw new DataStoreException("Cannot handle geometry type : " + (geom == null ? "null" : geom.getClass().getName())); } return type; } }