/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2007-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.geotools.referencing.operation.builder.algorithm; import java.awt.geom.Point2D; import java.util.HashMap; import java.util.Iterator; import org.opengis.geometry.DirectPosition; import org.opengis.geometry.Envelope; import org.geotools.referencing.crs.DefaultGeographicCRS; /** * Implementation of IDW Interpolation. * * @author jezekjan * */ public class IDWInterpolation extends AbstractInterpolation { /**Max distance to take points into account */ private double maxDist = 0; /** * * @param positions HashMap containing {@link org.opengis.geometry.DirectPosition} as * key and value of general parameter as value * @param dx Value of step in x direction between generated cells * @param dy Value of step in y direction between generated cells * @param envelope Envelope that should be filled by generated grid */ public IDWInterpolation(HashMap<DirectPosition, Float> positions, int xNumOfCells, int yNumOfCells, Envelope envelope) { super(positions, xNumOfCells, yNumOfCells, envelope); } /** * Constructs Interpolation from specified positions and its values. * @param positions */ public IDWInterpolation(HashMap/*<DirectPosition, float>*/ positions) { super(positions); } /** * Returns max distance that defines when the point are taken into account * during interpolation. * @return max distance (when 0 than all points are taken) */ public double getMaxDist() { return maxDist; } /** * Sets max distance that defines when the point are taken into account * during interpolation (when 0 than all points are taken - 0 is the default). * @param maxDist max distance */ public void setMaxDist(double maxDist) { this.maxDist = 10000; } public float getValue(DirectPosition p) { return calculateValue(p); } /** * Computes nearest points. * @param p * @param maxdistance * @param number * @return * * @todo consider some indexing mechanism for finding the nearest positions */ private HashMap getNearestPositions(DirectPosition p, double maxdistance) { HashMap nearest = new HashMap(); DirectPosition source = null; double dist; for (Iterator i = this.getPositions().keySet().iterator(); i.hasNext();) { source = (DirectPosition) i.next(); /** * @todo - calculate elipsoidal distance/ */ /* if ((source != null) || source.getCoordinateReferenceSystem().getClass() .isAssignableFrom(DefaultGeographicCRS.class)) { dist = ((DefaultGeographicCRS) source.getCoordinateReferenceSystem()).distance(p .getCoordinates(), source.getCoordinates()).doubleValue(); } else {*/ dist = ((Point2D) p).distance((Point2D) source); //} if (((dist != 0) || (dist < maxdistance))) { nearest.put(source, new Double(dist)); } } return nearest; } private float calculateValue(DirectPosition p) { return calculateValue(p, getMaxDist()); } /** * Computes value at point {@link p} from points that are not farer than {@link maxDistance} * @param p * @param maxDist * @return */ private float calculateValue(DirectPosition p, double maxDist) { HashMap nearest = getNearestPositions(p, maxDist); float value; double sumdValue = 0; double sumweight = 0; for (Iterator i = nearest.keySet().iterator(); i.hasNext();) { DirectPosition dp = (DirectPosition) i.next(); double distance = ((Double) nearest.get(dp)).doubleValue(); double weight = (1 / Math.pow(distance, 2)); sumdValue = sumdValue + (float) ( (this.getPositions().get(dp)) * weight); sumweight = sumweight + weight; } value = (float) (sumdValue / sumweight); return value; } }