在React中使用Potree 加载点云模型.las

这两天因为工作需要加载点云数据,整理了Potree 加载点云模型.las的方案,因为前端项目是React项目,所以需要解决在React中的引入。下面是我找的解决方案以及和示例代码。

PoTree 简介如下 官网 提供了丰富的示例展示Potree 的能力。

Potree is a free open-source WebGL based point cloud renderer for large point clouds, developed at the Institute of Computer Graphics and Algorithms, TU Wien.

1. Potree Converter 点云模型

.las文件时无法直接加载的,Potree这个方案提供了工具将 .las 点云模型转换为Potree可以加载的数据文件,其处理方式跟类似之前处理过的地形模型或者3D Tiles切片。在下载页面下载最新的版本 有linux和window版本。我在window下面做的转换,操作很简单。如果对采样算法没有要求用下面的命令做转换就可以了。

bash 复制代码
$ PotreeConverter.exe <input> -o <outputDir>

Potree Converter也能指定采样算法。Poisson-disk sampling 和 Random sampling,我理解两者的区别在于Poisson-disk sampling 点与点之间距离会有一个最小值,这样可能看来会更自然舒服。Random sampling则是完全随机。

Optionally specify the sampling strategy:

  • Poisson-disk sampling (default): PotreeConverter.exe <input> -o <outputDir> -m poisson
  • Random sampling: PotreeConverter.exe <input> -o <outputDir> -m random

转换之后等到文件如下:

2. 在React中加使用Potree加载点云模型

1)Potree引入

本来想尽量使用ES6按模块引入,Potree项目是JS写的,我的工程是TS的需要解决类型的问题,并且我之前探索了一会儿Potree core那个项目的介绍的使用,结果没成功还花了不少时间,于是我参考了这个issue介绍的方法,想尽快看到结果。

在React中引入同样需要把最新版Potree 1.8.1下载下来,然后放到public文件夹中以静态资源的方式引入。

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
    <link rel="stylesheet" type="text/css" href="potree-libs/potree/potree.css">
    <link rel="stylesheet" type="text/css" href="potree-libs/libs/jquery-ui/jquery-ui.min.css">
    <link rel="stylesheet" type="text/css" href="potree-libs/libs/openlayers3/ol.css">
    <link rel="stylesheet" type="text/css" href="potree-libs/libs/spectrum/spectrum.css">
    <link rel="stylesheet" type="text/css" href="potree-libs/libs/jstree/themes/mixed/style.css">
    <link rel="stylesheet" type="text/css" href="potree-libs/libs/Cesium/Widgets/CesiumWidget/CesiumWidget.css">
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
    <script src="/potree-libs/libs/jquery/jquery-3.1.1.min.js"></script>
    <script src="/potree-libs/libs/spectrum/spectrum.js"></script>
    <script src="/potree-libs/libs/jquery-ui/jquery-ui.min.js"></script>
    <script src="/potree-libs/libs/other/BinaryHeap.js"></script>
    <script src="/potree-libs/libs/tween/tween.min.js"></script>
    <script src="/potree-libs/libs/d3/d3.js"></script>
    <script src="/potree-libs/libs/proj4/proj4.js"></script>
    <script src="/potree-libs/libs/openlayers3/ol.js"></script>
    <script src="/potree-libs/libs/i18next/i18next.js"></script>
    <script src="/potree-libs/libs/jstree/jstree.js"></script>
    <script src="/potree-libs/potree/potree/potree.js"></script>
    <script src="/potree-libs/libs/plasio/js/laslaz.js"></script>
    <script src="/potree-libs/libs/Cesium/Cesium.js"></script>
  </body>
</html>

示例代码引入了所有的资源,也可以更根据自己的需求移除不必要的资源

2)组件中加载点云模型

上面讲Potree引入之后,potree类挂载到window下面的,在组件下面引入时直接直接在window对象下获取,下面是示例代码。

示例代码中,数据放在public文件夹中方便做本地测试

tsx 复制代码
// src/pages/potree/Potree.tsx

import React, { useEffect, useRef } from "react"
const TreeUrl = "/data/tree/metadata.json"
// @ts-ignore
const Potree = window.Potree

const PoTree = () => {
  const viewRef = useRef(null)
  const viewElemRef = useRef(null)

  useEffect(() => {
    // 场景初始化
    const viewer = new Potree.Viewer(viewElemRef.current)
    viewRef.current = viewer
    viewer.setEDLEnabled(true)
    viewer.setFOV(60)
    viewer.setPointBudget(1 * 1000 * 1000)
    viewer.setClipTask(Potree.ClipTask.SHOW_INSIDE)
    viewer.loadSettingsFromURL()
    viewer.setControls(viewer.earthControls)
    viewer.setBackground("black")

    // 加载 potree 转换出来的数据
    Potree.loadPointCloud(TreeUrl).then(
      // @ts-ignore
      (evet) => {
        let pointcloud = evet.pointcloud
        let material = pointcloud.material
        material.activeAttributeName = "rgba"
        material.minSize = 2
        material.pointSizeType = Potree.PointSizeType.FIXED
        
        viewer.scene.addPointCloud(pointcloud)
        viewer.fitToScreen()
        viewer.setLeftView()
      },
      // @ts-ignore
      (error) => console.error("ERROR: ", error)
    )
  }, [viewRef])

  return (
    <>
      <div
        style={{
          position: "absolute",
          left: 0,
          top: 0,
          width: "100%",
          height: "100%"
        }}
        className="csm-viewer-container"
        id="csm-viewer-container"
        ref={viewElemRef}
      ></div>
    </>
  )
}

export default PoTree

参考文章

github.com/potree/potr...

potree.github.io/index.html

相关推荐
哆啦A梦158819 小时前
搜索页面布局
前端·vue.js·node.js
_院长大人_19 小时前
el-table-column show-overflow-tooltip 只能显示纯文本,无法渲染 <p> 标签
前端·javascript·vue.js
哆啦A梦158821 小时前
axios 的二次封装
前端·vue.js·node.js
阿珊和她的猫21 小时前
深入理解与手写发布订阅模式
开发语言·前端·javascript·vue.js·ecmascript·状态模式
yinuo21 小时前
一行 CSS 就能搞定!用 writing-mode 轻松实现文字竖排
前端
snow@li21 小时前
html5:拖放 / demo / 拖放事件(Drag Events)/ DataTransfer 对象方法
前端·html·拖放
爱看书的小沐1 天前
【小沐杂货铺】基于Three.js渲染三维风力发电机(WebGL、vue、react、WindTurbine)
javascript·vue.js·webgl·three.js·opengl·风力发电机·windturbine
浪裡遊1 天前
Nivo图表库全面指南:配置与用法详解
前端·javascript·react.js·node.js·php
漂流瓶jz1 天前
快速定位源码问题:SourceMap的生成/使用/文件格式与历史
前端·javascript·前端工程化
samroom1 天前
iframe实战:跨域通信与安全隔离
前端·安全