Potree 003 基于Potree Desktop创建自定义工程
阅读原文时间:2023年07月08日阅读:1

1、第三方js库

第三方库js库选择dojo,其官网地址为https://dojotoolkit.org/,git地址为https://github.com/dojo/dojo,demo地址为https://demos.dojotoolkit.org/demos/,如果打不开,可以多刷新几次。

因为使用ArcGIS API for js开发,接触到了dojo,dojo是一个非常优秀的js框架库,包含的内容非常全,做单页面Web应用程序是一个非常不错的选择。

2、修改Mian.js文件

Main.js文件主要还是设置electron的一些参数,代码如下。

var electron = require("electron");
var app = electron.app;
var BrowserWindow = electron.BrowserWindow;
var path = require("path");
var Menu = electron.Menu;
var myMainWindow;
function CreateWindow() {
// 新建主窗体,设置图标、加载主页面
myMainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
backgroundThrottling: false
},
show: false
});
myMainWindow.maximize();
myMainWindow.setIcon(path.join(__dirname, "Res/Images/Ico64.png"));
myMainWindow.loadFile(path.join(__dirname, "Index.html"));
myMainWindow.show();
//把electron带的菜单隐藏
Menu.setApplicationMenu(null);
//屏蔽警告
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
myMainWindow.on("closed", function () {
myMainWindow = null;
});
}
app.on("ready", CreateWindow);
// Quit when all windows are closed.
app.on("window-all-closed", function () {
if (process.platform !== "darwin") {
app.quit()
}
});
app.on("activate", function () {
if (myMainWindow === null) {
CreateWindow()
}
});

我们在Potree Desktop代码中的Main.js文件的基础上上做了修改。通过引用electron,得到electron、app、BrowserWindow、path、Menu等引用,并定义了CreateWindow函数。

该函数是Main.js最主要的函数,在代码中,我们创建了一个BrowserWindow窗体,并最大化该窗体。设置了窗体图标、加载的页面等。最后调用窗体的Show函数,打开窗体。BrowserWindow窗体自带了一个菜单,通过Menu.setApplicationMenu(null);隐藏electron自带的菜单。当窗体关闭的时候,设置myMainWindow变量的值为null。

后面的代码主要针对全局App,当系统环境准备好的时候,调用CreateWindow函数。当所有的窗体都关闭后,退出App。当App被激活的时候,如果myMainWindow变量为null,则调用CreateWindow函数。这些逻辑基本上都是从Potree Desktop中拷贝过来的,修改了下变量名称,逻辑未变。

代码运行Mian.js,实例化BrowserWindow窗体,加载Index.html,此时系统就进入了Index.html页面。

3、修改index.html文件

我们的目的是做一个Web单页面应用程序,样式以及操作方式要尽量能贴近普通的桌面应用程序。整体布局包括菜单栏、工具栏、左侧工程树以及中间的主显示区。

首先引用外部的js和css文件,包括dojo、Potree定义的文件以及我们系统中自己定义的一些文件,代码如下。











接下来定义对electron和Nodejs中一些功能的引用。

ElectronDialog可弹出本地对话框,包括消息对话框,是否对话框等,类似于.Net中的MessageBox。NodeFS模块可对文件进行操作,类似于.Net中的File类。NodePath模块可文件路径进行操作,类似于.Net中的Path类。NodeChildProcess模块可调用本地的exe文件,并可以传入参数,捕捉输出信息等。

接下来是使用dojo库的一些配置以及Index.html页面直接引用的一些js文件。

Index.html文件最后,是该页面的布局代码,如下所示。

我们在body中直接定义了一个Table作为根元素,该表格分三行,第一行菜单栏,第二行工具条,第三行就是主显示区。如果想在底部增加状态栏,可再增加一行。

主显示区使用了dojo中定义的dijit/layout/BorderContainer,在BorderContainer中添加了两个dijit/layout/ContentPane,其中一个ContentPane的region属性设置为leading,另外一个ContentPane的region属性设置为center,并都设置splitter=true。这样主显示区域左侧会添加一个区域,宽度为260px,剩下的为中间区域,并且两区域可左右调整大小。

我们在Index.js中添加菜单。

4、添加菜单

菜单我们使用dojo中定义的dijit/MenuBar,如果我们添加文件子菜单,html代码如下。

文件

在js文件中,我们可以实例化一个dijit/MenuItem,添加到UI_File_DropDownMenu中。

CreateMenuItem: function () {
var myMenuItem = new MenuItem({
label: "打开文件",
iconClass: "AppMenuUIMenuItemIcon FileOpenIcon"
});
var myThis = this;
var myEventHander = on(myMenuItem, "click", function () {
myThis._OnClick();
});
this._EventHanderArray.push(myEventHander);
return myMenuItem;
},
//点击命令按钮执行的函数
_OnClick: function () {
var myFilePathArray = ElectronDialog.showOpenDialogSync(null, {
title: "选择工程文件",
properties: ["openFile"],
filters: [
{ name: '工程文件', extensions: ['project'] }
]
});
if (myFilePathArray == null) {
return;
}
var myProject = new Project();
myProject.Open(myFilePathArray[0]);
this._Application.SetProject(myProject);
},

把创建的MenuItem添加到菜单栏上的代码如下。

this.UI_File_DropDownMenu.addChild(new FileNewCommand({}, this._Application).CreateMenuItem());

5、添加工具条

工具条使用dojo中定义的dijit/Toolbar,html代码定义如下。

在js文件中,可以具体定义Button按钮点击后执行的函数,代码如下。

//点击全图按钮执行的函数
on(this.UI_FullExtent_Button, "click", function () {
myThis._Application.Viewer.fitToScreen();
});

一些逻辑较为复杂的工具,我们就要单独定义了,类似于定义菜单,我们会定义一个工具按钮。我们以新建工程为例,js代码如下。

define([
"dojo/_base/declare",
"dojo/on",
"dijit/MenuItem",
"dijit/form/Button"
], function (
declare,
on,
MenuItem,
Button
) {
return declare("ProjectNewCommand", null, {
_Application: null,
_EventHanderArray: null,
//构造函数
constructor: function (args, pApplication) {
declare.safeMixin(this, args);
this._Application = pApplication;
this._EventHanderArray = [];
},
//创建MenuItem
CreateMenuItem: function () {
var myMenuItem = new MenuItem({
label: "新建工程",
iconClass: "AppMenuUIMenuItemIcon ProjectNewIcon"
});
var myThis = this;
var myEventHander = on(myMenuItem, "click", function () {
myThis._OnClick();
});
this._EventHanderArray.push(myEventHander);
return myMenuItem;
},
//创建Button
CreateButton: function () {
var myButton = new Button({
label: "新建工程",
iconClass: "AppToolBarUIButtonIcon ProjectNewIcon",
showLabel: false,
});
var myThis = this;
var myEventHander = on(myButton, "click", function () {
myThis._OnClick();
});
this._EventHanderArray.push(myEventHander);
return myButton;
},
//点击命令按钮执行的函数
_OnClick: function () {
var myThis = this;
require(["WebRoot/CoreUI/Projects/ProjectNewDialog"],
function (Dialog) {
var myDialog = new Dialog({});
myDialog.ShowDialog();
myDialog.on("ProjectCreated", function (e) {
myThis._Application.SetProject(e.Project);
});
});
},
//默认销毁函数
destroy: function () {
for (var i = 0; i < this._EventHanderArray.length; i++) {
this._EventHanderArray[i].remove();
}
this._EventHanderArray = [];
},
});
});

代码中包含了CreateMenuItem和CreateButton函数,分别返回MenuItem和Button,点击这两个UI都是执行_OnClick函数,也就是说,我们当前定义的ProjectNewCommand.js,实例化得到ProjectNewCommand对象后,调用CreateMenuItem函数获取的按钮可以添加到菜单上,调用CreateButton函数获取的按钮可以添加到工具条上,且点击后,两个按钮的行为一致。

把按钮添加到工具栏上的代码如下。

var myProjectNewCommand = new ProjectNewCommand({}, myApplication);
myAppToolBarUI.UI_Toolbar.addChild(myProjectNewCommand.CreateButton(), 0);

6、Potree Viewer初始化

系统整体布局、菜单栏,工具条、左侧工程区域以及中间显示区域都定义好了之后,我们就要定义Viewer了。定义的时候,我们依然要参考Potree Desktop中实例化Viewer的代码,并根据实际需求修改。

var myPotreeRenderArea = document.getElementById("potree_render_area");
var myViewerArgs = {
noDragAndDrop: true,
};
var myViewer = new Potree.Viewer(myPotreeRenderArea, myViewerArgs);
myViewer.setEDLEnabled(true);
myViewer.setFOV(60);
myViewer.setPointBudget(3 * 1000 * 1000);
myViewer.setMinNodeSize(0);
myViewer.loadSettingsFromURL();
myViewer.setDescription("");
myViewer.setControls(myViewer.earthControls);

7、系统运行效果

执行.bat文件,运行,得到的系统主界面如下图所示。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器