index.js (2097B)
1 import declination from './declination.json'; 2 import {stringToArrayBuffer} from '~/lib/binary-strings'; 3 4 let data; 5 6 function mod(x, n) { 7 return ((x % n) + n) % n; 8 } 9 10 function loadData() { 11 const ar1 = new Uint8Array(stringToArrayBuffer(atob(declination.array))); 12 const ar2 = new Float32Array(ar1.length); 13 const scale = declination.valueScale; 14 const offset = declination.valueOffset; 15 for (let i = 0; i < ar1.length; i++) { 16 ar2[i] = ar1[i] / scale - offset; 17 } 18 return ar2; 19 } 20 21 function getArrayValue(row, col) { 22 if (row < 0 || col < 0 || col >= declination.colsCount || row >= declination.rowsCount) { 23 throw new Error(`Invalid col/row value col=${col} row=${row}`); 24 } 25 const ind = row * declination.colsCount + col; 26 if (ind >= data.length) { 27 throw new Error('Index value out of range'); 28 } 29 return data[ind]; 30 } 31 32 function getDeclination(lat, lon) { 33 if (lat < declination.minLat || lat > declination.maxLat) { 34 return null; 35 } 36 lon = mod(lon + 180, 360) - 180; 37 const row1 = Math.floor((lat - declination.minLat) / declination.step); 38 const row2 = row1 + 1; 39 const dlat = (lat - (row1 * declination.step + declination.minLat)) / declination.step; 40 let col1 = Math.floor((lon + 180) / declination.step); 41 let col2 = col1 + 1; 42 const dlon = (lon - (col1 * declination.step - 180)) / declination.step; 43 col1 %= declination.colsCount; 44 col2 %= declination.colsCount; 45 let a1 = getArrayValue(row1, col1); 46 let a2 = getArrayValue(row1, col2); 47 const v1 = a1 * (1 - dlon) + a2 * dlon; 48 if (row2 >= declination.rowsCount) { 49 return v1; 50 } 51 a1 = getArrayValue(row2, col1); 52 a2 = getArrayValue(row2, col2); 53 const v2 = a1 * (1 - dlon) + a2 * dlon; 54 const v = v1 * (1 - dlat) + v2 * dlat; 55 return v; 56 } 57 58 data = loadData(); 59 60 const magneticModelInfo = { 61 modelName: declination.model, 62 dateYMD: declination.dateYMD, 63 horizontalResolution: declination.step, 64 valueResolution: 1 / declination.valueScale, 65 }; 66 67 export {getDeclination, magneticModelInfo};