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