/** * For generating Geographically Weighted Statistics * Copyright (C) 2005 Andy Turner, CCG, University of Leeds, UK. * * 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. */ package uk.ac.leeds.ccg.andyt.gws.core; // java dependencies import java.awt.geom.Point2D; import java.util.HashSet; import java.util.Iterator; import java.util.Vector; import java.math.BigDecimal; // uk.ac.leeds.ccg.andyt.grids dependencies import uk.ac.leeds.ccg.andyt.grids.process.Grid2DSquareCellProcessor; import uk.ac.leeds.ccg.andyt.grids.utilities.ErrorHandler; // uk.ac.leeds.ccg.andyt.gws dependencies import uk.ac.leeds.ccg.andyt.gws.utilities.Utilities; import uk.ac.leeds.ccg.andyt.gws.utilities.Point2DBigDecimal; /** * TODO: * docs */ public class GWS extends ErrorHandler { protected Grid2DSquareCellProcessor grid2DSquareCellProcessor; protected long row; protected long col; protected double cellsizeDouble; // Kernel parameters protected double weightIntersect; protected double weightFactor; public GWS() { this.grid2DSquareCellProcessor = new Grid2DSquareCellProcessor(); } /** * Returns a Point2DDouble_DistanceDouble_IDInt[] thats points are the closest numberOfPoints * in points to point. * The returned array is ordered such that the closest point is the first * element and the furthest point is the final element. */ protected Point2DDouble_DistanceDouble_IDInt[] getNearestPoint2DDouble_DistanceDouble_IDInts( Point2D.Double[] points, Point2D.Double point, int numberOfPoints, int numberOfPointsFactor ) { if ( numberOfPoints > points.length ) { System.out.println( "Warning, more nearest neighbours asked for than are in points array!" ); } Point2DDouble_DistanceDouble_IDInt[] nearestPoint2DDouble_DistanceDouble_IDInts = new Point2DDouble_DistanceDouble_IDInt[ numberOfPoints * numberOfPointsFactor ]; for ( int i = 0; i < numberOfPoints * numberOfPointsFactor; i ++ ) { nearestPoint2DDouble_DistanceDouble_IDInts[ i ] = new Point2DDouble_DistanceDouble_IDInt( Double.POSITIVE_INFINITY ); } double numberOfPointsMinDistance = Double.POSITIVE_INFINITY; double distance; int counter = 0; for ( int i = 0; i < points.length; i ++ ) { distance = points[ i ].distance( point ); //if ( distance <= numberOfPointsMinDistance && distance <= checkDistance ) { // Is '<' better than '<=' for 'distance <= checkDistance'? if ( distance < numberOfPointsMinDistance ) { numberOfPointsMinDistance = setPoint( points[ i ], distance, i, nearestPoint2DDouble_DistanceDouble_IDInts ); counter ++; } } if ( counter < numberOfPoints ) { System.out.println("Error in uk.ac.leeds.ccg.gws.GWS.getNearestPoint2DDouble_DistanceDouble_IDInts(Point2D.Double[],Point2D.Double,int,int)" ); } if ( counter < nearestPoint2DDouble_DistanceDouble_IDInts.length ) { Point2DDouble_DistanceDouble_IDInt[] tnearestPoint2DDouble_DistanceDouble_IDInts = new Point2DDouble_DistanceDouble_IDInt[ counter ]; System.arraycopy( tnearestPoint2DDouble_DistanceDouble_IDInts, 0, tnearestPoint2DDouble_DistanceDouble_IDInts, 0, counter ); nearestPoint2DDouble_DistanceDouble_IDInts = tnearestPoint2DDouble_DistanceDouble_IDInts; } return nearestPoint2DDouble_DistanceDouble_IDInts; } /** * Returns a Point2DDouble_DistanceDouble_IDInt[] thats points are the closest numberOfPoints * in points to point. * The returned array is ordered such that the closest point is the first * element and the furthest point is the final element. * Only those IDs in IDsHashSet need be tested. * It is assumed that all IDs in IDHashSet are greater than 0 and less than * points.length. * @param pointIDs a HashSet containing IDs of Points in points which are * considered * @param points the entire set of Points being considered * @param point the Point of the location being analysed * @param numberOfPoints the least number of Points in points for which * Point2DDouble_DistanceDouble_IDInts are returned * @param numberOfPointsFactor a factor which when multiplied by */ protected Point2DDouble_DistanceDouble_IDInt[] getNearestPoint2DDouble_DistanceDouble_IDInts( HashSet pointIDs, Point2D.Double[] points, Point2D.Double point, int numberOfPoints, int numberOfPointsFactor ) { if ( pointIDs.size() > points.length / 2 ) { return getNearestPoint2DDouble_DistanceDouble_IDInts( points, point, numberOfPoints, numberOfPointsFactor ); } else { if ( numberOfPoints > points.length || numberOfPoints > pointIDs.size() ) { System.out.println( "Warning, more nearest neighbours asked for than are being looked at!" ); } // Initialise nearestPoint2DDouble_DistanceDouble_IDInts Point2DDouble_DistanceDouble_IDInt[] nearestPoint2DDouble_DistanceDouble_IDInts = new Point2DDouble_DistanceDouble_IDInt[ numberOfPoints * numberOfPointsFactor ]; for ( int i = 0; i < numberOfPoints * numberOfPointsFactor; i ++ ) { nearestPoint2DDouble_DistanceDouble_IDInts[ i ] = new Point2DDouble_DistanceDouble_IDInt( Double.POSITIVE_INFINITY ); } double numberOfPointsMinDistance = Double.POSITIVE_INFINITY; double distance; Iterator ite = pointIDs.iterator(); int i; int counter = 0; while ( ite.hasNext() ) { i = ( ( Integer ) ite.next() ).intValue(); distance = points[ i ].distance( point ); //if ( distance <= numberOfPointsMinDistance ) { if ( distance < numberOfPointsMinDistance ) { numberOfPointsMinDistance = setPoint( points[ i ], distance, i, nearestPoint2DDouble_DistanceDouble_IDInts ); counter ++; } } if ( counter < numberOfPoints ) { return getNearestPoint2DDouble_DistanceDouble_IDInts( points, point, numberOfPoints, numberOfPointsFactor ); } if ( counter < nearestPoint2DDouble_DistanceDouble_IDInts.length ) { Point2DDouble_DistanceDouble_IDInt[] tnearestPoint2DDouble_DistanceDouble_IDInts = new Point2DDouble_DistanceDouble_IDInt[ counter ]; System.arraycopy( nearestPoint2DDouble_DistanceDouble_IDInts, 0, tnearestPoint2DDouble_DistanceDouble_IDInts, 0, counter ); nearestPoint2DDouble_DistanceDouble_IDInts = tnearestPoint2DDouble_DistanceDouble_IDInts; } return nearestPoint2DDouble_DistanceDouble_IDInts; } } /** * Returns a Point2DDouble_DistanceDouble_IDInt[] thats points are the closest numberOfPoints * in pointsDistanceIDs to point. * The returned array is ordered such that the closest point is the first * element and the furthest point is the final element. * Only those IDs in IDsHashSet need be tested. * It is assumed that all IDs in IDHashSet are greater than 0 and less than * points.length. * @param point2DDouble_DistanceDouble_IDInts * @param points * @param point * @param numberOfPoints * @param numberOfPointsFactor, * @param checkDistance XXXX Strangely no longer used!!! */ protected Point2DDouble_DistanceDouble_IDInt[] getNearestPoint2DDouble_DistanceDouble_IDInts( Point2DDouble_DistanceDouble_IDInt[] point2DDouble_DistanceDouble_IDInts, Point2D.Double[] points, Point2D.Double point, int numberOfPoints, int numberOfPointsFactor, double checkDistance ) { if ( numberOfPoints > point2DDouble_DistanceDouble_IDInts.length ) { //return getNearestPoint2DDouble_DistanceDouble_IDInts( points, point, numberOfPoints, numberOfPointsFactor, checkDistance ); return getNearestPoint2DDouble_DistanceDouble_IDInts( points, point, numberOfPoints, numberOfPointsFactor ); } Point2D.Double tempPoint; HashSet subsetIDs = new HashSet(); int counter = 0; for ( int i = 0; i < point2DDouble_DistanceDouble_IDInts.length; i ++ ) { if ( point2DDouble_DistanceDouble_IDInts[ i ].point2DDouble.distance( point ) < checkDistance ) { counter ++; subsetIDs.add( new Integer( point2DDouble_DistanceDouble_IDInts[ i ].iDInt ) ); } } if ( counter < numberOfPoints ) { //return getNearestPoint2DDouble_DistanceDouble_IDInts( points, point, numberOfPoints, numberOfPointsFactor, checkDistance ); return getNearestPoint2DDouble_DistanceDouble_IDInts( points, point, numberOfPoints, numberOfPointsFactor ); } else { //return getNearestPoint2DDouble_DistanceDouble_IDInts( tempPoints, point, numberOfPoints, numberOfPointsFactor, checkDistance ); return getNearestPoint2DDouble_DistanceDouble_IDInts( subsetIDs, points, point, numberOfPoints, numberOfPointsFactor ); } } /** * Returns the distance of the furthest point in nearestPoint2DDouble_DistanceDouble_IDInts * after point at distance has been evaluated for proximity. * @param point the Point being evaluated * @param distance the distance of point from the location being analysed * @param id the unique int reference of point in the array of points being * evaluated * @param nearestPoint2DDouble_DistanceDouble_IDInts the array containing the nearest * Point2DDouble_DistanceDouble_IDInts of the array of points being evaluated */ private double setPoint( Point2D.Double point, double distance, int id, Point2DDouble_DistanceDouble_IDInt[] nearestPoint2DDouble_DistanceDouble_IDInts ) { for ( int i = 0; i < nearestPoint2DDouble_DistanceDouble_IDInts.length; i ++ ) { if ( distance < nearestPoint2DDouble_DistanceDouble_IDInts[ i ].distanceDouble ) { // Shift everything else down (if not last position in array) for ( int j = nearestPoint2DDouble_DistanceDouble_IDInts.length - 1; j > i; j -- ) { nearestPoint2DDouble_DistanceDouble_IDInts[ j ] = nearestPoint2DDouble_DistanceDouble_IDInts[ j - 1 ]; } // Put a new Point2DDouble_DistanceDouble_IDInt in place and return the distance of // the last element of nearestPoint2DDouble_DistanceDouble_IDInts nearestPoint2DDouble_DistanceDouble_IDInts[ i ] = new Point2DDouble_DistanceDouble_IDInt( point, distance, id ); return nearestPoint2DDouble_DistanceDouble_IDInts[ nearestPoint2DDouble_DistanceDouble_IDInts.length - 1 ].distanceDouble; } } // If distance not less than any distance in nearestPoint2DDouble_DistanceDouble_IDInts // then return the distance of the last element of // nearestPoint2DDouble_DistanceDouble_IDInts return nearestPoint2DDouble_DistanceDouble_IDInts[ nearestPoint2DDouble_DistanceDouble_IDInts.length - 1 ].distanceDouble; } /** * Returns an Object[] result * result[ 0 ] is a Point2DDouble_DistanceDouble_IDInt[] thats points are the closest * numberOfPoints in points to point. * result[ 1 ] is a HashSet of Integer IDs of all Points in points that are * within setDistance of point * result[ 0 ] is ordered such that the closest point is the first element * and the furthest point is the final element. * NB It is possible that result[ 1 ] is empty. */ protected Object[] getNearestPoint2DDouble_DistanceDouble_IDIntsAndOtherInfo( Point2D.Double[] points, Point2D.Double point, int numberOfPoints, int numberOfPointsFactor, double setDistance ) { if ( numberOfPoints > points.length ) { System.out.println( "getNearestPoint2DDouble_DistanceDouble_IDIntsAndOtherInfo(Point2D.Double[],Point2D.Double,int,int,double)" ); System.out.println( "Warning, more nearest neighbours asked for than are in points array!" ); } Object[] result = new Object[ 2 ]; Point2DDouble_DistanceDouble_IDInt[] nearestPoint2DDouble_DistanceDouble_IDInts = new Point2DDouble_DistanceDouble_IDInt[ numberOfPoints * numberOfPointsFactor ]; HashSet inSetDistancePoints = new HashSet(); // Initialise nearestPoint2DDouble_DistanceDouble_IDInts for ( int i = 0; i < numberOfPoints * numberOfPointsFactor; i ++ ) { nearestPoint2DDouble_DistanceDouble_IDInts[ i ] = new Point2DDouble_DistanceDouble_IDInt( Double.POSITIVE_INFINITY ); } double numberOfPointsMinDistance = Double.POSITIVE_INFINITY; double distance; int counter = 0; for ( int i = 0; i < points.length; i ++ ) { distance = points[ i ].distance( point ); // Calculate nearestPoint2DDouble_DistanceDouble_IDInts //if ( distance <= numberOfPointsMinDistance ) { if ( distance < numberOfPointsMinDistance ) { numberOfPointsMinDistance = setPoint( points[ i ], distance, i, nearestPoint2DDouble_DistanceDouble_IDInts ); counter ++; } // Store IDs of inSetDistancePoints if ( distance <= setDistance ) { inSetDistancePoints.add( new Integer( i ) ); } } if ( counter < numberOfPoints ) { System.out.println( "Error in getNearestPoint2DDouble_DistanceDouble_IDIntsAndOtherInfo(Point2D.Double[],Point2D.Double,int,int,double)" ); } // Trim nearestPoint2DDouble_DistanceDouble_IDInts if ( counter < nearestPoint2DDouble_DistanceDouble_IDInts.length ) { Point2DDouble_DistanceDouble_IDInt[] tnearestPoint2DDouble_DistanceDouble_IDInts = new Point2DDouble_DistanceDouble_IDInt[ counter ]; System.arraycopy( nearestPoint2DDouble_DistanceDouble_IDInts, 0, tnearestPoint2DDouble_DistanceDouble_IDInts, 0, counter ); nearestPoint2DDouble_DistanceDouble_IDInts = tnearestPoint2DDouble_DistanceDouble_IDInts; //System.arraycopy( nearestPoint2DDouble_DistanceDouble_IDInts, 0, nearestPoint2DDouble_DistanceDouble_IDInts, 0, counter ); } result[ 0 ] = nearestPoint2DDouble_DistanceDouble_IDInts; result[ 1 ] = inSetDistancePoints; return result; } /** * Returns an Object[] result * result[ 0 ] is a Point2DDouble_DistanceDouble_IDInt[] thats points are the closest * numberOfPoints in points to point. * result[ 1 ] is a HashSet of Integer IDs of all Points in points that are * within setDistance of point * result[ 0 ] is ordered such that the closest point is the first element * and the furthest point is the final element. * Warning: It is possible that result[ 1 ] is empty. */ protected Object[] getNearestPoint2DDouble_DistanceDouble_IDIntsAndOtherInfo( HashSet pointIDsHashSet, Point2D.Double[] points, Point2D.Double point, int numberOfPoints, int numberOfPointsFactor, double setDistance ) { if ( pointIDsHashSet.size() > points.length / 2 ) { return getNearestPoint2DDouble_DistanceDouble_IDIntsAndOtherInfo( points, point, numberOfPoints, numberOfPointsFactor, setDistance ); } else { if ( numberOfPoints > points.length ) { System.out.println( "getNearestPoint2DDouble_DistanceDouble_IDIntsAndOtherInfo(HashSet,Point2D.Double[],Point2D.Double,int,double)" ); System.out.println( "Warning, more nearest neighbours asked for than are in points array!" ); } Object[] result = new Object[ 2 ]; Point2DDouble_DistanceDouble_IDInt[] nearestPoint2DDouble_DistanceDouble_IDInts = new Point2DDouble_DistanceDouble_IDInt[ numberOfPoints * numberOfPointsFactor ]; HashSet inSetDistancePoints = new HashSet(); // Initialise nearestPoint2DDouble_DistanceDouble_IDInts for ( int i = 0; i < numberOfPoints * numberOfPointsFactor; i ++ ) { nearestPoint2DDouble_DistanceDouble_IDInts[ i ] = new Point2DDouble_DistanceDouble_IDInt( Double.POSITIVE_INFINITY ); } double numberOfPointsMinDistance = Double.POSITIVE_INFINITY; double distance; Iterator ite = pointIDsHashSet.iterator(); int i; Integer ID; int counter = 0; while ( ite.hasNext() ) { ID = ( Integer ) ite.next(); i = ID.intValue(); distance = points[ i ].distance( point ); // Calculate nearestPoint2DDouble_DistanceDouble_IDInts //if ( distance <= numberOfPointsMinDistance ) { if ( distance < numberOfPointsMinDistance ) { numberOfPointsMinDistance = setPoint( points[ i ], distance, i, nearestPoint2DDouble_DistanceDouble_IDInts ); counter ++; } // Store IDs of inSetDistancePoints if ( distance <= setDistance ) { inSetDistancePoints.add( ID ); } } if ( counter < numberOfPoints ) { return getNearestPoint2DDouble_DistanceDouble_IDIntsAndOtherInfo( points, point, numberOfPoints, numberOfPointsFactor, setDistance ); } else { // Trim nearestPoint2DDouble_DistanceDouble_IDInts if ( counter < nearestPoint2DDouble_DistanceDouble_IDInts.length ) { Point2DDouble_DistanceDouble_IDInt[] tnearestPoint2DDouble_DistanceDouble_IDInts = new Point2DDouble_DistanceDouble_IDInt[ counter ]; System.arraycopy( nearestPoint2DDouble_DistanceDouble_IDInts, 0, tnearestPoint2DDouble_DistanceDouble_IDInts, 0, counter ); nearestPoint2DDouble_DistanceDouble_IDInts = tnearestPoint2DDouble_DistanceDouble_IDInts; //System.arraycopy( nearestPoint2DDouble_DistanceDouble_IDInts, 0, nearestPoint2DDouble_DistanceDouble_IDInts, 0, counter ); } } result[ 0 ] = nearestPoint2DDouble_DistanceDouble_IDInts; result[ 1 ] = inSetDistancePoints; return result; } } /** * @depricated * @see uk.ac.leeds.ccg.gws.Utilities.getInDistancePointIDs */ protected HashSet getInDistancePointIDs( Point2D.Double[] points, Point2D.Double point, double distance ) { return Utilities.getInDistancePointIDs( points, point, distance ); /* HashSet inDistancePointIDsHashSet = new HashSet(); if ( points.length > 0 ) { double thisDistance; for ( int i = 0; i < points.length; i ++ ) { thisDistance = points[ i ].distance( point ); if ( thisDistance < distance ) { // This is unique because of the int i - id term so there are no worries about overwriting! inDistancePointIDsHashSet.add( new Integer( i ) ); } } } return inDistancePointIDsHashSet; */ } /** * @depricated * @see uk.ac.leeds.ccg.gws.Utilities.getInDistancePointIDs */ protected HashSet getInDistancePointIDs( HashSet pointIDsHashSet, Point2D.Double[] points, Point2D.Double point, double distance ) { return Utilities.getInDistancePointIDs( pointIDsHashSet, points, point, distance ); /* if ( pointIDsHashSet.size() > points.length / 2 ) { return getInDistancePointIDs( points, point, distance ); } else { HashSet inDistancePointIDsHashSet = new HashSet(); if ( ! pointIDsHashSet.isEmpty() ) { double thisDistance; Iterator ite = pointIDsHashSet.iterator(); int i; while ( ite.hasNext() ) { i = ( ( Integer ) ite.next() ).intValue(); thisDistance = points[ i ].distance( point ); if ( thisDistance < distance ) { inDistancePointIDsHashSet.add( new Integer( i ) ); } } } return inDistancePointIDsHashSet; } */ } /** * Returns a HashSet of Point2DDouble_DistanceDouble_IDInt objects comprised of those Points * from points that are withing distance of point */ protected HashSet getInDistancePoint2DDouble_DistanceDouble_IDInts( Point2D.Double[] points, Point2D.Double point, double distance ) { HashSet inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet = new HashSet(); if ( points.length > 0 ) { double thisDistance; for ( int i = 0; i < points.length; i ++ ) { thisDistance = points[ i ].distance( point ); //if ( thisDistance <= distance ) { if ( thisDistance < distance ) { // This is unique because of the int i - id term so there are no worries about overwriting! inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet.add( new Point2DDouble_DistanceDouble_IDInt( points[ i ], thisDistance, i ) ); } } } return inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet; } /** * Returns a HashSet of Point2DDouble_DistanceDouble_IDInt objects comprised of those Points * from points that are withing distance of point */ protected HashSet getInDistancePoint2DBigDecimal_DistanceBigDecimal_IDInts( Point2DBigDecimal[] points, Point2DBigDecimal point, BigDecimal distanceBigDecimal, int decimalPlaces ) { HashSet inDistancePoint2DBigDecimal_DistanceBigDecimal_IDIntsHashSet = new HashSet(); if ( points.length > 0 ) { BigDecimal thisDistanceBigDecimal; for ( int iDInt = 0; iDInt < points.length; iDInt ++ ) { thisDistanceBigDecimal = points[ iDInt ].distance( point, decimalPlaces ); //if ( thisDistance <= distance ) { if ( thisDistanceBigDecimal.compareTo( distanceBigDecimal ) == -1 ) { // This is unique because of the iDInt so there are no worries about overwriting! inDistancePoint2DBigDecimal_DistanceBigDecimal_IDIntsHashSet.add( new Point2DBigDecimal_DistanceBigDecimal_IDInt( points[ iDInt ], thisDistanceBigDecimal, iDInt ) ); } } } return inDistancePoint2DBigDecimal_DistanceBigDecimal_IDIntsHashSet; } /** * Returns a HashSet of Point2DDouble_DistanceDouble_IDInt objects comprised of those Points * from points that are withing distance of point * Only those points with IDs in IDsHashSet are necessarily tested. * It is assumed that all IDs in IDsHashSet are greater than 0 and less than * points.length. * The IDs are the positions in the array points given as Integers. */ protected HashSet getInDistancePoint2DDouble_DistanceDouble_IDInts( HashSet pointIDsHashSet, Point2D.Double[] points, Point2D.Double point, double distance ) { if ( pointIDsHashSet.size() > points.length / 2 ) { return getInDistancePoint2DDouble_DistanceDouble_IDInts( points, point, distance ); } else { HashSet inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet = new HashSet(); if ( ! pointIDsHashSet.isEmpty() ) { double thisDistance; Iterator ite = pointIDsHashSet.iterator(); int i; while ( ite.hasNext() ) { i = ( ( Integer ) ite.next() ).intValue(); thisDistance = points[ i ].distance( point ); //if ( thisDistance <= distance ) { if ( thisDistance < distance ) { // This is unique because of the int i - id term so there are no worries about overwriting! inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet.add( new Point2DDouble_DistanceDouble_IDInt( points[ i ], thisDistance, i ) ); } } } return inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet; } } /** * Returns a HashSet of Point2DDouble_DistanceDouble_IDInt objects comprised of those Points * from points that are withing distance of point * Only those points with IDs in IDsHashSet are necessarily tested. * It is assumed that all IDs in IDsHashSet are greater than 0 and less than * points.length. * The IDs are the positions in the array points given as Integers. */ protected HashSet getInDistancePoint2DBigDecimal_DistanceBigDecimal_IDInts( HashSet pointIDsHashSet, Point2DBigDecimal[] points, Point2DBigDecimal point, BigDecimal distanceBigDecimal, int decimalPlaces ) { if ( pointIDsHashSet.size() > points.length / 2 ) { return getInDistancePoint2DBigDecimal_DistanceBigDecimal_IDInts( points, point, distanceBigDecimal, decimalPlaces ); } else { HashSet inDistancePoint2DBigDecimal_DistanceBigDecimal_IDIntsHashSet = new HashSet(); if ( ! pointIDsHashSet.isEmpty() ) { BigDecimal thisDistanceBigDecimal; Iterator ite = pointIDsHashSet.iterator(); int iDInt; while ( ite.hasNext() ) { iDInt = ( ( Integer ) ite.next() ).intValue(); thisDistanceBigDecimal = points[ iDInt ].distance( point, decimalPlaces ); if ( thisDistanceBigDecimal.compareTo( distanceBigDecimal ) == -1 ) { // This is unique because of the int i - id term so there are no worries about overwriting! inDistancePoint2DBigDecimal_DistanceBigDecimal_IDIntsHashSet.add( new Point2DBigDecimal_DistanceBigDecimal_IDInt( points[ iDInt ], thisDistanceBigDecimal, iDInt ) ); } } } return inDistancePoint2DBigDecimal_DistanceBigDecimal_IDIntsHashSet; } } /** * Returns a Point2DDouble_DistanceDouble_IDInt[] comprised of those Points from points that * are within distance of point. * The returned array is ordered such that the closest point is the first * element and the furthest point is the final element. */ protected Point2DDouble_DistanceDouble_IDInt[] getInDistancePoint2DDouble_DistanceDouble_IDIntsArray( Point2D.Double[] points, Point2D.Double point, double distance ) { HashSet inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet = getInDistancePoint2DDouble_DistanceDouble_IDInts( points, point, distance ); Point2DDouble_DistanceDouble_IDInt[] inDistancePoint2DDouble_DistanceDouble_IDIntsArray = new Point2DDouble_DistanceDouble_IDInt[ inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet.size() ]; if ( ! inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet.isEmpty() ) { Point2DDouble_DistanceDouble_IDInt point2DDouble_DistanceDouble_IDInt; //= new GWS.Point2DDouble_DistanceDouble_IDInt( Double.POSITIVE_INFINITY ); Iterator ite = inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet.iterator(); Point2DDouble_DistanceDouble_IDInt thisPoint2DDouble_DistanceDouble_IDInt; while ( ite.hasNext() ) { point2DDouble_DistanceDouble_IDInt = ( Point2DDouble_DistanceDouble_IDInt ) ite.next(); for ( int i = 0; i < inDistancePoint2DDouble_DistanceDouble_IDIntsArray.length; i ++ ) { if ( inDistancePoint2DDouble_DistanceDouble_IDIntsArray[ i ] == null ) { inDistancePoint2DDouble_DistanceDouble_IDIntsArray[ i ] = point2DDouble_DistanceDouble_IDInt; i = inDistancePoint2DDouble_DistanceDouble_IDIntsArray.length; } else { if ( point2DDouble_DistanceDouble_IDInt.distanceDouble < inDistancePoint2DDouble_DistanceDouble_IDIntsArray[ i ].distanceDouble ) { for ( int j = inDistancePoint2DDouble_DistanceDouble_IDIntsArray.length - 1; j > i; j -- ) { inDistancePoint2DDouble_DistanceDouble_IDIntsArray[ j ] = inDistancePoint2DDouble_DistanceDouble_IDIntsArray[ j - 1 ]; } inDistancePoint2DDouble_DistanceDouble_IDIntsArray[ i ] = point2DDouble_DistanceDouble_IDInt; i = inDistancePoint2DDouble_DistanceDouble_IDIntsArray.length; } } } } } return inDistancePoint2DDouble_DistanceDouble_IDIntsArray; } /** * Returns a Point2DDouble_DistanceDouble_IDInt[] containing Point2DDouble_DistanceDouble_IDInt objects - those * points from points that are withing distance of point. * The returned array is ordered such that the closest point is the first * element and the furthest point is the final element. * Only those IDs in IDsHashSet need be tested. * It is assumed that all IDs in IDsHashSet are greater than 0 and less than * points.length. * The IDs are the positions in the array points given as Integers. */ protected Point2DDouble_DistanceDouble_IDInt[] getInDistancePoint2DDouble_DistanceDouble_IDIntsArray( HashSet pointIDsHashSet, Point2D.Double[] points, Point2D.Double point, double distance ) { if ( pointIDsHashSet.size() > points.length / 2 ) { return getInDistancePoint2DDouble_DistanceDouble_IDIntsArray( points, point, distance ); } else { HashSet inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet = getInDistancePoint2DDouble_DistanceDouble_IDInts( pointIDsHashSet, points, point, distance ); Point2DDouble_DistanceDouble_IDInt[] inDistancePoint2DDouble_DistanceDouble_IDIntsArray = new Point2DDouble_DistanceDouble_IDInt[ inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet.size() ]; if ( ! inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet.isEmpty() ) { Iterator ite = inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet.iterator(); Point2DDouble_DistanceDouble_IDInt point2DDouble_DistanceDouble_IDInt; Point2DDouble_DistanceDouble_IDInt thisPoint2DDouble_DistanceDouble_IDInt; while ( ite.hasNext() ) { point2DDouble_DistanceDouble_IDInt = ( Point2DDouble_DistanceDouble_IDInt ) ite.next(); // Sort Point2DDouble_DistanceDouble_IDInts in inDistancePoint2DDouble_DistanceDouble_IDIntsHashSet // into inDistancePoint2DDouble_DistanceDouble_IDIntsArray for ( int i = 0; i < inDistancePoint2DDouble_DistanceDouble_IDIntsArray.length; i ++ ) { thisPoint2DDouble_DistanceDouble_IDInt = inDistancePoint2DDouble_DistanceDouble_IDIntsArray[ i ]; if ( thisPoint2DDouble_DistanceDouble_IDInt == null ) { inDistancePoint2DDouble_DistanceDouble_IDIntsArray[ i ] = point2DDouble_DistanceDouble_IDInt; i = inDistancePoint2DDouble_DistanceDouble_IDIntsArray.length; } else { if ( point2DDouble_DistanceDouble_IDInt.distanceDouble < thisPoint2DDouble_DistanceDouble_IDInt.distanceDouble ) { for ( int j = inDistancePoint2DDouble_DistanceDouble_IDIntsArray.length - 1; j > i; j -- ) { inDistancePoint2DDouble_DistanceDouble_IDIntsArray[ j ] = inDistancePoint2DDouble_DistanceDouble_IDIntsArray[ j - 1 ]; } inDistancePoint2DDouble_DistanceDouble_IDIntsArray[ i ] = point2DDouble_DistanceDouble_IDInt; i = inDistancePoint2DDouble_DistanceDouble_IDIntsArray.length; } } } } } return inDistancePoint2DDouble_DistanceDouble_IDIntsArray; } } /** * A basic class for holding a Point2DBigDecimal a BigDecimal and an int. * TODO: * documentation */ protected class Point2DBigDecimal_DistanceBigDecimal_IDInt { protected Point2DBigDecimal point2DBigDecimal; protected BigDecimal distanceBigDecimal; protected int iDInt; protected Point2DBigDecimal_DistanceBigDecimal_IDInt() { } protected Point2DBigDecimal_DistanceBigDecimal_IDInt( BigDecimal distanceBigDecimal ) { this.distanceBigDecimal = distanceBigDecimal; } protected Point2DBigDecimal_DistanceBigDecimal_IDInt( Point2DBigDecimal point2DBigDecimal, BigDecimal distanceBigDecimal, int iDInt ) { this.point2DBigDecimal = point2DBigDecimal; this.distanceBigDecimal = distanceBigDecimal; this.iDInt = iDInt; } protected Object clone() { return new Point2DBigDecimal_DistanceBigDecimal_IDInt( this.point2DBigDecimal, this.distanceBigDecimal, this.iDInt ); } /** * TODO: * Arithmetic Exception check */ protected double getDistanceDouble() { return distanceBigDecimal.doubleValue(); } } /** * A basic class for holding a Point2D.Double a double and an int in a single object * TODO: * documentation */ protected class Point2DDouble_DistanceDouble_IDInt { protected Point2D.Double point2DDouble; protected double distanceDouble; protected int iDInt; protected Point2DDouble_DistanceDouble_IDInt() { } protected Point2DDouble_DistanceDouble_IDInt( double distanceDouble ) { this.distanceDouble = distanceDouble; } protected Point2DDouble_DistanceDouble_IDInt( Point2D.Double point2DDouble, double distanceDouble, int iDInt ) { this.point2DDouble = point2DDouble; this.distanceDouble = distanceDouble; this.iDInt = iDInt; } protected Object clone() { return new Point2DDouble_DistanceDouble_IDInt( this.point2DDouble, this.distanceDouble, this.iDInt ); } } }