1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
C Copyright 1981-2007 ECMWF
C
C Licensed under the GNU Lesser General Public License which
C incorporates the terms and conditions of version 3 of the GNU
C General Public License.
C See LICENSE and gpl-3.0.txt for details.
C
REAL FUNCTION KNFROM4(LVEGGY,RLAT,RLON,OLAT,OLON,PT,OLDFLD)
C
C---->
C**** KNFROM4
C
C Purpose
C -------
C
C Generates a new field point from its four nearest neighbours.
C
C
C Interface
C ---------
C
C VALUE = KNFROM4(RLAT,RLON,OLAT,OLON,PT,OLDFLD)
C
C Input
C -----
C
C LVEGGY - 'True' if 'nearest neighbour' processing required
C RLAT - Latitude of the new point
C RLON - Longitude of the new point
C OLAT - Latitudes of the four neighbouring points
C OLON - Longitudes of the four neighbouring points
C PT - Positions in old field array of the four neighbours
C OLDFLD - Array of old field values
C
C
C Output
C ------
C
C Function returns a value for the new field point.
C
C
C Method
C ------
C
C Uses neighbours to calculate a value by bi-linear interpolation.
C
C
C Externals
C ---------
C
C None.
C
C
C Author
C ------
C
C J.D.Chambers ECMWF November 2000
C
C----<
C
IMPLICIT NONE
C
C Function arguments
C
LOGICAL LVEGGY
REAL RLAT,RLON,OLAT(2),OLON(4),OLDFLD(*)
INTEGER PT(4)
C
#include "intisl.h"
#include "parim.h"
#include "nifld.common"
C
C Local variables
C
INTEGER COUNT, LOOP, NEAREST
REAL WEIGHT(4), NWEIGHT, SWEIGHT, NORMAL
C
C Externals
C
C
C Statement function
C
REAL A, B
LOGICAL NOTEQ
NOTEQ(A,B) = (ABS((A)-(B)).GT.(ABS(A)*1E-3))
C
C -----------------------------------------------------------------|
C* Section 1. Calculate weighting values for each neighbour
C -----------------------------------------------------------------|
C
100 CONTINUE
C
C Calculate the north/south weighting values allowing for
C southern latitude to be same as northern latitude
C
NWEIGHT = OLAT(NORTH) - RLAT
SWEIGHT = RLAT - OLAT(SOUTH)
IF( SWEIGHT.EQ.0.0 ) NWEIGHT = 1.0
C
C Calculate the weighting values for each matching neighbour
C
WEIGHT(NWEST) = ABS((OLON(SEAST) - RLON) * SWEIGHT)
WEIGHT(NEAST) = ABS((RLON - OLON(SWEST)) * SWEIGHT)
WEIGHT(SWEST) = ABS((OLON(NEAST) - RLON) * NWEIGHT)
WEIGHT(SEAST) = ABS((RLON - OLON(NWEST)) * NWEIGHT)
C
C Normalise the weights
C
NORMAL = ( WEIGHT(NWEST) + WEIGHT(NEAST) +
X WEIGHT(SWEST) + WEIGHT(SEAST) )
C
WEIGHT(NWEST) = WEIGHT(NWEST)/NORMAL
WEIGHT(NEAST) = WEIGHT(NEAST)/NORMAL
WEIGHT(SWEST) = WEIGHT(SWEST)/NORMAL
WEIGHT(SEAST) = WEIGHT(SEAST)/NORMAL
C
C -----------------------------------------------------------------|
C* Section 3. Interpolate
C -----------------------------------------------------------------|
C
300 CONTINUE
C
C Use nearest neighbour for vegetation field
C
IF( LVEGGY ) THEN
NEAREST = NWEST
IF( WEIGHT(NEAST).GT.WEIGHT(NEAREST) ) NEAREST = NEAST
IF( WEIGHT(SWEST).GT.WEIGHT(NEAREST) ) NEAREST = SWEST
IF( WEIGHT(SEAST).GT.WEIGHT(NEAREST) ) NEAREST = SEAST
KNFROM4 = OLDFLD(PT(NEAREST))
C
ELSE
C
C Count non-missing data values
C
COUNT = 0
IF( NOTEQ(OLDFLD(PT(NWEST)),RMISSGV) ) COUNT = COUNT + 1
IF( NOTEQ(OLDFLD(PT(NEAST)),RMISSGV) ) COUNT = COUNT + 1
IF( NOTEQ(OLDFLD(PT(SWEST)),RMISSGV) ) COUNT = COUNT + 1
IF( NOTEQ(OLDFLD(PT(SEAST)),RMISSGV) ) COUNT = COUNT + 1
C
C Interpolate using four neighbours if none are missing
C
IF( COUNT.EQ.4 ) THEN
KNFROM4 = ( (OLDFLD(PT(NWEST)) * WEIGHT(NWEST)) +
X (OLDFLD(PT(NEAST)) * WEIGHT(NEAST)) +
X (OLDFLD(PT(SWEST)) * WEIGHT(SWEST)) +
X (OLDFLD(PT(SEAST)) * WEIGHT(SEAST)) )
C
C Set missing if all neighbours are missing
C
ELSE IF( COUNT.EQ.0 ) THEN
KNFROM4 = RMISSGV
C
C Otherwise, use the nearest neighbour
C
ELSE
NEAREST = NWEST
IF( WEIGHT(NEAST).GT.WEIGHT(NEAREST) ) NEAREST = NEAST
IF( WEIGHT(SWEST).GT.WEIGHT(NEAREST) ) NEAREST = SWEST
IF( WEIGHT(SEAST).GT.WEIGHT(NEAREST) ) NEAREST = SEAST
KNFROM4 = OLDFLD(PT(NEAREST))
ENDIF
ENDIF
C
C -----------------------------------------------------------------|
C* Section 9. Return
C -----------------------------------------------------------------|
C
900 CONTINUE
C
RETURN
END
|