/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany 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 3 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, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.connectivity.jts; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.operation.distance.DistanceOp; /** * Computes the minimum and maximum distance and closest and furthest points * between two {@link com.vividsolutions.jts.geom.Geometry Geometry}s using the euclidian metric. * It is a direct extension of the class {@link com.vividsolutions.jts.operation.distance.DistanceOp DistanceOp} * of the Java Topology Suite. */ public class ExtendedDistanceOp extends DistanceOp{ /** * Computes the distance between the closest points of two geometries. * @param g0 a {@link com.vividsolutions.jts.geom.Geometry Geometry} * @param g1 another {@link com.vividsolutions.jts.geom.Geometry Geometry} * @return the distance between the geometries */ public static double minDistance(Geometry2DAdapter g0, Geometry2DAdapter g1){ return new DistanceOp(g0.getJTSGeometry(), g1.getJTSGeometry()).distance(); } /** * Computes the distance between the most distant points of two geometries. * @param g0 a {@link com.vividsolutions.jts.geom.Geometry Geometry} * @param g1 another {@link com.vividsolutions.jts.geom.Geometry Geometry} * @return the distance between the geometries */ public static double maxDistance(Geometry2DAdapter g0, Geometry2DAdapter g1) { return new ExtendedDistanceOp(g0.getJTSGeometry(), g1.getJTSGeometry()).maxDistance(); } /** * Computes the the closest points of two geometries. * The points are presented in the same order as the input Geometries. * * @param g0 a {@link com.vividsolutions.jts.geom.Geometry Geometry} * @param g1 another {@link com.vividsolutions.jts.geom.Geometry Geometry} * @return the closest points in the geometries */ public static Point2DAdapter[] closestPoints(Geometry2DAdapter g0, Geometry2DAdapter g1) { ExtendedDistanceOp distOp = new ExtendedDistanceOp(g0.getJTSGeometry(), g1.getJTSGeometry()); Coordinate[] coords = distOp.closestPoints(); Point2DAdapter[] points = new Point2DAdapter[coords.length]; for(int i=0; i< points.length;i++) points[i] = Geometry2DFactory.createPoint(coords[i].x, coords[i].y, g0.getPrecisionModel()); return points; } /** * Computes the the most distant points of two geometries. * The points are presented in the same order as the input Geometries. * * @param g0 a {@link com.vividsolutions.jts.geom.Geometry Geometry} * @param g1 another {@link com.vividsolutions.jts.geom.Geometry Geometry} * @return the closest points in the geometries */ public static Point2DAdapter[] furthestPoints(Geometry2DAdapter g0, Geometry2DAdapter g1) { ExtendedDistanceOp distOp = new ExtendedDistanceOp(g0.getJTSGeometry(), g1.getJTSGeometry()); Coordinate[] coords = distOp.furthestPoints(); Point2DAdapter[] points = new Point2DAdapter[coords.length]; for(int i=0; i< points.length;i++) points[i] = Geometry2DFactory.createPoint(coords[i].x, coords[i].y, g0.getPrecisionModel()); return points; } private Geometry[] geom; private Coordinate[] maxDistanceLocation; /** * Constructs a DistanceOp that computes the distance and closest points between * the two specified geometries. */ protected ExtendedDistanceOp(Geometry g0, Geometry g1) { super(g0,g1); this.geom = new Geometry[]{g0, g1}; } /** * Report the distance between the most distant points on the input geometries. * * @return the distance between the geometries */ protected double maxDistance(){ double max= Double.MIN_VALUE; Coordinate[] c0 = geom[0].getCoordinates(); Coordinate[] c1 = geom[1].getCoordinates(); maxDistanceLocation = new Coordinate[2]; for(int i=0; i< c0.length;i++){ for(int j=0; j< c1.length;j++){ double dist = pointToPointDistance(c0[i],c1[j]); if(max < dist){ max = dist; maxDistanceLocation[0] = c0[i]; maxDistanceLocation[1] = c1[j]; } } } return max; } /** * Report the coordinates of the most distant points in the input geometries. * The points are presented in the same order as the input Geometries. * * @return a pair of {@link Coordinate}s of the closest points */ protected Coordinate[] furthestPoints() { maxDistance(); return new Coordinate[] { maxDistanceLocation[0], maxDistanceLocation[1]}; } /** Compute the euclidian Distance beetween two Coordinates * * @param c0 the first Coordinate * @param c1 the second Coordinate * @return the euclidian Distance beetween the given Coordinates */ protected double pointToPointDistance(Coordinate c0, Coordinate c1){ double dx = c1.x - c0.x; double dy = c1.y - c0.y; return Math.sqrt( dx*dx + dy*dy); } }