001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/processing/raster/interpolation/Interpolation.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53177 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042: ---------------------------------------------------------------------------*/
043: package org.deegree.processing.raster.interpolation;
044:
045: import java.net.URI;
046: import java.net.URISyntaxException;
047:
048: import org.deegree.datatypes.values.Interval;
049: import org.deegree.datatypes.values.TypedLiteral;
050: import org.deegree.datatypes.values.Values;
051: import org.deegree.framework.log.ILogger;
052: import org.deegree.framework.log.LoggerFactory;
053: import org.deegree.graphics.transformation.WorldToScreenTransform;
054: import org.deegree.io.quadtree.IndexException;
055: import org.deegree.io.quadtree.Quadtree;
056: import org.deegree.model.coverage.grid.FloatGridCoverage;
057: import org.deegree.model.spatialschema.Envelope;
058:
059: /**
060: * <code>Interpolation</code> is the abstract base class for all interpolation algorithms. Data
061: * representation is done via the Quadtree interface.
062: *
063: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
064: * @author last edited by: $Author: rbezema $
065: *
066: * @version $Revision: 10609 $, $Date: 2008-03-18 01:46:37 -0700 (Tue, 18 Mar 2008) $
067: */
068: public abstract class Interpolation {
069:
070: /**
071: *
072: */
073: protected Quadtree<?> data;
074:
075: private static URI type = null;
076: static {
077: try {
078: type = new URI("xsd:integer");
079: } catch (URISyntaxException never_happens) {
080: //nottin
081: }
082: }
083:
084: protected Values ignoreValues = new Values(new Interval[0],
085: new TypedLiteral[0], new TypedLiteral("-9999", type));
086:
087: protected double searchRadius1 = 0;
088:
089: protected double searchRadius2 = 0;
090:
091: protected double searchRadiusAngle = 0;
092:
093: protected int minData = 3;
094:
095: protected int maxData = Integer.MAX_VALUE;
096:
097: protected double noValue = -9999;
098:
099: protected double autoincreaseSearchRadius1 = 0;
100:
101: protected double autoincreaseSearchRadius2 = 0;
102:
103: private static final ILogger LOG = LoggerFactory
104: .getLogger(Interpolation.class);
105:
106: /**
107: *
108: * @param data
109: */
110: protected Interpolation(Quadtree<?> data) {
111: this .data = data;
112: searchRadius1 = calcSearchRadius();
113: searchRadius2 = searchRadius1;
114: }
115:
116: /**
117: *
118: * @param data
119: * @param ignoreValues
120: */
121: protected Interpolation(Quadtree<?> data, Values ignoreValues) {
122: this .data = data;
123: this .ignoreValues = ignoreValues;
124: searchRadius1 = calcSearchRadius();
125: searchRadius2 = searchRadius1;
126: }
127:
128: /**
129: *
130: * @param data
131: * @param ignoreValues
132: * @param searchRadius1
133: * @param searchRadius2
134: * @param searchRadiusAngle
135: * @param minData
136: * @param maxData
137: * @param noValue
138: * @param autoincreaseSearchRadius1
139: * @param autoincreaseSearchRadius2
140: */
141: protected Interpolation(Quadtree<?> data, Values ignoreValues,
142: double searchRadius1, double searchRadius2,
143: double searchRadiusAngle, int minData, int maxData,
144: double noValue, double autoincreaseSearchRadius1,
145: double autoincreaseSearchRadius2) {
146: this .data = data;
147: this .ignoreValues = ignoreValues;
148: // this.envelope = envelope;
149: this .searchRadius1 = searchRadius1;
150: this .searchRadius2 = searchRadius2;
151: this .searchRadiusAngle = searchRadiusAngle;
152: this .minData = minData;
153: this .maxData = maxData;
154: this .noValue = noValue;
155: this .autoincreaseSearchRadius1 = autoincreaseSearchRadius1;
156: this .autoincreaseSearchRadius2 = autoincreaseSearchRadius2;
157: }
158:
159: private double calcSearchRadius() {
160: try {
161: double w = data.getRootBoundingBox().getWidth();
162: double h = data.getRootBoundingBox().getHeight();
163: // default search radius is 20% of the target envelope
164: return Math.sqrt(w * w + h * h) / 5d;
165: } catch (IndexException e) {
166: LOG.logError(e.getLocalizedMessage(), e);
167: }
168: return 0;
169: }
170:
171: /**
172: * performs the interpolation
173: *
174: * @param width
175: * width of the result grid in number of cells
176: * @param height
177: * height of the result grid in number of cells
178: * @return result grid as an instance of
179: * @see org.deegree.model.coverage.grid.GridCoverage
180: * @throws InterpolationException
181: */
182: public FloatGridCoverage interpolate(int width, int height)
183: throws InterpolationException {
184:
185: Envelope envelope = null;
186:
187: try {
188: envelope = data.getRootBoundingBox();
189: } catch (IndexException e) {
190: LOG.logError(e.getLocalizedMessage(), e);
191: }
192:
193: WorldToScreenTransform trans = new WorldToScreenTransform(
194: envelope.getMin().getX(), envelope.getMin().getY(),
195: envelope.getMax().getX(), envelope.getMax().getY(), 0,
196: 0, width - 1, height - 1);
197:
198: float[][][] data = new float[1][height][width];
199: for (int i = 0; i < data[0][0].length; i++) {
200: for (int j = 0; j < data[0].length; j++) {
201: data[0][j][i] = (float) calcInterpolatedValue(trans
202: .getSourceX(i), trans.getSourceY(j),
203: searchRadius1, searchRadius2);
204: }
205: }
206:
207: // the CoverageOffering is passed as null here, desired? TODO
208: FloatGridCoverage result = new FloatGridCoverage(null,
209: envelope, data);
210:
211: return result;
212: }
213:
214: /**
215: * calculates the interpolated value for a position defined by x and y
216: *
217: * @param x
218: * @param y
219: * @param searchRadius1
220: * @param searchRadius2
221: * @return the interpolated value
222: * @throws InterpolationException
223: */
224: public abstract double calcInterpolatedValue(double x, double y,
225: double searchRadius1, double searchRadius2)
226: throws InterpolationException;
227:
228: }
|