@@ -172,16 +172,60 @@ self.onmessage = async (message) => {
172172 const ind = j + i * TILE_SIZE ;
173173 const lon = tile2lon ( x + j / TILE_SIZE , z ) ;
174174
175- const { index, xFraction, yFraction } = getIndexAndFractions (
176- lat ,
177- lon ,
178- domain ,
179- projectionGrid ,
180- ranges ,
181- [ latMin , lonMin , latMax , lonMax ]
182- ) ;
183-
184- let px = interpolator ( values as Float32Array , index , xFraction , yFraction , ranges ) ;
175+ let px = NaN
176+ if ( domain . grid . gaussianGridLatitudeLines ) {
177+ const latitudeLines = domain . grid . gaussianGridLatitudeLines
178+ const dy = 180 / ( 2 * latitudeLines + 0.5 ) ;
179+ const count = 6599680 ;
180+
181+ const nearestNeighbor = false
182+ if ( nearestNeighbor ) {
183+ // nearest neighbor
184+ const y = ( Math . round ( latitudeLines - 1 - ( lat - dy / 2 ) / dy ) + 2 * latitudeLines ) % ( 2 * latitudeLines ) ;
185+ const nx = y < latitudeLines ? 20 + y * 4 : ( 2 * latitudeLines - y - 1 ) * 4 + 20 ;
186+ const dx = 360 / nx ;
187+ const x = ( Math . floor ( lon / dx ) + nx ) % nx ;
188+ const integral = y < latitudeLines ? 2 * y * y + 18 * y : count - ( 2 * ( 2 * latitudeLines - y ) * ( 2 * latitudeLines - y ) + 18 * ( 2 * latitudeLines - y ) ) ;
189+ const index = integral + x
190+ px = values [ index ]
191+ } else {
192+ // linear interpolation
193+ const yLower = ( Math . floor ( latitudeLines - 1 - ( lat - dy / 2 ) / dy ) + 2 * latitudeLines ) % ( 2 * latitudeLines ) ;
194+ const yFraction = ( latitudeLines - 1 - ( lat - dy / 2 ) / dy ) % 1
195+ const yUpper = yLower + 1 ;
196+ const nxLower = yLower < latitudeLines ? 20 + yLower * 4 : ( 2 * latitudeLines - yLower - 1 ) * 4 + 20 ;
197+ const nxUpper = yUpper < latitudeLines ? 20 + yUpper * 4 : ( 2 * latitudeLines - yUpper - 1 ) * 4 + 20 ;
198+ const dxLower = 360 / nxLower ;
199+ const dxUpper = 360 / nxUpper ;
200+ const xLower0 = ( Math . floor ( lon / dxLower ) + nxLower ) % nxLower ;
201+ const xUpper0 = ( Math . floor ( lon / dxUpper ) + nxUpper ) % nxUpper ;
202+ const integralLower = yLower < latitudeLines ? 2 * yLower * yLower + 18 * yLower : count - ( 2 * ( 2 * latitudeLines - yLower ) * ( 2 * latitudeLines - yLower ) + 18 * ( 2 * latitudeLines - yLower ) ) ;
203+ const integralUpper = yUpper < latitudeLines ? 2 * yUpper * yUpper + 18 * yUpper : count - ( 2 * ( 2 * latitudeLines - yUpper ) * ( 2 * latitudeLines - yUpper ) + 18 * ( 2 * latitudeLines - yUpper ) ) ;
204+ const indexLower = integralLower + xLower0 ;
205+ const indexUpper = integralUpper + xUpper0 ;
206+ const xFractionLower = ( lon / dxLower ) % 1
207+ const xFractionUpper = ( lon / dxUpper ) % 1
208+ const p0 = values [ indexLower ]
209+ const p1 = values [ indexLower + 1 ]
210+ const p2 = values [ indexUpper ]
211+ const p3 = values [ indexUpper + 1 ]
212+ px = p0 * ( 1 - xFractionLower ) * ( 1 - yFraction ) +
213+ p1 * xFractionLower * ( 1 - yFraction ) +
214+ p2 * ( 1 - xFractionUpper ) * yFraction +
215+ p3 * xFractionUpper * yFraction
216+ }
217+ } else {
218+ const { index, xFraction, yFraction } = getIndexAndFractions (
219+ lat ,
220+ lon ,
221+ domain ,
222+ projectionGrid ,
223+ ranges ,
224+ [ latMin , lonMin , latMax , lonMax ]
225+ ) ;
226+
227+ px = interpolator ( values as Float32Array , index , xFraction , yFraction , ranges ) ;
228+ }
185229
186230 if ( hideZero . includes ( variable . value ) ) {
187231 if ( px < 0.25 ) {
0 commit comments