UNPKG

@planet/ol-numpytiles

Version:

Data loader for NumpyTiles in OpenLayers

100 lines (92 loc) 3.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.fromArrayBuffer = fromArrayBuffer; exports.isNumpyArr = isNumpyArr; /* Copyright 2021 Planet Labs Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** Client-side parser for .npy files * * The numpy format specification is [here](http://docs.scipy.org/doc/numpy-dev/neps/npy-format.html). * This code is inspired by the GIST found [here](https://gist.github.com/nvictus/88b3b5bfe587d32ac1ab519fd0009607) but has been heavily modified. * * @module NumpyLoader */ function asciiDecode(buf) { return String.fromCharCode.apply(null, new Uint8Array(buf)); } function readUint16LE(buffer) { var view = new DataView(buffer); var val = view.getUint8(0); val |= view.getUint8(1) << 8; return val; } /** Sniff test to see if an arrayBuffer contains a Numpy arr * * @param {ArrayBuffer} buf - The array buffer to test. * * @returns {boolean} Returns true if likely a numpy array, false otherwise. */ function isNumpyArr(buf) { var magic = asciiDecode(buf.slice(0, 6)); return magic.slice(1, 6) === 'NUMPY'; } /** Read an ArrayBuffer as a NumpyTile * * @param {ArrayBuffer} buf - Numpy array to convert to Javascript typed array. * * @returns Javascript typed array. */ function fromArrayBuffer(buf) { if (buf.byteLength === 0) { return {}; } // Check the magic number if (!isNumpyArr(buf)) { throw new Error('Not a NumpyTile'); } var headerLength = readUint16LE(buf.slice(8, 10)), headerStr = asciiDecode(buf.slice(10, 10 + headerLength)), offsetBytes = 10 + headerLength; // this is a rough but working conversion of the // numpy header dict to Javascript object. var info = JSON.parse(headerStr.toLowerCase().replace(/'/g, '"').replace(/\(/g, '[').replace(/\),/g, ']')); // Intepret the bytes according to the specified dtype var data; if (info.descr === '|u1') { data = new Uint8Array(buf, offsetBytes); } else if (info.descr === '|i1') { data = new Int8Array(buf, offsetBytes); } else if (info.descr === '<u2') { data = new Uint16Array(buf, offsetBytes); } else if (info.descr === '<i2') { data = new Int16Array(buf, offsetBytes); } else if (info.descr === '<u4') { data = new Uint32Array(buf, offsetBytes); } else if (info.descr === '<i4') { data = new Int32Array(buf, offsetBytes); } else if (info.descr === '<f4') { data = new Float32Array(buf, offsetBytes); } else if (info.descr === '<f8') { data = new Float64Array(buf, offsetBytes); } else { throw new Error('unknown numeric dtype'); } return { shape: info.shape, data: data }; }