UNPKG

gars_v2

Version:

Geo Assistant Research System

145 lines (138 loc) 5 kB
import fs from 'fs'; import readline from 'readline'; import error from './error'; class Data { constructor() {} read(datapath) { var p = new Promise((resolve, reject) => { var s = fs.createReadStream(datapath, { encoding: 'utf8' }); var rl = readline.createInterface({ input: s }); var meta = []; var rows = []; var i = 0; rl.on('line', line => { line = line.trim(); if (i < 5) { meta.push(line); } else { var row = line.split(/\s+/).map(Number); rows.push(row); } i++; }); rl.on('close', () => { this.parse(datapath, meta, rows); resolve(); }); s.on('error', e => { console.error(e); reject(e); }); }); return p; } parse(datapath, meta, rows) { this.FP = datapath; this.title = meta[0]; this.unit = meta[1]; this.cols = Number(meta[2]); this.rows = Number(meta[3]); this.llrange = meta[4].split(/\s+/).map(Number); this.meta = meta; this.data = rows; var actualRows = this.data.length; var actualCols = this.data.length ? this.data[0].length : 0; if (actualRows != this.rows || actualCols != this.cols) { var msg = [ 'declared rows: ' + this.rows, 'declared cols: ' + this.cols, 'actual rows: ' + actualRows, 'actual cols: ' + actualCols ].join('\n'); error('Corrupted Data', msg); } console.log('map data loaded', `rows: ${this.rows} cols: ${this.cols}`); } // closed range to avoid data loss rangeAveX(x1, y1, x2, y2) { console.log('calculating average X for range', `x1:${x1},x2:${x2},y1:${y1},y2:${y2}`); x1 = Math.max(0, Math.floor(x1)); y1 = Math.max(0, Math.floor(y1)); x2 = Math.min(this.cols - 1, Math.ceil(x2)); y2 = Math.min(this.rows - 1, Math.ceil(y2)); var points = []; for (var x = x1; x < x2; x++) { var total = 0, count = 0; for (var y = y1; y < y2; y++) { var d = this.data[y][x]; if (d === -999) continue; total += d; count++; } if (count === 0) continue; var ave = total / count; var x2lon = (x / this.cols) * (this.llrange[1] - this.llrange[0]) + this.llrange[0]; points.push([x2lon, ave]); } console.log('average X computed', points.length, 'points'); return points; } rangeAveY(x1, y1, x2, y2) { console.log('calculating average Y for range', `x1:${x1},x2:${x2},y1:${y1},y2:${y2}`); x1 = Math.max(0, Math.floor(x1)); y1 = Math.max(0, Math.floor(y1)); x2 = Math.min(this.cols - 1, Math.ceil(x2)); y2 = Math.min(this.rows - 1, Math.ceil(y2)); var points = []; for (var y = y1; y < y2; y++) { var total = 0, count = 0; for (var x = x1; x < x2; x++) { var d = this.data[y][x]; if (d === -999) continue; total += d; count++; } if (count === 0) continue; var ave = total / count; var y2lat = - (y / this.rows) * (this.llrange[3] - this.llrange[2]) - this.llrange[2]; points.push([y2lat, ave]); } console.log('average Y computed', points.length, 'points'); return points; } accData(x1, y1, x2, y2) { x1 = Math.max(0, Math.floor(x1)); y1 = Math.max(0, Math.floor(y1)); x2 = Math.min(this.cols - 1, Math.ceil(x2)); y2 = Math.min(this.rows - 1, Math.ceil(y2)); var points = []; for (var y = y1; y < y2; y++) { for (var x = x1; x < x2; x++) { if (this.data[y][x] === -999) continue; points.push(this.data[y][x]); } } return points; } longitude(i) { return i * (this.llrange[1] - this.llrange[0]) / this.cols + this.llrange[0]; } latitude(i) { return - i * (this.llrange[3] - this.llrange[2]) / this.rows - this.llrange[2]; } longitudeText(i){ var val = this.longitude(i).toFixed(3); var unit = val >= 0 ? 'E' : 'W'; return val + '° ' + unit; } latitudeText(i){ var val = this.latitude(i).toFixed(3); var unit = val >= 0 ? 'N' : 'S'; return val + '° ' + unit; } } export default Data;