UNPKG

s2-tools

Version:

A collection of geospatial tools primarily designed for WGS84, Web Mercator, and S2.

128 lines 4.21 kB
import { toReader } from '..'; /** A DBF data class to parse the data from a DBF */ export class DataBaseFile { reader; #header; #rows; /** * @param input - the input data structure to parse * @param encoding - the encoding of the raw data. defaults to 'utf-8' */ constructor(input, encoding) { this.reader = toReader(input); if (encoding !== undefined) this.reader.setStringEncoding(encoding); this.#parseHeader(); this.#rows = this.#parseRowHeader(); } /** * Create a copy of the header data * @returns - a copy of the header */ getHeader() { return { ...this.#header }; } /** * Get the properties for the given index * @param index - the index of the properties data we want * @returns - the properties for the given index */ getProperties(index) { const { records, recLen } = this.#header; if (index > records) return undefined; const offset = ((this.#rows.length + 1) << 5) + 2 + index * recLen; return this.#parseProperties(offset); } /** * Get all the properties in the DBF * @returns - an array of Properties */ getAllProperties() { const { records } = this.#header; const res = []; for (let i = 0; i < records; i++) { const properties = this.getProperties(i); if (properties !== undefined) res.push(properties); } return res; } /** * Parse the header and store it in the class */ #parseHeader() { const { reader } = this; this.#header = { lastUpdated: new Date(reader.getUint8(1) + 1900, reader.getUint8(2), reader.getUint8(3)), records: reader.getUint32(4, true), headerLen: reader.getUint16(8, true), recLen: reader.getUint16(10, true), }; } /** * Parses the row header and builds an array of keys that each property may have * @returns - an array of Rows that describe keys in each property */ #parseRowHeader() { const { reader } = this; const { headerLen } = this.#header; const len = headerLen - 1; const res = []; let offset = 32; while (offset < len) { res.push({ name: reader.parseString(offset, 11), dataType: String.fromCharCode(reader.getUint8(offset + 11)), len: reader.getUint8(offset + 16), decimal: reader.getUint8(offset + 17), }); if (reader.getUint8(offset + 32) === 13) { break; } else { offset += 32; } } return res; } /** * Parse the properties starting from the given offset * @param offset - offset of the row * @returns - a Properties object */ #parseProperties(offset) { const properties = {}; for (const header of this.#rows) { const value = this.#parseValue(offset, header.len, header.dataType); offset += header.len; if (typeof value !== 'undefined') properties[header.name] = value; } return properties; } /** * Parse the value at the given offset * @param offset - offset of the value * @param len - length of the value * @param type - the type of the value * @returns - the value as a string, number or boolean */ #parseValue(offset, len, type) { const { reader } = this; const textData = reader.parseString(offset, len); switch (type) { case 'N': case 'F': case 'O': return parseFloat(textData); case 'D': return new Date(parseFloat(textData.slice(0, 4)), parseInt(textData.slice(4, 6)) - 1, parseFloat(textData.slice(6, 8))).getUTCDate(); case 'L': return textData.toLowerCase() === 'y' || textData.toLowerCase() === 't'; default: return textData; } } } //# sourceMappingURL=dbf.js.map