nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

index.js (1885B)


      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 export {getDeclination};