提交 e0be6b9a 作者: 翁进城

feat: 无人机应用模块标准化开发, 完成挂载代码接入, cesium地图加载

上级 064b725c
......@@ -18,8 +18,8 @@
* 不建议使用cnpm, 会生成.store目录, 并且会使用webpack5进行打包并出错, 本项目只能使用webpack4进行打包
# npm调试组件方法
* cnpm link (将npm包链接到本地全局目录(node_ktqmodules)下面,建议使用cnpm而不是npm,速度差很多)
* cd vue2 后执行 npm link mmc-stl-vue2 (在主项目中引用上一步挂到全局的软链接)
* cnpm link (将npm包链接到本地全局目录(node_modules)下面,建议使用cnpm而不是npm,速度差很多)
* cd vue2 后执行 cnpm link mmc-stl-vue2 (在主项目中引用上一步挂到全局的软链接)
* npm run dev (开启演示项目服务)
# 项目引入方法:
......@@ -32,7 +32,6 @@ import MMCSTL from 'mmc-stl-vue2';
Vue.use(MMCSTL);
```
# 备注
由于是使用git而非npm仓库, 不会自动拉取相应依赖, package.json中的dependencies依赖要复制到项目的package.json文件中.
生成目录树请安装
......
......@@ -9,16 +9,18 @@ import MMCPlayer from "./src/components/MMCPlayer";
import MMCUavList from "./src/components/MMCUavList";
import MMCMQTT from './src/plugins/MMCMQTT';
import MMCGroundStation from "./src/plugins/MMCGroundStation";
import MMCFlightControlCenter from './src/components/MMCFlightControlCenter';
const components = [
MMCCodeDemo,
MMCDataTransferPanel,
MMCPlayer,
MMCUavList
MMCUavList,
MMCFlightControlCenter
];
const plugins = [MMCMQTT, MMCGroundStation];
export default {
install: function (Vue, options) {
Vue.use(VueClipBoard);
......@@ -33,3 +35,5 @@ export default {
...components,
...plugins
};
export { default as MMCFlightControlCenterMain } from './src/components/MMCFlightControlCenter/main';
\ No newline at end of file
......@@ -23,6 +23,7 @@
"echarts": "^4.9.0",
"element-ui": "^2.15.13",
"file-saver": "^2.0.5",
"global": "^4.4.0",
"interactjs": "^1.10.17",
"jspack": "^0.0.4",
"moment": "^2.29.4",
......@@ -31,6 +32,9 @@
"recorder-core": "^1.2.23020100",
"terraformer-wkt-parser": "^1.2.1",
"url": "^0.11.0",
"vue-clipboard2": "^0.3.3"
"vue-clipboard2": "^0.3.3",
"vue": "^2.6.14",
"vue-router": "^3.5.2",
"vuex": "^3.6.2"
}
}
export { default as Control_API } from './modules/uav_control';
\ No newline at end of file
import { Message } from 'element-ui';
// 设置Message最多显示一条
let messageInstance = null;
export const resetMessage = (options) => {
if (messageInstance) {
messageInstance.close();
}
messageInstance = Message(options);
};
['error', 'success', 'info', 'warning'].forEach((type) => {
resetMessage[type] = (options) => {
if (typeof options === 'string') {
options = {
message: options
};
}
options.type = type;
return resetMessage(options);
};
});
import request from '../request_tg';
import request_uav from '../request_uav';
class Control_API {
/**
* 无人机token登录
* @param {*} data
* @returns
*/
static login(data) {
return request({
url: '/crm/account/loginInfo',
method: 'post',
data,
headers: {
token: window.localStorage.getItem('tmj_token')
}
});
}
/**
* 无人机接管更新状态
* @param {*} id //设备id
* @returns
*/
static updateTakeOver(id) {
return request({
url: `/dms/uav/updateTakeOver/${id}`,
method: 'put'
});
}
// 获取无人机树结构列表
static getUavTree(params) {
return request({
url: '/dms/uav/tree',
method: 'get',
params
});
}
// 获取无人机列表
static getUavDataList(params) {
return request({
url: '/dms/uav/page',
method: 'get',
params
});
}
// 获取航线列表
static getUavRouteList(params) {
return request({
url: '/dms/route/page',
method: 'get',
params
});
}
// 获取架次号
static getFlightSortic({ taskId, deviceHardId }) {
return request({
url: `/tss/task/getFlightSortic/${taskId}/${deviceHardId}`,
method: 'get'
});
}
// 无人机详情
static uavDetail(params) {
return request({
url: `/dms/uav/detail/${params.id}`,
method: 'get'
});
}
// 飞行日志
static getFlightLog(data) {
return request({
url: `/dms/sortie/flightLog`,
method: 'post',
data
});
}
// 保存图片
static addPhoto(data) {
return request({
url: `/dms/sortie-image/add`,
method: 'post',
data
});
}
// 保存AI图片
// static addAiPhoto(data) {
// return request({
// url: `/dms/sortie-image/addAi`,
// method: "post",
// data
// });
// }
// 获取所有机构列表
static getAllOrg() {
return request({
url: `/crm/organization/tree`,
method: 'get'
});
}
// 获取所有无人机操作日志
static getUavAllLog(params) {
return request_uav({
url: `/api/log/selectUavCmdLikeList`,
method: 'get',
params
});
}
// 获取1小时短时天气预报
static getUavShortForEcast(params) {
return request_uav({
url: `/whapi/json/aliweather/shortforecast`,
method: 'post',
params
});
}
// 获取24小时短时天气预报(详细)包含风向等等...
static getUavShortForEcast24(params) {
return request_uav({
url: `/whapi/json/aliweather/forecast24hours`,
method: 'post',
params
});
}
// 获取树结构-鹰巢
static getUavNestList(params) {
return request({
url: `/dms/nest/getNestList`,
method: 'get',
params
});
}
// 获取任务库列表
static getTaskList(data) {
return request({
url: `/tss/task/list`,
method: 'post',
data
});
}
// 获取任务库内的任务详情
static getTaskDetails(params) {
return request({
url: `/tss/task/${params.id}`,
method: 'get'
});
}
// 鹰巢-定时,周期自启动
static startUavNest = (data) =>
request({
url: '/tss/task/start',
method: 'POST',
data
});
// 鹰巢-运行日志
static getUavNestLog = (params) =>
request_uav({
url: `api/log/selectProcessLikeList`,
method: 'get',
params
});
}
export default Control_API;
import axios from 'axios';
import Vue from 'vue';
import { resetMessage } from './message';
import router from '../router';
import store from '../store';
let prodUrl = 'https://tmj.mmcuav.cn';
let devUrl = 'https://test.tmj.mmcuav.cn'
const $axios = axios.create({
// baseURL: process.env.VUE_APP_BASE_API_TG
});
Vue.prototype.$http = axios;
const loading = null;
/**
* 请求拦截器
* 用于处理请求前添加loading、判断是否已保存token,并在每次请求头部添加token
*/
$axios.interceptors.request.use(
(config) => {
if(store.state.devMode){
config.baseURL = devUrl;
} else {
config.baseURL = prodUrl;
}
const token = localStorage.getItem('tmj_token');
if (token) {
config.headers['token'] = token;
config.headers['channel'] = 'channel'; // 渠道 主平台 子平台 后台
}
return config;
},
(error) => {
console.log('进来了2....');
return Promise.reject(error);
}
);
/**
* 响应拦截器
* 用于处理loading状态关闭、请求成功回调、响应错误处理
*/
$axios.interceptors.response.use(
(response) => {
console.log('请求的URL:', response.config.url);
if (loading) {
loading.close();
}
console.log('回应参数...', response);
const status = response.status;
const res = response.data;
// 请求成功返回response.data
if ((status >= 200 && status < 300) || status === 304) {
switch (res.code) {
case 200:
return Promise.resolve(response.data);
case 525:
if (store.state.isIframe) {
resetMessage.error(response.data.msg);
}
return Promise.resolve(response.data);
case 401:
// resetMessage.error('登录失效');
store.commit('user/LOGIN_OUT');
router.replace({
path: '/login'
});
return Promise.reject(response);
case 403:
if (store.state.isIframe) {
resetMessage.error(response.data.msg);
}
break;
default:
if (response.config.responseType === 'blob') {
return Promise.resolve(response.data);
}
resetMessage.error(response?.data?.msg || '网络请求错误');
return Promise.reject(response.data);
}
} else {
return Promise.reject(response);
}
},
(error) => {
if (loading) {
loading.close();
}
console.log(error);
if (error.response) {
switch (error.response.data.code) {
case 401:
// 返回401 清除token信息并跳转到登陆页面
// store.commit("user/LOGIN_OUT");
// router.replace({
// path: "/login",
// query: {
// redirect: router.currentRoute.fullPath,
// },
// });
break;
case 403:
// 返回403 清除token信息并跳转到登陆页面
// store.commit("user/LOGIN_OUT");
resetMessage.error('token过期');
/* router.replace({
path: "/login",
query: {
redirect: router.currentRoute.fullPath,
},
}); */
break;
case 404:
resetMessage.error('网络请求不存在');
break;
default:
// 统一错误提示弹窗
resetMessage.error(error.response?.data?.msg || '网络请求错误');
}
} else {
// 请求超时或者网络有问题
if (error.message.includes('timeout')) {
resetMessage.error('请求超时!请检查网络是否正常');
} else {
resetMessage.error('请求失败,请检查网络是否已连接');
}
}
return Promise.reject(error);
}
);
export default $axios;
import axios from 'axios';
// import store from "../store";
// import router from "../router";
import Vue from 'vue';
// 引用element-ui的加载和消息提示组件
// import { Loading } from "element-ui";
import { resetMessage } from './message';
import store from '../store';
let prodUrl = 'https://tmj.mmcuav.cn/flight_control';
let devUrl = 'https://test.tmj.mmcuav.cn/flight_control'
const $axios = axios.create({
// 设置超时时间
// timeout: 30000,
// 基础url,会在请求url中自动添加前置链接
// baseURL: process.env.VUE_APP_BASE_UAV_API
});
Vue.prototype.$http = axios;
const loading = null;
/**
* 请求拦截器
* 用于处理请求前添加loading、判断是否已保存token,并在每次请求头部添加token
*/
$axios.interceptors.request.use(
(config) => {
// let FLYINGSESSIONID = localStorage.getItem("FLYINGSESSIONID");
// let mmcIdentity = localStorage.getItem("mmcIdentity");
// let token = localStorage.getItem("tmj_token")
// loading = Loading.service({ text: "Loading", background: "transparent" });
// if (FLYINGSESSIONID && mmcIdentity) {
// 请求头部添加token
// config.headers["FLYINGSESSIONID"] = FLYINGSESSIONID;
// config.headers["mmc-identity"] = mmcIdentity;
// config.headers["token"] = token; //测试token用例:607753147d46ba48b1ac30a4ad3d60cd
// }
if(store.state.devMode){
config.baseURL = devUrl;
} else {
config.baseURL = prodUrl;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
/**
* 响应拦截器
* 用于处理loading状态关闭、请求成功回调、响应错误处理
*/
$axios.interceptors.response.use(
(response) => {
if (loading) {
loading.close();
}
const code = response.status;
const res = response.data;
// 请求成功返回response.data
if ((code >= 200 && code < 300) || code === 304) {
if (res.status == 621) {
resetMessage.error(res.message);
// store.commit("user/LOGIN_OUT");
// router.push("/login");
}
return Promise.resolve(response.data);
} else {
return Promise.reject(response);
}
},
(error) => {
if (loading) {
loading.close();
}
console.log(error);
if (error.response) {
switch (error.response.status) {
case 401:
// 返回401 清除token信息并跳转到登陆页面
// store.commit("user/LOGIN_OUT");
// router.replace({
// path: "/login",
// query: {
// redirect: router.currentRoute.fullPath,
// },
// });
break;
case 404:
resetMessage.error('网络请求不存在');
break;
case 403:
if (store.state.isIframe) {
resetMessage.error('授权组件已被禁用,请联系管理员');
}
break;
default:
resetMessage.error(error.response.data.message);
}
} else {
// 请求超时或者网络有问题
if (error.message.includes('timeout')) {
resetMessage.error('请求超时!请检查网络是否正常');
} else {
resetMessage.error('请求失败,请检查网络是否已连接');
}
}
return Promise.reject(error);
}
);
export default $axios;
<template>
<div class="wih100 ht100 cpt-cesium_layerBox">
<div id="layer-container"></div>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import { User } from "../../api";
export default {
data() {
return {
viewer: null,
init_lng: 112.576667,
init_lat: 23.175833,
init_alt: 5000,
imageryLayers: {
night: null, // 夜景图
satellite: null, // 卫星图
text: null, // 地名标记
},
};
},
computed: {
...mapState([]),
...mapState(["mapMode"]),
},
watch: {
mapMode(newVal) {
switch (newVal) {
case 0:
this.imageryLayers.satellite.show = true;
this.imageryLayers.night.show = false;
// this.imageryLayers.text.show = true;
break;
case 1:
this.imageryLayers.satellite.show = false;
this.imageryLayers.night.show = true;
// this.imageryLayers.text.show = false;
break;
}
},
},
mounted() {
if (!window.$mmc) {
window.$mmc = {};
}
window.$mmc.viewer = {};
// this.get_user_position()//获取用户位置
this.init_viewer();
this.bus_getPositions();
},
methods: {
...mapActions([]),
selectMpa(item) {
console.log(item, "item");
},
bus_getPositions() {
this.$bus.$on("handlePositions", (e) => {
this.init_lng = e[0];
this.init_lat = e[1];
this.init_alt = 300000;
this.viewer.scene.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
this.init_lng,
this.init_lat,
this.init_alt
),
});
});
},
async init_viewer() {
// 超图服务加密访问
// Ap6qLhnKi1YT4ds90jxn6mftBG4tmLFbTH2Y79XRGMG4fophoB8axKlCj6IuQMW8dAXsyHAnmzrU-zF1tMuMpg..
// Cesium.Credential.CREDENTIAL = new Cesium.Credential('r0G6d8tdvfgN_Aad1j28SGqj6ILgt1DNHpP9dK-FNVOVBPgcyaHiEs2z2qyv455bTHU8QaFTbt_Y_AdeAsPp-Q..');
// 解决航线被三维模型遮盖
const oldPolylineUpdate = Cesium.PolylineCollection.prototype.update;
Cesium.PolylineCollection.prototype.update = function (frameState) {
const oldMorphTime = frameState.morphTime;
frameState.morphTime = 0.0;
oldPolylineUpdate.call(this, frameState);
frameState.morphTime = oldMorphTime;
};
const viewerOptions = {
animation: false,
shouldAnimate: true,
homeButton: false,
fullscreenButton: false,
baseLayerPicker: false,
geocoder: true,
timeline: false,
sceneModePicker: true,
navigationHelpButton: false,
infoBox: false,
requestRenderMode: true,
scene3DOnly: false,
sceneMode: 3,
fullscreenElement: document.body,
selectionIndicator: false,
};
window.$mmc.viewer = this.viewer = new Cesium.Viewer(
`layer-container`,
viewerOptions
);
this.imageryLayers.satellite = this.viewer.imageryLayers.addImageryProvider(
new Cesium.UrlTemplateImageryProvider({
url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
maximumLevel: 18,
})
);
this.imageryLayers.night = this.viewer.imageryLayers.addImageryProvider(
new Cesium.UrlTemplateImageryProvider({
url: "https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
maximumLevel: 16,
})
);
this.imageryLayers.night.show = false;
this.viewer.scene.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
this.init_lng,
this.init_lat,
this.init_alt
),
});
// 加载三维倾斜
window._3d = [];
/* const token =
'r0G6d8tdvfgN_Aad1j28SGqj6ILgt1DNHpP9dK-FNVOVBPgcyaHiEs2z2qyv455bTHU8QaFTbt_Y_AdeAsPp-Q..'; */
window.___s3m.forEach(async (item) => {
const obj = await this.viewer.scene.addS3MTilesLayerByScp(
`https://ct.mmcuav.cn:8443/iserver/services/${item}/rest/realspace/datas/Config/config`,
{
name: item,
// cullEnabled: false
}
);
window._3d.push(obj);
if (item === "3D-ZQ-JLH") {
// 肇庆九龙湖的模型需要修改海拔, 使其贴地
obj.style3D.bottomAltitude = -20;
}
});
// 二维影像缓存加载方式
window._2d = [];
["3D-ZQ-DH", "3D-local3DCache-s3mb"].forEach((item) => {
this.viewer.scene
.open(
`https://ct.mmcuav.cn:8443/iserver/services/${item}/rest/realspace`,
undefined,
{
subdomains: [""], // 子域
autoSetView: false, // 不自动定位
}
)
.then((obj) => {
window._2d.push(obj);
});
});
// 关闭地图深度检测
this.viewer.scene.globe.depthTestAgainstTerrain = false;
// 飞向指定的经纬度
window.$mmc.flyTo = function (lng, lat) {
this.viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(lng, lat, 1000),
});
};
},
add_polyline(entities, data) {
return entities.add({
id: data.entity_id,
parent: data.parent || null,
polyline: {
positions: new Cesium.CallbackProperty(() => {
return data.positions;
}, false),
width: 5,
material: Cesium.Color.fromCssColorString("#6DD400"),
show: true,
...(data.options ? data.options : {}),
},
});
},
},
};
</script>
<style lang="scss" scoped>
.cesium_layerBox {
}
.cpt-cesium_layer_1 {
position: absolute;
width: 100%;
height: 100%;
left: 0;
bottom: 0;
right: 0;
top: 0;
// #layer-container_1 {
// position: absolute;
// left: 0;
// bottom: 0;
// top: 0;
// right: 0;
// width: 100%;
// height: 100%;
// box-sizing: border-box;
// }
}
.videoWallMapStyle {
position: fixed !important;
left: 12px !important;
top: 63px !important;
bottom: 0 !important;
width: 415px !important;
height: 234px !important;
box-sizing: border-box !important;
z-index: 1;
}
.right_33 {
right: 33%;
}
</style>
/**
* covert canvas to image
* and save the image file
*/
var Canvas2Image = function() {
// check if support sth.
var $support = (function() {
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d')
return {
canvas: !!ctx,
// @ts-ignore
imageData: !!ctx.getImageData,
dataURL: !!canvas.toDataURL,
btoa: !!window.btoa,
}
})()
var downloadMime = 'image/octet-stream'
function scaleCanvas(canvas, width, height) {
var w = canvas.width,
h = canvas.height
if (width == undefined) {
width = w
}
if (height == undefined) {
height = h
}
var retCanvas = document.createElement('canvas')
var retCtx = retCanvas.getContext('2d')
retCanvas.width = width
retCanvas.height = height
// @ts-ignore
retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height)
return retCanvas
}
function getDataURL(canvas, type, width, height) {
canvas = scaleCanvas(canvas, width, height)
return canvas.toDataURL(type)
}
function saveFile(strData) {
document.location.href = strData
}
function genImage(strData) {
var img = document.createElement('img')
img.src = strData
return img
}
function fixType(type) {
type = type.toLowerCase().replace(/jpg/i, 'jpeg')
var r = type.match(/png|jpeg|bmp|gif/)[0]
return 'image/' + r
}
function encodeData(data) {
if (!window.btoa) {
throw 'btoa undefined'
}
var str = ''
if (typeof data == 'string') {
str = data
} else {
for (var i = 0; i < data.length; i++) {
str += String.fromCharCode(data[i])
}
}
return btoa(str)
}
function getImageData(canvas) {
var w = canvas.width,
h = canvas.height
return canvas.getContext('2d').getImageData(0, 0, w, h)
}
function makeURI(strData, type) {
return 'data:' + type + ';base64,' + strData
}
/**
* create bitmap image
* 按照规则生成图片响应头和响应体
*/
var genBitmapImage = function(oData) {
//
// BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
// BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
//
var biWidth = oData.width
var biHeight = oData.height
var biSizeImage = biWidth * biHeight * 3
var bfSize = biSizeImage + 54 // total header size = 54 bytes
//
// typedef struct tagBITMAPFILEHEADER {
// WORD bfType;
// DWORD bfSize;
// WORD bfReserved1;
// WORD bfReserved2;
// DWORD bfOffBits;
// } BITMAPFILEHEADER;
//
var BITMAPFILEHEADER = [
// WORD bfType -- The file type signature; must be "BM"
0x42,
0x4d,
// DWORD bfSize -- The size, in bytes, of the bitmap file
bfSize & 0xff,
(bfSize >> 8) & 0xff,
(bfSize >> 16) & 0xff,
(bfSize >> 24) & 0xff,
// WORD bfReserved1 -- Reserved; must be zero
0,
0,
// WORD bfReserved2 -- Reserved; must be zero
0,
0,
// DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
54,
0,
0,
0,
]
//
// typedef struct tagBITMAPINFOHEADER {
// DWORD biSize;
// LONG biWidth;
// LONG biHeight;
// WORD biPlanes;
// WORD biBitCount;
// DWORD biCompression;
// DWORD biSizeImage;
// LONG biXPelsPerMeter;
// LONG biYPelsPerMeter;
// DWORD biClrUsed;
// DWORD biClrImportant;
// } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
//
var BITMAPINFOHEADER = [
// DWORD biSize -- The number of bytes required by the structure
40,
0,
0,
0,
// LONG biWidth -- The width of the bitmap, in pixels
biWidth & 0xff,
(biWidth >> 8) & 0xff,
(biWidth >> 16) & 0xff,
(biWidth >> 24) & 0xff,
// LONG biHeight -- The height of the bitmap, in pixels
biHeight & 0xff,
(biHeight >> 8) & 0xff,
(biHeight >> 16) & 0xff,
(biHeight >> 24) & 0xff,
// WORD biPlanes -- The number of planes for the target device. This value must be set to 1
1,
0,
// WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
// has a maximum of 2^24 colors (16777216, Truecolor)
24,
0,
// DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
0,
0,
0,
0,
// DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
biSizeImage & 0xff,
(biSizeImage >> 8) & 0xff,
(biSizeImage >> 16) & 0xff,
(biSizeImage >> 24) & 0xff,
// LONG biXPelsPerMeter, unused
0,
0,
0,
0,
// LONG biYPelsPerMeter, unused
0,
0,
0,
0,
// DWORD biClrUsed, the number of color indexes of palette, unused
0,
0,
0,
0,
// DWORD biClrImportant, unused
0,
0,
0,
0,
]
var iPadding = (4 - ((biWidth * 3) % 4)) % 4
var aImgData = oData.data
var strPixelData = ''
var biWidth4 = biWidth << 2
var y = biHeight
var fromCharCode = String.fromCharCode
do {
var iOffsetY = biWidth4 * (y - 1)
var strPixelRow = ''
for (var x = 0; x < biWidth; x++) {
var iOffsetX = x << 2
strPixelRow +=
fromCharCode(aImgData[iOffsetY + iOffsetX + 2]) +
fromCharCode(aImgData[iOffsetY + iOffsetX + 1]) +
fromCharCode(aImgData[iOffsetY + iOffsetX])
}
for (var c = 0; c < iPadding; c++) {
strPixelRow += String.fromCharCode(0)
}
strPixelData += strPixelRow
} while (--y)
var strEncoded =
encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) +
encodeData(strPixelData)
return strEncoded
}
/**
* saveAsImage
* @param canvasElement
* @param {String} image type
* @param {Number} [optional] png width
* @param {Number} [optional] png height
*/
var saveAsImage = function(canvas, width, height, type) {
if ($support.canvas && $support.dataURL) {
if (typeof canvas == 'string') {
canvas = document.getElementById(canvas)
}
if (type == undefined) {
type = 'png'
}
type = fixType(type)
if (/bmp/.test(type)) {
var data = getImageData(scaleCanvas(canvas, width, height))
var strData = genBitmapImage(data)
saveFile(makeURI(strData, downloadMime))
} else {
// @ts-ignore
var strData = getDataURL(canvas, type, width, height)
saveFile(strData.replace(type, downloadMime))
}
}
}
var convertToImage = function(canvas, width, height, type) {
if ($support.canvas && $support.dataURL) {
if (typeof canvas == 'string') {
canvas = document.getElementById(canvas)
}
if (type == undefined) {
type = 'png'
}
type = fixType(type)
if (/bmp/.test(type)) {
var data = getImageData(scaleCanvas(canvas, width, height))
var strData = genBitmapImage(data)
return genImage(makeURI(strData, 'image/bmp'))
} else {
// @ts-ignore
var strData = getDataURL(canvas, type, width, height)
return genImage(strData)
}
}
}
return {
saveAsImage: saveAsImage,
saveAsPNG: function(canvas, width, height) {
return saveAsImage(canvas, width, height, 'png')
},
saveAsJPEG: function(canvas, width, height) {
return saveAsImage(canvas, width, height, 'jpeg')
},
saveAsGIF: function(canvas, width, height) {
return saveAsImage(canvas, width, height, 'gif')
},
saveAsBMP: function(canvas, width, height) {
return saveAsImage(canvas, width, height, 'bmp')
},
convertToImage: convertToImage,
convertToPNG: function(canvas, width, height) {
return convertToImage(canvas, width, height, 'png')
},
convertToJPEG: function(canvas, width, height) {
return convertToImage(canvas, width, height, 'jpeg')
},
convertToGIF: function(canvas, width, height) {
return convertToImage(canvas, width, height, 'gif')
},
convertToBMP: function(canvas, width, height) {
return convertToImage(canvas, width, height, 'bmp')
},
}
}
export default Canvas2Image
export function createPoint(viewer, { position, image, title }) {
let point = viewer.entities.add({
name: 'point',
position,
billboard: {
image,
width: 30,
height: 30,
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
label: {
text: title,
font: '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian3(0.0, 32, 0.0),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
})
return point
}
export function createLine(
viewer,
{ polyCenter, positions, width, color, title }
) {
let line = viewer.entities.add({
position: polyCenter,
polyline: {
positions,
width,
material: Cesium.Color.fromCssColorString(color),
},
label: {
// @ts-ignore
text: title,
font: '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, 0),
},
})
return line
}
export function createPolygon(
viewer,
{ polyCenter, outlineColor, positions, title, color }
) {
var polygon = viewer.entities.add({
position: polyCenter,
polygon: {
hierarchy: positions,
material: Cesium.Color.fromCssColorString(color),
outline: true,
outlineWidth: 1,
outlineColor: Cesium.Color.fromCssColorString(outlineColor),
},
label: {
text: title,
font: '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, 0),
},
})
return polygon
}
export default class CesiumWidget extends Cesium.CesiumWidget {
constructor(container, options){
super(container, {
creditContainer: document.createElement("div"),
...options
})
}
}
\ No newline at end of file
// const Cesium = require("cesium/Cesium")
// export default Cesium
\ No newline at end of file
export const CreatePolygon = function(viewer, style) {
this.objId = Number((new Date()).getTime() + "" + Number(Math.random() * 1000).toFixed(0));
this.viewer = viewer;
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.modifyHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.polygon = null;
this.polyline = null;
this.positions = [];
this.style = style;
this.state = 0; //1为新增 2为编辑 0为清除
this.gonPointArr = [];
this.modifyPoint = null;
}
CreatePolygon.prototype = {
startCreate: function(callBack) {
document.documentElement.style.cursor = 'crosshair';
var $this = this;
this.handler.setInputAction(function(evt) { //单机开始绘制
var cartesian = $this.getCatesian3FromPX(evt.position, $this.viewer,[$this.polygon]);
if ($this.positions.length == 0) {
$this.positions.push(cartesian.clone());
}
$this.positions.push(cartesian);
var point = $this.createPoint(cartesian);
point.wz = $this.gonPointArr.length;
$this.gonPointArr.push(point);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction(function(evt) { //移动时绘制面
if ($this.positions.length < 1) return;
var cartesian = $this.getCatesian3FromPX(evt.endPosition, $this.viewer,[$this.polygon]);
if ($this.positions.length == 2) {
if (!Cesium.defined($this.polygon)) {
$this.polygon = $this.createPolygon($this.style);
$this.polygon.objId = $this.objId;
}
}
if ($this.polygon) {
$this.positions.pop();
$this.positions.push(cartesian);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction(function(evt) {
if (!$this.polygon) return;
var cartesian = $this.getCatesian3FromPX(evt.position, $this.viewer,[$this.polygon]);
$this.state = 1;
$this.handler.destroy();
if ($this.floatPoint) {
if ($this.floatPoint) $this.floatPoint.show = false;
$this.floatPoint = null;
}
$this.positions.pop();
$this.positions.push(cartesian);
var point = $this.createPoint(cartesian);
point.wz = $this.gonPointArr.length;
$this.gonPointArr.push(point);
// var polygon = window.viewer.entities.add({
// name: "Cyan vertical polygon with per-position heights and outline",
// polygon: {
// hierarchy: $this.positions,
// perPositionHeight: false,
// // material: Cesium.Color.CYAN.withAlpha(0.5),
// material: Cesium.Color.fromCssColorString('rgba(255, 255, 0, 0.6)'),
// },
// })
// console.log('$this.positions', $this.positions)
// $this.viewer.entities.remove($this.polygon) // 结束删除实体
// $this.polygon.hierarchy = new Cesium.PolygonHierarchy($this.positions)
// callBack(polygon, $this.positions);
callBack($this.polygon, $this.positions);
document.documentElement.style.cursor = 'default';
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
},
createByPositions: function(lnglatArr, callBack) { //通过传入坐标数组创建面
if (!lnglatArr) return;
var positions = this.lnglatArrToCartesianArr(lnglatArr);
if (!positions) return;
this.polygon = this.createPolygon(this.style);
this.positions = positions;
callBack(this.polygon);
for (var i = 0; i < positions.length; i++) {
var point = this.createPoint(positions[i]);
point.wz = this.gonPointArr.length;
this.gonPointArr.push(point);
}
this.state = 1;
this.polygon.objId = this.objId;
},
startModify: function() {
if (this.state != 1 && this.state != 2) return; //表示还没绘制完成
if (!this.modifyHandler) this.modifyHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
var $this = this;
for (var i = 0; i < $this.gonPointArr.length; i++) {
var point = $this.gonPointArr[i];
if (point) point.show = true;
}
this.modifyHandler.setInputAction(function(evt) {
document.documentElement.style.cursor = 'move';
var pick = $this.viewer.scene.pick(evt.position);
if (Cesium.defined(pick) && pick.id) {
if (!pick.id.objId)
$this.modifyPoint = pick.id;
$this.forbidDrawWorld(true);
} else {
for (var i = 0; i < $this.gonPointArr.length; i++) {
var point = $this.gonPointArr[i];
if (point) point.show = false;
}
if ($this.modifyHandler) {
$this.modifyHandler.destroy();
$this.modifyHandler = null;
}
}
//$this.state = 2;
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
this.modifyHandler.setInputAction(function(evt) { //移动时绘制面
if ($this.positions.length < 1 || !$this.modifyPoint) return;
var cartesian = $this.getCatesian3FromPX(evt.endPosition, $this.viewer,[$this.polygon,$this.modifyPoint]);
if (cartesian) {
$this.modifyPoint.position.setValue(cartesian);
$this.positions[$this.modifyPoint.wz] = cartesian;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.modifyHandler.setInputAction(function(evt) {
$this.forbidDrawWorld(false);
if (!$this.modifyPoint) return;
// var cartesian = $this.getCatesian3FromPX(evt.position, $this.viewer,[$this.polygon,$this.modifyPoint]);
// $this.modifyPoint.position.setValue(cartesian);
// // $this.modifyPoint = null;
// $this.positions[$this.modifyPoint.wz] = cartesian;
$this.modifyPoint = null;
$this.forbidDrawWorld(false);
document.documentElement.style.cursor = 'default';
}, Cesium.ScreenSpaceEventType.LEFT_UP);
},
createPoint: function(position) {
if (!position) return;
return this.viewer.entities.add({
position: position,
point: {
pixelSize: 5,
color: Cesium.Color.YELLOW,
outlineWidth: 2,
outlineColor: Cesium.Color.DARKRED,
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY
},
show: false
});
},
createPolygon: function(obj) {
var $this = this;
return this.viewer.entities.add({
polygon: {
hierarchy: new Cesium.CallbackProperty(function() {
return new Cesium.PolygonHierarchy($this.positions);
}, false),
perPositionHeight: false,
// clampToGround: obj.clampToGround || true,
show: true,
fill: obj.fill || true,
// material: obj.material || Cesium.Color.WHITE,
material: obj.material || Cesium.Color.fromCssColorString('rgba(40, 126, 255, 0.7)'),
width: obj.width || 3,
outlineColor: obj.outlineColor || Cesium.Color.BLACK,
outlineWidth: obj.outlineWidth || 1,
outline: false || obj.outline
}
});
},
createPolyline: function() {
return this.viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(function() {
return $this.positions
}, false),
clampToGround: true || obj.clampToGround,
show: true,
fill: true || obj.fill,
material: Cesium.Color.WHITE || obj.material,
width: 3 || obj.width
}
});
},
getPositions: function() {
return this.positions;
},
setStyle: function(obj) {},
remove: function() {
if (this.polygon) {
this.state = 0;
this.viewer.entities.remove(this.polygon);
this.polygon = null;
}
},
setVisible: function(vis) {
this.polygon.show = vis;
},
forbidDrawWorld: function(isForbid) {
this.viewer.scene.screenSpaceCameraController.enableRotate = !isForbid;
this.viewer.scene.screenSpaceCameraController.enableTilt = !isForbid;
this.viewer.scene.screenSpaceCameraController.enableTranslate = !isForbid;
this.viewer.scene.screenSpaceCameraController.enableInputs = !isForbid;
},
destroy: function() {
if (this.handler) {
this.handler.destroy();
this.handler = null;
}
if (this.modifyHandler) {
this.modifyHandler.destroy();
this.modifyHandler = null;
}
if (this.polygon) {
this.viewer.entities.remove(this.polygon);
this.polygon = null;
}
if (this.polyline) {
this.viewer.entities.remove(this.polyline);
this.polyline = null;
}
this.positions = [];
this.style = null;
if (this.modifyPoint) {
this.viewer.entities.remove(this.modifyPoint);
this.modifyPoint = null;
}
for (var i = 0; i < this.gonPointArr.length; i++) {
var point = this.gonPointArr[i];
this.viewer.entities.remove(point);
}
this.gonPointArr = [];
this.state = 0;
},
getCatesian3FromPX:function(px, viewer, entitys) {
var pick = viewer.scene.pick(px);
var cartesian;
var drillPick = viewer.scene.drillPick(px);
var truePick = null;
// if (entitys) {
// for (var i = 0; i < drillPick.length; i++) {
// if (drillPick[i].id && drillPick[i].id._id != entitys[0].id && drillPick[i].id._id != entitys[1].id) {
// truePick = drillPick[i].id;
// break;
// }
// }
// } else {
// truePick = pick;
// }
// if (viewer.scene.pickPositionSupported && Cesium.defined(truePick)) {
// cartesian = viewer.scene.pickPosition(px);
// } else {
// var ray = viewer.camera.getPickRay(px);
// if (!ray) return;
// cartesian = viewer.scene.globe.pick(ray, viewer.scene);
// }
// return cartesian;
viewer.render();
let bool = drillPick.some(item => {
return item.content
})
// let bool = drillPick[0].content ? true : false
if (bool > 0) {
cartesian = viewer.scene.pickPosition(px);
} else {
var ray = viewer.camera.getPickRay(px);
if (!ray) return;
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
}
return cartesian;
},
lnglatArrToCartesianArr:function(lnglatArr){
if (!lnglatArr) return [];
var arr = [];
for (var i = 0; i < lnglatArr.length; i++) {
arr.push(Cesium.Cartesian3.fromDegrees(lnglatArr[i]));
}
return arr;
}
}
export const CreatePolyline = function(viewer, style) {
this.objId = Number((new Date()).getTime() + "" + Number(Math.random() * 1000).toFixed(0));
this.viewer = viewer;
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.modifyHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.polyline = null;
this.positions = [];
this.style = style;
this.floatPoint = null;
this.linePointArr = [];
this.modifyPoint = null;
this.state = 0; //1为新增 2为编辑 0为清除
this.centerPoint = null
}
CreatePolyline.prototype = {
startCreate: function(callBack) {
document.documentElement.style.cursor = 'crosshair';
var $this = this;
this.handler.setInputAction(function(evt) { //单机开始绘制
var cartesian = $this.getCatesian3FromPX(evt.position,$this.viewer,[$this.polyline]);
if ($this.positions.length == 0) {
$this.positions.push(cartesian.clone());
$this.floatPoint = $this.createPoint(cartesian.clone());
}
$this.positions.push(cartesian);
var point = $this.createPoint(cartesian);
point.wz = $this.linePointArr.length;
$this.linePointArr.push(point);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction(function(evt) { //移动时绘制线
if ($this.positions.length < 1) return;
var cartesian = $this.getCatesian3FromPX(evt.endPosition,$this.viewer,[$this.polyline]);
if($this.floatPoint) $this.floatPoint.position.setValue(cartesian);
if ($this.positions.length == 2) {
if (!Cesium.defined($this.polyline)) {
$this.polyline = $this.createPolyline($this.style);
}
}
if ($this.polyline) {
$this.positions.pop();
$this.positions.push(cartesian);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction(function(evt) { //单机开始绘制
if(!$this.polyline) return ;
var cartesian = $this.getCatesian3FromPX(evt.position,$this.viewer,[$this.polyline]);
$this.state = 1;
$this.handler.destroy();
if($this.floatPoint){
if($this.floatPoint) $this.floatPoint.show = false;
$this.floatPoint = null;
}
$this.positions.pop();
$this.positions.push(cartesian);
var point = $this.createPoint(cartesian);
point.wz = $this.linePointArr.length;
$this.linePointArr.push(point);
// 获取中心点
const polyCenter = Cesium.BoundingSphere.fromPoints($this.positions).center
// $this.centerPoint = $this.createPoint(polyCenter)
const centerPoint = $this.createPoint(polyCenter);
centerPoint.wz = $this.linePointArr.length;
centerPoint.zx = 1;
$this.linePointArr.push(centerPoint);
document.documentElement.style.cursor = 'default';
callBack($this.polyline, $this.positions);
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
},
createByPositions:function(lnglatArr,callBack){ //通过传入坐标数组创建面
if(!lnglatArr) return ;
var positions = this.lnglatArrToCartesianArr(lnglatArr);
if(!positions) return ;
this.polyline = this.createPolyline(this.style);
this.positions = positions;
callBack(this.polyline);
for(var i=0;i<positions.length;i++){
var point = this.createPoint(positions[i]);
point.wz = this.linePointArr.length;
this.linePointArr.push(point);
}
this.state = 1;
},
startModify: function() {
if(this.state!=2 && this.state !=1) return ; //表示还没绘制完成
if(!this.modifyHandler) this.modifyHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
var $this = this;
for(var i=0;i<$this.linePointArr.length;i++){
var point = $this.linePointArr[i];
if(point) point.show = true;
}
this.modifyHandler.setInputAction(function(evt) {
document.documentElement.style.cursor = 'move';
var pick = $this.viewer.scene.pick(evt.position);
if (Cesium.defined(pick) && pick.id){
if(!pick.id.objId)
$this.modifyPoint = pick.id;
$this.forbidDrawWorld(true);
}else{
for(var i=0;i<$this.linePointArr.length;i++){
var point = $this.linePointArr[i];
if(point) point.show = false;
}
if($this.modifyHandler){
$this.modifyHandler.destroy();
$this.modifyHandler = null;
}
}
$this.state = 2;
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
this.modifyHandler.setInputAction(function(evt) { //移动时绘制线
if ($this.positions.length < 1 || !$this.modifyPoint) return;
//记录尾随的坐标
let startPosition = $this.getCatesian3FromPX(evt.startPosition, $this.viewer,[$this.polyline,$this.modifyPoint]);
let endPosition = $this.getCatesian3FromPX(evt.endPosition, $this.viewer,[$this.polyline,$this.modifyPoint]);
if(endPosition){
if($this.modifyPoint.zx) {
//计算每次的偏差
if(startPosition) {
let changed_x = endPosition.x-startPosition.x;
let changed_y = endPosition.y-startPosition.y;
let changed_z = endPosition.z-startPosition.z;
$this.modifyPoint.position.setValue(endPosition);
for(let i=0; i<$this.positions.length; i++){
//与之前的算差 替换掉
$this.positions[i].x = $this.positions[i].x + changed_x;
$this.positions[i].y = $this.positions[i].y + changed_y;
$this.positions[i].z = $this.positions[i].z + changed_z;
}
}
} else {
$this.modifyPoint.position.setValue(endPosition);
$this.positions[$this.modifyPoint.wz] = endPosition;
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.modifyHandler.setInputAction(function(evt) {
if(!$this.modifyPoint) return;
// var cartesian = $this.getCatesian3FromPX(evt.position, $this.viewer,[$this.polyline,$this.modifyPoint]);
// $this.modifyPoint.position.setValue(cartesian);
// $this.positions[$this.modifyPoint.wz] = cartesian;
$this.modifyPoint = null;
$this.forbidDrawWorld(false);
document.documentElement.style.cursor = 'default';
}, Cesium.ScreenSpaceEventType.LEFT_UP);
},
createPoint: function(position) {
if (!position) return;
return this.viewer.entities.add({
position: position,
point: {
pixelSize:5,
color:Cesium.Color.YELLOW,
outlineWidth:2,
outlineColor:Cesium.Color.DARKRED,
// heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance : Number.POSITIVE_INFINITY
},
show : false
});
},
createPolyline: function(obj) {
if(!obj) obj = {};
var $this = this;
var polyline = this.viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(function() {
return $this.positions
}, false),
clampToGround: obj.clampToGround,
show: true,
fill: obj.fill || true ,
// material: obj.material || Cesium.Color.WHITE,
material: obj.material || Cesium.Color.fromCssColorString('rgba(40, 126, 255, 1)'),
width: obj.width || 3
}
});
polyline.objId = this.objId;
return polyline;
},
getPositions: function() {
return this.positions;
},
setStyle: function(obj) {},
remove: function() {
if (this.polyline) {
this.state = 0;
this.viewer.entities.remove(this.polyline);
this.polyline = null;
}
},
setVisible: function(vis) {
this.polyline.show = vis;
},
forbidDrawWorld:function(isForbid){
this.viewer.scene.screenSpaceCameraController.enableRotate = !isForbid;
this.viewer.scene.screenSpaceCameraController.enableTilt = !isForbid;
this.viewer.scene.screenSpaceCameraController.enableTranslate = !isForbid;
this.viewer.scene.screenSpaceCameraController.enableInputs = !isForbid;
},
destroy:function(){
this.linePointArr = [];
if(this.handler){
this.handler.destroy();
this.handler = null;
}
if(this.modifyHandler){
this.modifyHandler.destroy();
this.modifyHandler = null;
}
if(this.polyline){
this.viewer.entities.remove(this.polyline);
this.polyline = null;
}
if(this.floatPoint){
this.viewer.entities.remove(this.floatPoint);
this.floatPoint = null;
}
this.positions = [];
this.style = null;
for(var i=0;i<this.linePointArr.length;i++){
var point = this.linePointArr[i];
this.viewer.entities.remove(point);
}
this.linePointArr = [];
this.modifyPoint = null;
},
getCatesian3FromPX:function(px, viewer, entitys) {
var pick = viewer.scene.pick(px);
var cartesian;
var drillPick = viewer.scene.drillPick(px);
// console.log('drillPick', drillPick)
var truePick = null;
// if (entitys) {
// for (var i = 0; i < drillPick.length; i++) {
// if (drillPick[i].id._id != entitys[0].id && drillPick[i].id._id != entitys[1].id) {
// truePick = drillPick[i].id;
// break;
// }
// }
// } else {
// truePick = pick;
// }
// if (viewer.scene.pickPositionSupported && Cesium.defined(truePick)) {
// console.log('truePick')
// cartesian = viewer.scene.pickPosition(px);
// } else {
// var ray = viewer.camera.getPickRay(px);
// if (!ray) return;
// cartesian = viewer.scene.globe.pick(ray, viewer.scene);
// }
// return cartesian;
viewer.render();
let bool = drillPick.some(item => {
return item.content
})
if (bool > 0) {
cartesian = viewer.scene.pickPosition(px);
} else {
var ray = viewer.camera.getPickRay(px);
if (!ray) return;
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
}
return cartesian;
},
lnglatArrToCartesianArr:function(lnglatArr){
if (!lnglatArr) return [];
var arr = [];
for (var i = 0; i < lnglatArr.length; i++) {
arr.push(Cesium.Cartesian3.fromDegrees(lnglatArr[i]));
}
return arr;
}
}
/**
* dataURL to blob, ref to https://gist.github.com/fupslot/5015897
* @param dataURI
* @returns {Blob}
*/
export default function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1])
var mimeString = dataURI
.split(',')[0]
.split(':')[1]
.split(';')[0]
var ab = new ArrayBuffer(byteString.length)
var ia = new Uint8Array(ab)
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i)
}
var blob = new Blob([ab], { type: mimeString })
return new File([blob], new Date() + '.png', { type: mimeString })
}
export const DRAW_TYPE = Object.freeze({
POINT: Symbol('POINT'),
LINE: Symbol('LINE'),
AREA: Symbol('AREA'),
})
class AbstractDraw {
layer_name = 'DRAW_LAYER'
$onStart = null
$onMove = null
$onEnd = null
$dataSource = null
$entities = null
$isMouseDown = false
$drawType = null
constructor(options) {
this.$options = options
options.layer_name && (this.layer_name = options.layer_name)
this.$viewer = options.viewer
this.$drawType = options.drawType
this.$init()
this.$createEventHandler()
}
$init() {
this.$onStart = new Cesium.Event()
this.$onMove = new Cesium.Event()
this.$onEnd = new Cesium.Event()
// 不创建重复的 dataSource
let dataSource = this.$viewer.dataSources.getByName(this.layer_name)
if (!dataSource.length) {
dataSource = new Cesium.CustomDataSource(this.layer_name)
this.$viewer.dataSources.add(dataSource)
}
this.$dataSource = dataSource
this.$entities = dataSource.entities
}
$createEventHandler() {
if (this.$drawType) {
let handler = (this.handler = new Cesium.ScreenSpaceEventHandler(
this.$viewer.canvas
))
handler.setInputAction((moment) => {
this.$isMouseDown = true
this.$onStart.raiseEvent(moment)
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
// 绘制点的时候没有移动事件监听
if (this.$drawType !== DRAW_TYPE.POINT) {
handler.setInputAction((moment) => {
if (this.$isMouseDown) {
this.$onMove.raiseEvent(moment)
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
handler.setInputAction((moment) => {
this.$onEnd.raiseEvent(moment)
this.$isMouseDown = false
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}
}
}
$createDrawPoint(position, options) {
let entity = new Cesium.Entity()
entity.position = position
entity.point = {
pixelSize: 6,
color: Cesium.Color.YELLOWGREEN,
outlineColor: Cesium.Color.ORANGE,
outlineWidth: 2,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
}
if (options && options.label) {
entity.label = {
text: options.text,
show: true,
showBackground: true,
font: '14px monospace',
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(-3, -20),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
}
}
return entity
}
$createDrawPolyline(positions, options) {
let entity = new Cesium.Entity()
entity.polyline = {
positions,
arcType: Cesium.ArcType.NONE,
width: 2,
material: new Cesium.PolylineOutlineMaterialProperty({
color: Cesium.Color.RED,
}),
depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty({
color: Cesium.Color.RED,
}),
...options,
}
return entity
}
$createDrawPolygon(positions, options) {
let entity = new Cesium.Entity()
entity.polygon = {
show: true,
hierarchy: positions,
// classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
material: new Cesium.ColorMaterialProperty(
Cesium.Color.YELLOWGREEN.withAlpha(0.7)
),
perPositionHeight: true,
arcType: undefined,
zIndex: Number.POSITIVE_INFINITY,
}
return entity
}
$createDrawRectangle() {}
$addLabelOnDrawEntity(entity, options) {
entity.label = {
text: 'label',
show: true,
showBackground: true,
font: '14px monospace',
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(-3, -20),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
...options,
}
return entity
}
$addLabelOnEntityByCenter(drawType, entity, options) {
// 算出中点
let positions = null
if (drawType === DRAW_TYPE.LINE) {
positions = entity.polyline.positions.getValue(Cesium.JulianDate.now())
} else if (drawType === DRAW_TYPE.AREA) {
let hierarchy = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now())
positions = hierarchy.positions
}
if (positions) {
let center = Cesium.BoundingSphere.fromPoints(positions).center
entity.position = center
// 添加 label
this.$addLabelOnDrawEntity(entity, {
text: '默认标注',
...options,
})
}
}
}
export default AbstractDraw
import AbstractDraw, { DRAW_TYPE } from "./AbstractDraw";
import { getCartesian3FromPX } from "../utils"
class AreaDraw extends AbstractDraw {
positions = []
entity = null
constructor(options) {
super({
...options,
drawType: DRAW_TYPE.AREA
})
this.init()
}
init() {
this.positions = []
this.initEventHandler()
}
initEventHandler() {
this.$onStart.addEventListener(this.onStart.bind(this))
this.$onMove.addEventListener(this.onMove.bind(this))
this.$onEnd.addEventListener(this.onEnd.bind(this))
}
onStart(moment) {
let cartesian = getCartesian3FromPX(this.$viewer, moment.position)
if (cartesian) {
if (!this.positions.length) {
this.positions.push(cartesian)
let entity = this.entity = this.$createDrawPolygon(new Cesium.CallbackProperty(() => {
return new Cesium.PolygonHierarchy(this.positions)
}, false))
this.$entities.add(entity)
}
this.positions.push(cartesian)
this.$options.start && this.$options.start({
entity: this.entity,
positions: this.positions
})
}
}
onMove(moment) {
let cartesian = getCartesian3FromPX(this.$viewer, moment.endPosition)
if (cartesian) {
this.positions.pop()
this.positions.push(cartesian)
}
}
async onEnd(moment) {
this.positions.pop()
this.$entities.remove(this.entity)
this.entity = null
let entity = await this.createClampedPolygon(this.$viewer, this.positions.map(item => Cesium.Cartesian3.clone(item)))
this.$entities.add(entity)
//给中心点添加 label
this.$addLabelOnEntityByCenter(DRAW_TYPE.AREA, entity)
this.$options.end && this.$options.end({
entity: this.entity,
positions: this.positions,
})
}
createClampedPolygon(viewer, positions, options) {
return new Promise((resolve, reject) => {
viewer.scene
.clampToHeightMostDetailed(positions)
.then((clampedCartesians) => {
let entity = new Cesium.Entity()
entity.polygon = {
hierarchy: new Cesium.PolygonHierarchy(clampedCartesians),
// material: new Cesium.ColorMaterialProperty(
// Cesium.Color.YELLOWGREEN.withAlpha(0.7)
// ),
classificationType: Cesium.ClassificationType.TERRAIN,
show: true,
material: new Cesium.ColorMaterialProperty(
Cesium.Color.YELLOWGREEN.withAlpha(0.7)
),
depthFailMaterial: new Cesium.ColorMaterialProperty(
Cesium.Color.YELLOWGREEN.withAlpha(0.7)
),
perPositionHeight: true,
arcType: undefined,
zIndex: Number.POSITIVE_INFINITY
}
resolve(entity)
})
})
}
}
export default AreaDraw
\ No newline at end of file
import AreaDraw from "./AreaDraw"
import LineDraw from "./LineDraw"
import PointDraw from "./PointDraw"
import { DRAW_TYPE } from "./AbstractDraw";
class DrawFactory {
static getFactory(type, options) {
switch (type) {
case DRAW_TYPE.POINT:
return new PointDraw(options)
case DRAW_TYPE.LINE:
return new LineDraw(options)
case DRAW_TYPE.AREA:
return new AreaDraw(options)
default:
throw new Error("类型错误")
}
}
}
export default DrawFactory
\ No newline at end of file
import AbstractDraw, { DRAW_TYPE } from "./AbstractDraw";
import { getCartesian3FromPX, transformCartesian2WGS84 } from "../utils"
class LineDraw extends AbstractDraw {
positions = []
entity = null
constructor(options) {
super({
...options,
drawType: DRAW_TYPE.LINE
})
this.init()
}
init() {
this.positions = []
this.initEventHandler()
}
initEventHandler() {
this.$onStart.addEventListener(this.onStart.bind(this))
this.$onMove.addEventListener(this.onMove.bind(this))
this.$onEnd.addEventListener(this.onEnd.bind(this))
}
onStart(moment) {
let cartesian = getCartesian3FromPX(this.$viewer, moment.position)
if (cartesian) {
if (!this.positions.length) {
this.positions.push(cartesian)
let entity = this.entity = this.$createDrawPolyline(new Cesium.CallbackProperty(() => {
return this.positions
}, false))
this.$entities.add(entity)
}
this.positions.push(cartesian)
this.$options.start && this.$options.start({
entity: this.entity,
positions: this.positions,
//wgs84s: this.positions.map(item => transformCartesian2WGS84(item))
})
}
}
onMove(moment) {
let cartesian = getCartesian3FromPX(this.$viewer, moment.endPosition)
if (cartesian) {
this.positions.pop()
this.positions.push(cartesian)
}
}
async onEnd(moment) {
this.positions.pop()
this.$entities.remove(this.entity)
this.entity = null
let positions = this.positions.map(item => Cesium.Cartesian3.clone(item))
let entity = await this.createClampedPolyline(this.$viewer, positions)
this.$entities.add(entity)
//给 entity 添加中心点 label
this.$addLabelOnEntityByCenter(DRAW_TYPE.LINE, entity)
this.$options.end && this.$options.end({
entity: entity,
positions: positions,
})
}
createClampedPolyline(viewer, positions, options) {
return new Promise((resolve, reject) => {
viewer.scene
.clampToHeightMostDetailed(positions)
.then((clampedCartesians) => {
let entity = new Cesium.Entity()
entity.polyline = {
positions: clampedCartesians,
arcType: Cesium.ArcType.NONE,
width: 2,
material: new Cesium.PolylineOutlineMaterialProperty({
color: Cesium.Color.YELLOW,
}),
depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty({
color: Cesium.Color.YELLOW,
}),
...options
}
resolve(entity)
})
})
}
}
export default LineDraw
\ No newline at end of file
import AbstractDraw, { DRAW_TYPE } from "./AbstractDraw";
import { getCartesian3FromPX, transformCartesian2WGS84 } from "../utils"
class PointDraw extends AbstractDraw {
positions = []
entity = null
constructor(options){
super({
...options,
drawType: DRAW_TYPE.POINT
})
this.init()
}
init(){
this.initEventHandler()
}
initEventHandler(){
this.$onStart.addEventListener(this.onStart.bind(this))
this.$onEnd.addEventListener(this.onEnd.bind(this))
}
onStart(moment){
let cartesian = getCartesian3FromPX(this.$viewer, moment.position)
if(cartesian){
let point = this.entity = this.$createDrawPoint(cartesian)
this.$entities.add(point)
this.positions.push(point)
this.$addLabelOnDrawEntity(point, {
text: "默认点标注"
})
this.$options.start && this.$options.start({
entity: point,
wgs84: transformCartesian2WGS84(cartesian)
})
}
}
// onMove(moment){
// this.$options.move && this.$options.move(this.positions)
// }
onEnd(moment){
this.$options.end && this.$options.end({
entity: this.entity,
positions: this.positions
})
}
}
export default PointDraw
\ No newline at end of file
import AbstractDraw, { DRAW_TYPE } from "./AbstractDraw";
import { getCartesian3FromPX } from "../utils"
class Rectangle extends AbstractDraw {
positions = []
entity = null
constructor(options) {
super({
...options,
drawType: DRAW_TYPE.LINE
})
this.init()
}
init() {
this.positions = []
this.initEventHandler()
}
initEventHandler() {
this.$onStart.addEventListener(this.onStart.bind(this))
this.$onMove.addEventListener(this.onMove.bind(this))
this.$onEnd.addEventListener(this.onEnd.bind(this))
}
onStart(moment) {
let cartesian = getCartesian3FromPX(this.$viewer, moment.position)
if (cartesian) {
if (!this.positions.length) {
this.positions.push(cartesian)
let entity = this.entity = this.$createDrawPolyline(new Cesium.CallbackProperty(() => {
return this.positions
}, false))
this.$entities.add(entity)
}
this.positions.push(cartesian)
this.$options.start && this.$options.start({
entity: this.entity,
positions: this.positions,
//wgs84s: this.positions.map(item => transformCartesian2WGS84(item))
})
}
}
onMove(moment) {
let cartesian = getCartesian3FromPX(this.$viewer, moment.endPosition)
if (cartesian) {
this.positions.pop()
this.positions.push(cartesian)
}
}
async onEnd(moment) {
this.positions.pop()
this.$entities.remove(this.entity)
this.entity = null
let positions = this.positions.map(item => Cesium.Cartesian3.clone(item))
let entity = await this.createClampedPolyline(this.$viewer, positions)
this.$entities.add(entity)
//给 entity 添加中心点 label
this.$addLabelOnEntityByCenter(DRAW_TYPE.LINE, entity)
this.$options.end && this.$options.end({
entity: entity,
positions: positions,
})
}
createClampedPolyline(viewer, positions, options) {
return new Promise((resolve, reject) => {
viewer.scene
.clampToHeightMostDetailed(positions)
.then((clampedCartesians) => {
let entity = new Cesium.Entity()
entity.polyline = {
positions: clampedCartesians,
arcType: Cesium.ArcType.NONE,
width: 2,
material: new Cesium.PolylineOutlineMaterialProperty({
color: Cesium.Color.YELLOW,
}),
depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty({
color: Cesium.Color.YELLOW,
}),
...options
}
resolve(entity)
})
})
}
}
export default Rectangle
\ No newline at end of file
import { DRAW_TYPE } from "./AbstractDraw"
import DrawFactory from "./DrawFactory";
export default {
DRAW_TYPE,
DrawFactory
}
\ No newline at end of file
import { CreatePoint } from './CreatePoint'
import { CreatePolyline } from './createPolyline'
import { CreatePolygon } from './createPolygon'
const DrawTool = function(obj) {
this.viewer = obj.viewer;
this.hasEdit = obj.hasEdit;
this.toolArr = [];
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
}
DrawTool.prototype = {
startDraw: function(opt) {
if (this.hasEdit) {
this.bindEdit();
}
if (opt.type == "polyline") {
var polyline = new CreatePolyline(this.viewer, opt.style);
polyline.startCreate(opt.success); //绘制完成之后的回调
this.toolArr.push(polyline);
}
if (opt.type == "polygon") {
var polygon = new CreatePolygon(this.viewer, opt.style);
polygon.startCreate(opt.success); //绘制完成之后的回调
this.toolArr.push(polygon);
}
// if (opt.type == "singleline") {
// var singleline = new CreateSingleline(this.viewer, opt.style);
// singleline.startCreate(opt.success); //绘制完成之后的回调
// this.toolArr.push(singleline);
// }
if (opt.type == "point") {
var point = new CreatePoint(this.viewer, opt.style);
point.startCreate(opt.success);
this.toolArr.push(point)
}
},
drawByPositions:function(opt){
if (this.hasEdit) {
this.bindEdit();
}
if(!opt) opt = {};
if (opt.type == "polyline") {
var polyline = new CreatePolyline(this.viewer, opt.style);
polyline.createByPositions(opt.positions,opt.success);
this.toolArr.push(polyline);
}
if (opt.type == "polygon") {
var polygon = new CreatePolygon(this.viewer, opt.style);
polygon.createByPositions(opt.positions,opt.success);
this.toolArr.push(polygon);
}
if (opt.type == "point") {
console.log("point")
}
},
destroy:function(){
for(var i=0;i<this.toolArr.length;i++){
var obj = this.toolArr[i];
obj.destroy();
}
},
lastSelectEntity: null,
bindEdit: function() {
var $this = this;
this.handler.setInputAction(function(evt) { //单机开始绘制
var pick = $this.viewer.scene.pick(evt.position);
if (Cesium.defined(pick) && pick.id) {
for (var i = 0; i < $this.toolArr.length; i++) {
if (pick.id.objId == $this.toolArr[i].objId) {
$this.lastSelectEntity = $this.toolArr[i];
$this.toolArr[i].startModify();
break;
}
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
}
export default DrawTool
\ No newline at end of file
import point_icon_01 from '@/assets/images/point-icon/point_icon_01.svg'
import point_icon_02 from '@/assets/images/point-icon/point_icon_02.svg'
import point_icon_03 from '@/assets/images/point-icon/point_icon_03.svg'
import point_icon_04 from '@/assets/images/point-icon/point_icon_04.svg'
import point_icon_05 from '@/assets/images/point-icon/point_icon_05.svg'
import point_icon_06 from '@/assets/images/point-icon/point_icon_06.svg'
import point_icon_07 from '@/assets/images/point-icon/point_icon_07.svg'
import point_icon_08 from '@/assets/images/point-icon/point_icon_08.svg'
import point_icon_09 from '@/assets/images/point-icon/point_icon_09.svg'
import point_icon_10 from '@/assets/images/point-icon/point_icon_10.svg'
import point_icon_11 from '@/assets/images/point-icon/point_icon_11.svg'
import point_icon_12 from '@/assets/images/point-icon/point_icon_12.svg'
const iconData = [
{
id: 1,
label: '默认',
image: point_icon_01
},
{
id: 2,
label: '排污',
image: point_icon_02
},
{
id: 3,
label: '违建',
image: point_icon_03
},
{
id: 4,
label: '垃圾',
image: point_icon_04
},
{
id: 5,
label: '彩钢棚',
image: point_icon_05
},
{
id: 6,
label: '水面垃圾',
image: point_icon_06
},
{
id: 7,
label: '水闸',
image: point_icon_07
},
{
id: 8,
label: '烟窗',
image: point_icon_08
},
{
id: 9,
label: '秸秆焚烧点',
image: point_icon_09
},
{
id: 10,
label: '政府',
image: point_icon_10
},
{
id: 11,
label: '学校',
image: point_icon_11
},
{
id: 12,
label: '医院',
image: point_icon_12
},
]
export default iconData
// import core from "./core"
// export { default as Viewer } from "./viewer"
export { default as CesiumWidget } from "./cesiumWidget"
export { default as PopupWidget } from "./popupWidget"
export { default as Utils } from "./utils"
export { default as Draw } from "./draw"
// export default core
\ No newline at end of file
class Popup {
handler=null
constructor(viewer, options){
this.$viewer = viewer
this.$options = options
this.init()
}
init(){
let viewer = this.$viewer
this.handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas)
viewer.clock.onTick.addEventListener(() => {
console.log("onTick:");
})
}
render(){}
destroy(){}
createHtml(header, content){
let html = `<div>html test</div>`
}
}
export default Popup
\ No newline at end of file
// import Cesium from "./core"
import wkt from 'terraformer-wkt-parser'
export function transformWGS842Cartesian(position, alt) {
return position
? Cesium.Cartesian3.fromDegrees(
position.lng,
position.lat,
(position.alt = alt || position.alt),
Cesium.Ellipsoid.WGS84
)
: Cesium.Cartesian3.ZERO;
}
export function transformCartesian2WGS84(cartesian) {
let ellipsoid = Cesium.Ellipsoid.WGS84;
let cartographic = ellipsoid.cartesianToCartographic(cartesian);
return {
lng: Cesium.Math.toDegrees(cartographic.longitude),
lat: Cesium.Math.toDegrees(cartographic.latitude),
alt: cartographic.height,
};
}
export function getCartesian3FromPX(viewer, px) {
let picks = viewer.scene.drillPick(px);
let isOn3dtiles = false,
isOnTerrain = false,
cartesian = null;
for (let i in picks) {
let pick = picks[i];
if (
pick &&
(pick.primitive instanceof Cesium.Cesium3DTileFeature ||
pick.primitive instanceof Cesium.Cesium3DTileset ||
pick.primitive instanceof Cesium.Model)
) {
isOn3dtiles = true;
}
//is on 3dtiles
if (isOn3dtiles) {
viewer.scene.pick(px);
cartesian = viewer.scene.pickPosition(px);
if (cartesian) {
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
if (cartographic.height < 0) cartographic.height = 0;
let lng = Cesium.Math.toDegrees(cartographic.longitude);
let lat = Cesium.Math.toDegrees(cartographic.latitude);
let alt = cartographic.height;
cartesian = transformWGS842Cartesian({ lng, lat, alt });
}
}
}
// is ellipsoid terrain
let boolTerrain =
viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider;
// is other terrain
if (!isOn3dtiles && !boolTerrain) {
let ray = viewer.scene.camera.getPickRay(px);
if (!ray) return null;
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
isOnTerrain = true;
}
if (!isOn3dtiles && !isOnTerrain && boolTerrain) {
cartesian = viewer.scene.camera.pickEllipsoid(
px,
viewer.scene.globe.ellipsoid
);
}
// 避免位置陷入地下
if (cartesian) {
let position = transformCartesian2WGS84(cartesian);
if (position.alt < 0) {
cartesian = transformWGS842Cartesian(position, 0.1);
}
}
return cartesian;
}
//geom转position
export function geomToCartesian3(geom) {
let positions = []
let geojson = wkt.parse(geom)
let { type, coordinates } = geojson
if (type === 'Point') {
let [x, y, z] = coordinates
positions.push(Cesium.Cartesian3.fromDegrees(x, y, z))
} else if (type === 'LineString') {
coordinates.forEach((element) => {
let [x, y, z] = element
positions.push(Cesium.Cartesian3.fromDegrees(x, y, z))
})
} else if (type === 'Polygon') {
coordinates.forEach((element) => {
element.forEach((item) => {
let [x, y, z] = item
positions.push(Cesium.Cartesian3.fromDegrees(x, y, z))
})
})
}
return {
type,
positions,
}
}
/**
* 将单个 Cartesian3 坐标转换为 WGS84 坐标
*
* @export
* @param {*} position
* @returns
*/
export function simpleCartesian3ToWGS84(position, viewer) {
let ellipsoid = viewer.scene.globe.ellipsoid
let cartographic = ellipsoid.cartesianToCartographic(position)
//弧度转经度
let wgs84 = {}
wgs84.longitude = Cesium.Math.toDegrees(cartographic.longitude)
wgs84.latitude = Cesium.Math.toDegrees(cartographic.latitude)
wgs84.altitude = cartographic.height
return wgs84
}
// 点位转WKTString
export function positionToGeom(wgs84Obj) {
const { type, positions } = wgs84Obj
let geom = ''
if (type === 'Point') {
geom = wkt.convert({
type: 'Point',
coordinates: positions[0],
})
} else if (type === 'LineString') {
geom = wkt.convert({
type: 'LineString',
coordinates: positions,
})
} else if (type === 'Polygon') {
geom = wkt.convert({
type: 'Polygon',
coordinates: [positions],
})
}
return geom
}
// Cartesian3ToWGS84
export function cartesian3ToWGS84(viewer, cartesian3Obj) {
const { type, positions } = cartesian3Obj
let wgs84Positions
if (type === 'Point') {
wgs84Positions = Array.prototype.map.call(positions, (item) => {
let wgs84 = simpleCartesian3ToWGS84(item, viewer)
return [wgs84.longitude, wgs84.latitude, wgs84.altitude]
})
} else if (type === 'LineString') {
wgs84Positions = Array.prototype.map.call(positions, (item) => {
let wgs84 = simpleCartesian3ToWGS84(item, viewer)
return [wgs84.longitude, wgs84.latitude, wgs84.altitude]
})
} else if (type === 'Polygon') {
wgs84Positions = Array.prototype.map.call(positions, (item) => {
let wgs84 = simpleCartesian3ToWGS84(item, viewer)
return [wgs84.longitude, wgs84.latitude, wgs84.altitude]
})
wgs84Positions.push(wgs84Positions[0])
}
return {
type,
positions: wgs84Positions,
}
}
export function addZero(num) {
if (parseInt(num) < 10) {
num = '0' + num
}
return num
}
export default {
transformWGS842Cartesian,
transformCartesian2WGS84,
getCartesian3FromPX,
}
\ No newline at end of file
// import Cesium from "./core"
export default class Viewer extends Cesium.Viewer {
constructor(container, options){
super(container, {
animation: false, // 动画控制不显示
shouldAnimate: true,
timeline: false, // 时间线不显示
fullscreenButton: false, // 全屏按钮不显示
creditContainer: document.createElement("div"),
geocoder: false,
homeButton: false,
sceneModePicker: false, // 切换球形和平面型
baseLayerPicker: false,
navigationHelpButton: false,
infoBox: false,
selectionIndicator: false,
// imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
// url: "https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer",
// }),
// imageryProvider: false,
...options
})
}
}
switch (process.env.VUE_APP_ENV_TYPE) {
case "公网":
window.___s3m = [
"3D-DH-LHZ",
"3D-FSJD",
"3D-HY-GXQ",
"3D-SX-TY",
"3D-SZ-SLSQ",
"3D-ZQYS",
"3D-SCYTS",
"3D-SZ-FT",
"3D-GZ",
];
break;
default:
window.___s3m = [
"3D-9-1",
"3D-9-2",
"3D-9-3",
"3D-9-4",
"3D-9-4-bu",
// "3D-13-1",
// "3D-13-2",
"3D-LGZ-1",
"3D-XFZ",
"3D-XXZ-1-2",
"3D-XXZ-2-2",
"3D-XXZ-3-2",
"3D-YDZ",
// 永丰镇
"3D-YFZ-JM",
// 秦南镇
// 龙岗镇 JM
"3D-DGZ-JM-1",
"3D-DGZ-JM-2",
"3D-XXZ-3-3",
//数梦小镇
"3D-SMXZ",
//珠溪古镇
"3D-ZXGZ",
//先锋岛
"3D-XFD",
//金茂府周边
"3D-JMFZB",
//特警基地附近
"3D-TJJD",
// 2023年更新
"3D-YDZ",
"3D-QK15-2",
"3D-1619",
"3D-QK12",
"3D-QK14-6",
"3D-BCZ-2",
"3D-QK18-2",
"3D-dgz",
"3D-QK3",
"3D-QK5-S3MB",
"3D-QK10_11S3MB_2023",
"3D-YiQiQK10-2S3MB",
"3D-YiQiQK10-3-S3MB",
"3D-YiQiQK11-1S3MB",
"3D-YiQiQK11-2-S3MB",
"3D-YiQiQK11-3-S3MB",
"3D-QK1",
"3D-QK2",
"3D-QK6_2021_S3MB",
"3D-QK7_2021_S3MB",
"3D-QK8-2-S3MB",
"3D-QK8-5-S3MB",
"3D-QK9_S3MB",
// 粗模
"3D-_2_S3MB",
"3D-_1_S3MB_JM",
"3D-DZHZ-S3MB",
"3D-GW-S3MB",
"3D-LG-S3MB",
"3D-LW-S3MB",
// 南洋镇
"3D-NY-S3MB",
"3D-QN-S3MB",
"3D-SZ-S3MB",
"3D-XF-S3MB",
"3D-17S3MB",
"3D-QK8-3-S3MB",
"3D-QK8-4-S3MB",
"3D-QK13_S3M7",
"3D-BJ-S3MB-JM",
"3D-GM-S3MB-JM",
"3D-QK6-S3MB-JM",
"3D-QK7-S3MB-JM",
"3D-QK8-S3MB-JM",
"3D-YF-S3MB-JM",
"3D-ZZJD-S3MB-JM",
"3D-XX-S3MB-JM",
// 10-21 部署
"3D-QK4-X",
"3D-DZHDJQ",
"3D-BLGZ",
"3D-GWSQ-2",
"3D-NYZ",
"3D-LWZ-2",
"3D-DZH",
"3D-XFZ-4",
"3D-SZZ-2",
"3D-QK13_S3M"
];
break;
}
\ No newline at end of file
<template>
<div class="cpt-MMC_Gimbal_FB1" :style="containerStyle">
<div v-interact class="hd">
<div class="left ml8">
<img src="../assets/images/mount/mount_head.png" />
<div class="title">破窗灭火器</div>
</div>
<div class="close" @click="$emit('close')">关闭</div>
</div>
<div class="bd">
<img src="../assets/images/observe/010.svg" alt />
<div class="form-wrap">
<div class="form-item">
<div class="label-box">保险:</div>
<div class="input-box">
<el-switch
v-model="safety_switch_state"
size="mini"
@change="handle_safety_switch_state"
/>
</div>
</div>
<div class="form-item mt16">
<div class="label-box">开关:</div>
<div class="input-box">
<el-switch v-model="laser_shine_ctrl" size="mini" @change="handle_laser_shine_ctrl" />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_FB1 } from '../utils';
export default {
props: {
containerStyle: {
type: Object,
default: () => ({})
}
},
data() {
return {
timer: null,
radio: 1,
safety_switch_state: true,
laser_shine_ctrl: false
};
},
mounted() {},
methods: {
handle_laser_shine_ctrl() {
if (this.safety_switch_state) {
this.$message.warning('请关闭保险');
this.laser_shine_ctrl = false;
} else {
const buff = MMC_Gimbal_FB1.laser_shine_ctrl(Number(this.laser_shine_ctrl));
this.commit_directive(buff);
if (this.laser_shine_ctrl) {
this.$message.success('已打开');
}
// this.safety_switch_state = !this.safety_switch_state
}
},
handle_safety_switch_state() {
if (this.safety_switch_state) {
const buff = MMC_Gimbal_FB1.laser_shine_ctrl(0);
this.commit_directive(buff);
this.laser_shine_ctrl = false;
}
},
commit_directive(buffer) {
// console.log(buffer);
this.$emit('directive', buffer);
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_FB1 {
position: absolute;
// bottom: 0;
right: 0;
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
width: 280px;
// height: 218px;
box-sizing: border-box;
.hd {
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(16, 65, 215, 0.2);
box-shadow: inset 0 0 15px 0 rgba(0, 182, 255, 0.6);
border-radius: 10px 10px 0 0;
.left {
display: flex;
align-items: center;
.title {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.close {
font-size: 14px;
font-family: MicrosoftYaHei;
color: #d2dfff;
margin-right: 8px;
cursor: pointer;
}
}
.bd {
display: flex;
.form-wrap {
padding: 16px 0;
width: 100%;
height: 100px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
.form-item {
display: flex;
align-items: center;
.label-box {
color: #cbd0eb;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
.launch {
margin-left: 16px;
display: flex;
flex-direction: column;
align-items: center;
}
}
}
}
</style>
<template>
<div class="cpt-MMC_Gimbal_FN3" :style="containerStyle">
<div v-interact class="hd">
<div class="left ml8">
<img src="../assets/images/mount/mount_head.png" />
<div class="title">网枪</div>
</div>
<div class="close" @click="$emit('close')">关闭</div>
</div>
<div class="bd">
<div class="form-wrap">
<div class="form-item">
<div class="label-box">保险:</div>
<div class="input-box">
<el-switch v-model="safety_switch_state" size="mini" />
</div>
</div>
<div class="form-item mt16">
<img src="../assets/images/observe/011.svg" alt="" />
<div class="launch">
<img src="../assets/images/mount/launch.png" alt="" @click="handle_laser_shine_ctrl" />
<div class="label-box">发射</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_FN3 } from '../utils';
export default {
props: {
containerStyle: {
type: Object,
default: () => ({})
}
},
data() {
return {
timer: null,
radio: 1,
safety_switch_state: true
};
},
mounted() {},
methods: {
handle_laser_shine_ctrl(value) {
if (this.safety_switch_state) {
this.$message.warning('请关闭保险');
} else {
const buff = MMC_Gimbal_FN3.laser_shine_ctrl(1);
this.commit_directive(buff);
this.$message.success('发射成功');
this.safety_switch_state = !this.safety_switch_state;
}
},
commit_directive(buffer) {
// console.log(buffer);
this.$emit('directive', buffer);
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_FN3 {
position: absolute;
// bottom: 0;
right: 0;
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
width: 240px;
// height: 218px;
box-sizing: border-box;
.hd {
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(16, 65, 215, 0.2);
box-shadow: inset 0 0 15px 0 rgba(0, 182, 255, 0.6);
border-radius: 10px 10px 0 0;
.left {
display: flex;
align-items: center;
.title {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.close {
font-size: 14px;
font-family: MicrosoftYaHei;
color: #d2dfff;
margin-right: 8px;
cursor: pointer;
}
}
.bd {
display: flex;
.form-wrap {
padding: 16px 0;
width: 100%;
height: 130px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
.form-item {
display: flex;
align-items: center;
.label-box {
color: #cbd0eb;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
.launch {
margin-left: 16px;
display: flex;
flex-direction: column;
align-items: center;
}
}
}
}
</style>
<template>
<div class="cpt-MMC_Gimbal_FE3" :style="containerStyle">
<div v-interact class="hd">
<div class="left ml8">
<img src="../assets/images/mount/mount_head.png" />
<div class="title">干粉灭火器</div>
</div>
<div class="close" @click="$emit('close')">关闭</div>
</div>
<div class="bd">
<img class="ml16" src="../assets/images/observe/019.svg" alt="" />
<div class="form-wrap">
<div class="form-item">
<div class="label-box">保险</div>
<div class="input-box">
<el-switch v-model="safety_switch_state" size="mini" />
</div>
</div>
<div class="form-item">
<div class="label-box">开关</div>
<div class="input-box" @click="handle_fire_ctrl">
<el-switch v-model="fire_status" size="mini" />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_FE3 } from '../utils';
export default {
props: {
containerStyle: {
type: Object,
default: () => ({})
}
},
data() {
return {
radio: 1,
// 保险状态
safety_switch_state: false,
// 开关状态
fire_status: false
};
},
methods: {
handle_fire_ctrl() {
console.log(111, this.safety_switch_state);
if (!this.safety_switch_state) {
this.$message.warning('保险未打开!');
return (this.fire_status = false);
}
let buff = null;
if (this.fire_status) {
buff = MMC_Gimbal_FE3.gimbal_mode2_ctrl(1);
} else {
buff = MMC_Gimbal_FE3.gimbal_mode2_ctrl(0);
}
this.commit_directive(buff);
},
commit_directive(buffer) {
this.$emit('directive', buffer);
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_FE3 {
position: absolute;
// bottom: 0;
right: 0;
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
width: 280px;
// height: 218px;
box-sizing: border-box;
.hd {
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(16, 65, 215, 0.2);
box-shadow: inset 0 0 15px 0 rgba(0, 182, 255, 0.6);
border-radius: 10px 10px 0 0;
.left {
display: flex;
align-items: center;
.title {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.close {
font-size: 14px;
font-family: MicrosoftYaHei;
color: #d2dfff;
margin-right: 8px;
cursor: pointer;
}
}
.bd {
display: flex;
.form-wrap {
padding: 16px 0;
width: 100%;
height: 100px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
.form-item {
display: flex;
align-items: center;
.label-box {
color: #cbd0eb;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
.launch {
margin-left: 16px;
display: flex;
flex-direction: column;
align-items: center;
}
}
}
}
</style>
<template>
<div class="cpt-MMC_Gimbal_FE8" :style="containerStyle">
<div v-interact class="hd">
<!-- <div class="title">八孔投弹器</div> -->
<div class="left ml8">
<img src="../assets/images/mount/mount_head.png" />
<div class="title">催泪弹</div>
</div>
<div class="close" @click="$emit('close'), $emit('showCenter', false)">关闭</div>
</div>
<div class="bd">
<div class="rocker-wrap">
<div class="title-box">
<!-- <div class="title">操作</div> -->
</div>
<div ref="rocker" class="rocker">
<div class="shangUp" @click="fangxiang('up')" />
<div class="xaiUp" @click="fangxiang('down')" />
<div class="zuoUp" @click="fangxiang('right')" />
<div class="youUp" @click="fangxiang('left')" />
</div>
</div>
<div class="form-wrap">
<div class="form-item">
<div class="label-box">保险:</div>
<div class="input-box">
<el-switch v-model="safety_switch_state" size="mini" />
</div>
</div>
<div class="form-item launch">
<img src="../assets/images/mount/launch.png" alt="" @click="handle_laser_shine_ctrl" />
<div class="label-box">发射</div>
<!--<div class="input-box" @click="handle_laser_shine_ctrl">
<el-switch v-model="laser_shine_status" size="mini"></el-switch>
</div> -->
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_FE8 } from '../utils';
export default {
props: {
containerStyle: {
type: Object,
default: () => ({})
}
},
data() {
return {
timer: null,
radio: 1,
safety_switch_state: false,
laser_shine_status: false
};
},
mounted() {
this.$emit('showCenter', true);
this.$nextTick(() => {
this.init_rocker();
});
},
methods: {
handle_laser_shine_ctrl(value) {
if (!this.safety_switch_state) {
this.$message.warning('未打开保险');
return (this.laser_shine_status = false);
} else {
// if (this.laser_shine_status) {
const buff = MMC_Gimbal_FE8.laser_shine_ctrl(1);
this.commit_directive(buff);
this.$message.success('发射成功');
// setTimeout(() => {
// this.laser_shine_status = false;
// }, 500);
// }
}
},
commit_directive(buffer) {
// console.log(buffer);
this.$emit('directive', buffer);
},
fangxiang(type) {
let buffer = null;
switch (type) {
case 'up':
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(1);
this.commit_directive(buffer);
break;
case 'right':
// buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
// this.commit_directive(buffer);
// setTimeout(() => {
// buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(-1);
// this.commit_directive(buffer);
// }, 50);
break;
case 'left':
// buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
// this.commit_directive(buffer);
// setTimeout(() => {
// buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(1);
// this.commit_directive(buffer);
// }, 50);
break;
case 'down':
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(-1);
this.commit_directive(buffer);
}
this.timer = setTimeout(() => {
clearTimeout(this.timer);
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
}, 500);
},
init_rocker() {
let buffer = null;
joystick({
// zone: this.$refs["rocker"],
// mode: "static",
// position: { left: "50%", top: "50%" },
// color: "#9bacbe",
onstart: (type) => {
switch (type) {
case 'up':
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(1);
this.commit_directive(buffer);
break;
case 'right':
// buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
// this.commit_directive(buffer);
// setTimeout(() => {
// buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(-1);
// this.commit_directive(buffer);
// }, 50);
break;
case 'left':
// buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
// this.commit_directive(buffer);
// setTimeout(() => {
// buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(1);
// this.commit_directive(buffer);
// }, 50);
break;
case 'down':
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(-1);
this.commit_directive(buffer);
}
},
onend: () => {
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
}
});
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_FE8 {
position: absolute;
// bottom: 0;
right: 0;
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
width: 470px;
height: 290px;
box-sizing: border-box;
.hd {
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(16, 65, 215, 0.2);
box-shadow: inset 0 0 15px 0 rgba(0, 182, 255, 0.6);
border-radius: 10px 10px 0 0;
.left {
display: flex;
align-items: center;
.title {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.close {
font-size: 14px;
font-family: MicrosoftYaHei;
color: #d2dfff;
margin-right: 8px;
cursor: pointer;
}
}
.bd {
padding: 10px 20px;
display: flex;
// justify-content: space-between;
overflow-y: auto;
height: 230px;
overflow-x: hidden;
.form-wrap {
margin-left: 124px;
// min-width: 300px;
// flex-shrink: 0;
.form-item {
display: flex;
align-items: center;
height: 40px;
.label-box {
color: #cbd0eb;
// width: 75px;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
.launch {
margin-top: 35px;
margin-left: 22px;
display: flex;
flex-direction: column;
}
}
.rocker-wrap {
// flex: 1;
.title-box {
.title {
color: #cbd0eb;
}
}
.rocker {
// margin: 10px auto 0;
width: 150px;
height: 150px;
position: relative;
// margin: 0 auto;
background: center url('../assets/images/accident/caozuo.png') no-repeat;
background-size: 100% 100%;
.shangUp {
position: absolute;
left: 37%;
top: 4px;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.xaiUp {
position: absolute;
left: 37%;
bottom: 4px;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.zuoUp {
position: absolute;
left: 4px;
top: 37%;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.youUp {
position: absolute;
right: 4px;
top: 37%;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
}
}
}
}
::v-deep {
.el-select {
width: 165px;
margin-right: 5px;
.el-input {
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
}
.el-input {
width: 165px;
margin-right: 5px;
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
.el-radio-group {
.el-radio {
.el-radio__input {
&.is-checked {
.el-radio__inner {
border-color: #08c2d1;
background: #08c2d1;
}
}
}
.el-radio__label {
color: #cbd0eb;
}
}
}
.el-button {
background: #2aefed;
color: #000;
border: none;
}
}
</style>
<template>
<div class="cpt-MMC_Gimbal_FF6">
<div v-interact class="hd">
<div class="title">喷火器</div>
</div>
<div class="bd">
<div class="form-wrap">
<div class="form-item">
<div class="label-box">保险</div>
<div class="input-box">
<el-switch v-model="safety_switch_state" size="mini" />
</div>
</div>
<div class="form-item">
<div class="label-box">喷火</div>
<div class="input-box">
<el-switch v-model="fire_status" size="mini" @change="handle_fire_ctrl" />
</div>
</div>
</div>
<div class="rocker-wrap">
<div class="title-box">
<div class="title">操作</div>
</div>
<div ref="rocker" class="rocker">
<div class="shangUp" @click="fangxiang('up')" />
<div class="xaiUp" @click="fangxiang('down')" />
<div class="zuoUp" @click="fangxiang('right')" />
<div class="youUp" @click="fangxiang('left')" />
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_FF6 } from '../utils';
export default {
data() {
return {
timer: null,
radio: 1,
safety_switch_state: false,
fire_status: false
};
},
mounted() {
this.$nextTick(() => {
this.init_rocker();
});
},
methods: {
handle_fire_ctrl(value) {
if (!this.safety_switch_state) {
return (this.fire_status = false);
}
const buff = MMC_Gimbal_FF6.fire_ctrl(1);
this.commit_directive(buff);
},
commit_directive(buffer) {
this.$emit('directive', buffer);
},
fangxiang(type) {
let buffer = null;
switch (type) {
case 'up':
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(1);
this.commit_directive(buffer);
}, 50);
break;
case 'right':
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(-1);
this.commit_directive(buffer);
}, 50);
break;
case 'left':
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(1);
this.commit_directive(buffer);
}, 50);
break;
case 'down':
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(-1);
this.commit_directive(buffer);
}, 50);
}
this.timer = setTimeout(() => {
clearTimeout(this.timer);
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
}, 500);
},
init_rocker() {
let buffer = null;
joystick({
// zone: this.$refs["rocker"],
// mode: "static",
// position: { left: "50%", top: "50%" },
// color: "#9bacbe",
onstart: (type) => {
switch (type) {
case 'up':
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(1);
this.commit_directive(buffer);
}, 50);
break;
case 'right':
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(-1);
this.commit_directive(buffer);
}, 50);
break;
case 'left':
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(1);
this.commit_directive(buffer);
}, 50);
break;
case 'down':
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(-1);
this.commit_directive(buffer);
}, 50);
}
},
onend: () => {
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
}
});
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_FF6 {
position: absolute;
top: 0px;
right: 0;
/* background: center url("../assets/images/observe/fckernel/mount/01_bg.png")
no-repeat; */
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
background-size: 100% 100%;
width: 500px;
height: 290px;
box-sizing: border-box;
padding: 10px 20px;
.hd {
.title {
font-size: 18px;
color: #08c2d1;
font-weight: bold;
line-height: 2;
}
}
.bd {
display: flex;
justify-content: space-between;
.form-wrap {
min-width: 245px;
flex-shrink: 0;
.form-item {
display: flex;
align-items: center;
height: 40px;
.label-box {
color: #cbd0eb;
width: 75px;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
}
.rocker-wrap {
flex: 1;
.title-box {
.title {
color: #cbd0eb;
}
}
.rocker {
margin: 10px auto 0;
width: 150px;
height: 150px;
position: relative;
margin: 0 auto;
background: center url('../assets/images/accident/caozuo.png') no-repeat;
background-size: 100% 100%;
.shangUp {
position: absolute;
left: 37%;
top: 4px;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.xaiUp {
position: absolute;
left: 37%;
bottom: 4px;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.zuoUp {
position: absolute;
left: 4px;
top: 37%;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.youUp {
position: absolute;
right: 4px;
top: 37%;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
}
}
}
}
::v-deep {
.el-select {
width: 165px;
margin-right: 5px;
.el-input {
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
}
.el-input {
width: 165px;
margin-right: 5px;
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
.el-radio-group {
.el-radio {
.el-radio__input {
&.is-checked {
.el-radio__inner {
border-color: #08c2d1;
background: #08c2d1;
}
}
}
.el-radio__label {
color: #cbd0eb;
}
}
}
.el-button {
background: #2aefed;
color: #000;
border: none;
}
}
</style>
<template>
<div class="chart-container-box ml55 pr" @click="$emit('fn', 'co')">
<span class="pa top7 left-60 tc cf cp" style="z-index: 999">
<div>CO</div>
(ppm)
</span>
<div ref="CoChart" class="chart w299 h65"></div>
<div class="pa right8 cf tc top8">{{ value && value.toFixed(2) }}</div>
</div>
</template>
<script>
const echarts = require("echarts");
export default {
name: "C0Chart",
data() {
return {
chart: null,
value: 0,
option: {
grid: {
top: "40%",
height: "40%",
borderWidth: 1,
borderColor: "#294598",
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false,
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false,
splitLine: {
show: false,
},
},
series: [
{
name: "CO",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
};
},
props: {
airData: {
type: String | Number,
default: 0,
},
},
mounted() {
this.initChart();
this.time = setInterval(() => {
if (this.airData >= 0) {
this.updateData(this.airData);
}
}, 1000);
},
methods: {
initChart() {
console.log(echarts, "echarts");
this.chart = echarts.init(this.$refs.CoChart);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date().getTime();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
}
</style>
<template>
<div class="chart-container-box ml55 pr cp" @click="$emit('fn','no2')">
<span class="pa cp top20 left-60 tc cf" style="z-index:999">
<div>NO2</div>(ppm)
</span>
<div ref="NO2" class="chart w299 h73"></div>
<div class="pa right8 cf tc top8">{{ value&&value.toFixed(2) }}</div>
</div>
</template>
<script>
const echarts = require("echarts");
export default {
name: "NO2",
data() {
return {
chart: null,
value: 0,
option: {
color: ["#fc9f00"],
grid: {
top: "40%",
height: "40%", // 调整 grid 的 height 值,缩小图表的高度
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false, // 隐藏 Y 轴
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false, // 隐藏 Y 轴
splitLine: {
show: false,
},
},
series: [
{
name: "NO2",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
time:null
};
},
props: {
airData: {
type: String | Number,
default: () => 0,
},
},
beforeDestroy(){
clearInterval(this.time)
},
mounted() {
this.initChart();
this.time= setInterval(() => {
if(this.airData>=0){
this.updateData( this.airData);
}
}, 1000);
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.NO2);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
.chart {
height: 73px;
}
}
</style>
\ No newline at end of file
<template>
<div class="chart-container-box ml55 pr" @click="$emit('fn','ox')">
<span class="pa top20 left-64 tc cp cf" style="z-index:999">
<div>Ox</div>(ppm)
</span>
<div ref="Ox" class="chart w299 h65"></div>
<div class="pa right8 cf tc top8">{{ value&&value.toFixed(2) }}</div>
</div>
</template>
<script>
const echarts = require("echarts");
export default {
name: "Ox",
data() {
return {
chart: null,
value: 0,
option: {
color: ["#1fca21"],
// title: {
// text: '动态数据',
// left: 'left', // 设置标题位置为左侧中间
// textAlign: 'center', // 设置标题在左侧居中显示
// // 其他选项...
// },
grid: {
top: "40%",
height: "40%", // 调整 grid 的 height 值,缩小图表的高度
borderWidth: 1,
borderColor: "#294598",
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false, // 隐藏 Y 轴
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false, // 隐藏 Y 轴
splitLine: {
show: false,
},
},
series: [
{
name: "Ox",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
time:null
};
},
props: {
airData: {
type: String | Number,
default: () => 0,
},
},
mounted() {
this.initChart();
this.time= setInterval(() => {
if(this.airData>=0){
this.updateData(this.airData);
}
}, 1000);
},
beforeDestroy(){
clearInterval(this.time)
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.Ox);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
.chart {
height: 73px;
}
}
</style>
\ No newline at end of file
<template>
<div class="chart-container-box ml55 pr" @click="$emit('fn','pm1dot0')">
<span class="pa cp top20 left-64 tc cf" style="z-index:999">
<div>PM1.0</div>(ug/m3)
</span>
<div ref="PM" class="chart w299 h65"></div>
<div class="pa right8 cf tc top8">{{ value&&value.toFixed(2) }}</div>
</div>
</template>
<script>
const echarts = require("echarts");
export default {
name: "PM",
data() {
return {
chart: null,
value: 0,
option: {
color: ["#00a3da"],
// title: {
// text: '动态数据',
// left: 'left', // 设置标题位置为左侧中间
// textAlign: 'center', // 设置标题在左侧居中显示
// // 其他选项...
// },
grid: {
top: "40%",
height: "40%", // 调整 grid 的 height 值,缩小图表的高度
borderWidth: 1,
borderColor: "#294598",
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false, // 隐藏 Y 轴
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false, // 隐藏 Y 轴
splitLine: {
show: false,
},
},
series: [
{
name: "PM1.0",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
time:null
};
},
mounted() {
this.initChart();
this.time= setInterval(() => {
if(this.airData>=0){
this.updateData(this.airData);
}
}, 1000);
},
beforeDestroy(){
clearInterval(this.time)
},
props: {
airData: {
type: String | Number,
default: () => 0,
},
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.PM);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
.chart {
height: 73px;
}
}
</style>
\ No newline at end of file
<template>
<div class="chart-container-box ml55 pr" @click="$emit('fn','pm10')">
<span class="pa top20 left-64 tc cf cp" style="z-index:999">
<div>PM10</div>(ug/m3)
</span>
<div ref="PM10" class="chart w299 h65"></div>
<div class="pa right8 cf tc top8">{{ value&&value.toFixed(2) }}</div>
</div>
</template>
<script>
const echarts = require("echarts");
export default {
name: "PM10",
data() {
return {
chart: null,
value: 0,
option: {
color: ["#1fca21"],
// title: {
// text: '动态数据',
// left: 'left', // 设置标题位置为左侧中间
// textAlign: 'center', // 设置标题在左侧居中显示
// // 其他选项...
// },
grid: {
top: "40%",
height: "40%", // 调整 grid 的 height 值,缩小图表的高度
borderWidth: 1,
borderColor: "#294598",
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false, // 隐藏 Y 轴
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false, // 隐藏 Y 轴
splitLine: {
show: false,
},
},
series: [
{
name: "PM10",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
time: null,
};
},
props: {
airData: {
type: String | Number,
default: () => 0,
},
},
mounted() {
this.initChart();
this.time = setInterval(() => {
if (this.airData >= 0) {
this.updateData(this.airData);
}
}, 1000);
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.PM10);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
.chart {
height: 73px;
}
}
</style>
\ No newline at end of file
<template>
<div class="chart-container-box ml55 pr" @click="$emit('fn','pm2dot5')">
<span class="pa cp top20 left-64 tc cf" style="z-index:999">
<div>PM2.5</div>(ug/m3)
</span>
<div ref="PM2" class="chart w299 h65"></div>
<div class="pa right8 cf tc top8">{{ value&&value.toFixed(2) }}</div>
</div>
</template>
<script>
const echarts = require("echarts");
export default {
name: "PM2",
data() {
return {
chart: null,
value: 0,
option: {
color: ["#f63832"],
// title: {
// text: '动态数据',
// left: 'left', // 设置标题位置为左侧中间
// textAlign: 'center', // 设置标题在左侧居中显示
// // 其他选项...
// },
grid: {
top: "40%",
height: "40%", // 调整 grid 的 height 值,缩小图表的高度
borderWidth: 1,
borderColor: "#294598",
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false, // 隐藏 Y 轴
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false, // 隐藏 Y 轴
splitLine: {
show: false,
},
},
series: [
{
name: "PM2.5",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
time:null
};
},
props: {
airData: {
type: String | Number,
default: () => 0,
},
},
mounted() {
this.initChart();
this.time= setInterval(() => {
if(this.airData>=0){
this.updateData(this.airData);
}
}, 1000);
},
beforeDestroy(){
clearInterval(this.time)
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.PM2);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
.chart {
height: 73px;
}
}
</style>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论