Potree

From OpenStreetMap Wiki
Jump to navigation Jump to search

Description

Potree is a FOSS WebGL based point cloud renderer for large point clouds, developed at the Institute of Computer Graphics and Algorithms, TU Wien

1. Installation and setup[1]

There's many either outdated tutorials or expect the novice user to know everything already about Linux. Further on YouTube quite some videos on this topic that give errors, at least to me. So I decided here on OpenStreetMap wiki to add a tutorial how to set up a point cloud server for mapping purposes.

Please note this if for Ubuntu 22.04 LTS Server

  1. cd ~ Go to your home folder
  2. mkdir build
  3. cd build
  4. git clone https://github.com/potree/potree.git
  5. cd potree
  6. sudo apt -yy install npm
  7. npm install
  8. cd ..
  9. mkdir deploy
  10. cp -R potree/build deploy/
  11. cp -R potree/libs deploy/
  12. cp -R potree/examples deploy/
  13. cp -R potree/docs deploy/
  14. mkdir deploy/template
  15. cd deploy
  16. zip -rq ../../deploy.zip *
  17. clear

At this point you created a deploy.zip file in your home folder which you can unzip[2] unzip deploy.zip -d destination_folder, wherever you feel it's appropriate, might also unzip it into your Apache html directory, or a virtual [https:Apache_HTTP_Server Apache] server for alternative ports. Also the build folder you created under step 2 can be deleted at this point.

If you don't have Apache or similar running you can simply use python] to run a |web server instance

  • python3 -m http.server 8080

After completing to populate the data to the server you can access the 3D point cloud data by using your browser and go to

For the next part of this tutorial we assume you used Entwine to turn your LAZ files into Entwine Point Tile data aka ept-data.

2. Apache configuration

We already installed successfully Apache while doing our Mantis installation, feel free to check up on that one. For Potree we need to configure this installation a bit[3]

Template to host Entwine Point Tiles

The following file shows how to host multiple files, this javascript can of course be refined to automatically scan a folder for files and add them, which I'll do at a later stage. As for now it's about the proof of concept to have a working example[4][5]

<!DOCTYPE html>
<html lang="en">
<head>
        <meta charset="utf-8">
        <meta name="description" content="">
        <meta name="author" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
        <title>Potree Viewer</title>

        <link rel="stylesheet" type="text/css" href="../build/potree/potree.css">
        <link rel="stylesheet" type="text/css" href="../libs/jquery-ui/jquery-ui.min.css">
        <link rel="stylesheet" type="text/css" href="../libs/openlayers3/ol.css">
        <link rel="stylesheet" type="text/css" href="../libs/spectrum/spectrum.css">
        <link rel="stylesheet" type="text/css" href="../libs/jstree/themes/mixed/style.css">
</head>

<body>
        <script src="../libs/jquery/jquery-3.1.1.min.js"></script>
        <script src="../libs/spectrum/spectrum.js"></script>
        <script src="../libs/jquery-ui/jquery-ui.min.js"></script>
        <script src="../libs/other/BinaryHeap.js"></script>
        <script src="../libs/tween/tween.min.js"></script>
        <script src="../libs/d3/d3.js"></script>
        <script src="../libs/proj4/proj4.js"></script>
        <script src="../libs/openlayers3/ol.js"></script>
        <script src="../libs/i18next/i18next.js"></script>
        <script src="../libs/jstree/jstree.js"></script>
        <script src="../libs/copc/index.js"></script>
        <script src="../build/potree/potree.js"></script>
        <script src="../libs/plasio/js/laslaz.js"></script>

        <!-- INCLUDE ADDITIONAL DEPENDENCIES HERE -->
        <!-- INCLUDE SETTINGS HERE -->

        <div class="potree_container" style="position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; ">
                <div id="potree_render_area" style="background-image: url('../build/potree/resources/images/background.jpg');"></div>
                <div id="potree_sidebar_container"> </div>
        </div>

        <script type="module">

        import * as THREE from "../libs/three.js/build/three.module.js";
                window.viewer = new Potree.Viewer(document.getElementById("potree_render_area"));

                viewer.setEDLEnabled(true);
                viewer.setFOV(60);
                viewer.setPointBudget(2_000_000);
                viewer.loadSettingsFromURL();

                viewer.setDescription("Loading Entwine-generated EPT format");

                viewer.loadGUI(() => {
                        viewer.setLanguage('en');
                        $("#menu_appearance").next().show();
                });

        var path = "../pointclouds/2021-06-01/ept.json";
        var name = "2021";

       var getQueryParam = function(name) 
		{
			name = name.replace(/[\[\]]/g, "\\$&");
			var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), results = regex.exec(window.location.href);
           if (!results || !results[2]) return null;
			return decodeURIComponent(results[2].replace(/\+/g, " "));
		}

       var r = getQueryParam('r');
        if (r) 
		{
			name = r;
            var http = 'http';
            if (r.substr(0, http.length) == http) path = name;
           else path = "../pointclouds/" + name + "/ept.json";
        }
		
		var c = getQueryParam('c');
		Potree.loadPointCloud("../pointclouds/2021-06-01/ept.json", "2021-06-01", function(e)
		{
			viewer.scene.addPointCloud(e.pointcloud);
			
			let material = e.pointcloud.material;
			material.size = 1;
			material.pointSizeType = Potree.PointSizeType.ADAPTIVE;
			if (c) material.activeAttributeName = c;
				viewer.fitToScreen(0.5);
		});
		
		Potree.loadPointCloud("../pointclouds/2021-06-02/ept.json", "2021-06-02", function(e)
		{
			viewer.scene.addPointCloud(e.pointcloud);
			
			let material = e.pointcloud.material;
			material.size = 1;
			material.pointSizeType = Potree.PointSizeType.ADAPTIVE;
			if (c) material.activeAttributeName = c;
				viewer.fitToScreen(0.5);
		});
		
		Potree.loadPointCloud("../pointclouds/2021-06-03/ept.json", "2021-06-03", function(e)
		{
			viewer.scene.addPointCloud(e.pointcloud);
			
			let material = e.pointcloud.material;
			material.size = 1;
			material.pointSizeType = Potree.PointSizeType.ADAPTIVE;
			if (c) material.activeAttributeName = c;
				viewer.fitToScreen(0.5);
		});
		
		</script>
  </body>
</html>

References