import "./chunk-JSBRDJBE.js";

// src/js-tools/las/las-formats.ts
var char = "char";
var uchar = "uchar";
var short = "short";
var ushort = "ushort";
var long = "long";
var ulong = "ulong";
var longlong = "longlong";
var ulonglong = "ulonglong";
var float = "float";
var double = "double";
var string = "string";
var composite = "composite";
var lasByteSizes = {
  [char]: 1,
  [uchar]: 1,
  [short]: 2,
  [ushort]: 2,
  [long]: 4,
  [ulong]: 4,
  [longlong]: 8,
  [ulonglong]: 8,
  [float]: 4,
  [double]: 8,
  [string]: 1,
  [composite]: 1
};
var fileSignature = "fileSignature";
var fileSourceID = "fileSourceID";
var globalEncoding = "globalEncoding";
var projectID_GUIDData1 = "projectID_GUIDData1";
var projectID_GUIDData2 = "projectID_GUIDData2";
var projectID_GUIDData3 = "projectID_GUIDData3";
var projectID_GUIDData4 = "projectID_GUIDData4";
var versionMajor = "versionMajor";
var versionMinor = "versionMinor";
var systemIdentifier = "systemIdentifier";
var generatingSoftware = "generatingSoftware";
var fileCreationDayOfYear = "fileCreationDayOfYear";
var fileCreationYear = "fileCreationYear";
var headerSize = "headerSize";
var offsetToPointData = "offsetToPointData";
var numberOfVariableLengthRecords = "numberOfVariableLengthRecords";
var pointDataRecordFormat = "pointDataRecordFormat";
var pointDataRecordLength = "pointDataRecordLength";
var numberOfPointRecords = "numberOfPointRecords";
var numberOfPointByReturn = "numberOfPointByReturn";
var xScaleFactor = "xScaleFactor";
var yScaleFactor = "yScaleFactor";
var zScaleFactor = "zScaleFactor";
var xOffset = "xOffset";
var yOffset = "yOffset";
var zOffset = "zOffset";
var xMax = "xMax";
var yMax = "yMax";
var zMax = "zMax";
var xMin = "xMin";
var yMin = "yMin";
var zMin = "zMin";
var startOfWaveformDataPacketRecord = "startOfWaveformDataPacketRecord";
var legacyNumberOfPointRecords = "legacyNumberOfPointRecords";
var legacyNumberOfPointByReturn = "legacyNumberOfPointByReturn";
var startOfFirstExtVariableLengthRecord = "startOfFirstExtVariableLengthRecord";
var numberOfExtVariableLengthRecords = "numberOfExtVariableLengthRecords";
function createHeaderField(name, type, size) {
  return {
    name,
    type,
    size
  };
}
var version_1_2 = "1.2";
var version_1_3 = "1.3";
var version_1_4 = "1.4";
var pointRecordType0 = 0;
var pointRecordType1 = 1;
var pointRecordType2 = 2;
var pointRecordType3 = 3;
var pointRecordType4 = 4;
var pointRecordType5 = 5;
var pointRecordType6 = 6;
var pointRecordType7 = 7;
var pointRecordType8 = 8;
var pointRecordType9 = 9;
var pointRecordType10 = 10;
var headerFormats = {
  [version_1_2]: [
    createHeaderField(fileSignature, char, 4),
    createHeaderField(fileSourceID, ushort, 1),
    createHeaderField(globalEncoding, ushort, 1),
    createHeaderField(projectID_GUIDData1, ulong, 1),
    createHeaderField(projectID_GUIDData2, ushort, 1),
    createHeaderField(projectID_GUIDData3, ushort, 1),
    createHeaderField(projectID_GUIDData4, uchar, 8),
    createHeaderField(versionMajor, uchar, 1),
    createHeaderField(versionMinor, uchar, 1),
    createHeaderField(systemIdentifier, char, 32),
    createHeaderField(generatingSoftware, char, 32),
    createHeaderField(fileCreationDayOfYear, ushort, 1),
    createHeaderField(fileCreationYear, ushort, 1),
    createHeaderField(headerSize, ushort, 1),
    createHeaderField(offsetToPointData, ulong, 1),
    createHeaderField(numberOfVariableLengthRecords, ulong, 1),
    createHeaderField(pointDataRecordFormat, uchar, 1),
    createHeaderField(pointDataRecordLength, ushort, 1),
    createHeaderField(numberOfPointRecords, ulong, 1),
    createHeaderField(numberOfPointByReturn, ulong, 5),
    createHeaderField(xScaleFactor, double, 1),
    createHeaderField(yScaleFactor, double, 1),
    createHeaderField(zScaleFactor, double, 1),
    createHeaderField(xOffset, double, 1),
    createHeaderField(yOffset, double, 1),
    createHeaderField(zOffset, double, 1),
    createHeaderField(xMax, double, 1),
    createHeaderField(yMax, double, 1),
    createHeaderField(zMax, double, 1),
    createHeaderField(xMin, double, 1),
    createHeaderField(yMin, double, 1),
    createHeaderField(zMin, double, 1)
  ],
  [version_1_3]: [
    createHeaderField(fileSignature, char, 4),
    createHeaderField(fileSourceID, ushort, 1),
    createHeaderField(globalEncoding, ushort, 1),
    createHeaderField(projectID_GUIDData1, ulong, 1),
    createHeaderField(projectID_GUIDData2, ushort, 1),
    createHeaderField(projectID_GUIDData3, ushort, 1),
    createHeaderField(projectID_GUIDData4, uchar, 8),
    createHeaderField(versionMajor, uchar, 1),
    createHeaderField(versionMinor, uchar, 1),
    createHeaderField(systemIdentifier, char, 32),
    createHeaderField(generatingSoftware, char, 32),
    createHeaderField(fileCreationDayOfYear, ushort, 1),
    createHeaderField(fileCreationYear, ushort, 1),
    createHeaderField(headerSize, ushort, 1),
    createHeaderField(offsetToPointData, ulong, 1),
    createHeaderField(numberOfVariableLengthRecords, ulong, 1),
    createHeaderField(pointDataRecordFormat, uchar, 1),
    createHeaderField(pointDataRecordLength, ushort, 1),
    createHeaderField(numberOfPointRecords, ulong, 1),
    createHeaderField(numberOfPointByReturn, ulong, 5),
    createHeaderField(xScaleFactor, double, 1),
    createHeaderField(yScaleFactor, double, 1),
    createHeaderField(zScaleFactor, double, 1),
    createHeaderField(xOffset, double, 1),
    createHeaderField(yOffset, double, 1),
    createHeaderField(zOffset, double, 1),
    createHeaderField(xMax, double, 1),
    createHeaderField(yMax, double, 1),
    createHeaderField(zMax, double, 1),
    createHeaderField(xMin, double, 1),
    createHeaderField(yMin, double, 1),
    createHeaderField(zMin, double, 1),
    createHeaderField(startOfWaveformDataPacketRecord, ulonglong, 1)
  ],
  [version_1_4]: [
    createHeaderField(fileSignature, char, 4),
    createHeaderField(fileSourceID, ushort, 1),
    createHeaderField(globalEncoding, ushort, 1),
    createHeaderField(projectID_GUIDData1, ulong, 1),
    createHeaderField(projectID_GUIDData2, ushort, 1),
    createHeaderField(projectID_GUIDData3, ushort, 1),
    createHeaderField(projectID_GUIDData4, uchar, 8),
    createHeaderField(versionMajor, uchar, 1),
    createHeaderField(versionMinor, uchar, 1),
    createHeaderField(systemIdentifier, char, 32),
    createHeaderField(generatingSoftware, char, 32),
    createHeaderField(fileCreationDayOfYear, ushort, 1),
    createHeaderField(fileCreationYear, ushort, 1),
    createHeaderField(headerSize, ushort, 1),
    createHeaderField(offsetToPointData, ulong, 1),
    createHeaderField(numberOfVariableLengthRecords, ulong, 1),
    createHeaderField(pointDataRecordFormat, uchar, 1),
    createHeaderField(pointDataRecordLength, ushort, 1),
    createHeaderField(legacyNumberOfPointRecords, ulong, 1),
    createHeaderField(legacyNumberOfPointByReturn, ulong, 5),
    createHeaderField(xScaleFactor, double, 1),
    createHeaderField(yScaleFactor, double, 1),
    createHeaderField(zScaleFactor, double, 1),
    createHeaderField(xOffset, double, 1),
    createHeaderField(yOffset, double, 1),
    createHeaderField(zOffset, double, 1),
    createHeaderField(xMax, double, 1),
    createHeaderField(yMax, double, 1),
    createHeaderField(zMax, double, 1),
    createHeaderField(xMin, double, 1),
    createHeaderField(yMin, double, 1),
    createHeaderField(zMin, double, 1),
    createHeaderField(startOfWaveformDataPacketRecord, ulonglong, 1),
    createHeaderField(startOfFirstExtVariableLengthRecord, ulonglong, 1),
    createHeaderField(numberOfExtVariableLengthRecords, ulong, 1),
    createHeaderField(numberOfPointRecords, ulonglong, 1),
    createHeaderField(numberOfPointByReturn, ulonglong, 15)
  ]
};
var x = "x";
var y = "y";
var z = "z";
var intensity = "intensity";
var returnNumber = "returnNumber";
var numberOfReturns = "numberOfReturns";
var scanDirectionFlag = "scanDirectionFlag";
var edgeOfFlightLine = "edgeOfFlightLine";
var classification = "classification";
var scanAngleRank_LeftSide = "scanAngleRank_LeftSide";
var userData = "userData";
var pointSourceID = "pointSourceID";
var GPSTime = "GPSTime";
var red = "red";
var green = "green";
var blue = "blue";
var wavePacketDescriptorIndex = "wavePacketDescriptorIndex";
var byteOffsetToWaveFormData = "byteOffsetToWaveFormData";
var waveformPacketSizeInBytes = "waveformPacketSizeInBytes";
var returnPointWaveformLocation = "returnPointWaveformLocation";
var parametricDx = "parametricDx";
var parametricDy = "parametricDy";
var parametricDz = "parametricDz";
var classificationFlags = "classificationFlags";
var scannerChannel = "scannerChannel";
var scanAngle = "scanAngle";
var NIR = "NIR";
function createPointRecordNormalField(name, type) {
  return {
    attribute: {
      type: "normal",
      name
    },
    type
  };
}
function createPointRecordCompositeField(attributes) {
  const outputAttributes = Array();
  let offset = 0;
  for (const attribute of attributes) {
    outputAttributes.push({
      type: "composite",
      ...attribute,
      startBit: offset
    });
    offset += attribute.size;
  }
  if (offset !== 8) {
    throw new Error(
      "Invalid composite field, attribute sizes must add up to 8 (bits)"
    );
  }
  return {
    type: "composite",
    attributes: outputAttributes
  };
}
var pointRecordFormatBase = [
  createPointRecordNormalField(x, long),
  createPointRecordNormalField(y, long),
  createPointRecordNormalField(z, long),
  createPointRecordNormalField(intensity, ushort)
];
var pointRecordFormatColor = [
  createPointRecordNormalField(red, ushort),
  createPointRecordNormalField(green, ushort),
  createPointRecordNormalField(blue, ushort)
];
var pointRecordFormatWaveform = [
  createPointRecordNormalField(wavePacketDescriptorIndex, uchar),
  createPointRecordNormalField(byteOffsetToWaveFormData, ulonglong),
  createPointRecordNormalField(waveformPacketSizeInBytes, ulong),
  createPointRecordNormalField(returnPointWaveformLocation, float),
  createPointRecordNormalField(parametricDx, float),
  createPointRecordNormalField(parametricDy, float),
  createPointRecordNormalField(parametricDz, float)
];
var pointRecordFormat0 = [
  ...pointRecordFormatBase,
  createPointRecordCompositeField([
    {
      name: returnNumber,
      size: 3
    },
    {
      name: numberOfReturns,
      size: 3
    },
    {
      name: scanDirectionFlag,
      size: 1
    },
    {
      name: edgeOfFlightLine,
      size: 1
    }
  ]),
  createPointRecordNormalField(classification, uchar),
  createPointRecordNormalField(scanAngleRank_LeftSide, char),
  createPointRecordNormalField(userData, uchar),
  createPointRecordNormalField(pointSourceID, ushort)
];
var pointRecordFormat1 = [
  ...pointRecordFormat0,
  createPointRecordNormalField(GPSTime, double)
];
var pointRecordFormat2 = [
  ...pointRecordFormat0,
  ...pointRecordFormatColor
];
var pointRecordFormat3 = [
  ...pointRecordFormat1,
  ...pointRecordFormatColor
];
var pointRecordFormat4 = [
  ...pointRecordFormat1,
  ...pointRecordFormatWaveform
];
var pointRecordFormat5 = [
  ...pointRecordFormat3,
  ...pointRecordFormatWaveform
];
var pointRecordFormat6 = [
  ...pointRecordFormatBase,
  createPointRecordCompositeField([
    {
      name: returnNumber,
      size: 4
    },
    {
      name: numberOfReturns,
      size: 4
    }
  ]),
  createPointRecordCompositeField([
    {
      name: classificationFlags,
      size: 4
    },
    {
      name: scannerChannel,
      size: 2
    },
    {
      name: scanDirectionFlag,
      size: 1
    },
    {
      name: edgeOfFlightLine,
      size: 1
    }
  ]),
  createPointRecordNormalField(classification, uchar),
  createPointRecordNormalField(userData, uchar),
  createPointRecordNormalField(scanAngle, short),
  createPointRecordNormalField(pointSourceID, ushort),
  createPointRecordNormalField(GPSTime, double)
];
var pointRecordFormat7 = [
  ...pointRecordFormat6,
  ...pointRecordFormatColor
];
var pointRecordFormat8 = [
  ...pointRecordFormat7,
  createPointRecordNormalField(NIR, ushort)
];
var pointRecordFormat9 = [
  ...pointRecordFormat6,
  ...pointRecordFormatWaveform
];
var pointRecordFormat10 = [
  ...pointRecordFormat8,
  ...pointRecordFormatWaveform
];
var pointRecordFormats = {
  [pointRecordType0]: pointRecordFormat0,
  [pointRecordType1]: pointRecordFormat1,
  [pointRecordType2]: pointRecordFormat2,
  [pointRecordType3]: pointRecordFormat3,
  [pointRecordType4]: pointRecordFormat4,
  [pointRecordType5]: pointRecordFormat5,
  [pointRecordType6]: pointRecordFormat6,
  [pointRecordType7]: pointRecordFormat7,
  [pointRecordType8]: pointRecordFormat8,
  [pointRecordType9]: pointRecordFormat9,
  [pointRecordType10]: pointRecordFormat10
};

// src/js-tools/las/las-pointcloud.ts
import { proxy, transfer } from "comlink";

// src/js-tools/las/las-worker-api.ts
import { releaseProxy, wrap } from "comlink";
function createLasWorker() {
  const worker = new Worker(
    new URL("./workers/las-worker.min.js", import.meta.url),
    { type: "module" }
  );
  const api = wrap(worker);
  return {
    api,
    terminate() {
      api[releaseProxy]();
      worker.terminate();
    }
  };
}

// src/js-tools/las/las-pointcloud.ts
var LasPointCloud = class _LasPointCloud {
  constructor(header, data) {
    this._header = header;
    this._data = data;
  }
  get header() {
    return this._header;
  }
  getPoint(i) {
    const point = {};
    for (const attr of Object.keys(this._data)) {
      point[attr] = this._data[attr][i];
    }
    return point;
  }
  getData(attr) {
    return this._data[attr];
  }
  getAttributes() {
    const baseAttrs = ["x", "y", "z"];
    return Object.keys(this._data).filter(
      (attr) => baseAttrs.indexOf(attr) < 0
    );
  }
  async write({
    attributes = {},
    compressed = false,
    wasmPath = "",
    onProgress
  }) {
    const handle = createLasWorker();
    try {
      const { data } = await handle.api.writePoints(
        {
          header: this._header,
          attributes: {
            ...this._data,
            ...attributes
          },
          compressed,
          wasmPath
        },
        onProgress ? proxy(onProgress) : void 0
      );
      return data;
    } finally {
      handle.terminate();
    }
  }
  static async parse(data, {
    attributes,
    wasmPath,
    onProgress
  } = {}) {
    const handle = createLasWorker();
    let header;
    let pointData;
    try {
      const result = await handle.api.parsePoints(
        transfer(
          {
            data,
            additionalAttributes: attributes || [],
            wasmPath: wasmPath || ""
          },
          [data]
        ),
        onProgress ? proxy(onProgress) : void 0
      );
      header = result.header;
      pointData = result.pointData;
    } finally {
      handle.terminate();
    }
    const xData = new Float64Array(pointData["x"]);
    const yData = new Float64Array(pointData["y"]);
    const zData = new Float64Array(pointData["z"]);
    const additionalData = {};
    if (attributes) {
      for (const attr of attributes) {
        const data2 = pointData[attr];
        if (data2) {
          additionalData[attr] = new Float32Array(data2);
        }
      }
    }
    return new _LasPointCloud(header, {
      x: xData,
      y: yData,
      z: zData,
      ...additionalData
    });
  }
};

// src/js-tools/las/las-three.ts
import {
  BufferAttribute,
  BufferGeometry,
  Float32BufferAttribute,
  ShaderMaterial
} from "three";

// src/js-tools/las/shaders/point-shader.ts
var PointShader = {
  vertex: `
        precision highp float;

    #ifndef THREE
        attribute vec3 position;
        uniform mat4 modelViewMatrix;
        uniform mat4 projectionMatrix;
    #endif

        attribute float RED_ATTRIBUTE;

    #ifdef GREEN_ATTRIBUTE
        attribute float GREEN_ATTRIBUTE;
    #endif
    #ifdef BLUE_ATTRIBUTE
        attribute float BLUE_ATTRIBUTE;
    #endif
    #ifdef VERTEX_OPACITY
        attribute float opacity;
    #else
        uniform float opacity;
    #endif

        uniform vec2 redAttributeRange;
        uniform vec2 greenAttributeRange;
        uniform vec2 blueAttributeRange;

        uniform float pointSize;

        varying vec4 vColor;

        void main() {
            vec4 viewCoord = modelViewMatrix * vec4(position, 1.0);
            gl_Position = projectionMatrix * viewCoord;

    #ifdef SIZE_ATTENUATION
            gl_PointSize = pointSize / gl_Position.w;
    #else
            gl_PointSize = pointSize;
    #endif

            vColor.x = (RED_ATTRIBUTE - redAttributeRange.x) / (redAttributeRange.y - redAttributeRange.x);

    #ifdef GREEN_ATTRIBUTE
            vColor.y = (GREEN_ATTRIBUTE - greenAttributeRange.x) / (greenAttributeRange.y - greenAttributeRange.x);
    #else
            vColor.y = vColor.x;
    #endif

    #ifdef BLUE_ATTRIBUTE
            vColor.z = (BLUE_ATTRIBUTE - blueAttributeRange.x) / (blueAttributeRange.y - blueAttributeRange.x);
    #else
            vColor.z = vColor.x;
    #endif

            vColor.w = opacity;
        }
    `,
  fragment: `
        precision highp float;

        varying vec4 vColor;

        void main() {
            if (vColor.w == 0.0) {
                discard;
            }

            gl_FragColor = vColor;
    #ifdef THREE
            gl_FragColor = linearToOutputTexel(gl_FragColor);
    #endif
        }
    `
};

// src/js-tools/las/las-three.ts
var LasPointsGeometry = class extends BufferGeometry {
  constructor(pointCloud, {
    anchor = [0, 0],
    sampleRate = 1,
    withOpacity = false,
    withId = false
  } = {}) {
    super();
    if (pointCloud) {
      if (!sampleRate || sampleRate <= 0) {
        sampleRate = 1;
      }
      const nPoints = pointCloud.header.numberOfPointRecords;
      const positions = new Float32Array(
        Math.floor(nPoints / sampleRate) * 3
      );
      const x2 = pointCloud.getData("x");
      const y2 = pointCloud.getData("y");
      const z2 = pointCloud.getData("z");
      for (let i = 0, j = 0; i < nPoints; i += sampleRate, ++j) {
        positions[j * 3] = x2[i] - anchor[0];
        positions[j * 3 + 1] = z2[i];
        positions[j * 3 + 2] = -y2[i] + anchor[1];
      }
      this.setAttribute("position", new BufferAttribute(positions, 3));
      const attributes = pointCloud.getAttributes();
      for (const attr of attributes) {
        let data;
        if (sampleRate === 1) {
          data = pointCloud.getData(attr).slice();
        } else {
          const allData = pointCloud.getData(attr);
          data = new Float32Array(positions.length / 3);
          for (let i = 0, j = 0; i < nPoints; i += sampleRate, ++j) {
            data[j] = allData[i];
          }
        }
        this.setAttribute(attr, new BufferAttribute(data, 1, false));
      }
      if (withId) {
        this.setAttribute(
          "id",
          new Float32BufferAttribute(
            Float32Array.from({ length: positions.length / 3 }, (_, i) => i * sampleRate + 1),
            1,
            false
          )
        );
      }
      if (withOpacity) {
        this.setAttribute(
          "opacity",
          new BufferAttribute(
            new Float32Array(positions.length / 3).fill(1),
            1,
            false
          )
        );
      }
      this.computeBoundingBox();
      this.computeBoundingSphere();
    }
  }
};
var LasPointsMaterial = class extends ShaderMaterial {
  constructor({
    colorAttribute,
    colorAttributeRange,
    redAttributeRange,
    greenAttributeRange,
    blueAttributeRange,
    vertexOpacity,
    pointSize = 1,
    opacity = 1,
    sizeAttenuation = true
  }) {
    const defines = {};
    if (typeof colorAttribute === "string") {
      defines.RED_ATTRIBUTE = colorAttribute;
    } else {
      defines.RED_ATTRIBUTE = colorAttribute[0];
      defines.GREEN_ATTRIBUTE = colorAttribute[1];
      defines.BLUE_ATTRIBUTE = colorAttribute[2];
    }
    if (sizeAttenuation) {
      defines.SIZE_ATTENUATION = "";
    }
    if (vertexOpacity) {
      defines.VERTEX_OPACITY = "";
    }
    super({
      defines: {
        THREE: "",
        ...defines
      },
      uniforms: {
        pointSize: {
          value: pointSize
        },
        opacity: {
          value: opacity
        },
        redAttributeRange: {
          value: redAttributeRange || colorAttributeRange || [0, 1]
        },
        greenAttributeRange: {
          value: greenAttributeRange || colorAttributeRange || [0, 1]
        },
        blueAttributeRange: {
          value: blueAttributeRange || colorAttributeRange || [0, 1]
        }
      },
      vertexShader: PointShader.vertex,
      fragmentShader: PointShader.fragment,
      transparent: true
    });
  }
  get pointSize() {
    return this.uniforms.pointSize.value;
  }
  set pointSize(size) {
    this.uniforms.pointSize.value = size;
    this.uniformsNeedUpdate = true;
  }
  set colorAttributeRange(range) {
    this.uniforms.redAttributeRange.value = range;
    this.uniforms.greenAttributeRange.value = range;
    this.uniforms.blueAttributeRange.value = range;
    this.uniformsNeedUpdate = true;
  }
};
export {
  LasPointCloud,
  LasPointsGeometry,
  LasPointsMaterial,
  headerFormats,
  lasByteSizes,
  pointRecordFormats
};
