UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

75 lines (68 loc) 3.85 kB
import * as THREE from 'three'; import { Extent } from '@itowns/geographic'; import GeoidGrid from "../Core/Geographic/GeoidGrid.js"; export const BYTES_PER_DOUBLE = 8; export const BYTES_PER_FLOAT = 4; /** * The `GTXParser` module provides a `[parse]{@link module:GTXParser.parse}` method. This method takes the content of a * GTX file in, and returns a {@link GeoidGrid}. The {@link GeoidGrid} contains all the necessary attributes and * methods to access the GTX data in iTowns. * * @module GTXParser */ export default { /** * Parses a GTX file content and returns a corresponding {@link GeoidGrid}. * * @param {ArrayBuffer} gtx The content of the GTX file to parse. * @param {Object} options An object gathering the optional parameters to pass to * the parser. * @param {Object} [options.in={}] Information on the GTX data. * @param {string} [options.in.crs='EPSG:4326'] The Coordinates Reference System (CRS) of the GTX data. * It must be a geographic CRS, and must be given as an * EPSG code. * @param {string} [options.in.dataType='float'] The encoding of geoid height data within the GTX file. * Must be `'float'` or `'double'`. * * @returns {Promise<GeoidGrid>} A promise resolving with a {@link GeoidGrid}, which contains all the necessary * attributes and methods to access GTX file data. */ parse(gtx) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { in: {} }; const dataType = options.in.dataType || 'float'; if (!['float', 'double'].includes(dataType)) { throw new Error('`dataType` parameter is incorrect for GTXParser.parse method. ' + 'This parameter must be either `double` or `float`.'); } // ---------- GET METADATA FROM THE FILE : ---------- const headerView = new DataView(gtx, 0, 40); const metadata = { minX: headerView.getFloat64(8), minY: headerView.getFloat64(0), stepX: headerView.getFloat64(24), stepY: headerView.getFloat64(16), nColumns: headerView.getInt32(36), nRows: headerView.getInt32(32) }; // ---------- BUILD A DATA VIEWER : ---------- const dataView = new DataView(gtx, 40); // ---------- CREATE A GeoidGrid FOR THE GIVEN FILE DATA : ---------- // formula for the max longitude : maxLongitude = minLongitude + deltaLongitude * (nColumns - 1) const maxX = metadata.minX + metadata.stepX * (metadata.nColumns - 1); // formula for the max latitude : maxLatitude = minLatitude + deltaLatitude * (nRows - 1) const maxY = metadata.minY + metadata.stepY * (metadata.nRows - 1); const dataExtent = new Extent(options.in.crs || 'EPSG:4326', metadata.minX, maxX, metadata.minY, maxY); const dataStep = new THREE.Vector2(metadata.stepX, metadata.stepY); return Promise.resolve(new GeoidGrid(dataExtent, dataStep, (verticalIndex, horizontalIndex) => { // formula to get the index of a geoid height from a latitude and longitude indexes is : // ``(nColumns * latIndex + lonIndex) * nBytes``, where nBytes stands for the number of bytes geoid // height data are encoded on. if (dataType === 'float') { return dataView.getFloat32((metadata.nColumns * verticalIndex + horizontalIndex) * BYTES_PER_FLOAT); } else if (dataType === 'double') { return dataView.getFloat64((metadata.nColumns * verticalIndex + horizontalIndex) * BYTES_PER_DOUBLE); } })); } };