【使用手册】用PaaS搭建第一个属于你的数字孪生应用(11.18更新至6.1.0版本)

SuperAPI是开发者和AES场景底板的桥梁,它是一套由JavaScript语言开发的负责交涉Web页面(51浏览器)和51Cloud云渲染平台之间的编程接口,基于51Cloud云渲染平台使用;用户可在Web页面(51浏览器)上创建任意HTML5 UI元素,利用SuperAPI与AES场景底板进行双向交互。

SuperAPI兼容当前主流的JavaScript前端框架,为前端开发人员提供快速便捷的开发接口。

❗❗ SuperAPI for PaaS 用于服务WDP4.0的相关场景(本文)

❗❗ SuperAPI for Project 用于服务WDP3.0的相关场景

 

相关汇总指路👉:

一、概览——SuperAPI快速了解&API适配

二、学习SuperAPI(6.1.0)——使用 PaaS 搭建第一个属于你的数字孪生应用(本文)

三、版本信息——版权信息&版本更新

四、关于SuperAPI的常见问题

 


SuperAPI for PaaS

获取口令

--打开数字孪生世界的大门--

一、初识渲染地址和渲染口令

 

AES场景通过云渲染服务,采用实时视频流推送到网页端,并且能够实现前端到后端的交互同步,进入指定场景需要用到两个关键标识,分别是渲染地址和渲染口令

渲染地址:指部署云渲染服务(安装了51WDP并正常运行)机器的IP地址,端口8890

例 :cloudurl = “http:本机IP:8890”

 

渲染口令:由PaaS平台服务根据账号生成的一串唯一序列,是开启渲染界面的凭证

例 :orderID= “613eafe9a888380006d666e8”

 

二、用途

 

1. 编辑平台

渲染口令是登入在线编辑平台的钥匙,编辑平台需要输入渲染地址及渲染口令进行启动

 

2. 前端应用

渲染地址决定了渲染的服务在哪台机器上运行,渲染口令决定了最后渲染的是哪个场景

<script>
  var cloudRender = new cloudRenderer("player", 0);
  let cloudurl = "http://172.31.9.21:8889", //云渲染服务地址, 8889:固定端口
  orderID = "613eafe9a888380006d666e8"; //渲染口令, 在云渲染客户端上获得
</script>

 

三、获取

 

1. 准备工作(部署WDP数字孪生PaaS平台服务)

如未安装51WDP或遇到相关问题请移步至 🔗WDP4.0快速快速上手使用手册完成前期准备

安装51WDP并正常运行。出现如下图所示的界面,即说明云渲染已成功启动。

cloudstart

2. 获取云渲染地址

http:172.31.10.226:8890 为WDP数字孪生PaaS平台地址,端口号8890

http:172.31.10.226:8889 为开启云渲染服务地址,端口号8889

3. 获取渲染口令

登录WDP数字孪生PaaS平台,在案例发布中找到目标场景(没有场景时需要先创建场景后发布),点击“复制渲染口令”

 

copyOrder


 

编辑平台

--解放你的双手,更专注功能本身--

代码实时编辑,场景随之响应,灵活玩转数字孪生

 

左侧目录页,分门别类展示API功能

 

右侧代码编辑区;点击运行,效果立现 错误提示,一目了然 ;一键恢复,不怕试错 开启键盘事件,WASD控制方向

调色板,轻松自定义热力图渐变色,一键复制到代码中

 

下方日志全记录,事事有回应

 

即刻上手体验

在线地址:http://superapi.51aes.com/tools/edit?version=6.1.0

?version=6.1.0 可选, 默认最新版

version: 6.1.0     6.0.0

渲染口令: 613eafe9a888380006d666e8, 在WDP数字孪生PaaS平台上获取

云渲染地址: http://10.66.9.103:8889(例)


首个应用

--搭建第一个属于你的数字孪生应用--

 

一、前期准备

 

1、启动PaaS平台,创建并发布一个场景,安装流程请参考:https://bbs.51aes.com/study/list/1414471703908311041.html

2、 获取渲染口令。有关更多信息参考获取口令

 

二、API安装引用

 

SuperAPI的安装引用可以分为两种形式

 直接用 <script> 引入SuperAP

引入指定版本

 <script src="http://superapi.51aes.com/dist/superAPI-6.1.0.min.js"></script>

② 通过npm, cnpm, yarn安装: preview badge

 npm i 51superapi
 npm i 51superapi@6.1.0//请查看API适配按需引入指定版本
 cnpm install 51superapi
 yarn add 51superapi
 import cloudRenderer from "51superapi"

三、搭建页面

 

1. 创建DOM:

需要先定义一个div,id="player",作为渲染3D场景窗口的DOM节点。

 <div  id="player" style="display:none;"></div>

注意:不要在里面加任何自定义开发的元素, 特别是video; 也不要使用VUE自身的 v-show。

 

2. 创建云渲染对象:

初始化一个实例

<script>
    var cloudRender = new cloudRenderer("player", 0);
    let cloudurl = "http://172.31.9.21:8889",    //云渲染服务地址, 8889:固定端口
        orderID = "BE14b670";  //渲染口令, 在云渲染客户端上获得
</script>

参数描述:

参数 类型 备注
renderViewID id String 渲染3D场景窗口的Dom节点
playType 0 Integer 固定参数

将在<前期准备>中复制的渲染口令及其渲染地址替换代码中的cloudurl和orderID

 

3. 启动云渲染:

向云渲染主机发送post请求,并通过"StartRenderCloud"启动云渲染服务

<script>
    fetch(`${cloudurl}/Renderers/Any/order`, {
        method: "POST",
        headers: { "Content-type": "application/json" },
        body: JSON.stringify({order:orderID, width:window.innerWidth, height:window.innerHeight})
        //① order 渲染口令必填; ② width, height: 设置云渲染输出分辨率(此设置为固定分辨率,可选; 默认以云渲染客户端设置的分辨率输出)
    }).then(res => {
        if (!res.ok) { throw Error(res.statusText) }
        return res.json()
    }).then(json => {
        if (json.url) {

            //启动云渲染
            cloudRender.SuperAPI("StartRenderCloud", json.url);

            //事件注册
            cloudRender.SuperAPI("RegisterCloudResponse", myHandleResponseFunction);

            //场景中心点坐标(适用于wdp4.0)
            if (json.mapPin) {
                var SetCameraInfo_center_coord = `${json.mapPin.longitude},${json.mapPin.latitude}`;
            }
            //在事件注册函数中收到"APIAlready"后执行: 设置场景镜头API "SetCameraInfo", 设置场景镜头视角所用坐标点
        }
    }).catch((error) => {
        console.error('Error: ', error);
    });
</script>

备注:如果想开始键盘事件,请在“StartRenderCloud”后面添加“keyboard”

 cloudRender.SuperAPI("StartRenderCloud", json.url, "keyboard");

开启WASD方向键事件, 其它场景自定义事件, 添加"keyboardnofn"参数, 排除F1~F12功能键(浏览器可用); 需4.1.0及以上版本

 cloudRender.SuperAPI("StartRenderCloud", json.url, "keyboardnofn");

参数描述:

参数 备注
body order 渲染口令, 在云渲染客户端上获得
width=2560&height=1440 可选: 设置云渲染输出分辨率(此设置为固定分辨率; 默认以云渲染客户端设置的分辨率输出)
注: chrome浏览器最高支持4K, 4096 x 2160; 使用51Browser可以达到8K支持

 

四、事件监听

cloudRender.SuperAPI("RegisterCloudResponse", myHandleResponseFunction);

更多的监听细节请浏览 👉:产品文档-事件监听(6.1.0)

提示:“对场景的一切操作,请在apialready之后执行”

<script>
    function myHandleResponseFunction(data) {
        console.log('收到的事件: ' + data);
        const jsonObject = typeof data === 'object' ? JSON.parse(JSON.stringify(data)) : JSON.parse(data)
        switch(jsonObject.func_name) {
            case "beginPlay":
                // 云渲染连接成功 do Something
                break;
            case "APIAlready":
                // 3D世界加载完成 do Something
                break;
            case "OnAddPathSuccess":
                // 添加路径成功 do Something
                break;
            case "OnAddPathFailed":
                // 添加路径失败 do Something
                break;
            case "OnUpdatePathCoordSuccess":
                // 更新路径数据点成功 do Something
                break;
            case "OnUpdatePathCoordFailed":
                // 更新路径数据点失败 do Something
                break;
            case "OnFocusPathEnd":
                // 聚焦路径结束 do Something
                break;
            case "OnPathClick":
                // 点击路径 do Something
                break;
            case "OnSuperAPI_Error_Catch":
                // 错误捕捉 do Something
                // "args": {
                //   "error_type": "SuperAPI JSon Body Field Error",
                //   "error_information": "id"
                // }
                break;
            //更多func_name类型 回调通知, 详见各API事件
        }
        return data;
    }
</script>

 

五、使用API

 

在场景中添加POI功能

<script>
    function AddPOI() {
        let jsondata = {
            "id": "poi_id",
            "label": "Hello 51WORLD!",
            "coord_type": 0,
            "cad_mapkey": "",
            "coord": "103.995697,1.399239",
            "coord_z": 150,
            "coord_z_type": 0,
            "always_show_label": true,
            "show_label_range": "0,2000",
            "umg_type": "default",
            "sort_order": true
        }

        cloudRender.SuperAPI("AddPOI", jsondata, (status) => {
            console.log(status); //成功、失败回调
        })
    }

    AddPOI()
</script>

 

六、开始运行

❤️Hello 51WORLD!恭喜!你顺利地完成你的第一个应用❤️

 

 

七、完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="http://superapi.51aes.com/dist/superAPI.min.js"></script>
    <title">Hello 51WORLD!</title>
</head>
<body>
    <div id="player" style="display:none;"></div>
    <button class="btn" onclick="AddPOI()">添加点</button>

<script>
  var cloudRender = new cloudRenderer("player", 0);
  let cloudurl = "http://172.31.9.21:8889", //云渲染服务地址, 8889:固定端口
      orderID = "96923c86"; //渲染口令, 在云渲染客户端上获得

  fetch(`${cloudurl}/Renderers/Any/order`, {
        method: "POST",
        headers: { "Content-type": "application/json" },
        body: JSON.stringify({order:orderID, width:window.innerWidth, height:window.innerHeight})
        //① order 渲染口令必填; ② width, height: 设置云渲染输出分辨率(此设置为固定分辨率,可选; 默认以云渲染客户端设置的分辨率输出)
    }).then(res => {
        if (!res.ok) { throw Error(res.statusText) }
        return res.json()
    }).then(json => {
        if (json.url) {

            //启动云渲染
            cloudRender.SuperAPI("StartRenderCloud", json.url);

            //事件注册
            cloudRender.SuperAPI("RegisterCloudResponse", myHandleResponseFunction);
        }
    }).catch((error) => {
        console.error('Error: ', error);
    });

    function AddPOI() {
        let jsondata = {
            "id": "poi_id",
            "label": "Hello 51WORLD!",
            "coord_type": 0,
            "cad_mapkey": "",
            "coord": "103.995697,1.399239",
            "coord_z": 150,
            "coord_z_type": 0,
            "always_show_label": true,
            "show_label_range": "0,2000",
            "umg_type": "default",
            "sort_order": true
        }

        cloudRender.SuperAPI("AddPOI", jsondata, (status) => {
            console.log(status); //成功、失败回调
        })
    }

    AddPOI()
</script>
</body>
</html>

 

如需下载demo示例请加入开发者社区官方QQ答疑群(群号:780777412)领取

👇👇👇

 


附录其他-SPA开发

SuperAPI使用 (VUE2.X篇)

<template>
  <div id="player" style="display:none;"></div>
  //id="player": 渲染3D场景窗口的Dom节点; 不要在里面加任何自定义开发的元素, 特别是video; 不要使用VUE自身的 v-show;
</template>

<script>
    //引入SuperAPI.js
    import cloudRenderer from "superapi-51world"

    export default {
      name: 'Player',
      data() {
        return {
          cloudRender: null
        }
      },
      created() {
        //初始化实例
        this.cloudRender = new cloudRenderer("player", 0)
        //启动云渲染
        this.cloudRender.SuperAPI("StartRenderCloud", "json.url")//json.url的获取请参考首个应用中的如何启动云渲染
      },
      destroyed() {
        this.cloudRender.SuperAPI("StopRenderCloud") //关闭云渲染, 释放资源 (此处是关键。单页应用释放资源请注意)
      }
    }
</script>

 ❗ destroyed() 关闭云渲染, 释放资源, 单页应用释放资源请注意  

 

SuperAPI使用 (React篇)

componentWillUnmount() 关闭云渲染, 释放资源, 单页应用释放资源请注意

//引入SuperAPI.js
import cloudRenderer from "superapi-51world"

class Content extends React.Component {
  constructor(props) {
      this.cloudRender = null
  }
  componentDidMount() {
      //初始化实例
      this.cloudRender = new cloudRenderer("player", 0)
      //启动云渲染
      this.cloudRender.SuperAPI("StartRenderCloud", "json.url")//json.url的获取请参考首个应用中的如何启动云渲染
  }
  componentWillUnmount() {
      this.cloudRender.SuperAPI("StopRenderCloud") //关闭云渲染, 释放资源 (此处是关键。单页应用释放资源请注意)
  }
  render() {
      return (
        <div>
          <div id="player" style="display:none;"></div>
          //id="player": 渲染3D场景窗口的Dom节点; 不要在里面加任何自定义开发的元素, 特别是video;
        </div>
      );
  }
}

SuperAPI使用 (Angular篇)

//引入SuperAPI.js
import cloudRenderer from "superapi-51world"

@Component({
  selector: 'app-root',
  template: `<div id="player" style="display:none;"></div>`
})
export class AppComponent implements AfterViewInit, OnDestroy {
  player;  //渲染3D场景窗口的Dom节点
  cloudRender;

  ngAfterViewInit() {
    //初始化实例
    this.cloudRender = new cloudRenderer("player", 0)
    //启动云渲染
    this.cloudRender.SuperAPI("StartRenderCloud", "json.url")//json.url的获取请参考首个应用中的如何启动云渲染
  }

  ngOnDestroy() {
      this.cloudRender.SuperAPI('StopRenderCloud');
  }
}

ngOnDestroy() 关闭云渲染, 释放资源, 单页应用释放资源请注意

 

根据经纬度计算距离

1、根据经纬度计算距离公式

对上面的公式解释如下:

  1. Lung1 Lat1表示A点经纬度, Lung2 Lat2表示B点经纬度;
  2. a=Lat1 – Lat2 为两点纬度之差 b=Lung1 -Lung2 为两点经度之差;
  3. 6378.137为地球半径, 单位:为千米;
  4. 计算出来的结果单位:为千米, 若将半径改为米为单位:则计算的结果单位:为米;
  5. 计算精度与谷歌地图的距离精度差不多, 相差范围在0.2米以下。

2、参数描述:

lng: 经度

lat: 纬度

地球半径: 6378.137 (千米)

一般地图上显示的坐标顺序为, 纬度在前(范围-90 ~ 90), 经度在后(范围-180 ~ 180)

 

3、各种语言计算距离的代码

这种计算方式一般都是直线距离

4、sql计算距离
SELECT
          *,
          6378.138 * 2 * ASIN(
          SQRT(
              POW(
              SIN(
                  (
                  '.$lat.' * PI() / 180 - lat * PI() / 180
                  ) / 2
              ), 2
              ) + COS('.$lat.' * PI() / 180) * COS(lat * PI() / 180) * POW(
              SIN(
                  (
                  '.$lng.' * PI() / 180 - lng * PI() / 180
                  ) / 2
              ), 2
              )
          )
          ) *1000 AS distance
      FROM
          distance
      ORDER BY
          distance ASC
5、php计算距离
/**
      * 根据两点间的经纬度计算距离
      * @param $lng1
      * @param $lat1
      * @param $lng2
      * @param $lat2
      * @return int
      */
      public static function getDistance($lng1, $lat1, $lng2, $lat2)
      {
                  //将角度转为狐度
          $radLat1 = deg2rad($lat1);//deg2rad()函数将角度转换为弧度
          $radLat2 = deg2rad($lat2);
          $radLng1 = deg2rad($lng1);
          $radLng2 = deg2rad($lng2);
          $a = $radLat1 - $radLat2;
          $b = $radLng1 - $radLng2;
          $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 
2))) * 6378.137 * 1000;
          return $s;
      }
6、js计算距离
function getDistance(lat1, lng1, lat2, lng2) {
          let radLat1 = toRadians(lat1);
          let radLat2 = toRadians(lat2);
          let deltaLat = radLat1 - radLat2;
          let deltaLng = toRadians(lng1) - toRadians(lng2);
          let dis = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(deltaLat / 2), 2) + Math.cos(radLat1)
 * Math.cos(radLat2) * Math.pow(Math.sin(deltaLng / 2), 2)));
              return dis * 6378.137;

          function toRadians(d) {  return d * Math.PI / 180;}
      }

      getDistance(39.54, 116.23, 38.85, 115.48)           //100.43073284694667                 //单位:公里

7、Java计算距离

private static final  double EARTH_RADIUS = 6378137;//赤道半径
      private static double rad(double d){
          return d * Math.PI / 180.0;
      }
      public static double GetDistance(double lon1,double lat1,double lon2, double lat2) {
          double radLat1 = rad(lat1);
          double radLat2 = rad(lat2);
          double a = radLat1 - radLat2;
          double b = rad(lon1) - rad(lon2);
          double s = 2 *Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2)+Math.cos(radLat1)
*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
          s = s * EARTH_RADIUS;
      return s;            //单位:米
      }

8、Python求距离的方法

from math import sin, asin, cos, radians, fabs, sqrt

      def haversine(lon1, lat1, lon2, lat2): # 经度1, 纬度1, 经度2, 纬度2 (十进制度数)
          """
          Calculate the great circle distance between two points
          on the earth (specified in decimal degrees)
          """
          # 将十进制度数转化为弧度
          lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

          # haversine公式
          dlon = lon2 - lon1
          dlat = lat2 - lat1
          a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
          c = 2 * asin(sqrt(a))
          r = 6371 # 地球平均半径, 单位:为公里
          return c * r * 1000

      # 38352.523132 (m为单位:)
      print haversine(113.973129, 22.599578, 114.3311032, 22.6986848)

9、使用MySQL的geometry类型处理经纬度距离问题

建表

CREATE TABLE `map` (
      `id` int(11) NOT NULL,
      `address` varchar(255) NOT NULL DEFAULT '',
      `location` geometry NOT NULL,
      PRIMARY KEY (`id`),
      SPATIAL KEY `idx_location` (`location`)
      )

插入

INSERT INTO map (id, address, location) VALUES (1, 'somewhere', ST_GeomFromText('POINT(121.366961 31.190049)'))

注意必须使用 ST_GeomFromText 函数, 且 POINT() 里面是: 经度+空格+纬度

 

查询

1、查看经纬度

SELECT ST_Distance_Sphere(POINT(121.590347, 31.388094),location) AS distant FROM map

2、计算两点之间的距离

算出来的结果, 单位:是米。注意现在POINT()里面经纬度之间是逗号分隔的

3. 查询距离小于1000m的地点, 并由远及近排序

SELECT id, address, ST_Distance_Sphere(POINT(121.590347, 31.388094),
location) AS distant FROM map WHERE ST_Distance_Sphere(POINT(121.590347, 31.388094),
location) < 1000 ORDER BY distant

 

SuperAPI 边界能力

 

以下测试结果是基于项目包能够稳定运行 (20~24帧) 得出的结果, 仅供参考;
实际项目的覆盖物上限会根据项目场景大小, 云渲染服务器配置高低, 略有差异

覆盖物 单一覆盖物的坐标上限 相同覆盖物的数量上限 备注
POI   360个  
自定义POI   360  
路径 1200 100 单一路径包含20个坐标点
区域热力图 600 20 单一区域热力图包含100个坐标点
点云热力图 1500 20 单一点云热力图包含50个坐标点
柱状热力图 800 10 单一柱状热力图包含100个坐标点
路径热力图 800 100 单一路径热力图包含100个坐标点
迁徙图 1000 100 单一迁徙图包含10个坐标点
战略图 500 50 单一战略图包含10个坐标点
区域轮廓 600 400 单一区域轮廓包含10个坐标点
圆形区域轮廓   1200  
场景特效   120  
可视域   120  

如需产品同学协助解决问题的开发者

请加入开发者社区官方QQ答疑群(群号:780777412)领取

👇👇👇

 

您愿意向朋友推荐 ‘社区博客’ 吗?
强烈不推荐 不推荐 无所谓 推荐 强烈推荐
感谢您的反馈,谢谢!
阅读 922 本作品系原创,转载请联系作者授权
赞 1 收藏
全部评论({{commentCount}}条评论)
得票数 最新

暂无数据