123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /**
- * ASCIIGridLoader.js
- *
- * @author realor
- */
- import { ObjectBuilder } from '../../builders/ObjectBuilder.js'
- import { Solid } from '../../core/Solid.js'
- import { SolidGeometry } from '../../core/SolidGeometry.js'
- import { WebUtils } from '../../utils/WebUtils.js'
- import * as THREE from '../../lib/three.module.js'
- class ASCIIGridLoader extends THREE.Loader {
- constructor(manager) {
- super(manager)
- this.ncols = 0
- this.nrows = 0
- this.xcenter = 0
- this.ycenter = 0
- this.cellSize = 0
- this.noDataValue = 0
- this.grid = []
- this.groupSize = 100
- this.material = new THREE.MeshPhongMaterial({ color: 0x808030 })
- this.options = {}
- }
- load(url, onLoad, onProgress, onError) {
- const loader = new FileLoader(this.manager)
- loader.setPath(this.path)
- loader.setRequestHeader(this.requestHeader)
- loader.setWithCredentials(this.withCredentials)
- loader.load(
- url,
- text => {
- try {
- onLoad(this.parse(text))
- } catch (ex) {
- if (onError) {
- onError(ex)
- } else {
- console.error(ex)
- }
- this.manager.itemError(url)
- }
- },
- onProgress,
- onError
- )
- }
- parse(text, onCompleted, onProgress, onError) {
- this.parseGrid(text)
- let terrain = new THREE.Group()
- terrain.name = 'Terrain'
- terrain.userData.selection = { type: 'none' }
- terrain.userData.grid = {
- ncols: this.ncols,
- nrows: this.nrows,
- xcenter: this.xcenter,
- ycenter: this.ycenter,
- noDataValue: this.noDataValue
- }
- const groupSize = this.groupSize
- let xsize = Math.ceil(this.ncols / groupSize)
- let ysize = Math.ceil(this.nrows / groupSize)
- let tileCount = xsize * ysize
- const createTile = tileIndex => {
- let i = tileIndex % xsize
- let j = Math.floor(tileIndex / xsize)
- let solid = this.createTileGeometry(groupSize * i, groupSize * j)
- solid.name = 'cell-' + i + '-' + j
- solid.edgesVisible = false
- terrain.add(solid)
- }
- if (onCompleted) {
- WebUtils.executeTasks(
- [
- { run: () => this.parseGrid(text), message: 'Parsing file...' },
- { run: createTile, message: 'Creating tiles...', iterations: () => tileCount }
- ],
- () => onCompleted(terrain),
- onProgress,
- error => onError(error),
- 100,
- 10
- )
- } else {
- this.parseGrid(text)
- for (let tileIndex = 0; tileIndex < tileCount; tileIndex++) {
- createTile(tileIndex)
- }
- }
- return terrain
- }
- parseGrid(text) {
- let lines = text.split('\n')
- let dataRow = []
- for (let line of lines) {
- line = line.trim()
- if (line.length > 0) {
- if (line[0].match(/[a-z]/i)) {
- // field
- this.readField(line)
- } else {
- // grid row
- let row = line.split(' ')
- for (let col = 0; col < row.length; col++) {
- let point = new THREE.Vector3()
- point.x = dataRow.length * this.cellSize
- point.y = this.grid.length * this.cellSize
- point.z = parseFloat(row[col])
- dataRow.push(point)
- }
- if (dataRow.length === this.ncols) {
- this.grid.push(dataRow)
- dataRow = []
- }
- }
- }
- }
- }
- createTileGeometry(ox, oy) {
- const groupSize = this.groupSize
- let geometry = new SolidGeometry()
- let dimx = Math.min(this.ncols - ox, groupSize + 1)
- let dimy = Math.min(this.nrows - oy, groupSize + 1)
- for (let j = oy; j < oy + dimy; j++) {
- for (let i = ox; i < ox + dimx; i++) {
- geometry.vertices.push(this.grid[j][i])
- }
- }
- for (let j = 0; j < dimy - 1; j++) {
- for (let i = 0; i < dimx - 1; i++) {
- geometry.addFace(j * dimx + i, j * dimx + (i + 1), (j + 1) * dimx + i)
- geometry.addFace(j * dimx + (i + 1), (j + 1) * dimx + (i + 1), (j + 1) * dimx + i)
- }
- }
- let solid = new Solid()
- solid.material = this.material
- solid.updateGeometry(geometry, false)
- return solid
- }
- readField(line) {
- line = line.toUpperCase()
- if (line.startsWith('NCOLS')) {
- this.ncols = parseInt(line.substring(6).trim())
- } else if (line.startsWith('NROWS')) {
- this.nrows = parseInt(line.substring(6).trim())
- } else if (line.startsWith('XLLCENTER')) {
- this.xcenter = parseFloat(line.substring(10).trim())
- } else if (line.startsWith('YLLCENTER')) {
- this.ycenter = parseFloat(line.substring(10).trim())
- } else if (line.startsWith('CELLSIZE')) {
- this.cellSize = parseFloat(line.substring(8).trim())
- } else if (line.startsWith('NODATA_VALUE')) {
- this.noDataValue = parseFloat(line.substring(13).trim())
- }
- }
- }
- export { ASCIIGridLoader }
|