vue + cesium开发(4) 绘制图形
在官方例子中每个图形都是一个entity,官方例子提供了显示正方形、圆形、锥形、图片等多种案例!
// 初始花
var viewer = new Cesium.Viewer("cesiumContainer");
// 创建蓝色entity
var blueBox = viewer.entities.add({ // 添加到图形实体
// 名称
name: "Blue box",
// 位置 笛卡尔
position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
// 形状,可以是盒子 线段 椎体等,当前是盒子
box: {
// 设置框的长度、宽度和高度 笛卡尔单位
dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),
// 颜色 还可以设置边框、阴影等
material: Cesium.Color.BLUE,
},
});
// 创建红色entity
var redBox = viewer.entities.add({
name: "Red box with black outline",
position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0),
box: {
dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),
material: Cesium.Color.RED.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.BLACK,
},
});
// 创建透明entity
var outlineOnly = viewer.entities.add({
name: "Yellow box outline",
position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 300000.0),
box: {
dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),
fill: false,
outline: true,
outlineColor: Cesium.Color.YELLOW,
},
});
viewer.zoomTo(viewer.entities);
此外还可以通过加载czml文件来进行显示,其它例子也可通过 https://sandcastle.cesium.com/?src=Box.html&label=All 进行查看!
但是,这些例子都是根据固定的位置和形状进行显示的,如果我们要自己进行手动绘制呢?官方依然提供了一个例子:
该实例提供了手动绘制线段与多边形的方法,代码如下:
var viewer = new Cesium.Viewer("cesiumContainer", {
selectionIndicator: false,
infoBox: false,
/**
* 开启世界图形,防止图形错位
* 如果不开启则使用:
* 几何图形要依附于模型必须开启depthTestAgainstTerrain
* viewer.scene.globe.depthTestAgainstTerrain = true
* */
terrainProvider: Cesium.createWorldTerrain(),
});
// 防止双击放大球体
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
);
// 创建一个点
function createPoint(worldPosition) {
var point = viewer.entities.add({
position: worldPosition,
point: {
color: Cesium.Color.WHITE,
// 大小
pixelSize: 5,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
});
return point;
}
var drawingMode = "line";
// 绘制
function drawShape(positionData) {
var shape;
if (drawingMode === "line") {
shape = viewer.entities.add({
// 线段
polyline: {
positions: positionData,
clampToGround: true,
width: 3,
},
});
} else if (drawingMode === "polygon") {
// 多边形
shape = viewer.entities.add({
polygon: {
hierarchy: positionData,
material: new Cesium.ColorMaterialProperty(
Cesium.Color.WHITE.withAlpha(0.7)
),
},
});
}
return shape;
}
// 所有活动点的实体
var activeShapePoints = [];
// 绘制图形
var activeShape;
// 第一个活动点
var floatingPoint;
// 创建鼠标事件
var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(function (event) {
// 获取鼠标当前位置 viewer.scene.pickPosition 将位置转化为笛卡尔单位
var earthPosition = viewer.scene.pickPosition(event.position);
if (Cesium.defined(earthPosition)) {
if (activeShapePoints.length === 0) {
// 创建第一个点
floatingPoint = createPoint(earthPosition);
activeShapePoints.push(earthPosition);
// 最重要的一步,绘制过程中图形会动态跟着鼠标移动
// CallbackProperty返回一个回调函数 当activeShapePoints改变时会触发
// 不管activeShapePoints是增加还是删除都会动态改变图形的形状
// 在绘制结束必须重置activeShapePoints = [] 不然 CallbackProperty 一直处于回调中,严重消耗性能
var dynamicPositions = new Cesium.CallbackProperty(function () {
if (drawingMode === "polygon") {
// 多边形的position需要用 PolygonHierarchy进行转化
return new Cesium.PolygonHierarchy(activeShapePoints);
}
return activeShapePoints;
}, false);
activeShape = drawShape(dynamicPositions);
}
activeShapePoints.push(earthPosition);
createPoint(earthPosition);
}
// 鼠标左键点击事件 LEFT_CLICK
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.setInputAction(function (event) {
// 判断是否存在
if (Cesium.defined(floatingPoint)) {
var newPosition = viewer.scene.pickPosition(event.endPosition);
if (Cesium.defined(newPosition)) {
// 动态改变活动点的位置与鼠标当前位置保持一致
floatingPoint.position.setValue(newPosition);
activeShapePoints.pop();
activeShapePoints.push(newPosition);
}
}
// 鼠标左键移动事件 MOUSE_MOVE
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 重新绘制形状,使其不是动态的,然后删除动态形状.
function terminateShape() {
// 删除最后一个点
activeShapePoints.pop();
// 绘制完整的图形
drawShape(activeShapePoints);
// 删除创建的第一个点和处于活动状态的实体
viewer.entities.remove(floatingPoint);
viewer.entities.remove(activeShape);
// 格式化
floatingPoint = undefined;
activeShape = undefined;
activeShapePoints = [];
}
// 结束绘制
handler.setInputAction(function (event) {
terminateShape();
// 鼠标右键点击事件 RIGHT_CLICK
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
// Sandcastle 百度解决,不用也行,只是在cesium上挂载组件
var options = [
{
text: "Draw Lines",
onselect: function () {
if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) {
window.alert(
"This browser does not support polylines on terrain."
);
}
terminateShape();
drawingMode = "line";
},
},
{
text: "Draw Polygons",
onselect: function () {
terminateShape();
drawingMode = "polygon";
},
},
];
Sandcastle.addToolbarMenu(options);
// Zoom in to an area with mountains
viewer.camera.lookAt(
Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0),
new Cesium.Cartesian3(5000.0, 5000.0, 5000.0)
);
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
下面是自己封装的一个绘制多边形的代码:DrawPolygon.js
点击查看代码
/*
绘制面
*/
import * as Cesium from 'cesium'
import * as turf from '@turf/turf'
import Entity from './Entity'
const LEFT_CLICK = Cesium.ScreenSpaceEventType.LEFT_CLICK
const RIGHT_CLICK = Cesium.ScreenSpaceEventType.RIGHT_CLICK
const MOUSE_MOVE = Cesium.ScreenSpaceEventType.MOUSE_MOVE
const LEFT_DOUBLE_CLICK = Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
// 绘制面
export default class DaChDraw {
// 初始化
constructor(viewer = null, options = { singleMode: false }) {
if (!viewer) {
throw new Error('请传入cesium实例!')
}
this.viewer = viewer
// 当前面所有点
this._position = []
// 最后一个活动点
this._positionLast = null
// 第一次绘制的图形
this._shape = null
// 绘制的所有实体
this._entityList = []
// 通过加载geojson显示的面
this._polygonJson = []
// 是否显示面积
this._isShowArea = false
// 通过加载geojson显示的图形
this._geoMap = new Map()
// 绘制的图形
this._drawMap = new Map()
this.entity = new Entity(viewer)
// 测量
this._resultTip = null
// 测量所保存的实体
this._resultTipArr = []
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas)
const _serf = this
// 是否开启单例模式,默认关闭 开启后在多个页面实例化都取到相同的DaChDraw 实例
_serf.singleMode = null
if (options.singleMode) {
if (!DaChDraw.singleMode) {
DaChDraw.singleMode = _serf
}
return DaChDraw.singleMode
}
}
// 结束
destroy() {
this._position = []
this._positionLast = null
this._shape = null
this._entityList = []
}
// 开始绘制
startDraw(showArea = this._isShowArea) {
const _serf = this
_serf._isShowArea = showArea
// 鼠标点击
_serf.handler.setInputAction(function(event) {
// 获取当前点击坐标
let earthPosition = _serf.viewer.scene.pickPosition(event.position)
if (Cesium.defined(earthPosition)) {
if (_serf._position.length === 0) {
// 创建点击的第一个点
_serf._positionLast = _serf.entity.createPoint(earthPosition)
_serf._position.push(earthPosition)
var dynamicPositions = new Cesium.CallbackProperty(function() {
// return new Cesium.PolygonHierarchy(_serf._position)
return _serf._position
}, false)
_serf._shape = _serf.entity.createLine(dynamicPositions)
_serf._entityList.push(_serf._positionLast)
_serf._entityList.push(_serf._shape)
}
_serf._position.push(earthPosition)
const pot = _serf.entity.createPoint(earthPosition)
_serf._entityList.push(pot)
}
}, LEFT_CLICK)
// 鼠标移动
this.handler.setInputAction(function(event) {
if (Cesium.defined(_serf._positionLast)) {
// 如果已经存在了一个点,说明当前处于绘制状态
// 获取移动后的最后一个位置 pickPosition获取笛卡尔坐标
let newPosition = _serf.viewer.scene.pickPosition(event.endPosition)
if (Cesium.defined(newPosition)) {
_serf._positionLast.position.setValue(newPosition)
_serf._position.pop()
_serf._position.push(newPosition)
}
}
}, MOUSE_MOVE)
// 鼠标双击绘制完成
_serf.handler.setInputAction(function(event) {
console.log(_serf._position)
if (_serf._position.length <= 4) {
_serf.breakDraw()
} else {
_serf.finishDraw()
}
}, LEFT_DOUBLE_CLICK)
// 鼠标右键结束绘制
_serf.handler.setInputAction(function(event) {
_serf.breakDraw()
}, RIGHT_CLICK)
}
// 绘制中断
breakDraw() {
const _serf = this
_serf._entityList.forEach((entity) => {
_serf.entity.remove(entity)
})
// 移除鼠标监听
this.handler.removeInputAction(LEFT_CLICK)
this.handler.removeInputAction(MOUSE_MOVE)
this.handler.removeInputAction(RIGHT_CLICK)
this.handler.removeInputAction(LEFT_DOUBLE_CLICK)
_serf.destroy()
}
// 绘制结束
finishDraw() {
const _serf = this
_serf.entity.remove(_serf._positionLast)
_serf.entity.remove(_serf._shape)
_serf._position.pop()
_serf._position.unshift(_serf._position[_serf._position.length - 1])
// _serf._polygonLast = _serf.entity.createPolygon(_serf._position)
_serf._polygonLast = _serf.entity.createLine(_serf._position)
const position = _serf.coordinates(
_serf._position,
_serf._position,
'Polygon'
)
// 绘制图形转geosjson
let geoJson = turf.polygon([position])
console.log(JSON.stringify(geoJson))
// 绘制完成后显示面积
if (_serf._isShowArea) {
let area = (turf.area(obj) / 1000000.0).toFixed(4) + '平方公里'
_serf.entity.createLabel(
area,
_serf._position[_serf._position.length - 1]
)
}
const { _id: id } = _serf._polygonLast
const polyObj = {
id,
geoJson,
}
this._drawMap.set(id, polyObj)
// 去掉所有绘制的点
_serf._entityList.forEach((entity) => {
_serf.entity.remove(entity)
})
this.destroy()
}
cartesian2Degrees(cartesian) {
const ellipsoid =
this.viewer.scene.globe.ellipsoid || Cesium.Ellipsoid.WGS84
let cartographic = Cesium.Cartographic.fromCartesian(cartesian, ellipsoid)
let lat = Cesium.Math.toDegrees(cartographic.latitude)
let lon = Cesium.Math.toDegrees(cartographic.longitude)
let height = cartographic.height
return {
lat,
lon,
height,
}
}
coordinates(position, positions, type) {
if (position instanceof Cesium.Cartesian3) {
const coor = this.cartesian2Degrees(position)
return [coor.lon, coor.lat, coor.height]
} else if (positions instanceof Array) {
const pts = []
for (let p of positions) {
const c = this.cartesian2Degrees(p)
pts.push([c.lon, c.lat, c.height])
}
if (type === 'Polygon') {
return pts
} else {
return [pts]
}
}
}
// 加载geojson显示图形
getDraw(feat, style = {}) {
let positions = []
const coordinates = feat.geometry.coordinates[0]
for (let c of coordinates) {
positions.push({
lon: c[0],
lat: c[1],
height: c[2],
})
}
positions = positions.map((_) => {
return Cesium.Cartesian3.fromDegrees(_.lon, _.lat, _.height)
})
return this.entity.createPolygon(positions, style)
}
}
Entity.js
点击查看代码
// 定义实体对象
import * as Cesium from 'cesium'
export default class Entitys {
constructor(core) {
this.entitys = core.entities
}
// 新增
add(entity) {
return this.entitys.add(entity)
}
// 删除
remove(entity) {
this.entitys.remove(entity)
}
// 移除所有
removeAll() {
this.entitys.removeAll()
}
// 创建实体类
create() {
return new Cesium.Entity()
}
// 根据ID获取实体类
withIdGainEntity(id) {
return this.entitys.getById(id)
}
getPoint() {
return new Cesium.PointGraphics({
pixelSize: 5,
color: Cesium.Color.BLUE,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 1,
})
}
getLine(positions, color, width = 1) {
return new Cesium.PolylineGraphics({
show: true,
positions: positions,
material: color,
width,
clampToGround: true,
})
}
getPolygon(position) {
return new Cesium.PolygonGraphics({
show: true,
hierarchy: position,
material: Cesium.Color.RED.withAlpha(0.5),
})
}
// 创建点
createPoint(position, label = null, point = true, billboard = false) {
let entity = this.create()
entity.position = position
if (point) entity.point = this.getPoint()
if (label) entity.label = this.getLabel(label)
return this.add(entity)
}
// 创建线
createLine(positions, oid = '', color = Cesium.Color.BLUE) {
let entity = this.create()
entity.position = positions
entity.polyline = this.getLine(positions, color)
entity.oid = oid
return this.add(entity)
}
// 创建面
createPolygon(positions) {
const entity = this.create()
entity.polygon = this.getPolygon(positions)
return this.add(entity)
}
// 创建label
createLabel(text, positions) {
let entity = this.create()
entity.label = this.getLabel(text)
entity.position = positions
return this.add(entity)
}
getLabel(text, offset) {
return new Cesium.LabelGraphics({
//文字标签
text: text,
font: '16px sans-serif',
fillColor: Cesium.Color.GOLD,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
showBackground: true,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: offset == undefined ? new Cesium.Cartesian2(10, 30) : offset,
})
}
}
vue + cesium开发(4) 绘制图形的更多相关文章
- vue + cesium开发(5) 搭建 vue + cesium开发环境(2)
上vue+cesium开发(1)中,没有进行配置webpack,而是使用了插件进行代替,在使用过程中出现了一些未知BUG,影响体验,因此参考了官方文档对项目进行重新配置,使用了 copy-webpac ...
- Android OpenGL ES 开发:绘制图形
OpenGL 绘制图形步骤 上一篇介绍了 OpenGL 的相关概念,今天来实际操作,使用 OpenGL 绘制出图形,对其过程有一个初步的了解. OpenGL 绘制图形主要概括成以下几个步骤: 创建程序 ...
- cesium开发(1)搭建 vue + cesium开发环境
进入新公司一段时间了,新公司业务主要从事卫星方面等webgl的开发,主要使用了leafletjs和cesium,其中cesium难度较大,需求较多,再进行了一段时间的使用开发后依旧感到有些力不从心, ...
- vue + cesium开发(3) cesium1.87更新问题
官方在2021年11月1号更新日志中记录了他们把zip.js升级到了2.3.12以适应webpack4中的关于import.meta不兼容的语法问题,但是经过实测,1.87版本依然没有解决这个问题,所 ...
- 在Android中使用OpenGL ES进行开发第(三)节:绘制图形
一.前期基础知识储备笔者计划写三篇文章来详细分析OpenGL ES基础的同时也是入门关键的三个点: ①OpenGL ES是什么?与OpenGL的关系是什么?——概念部分 ②使用OpenGLES绘制2D ...
- Windows App开发之编辑文本与绘制图形
编辑文本及键盘输入 相信大家都会使用TextBox,但假设要让文本在TextBox中换行该怎么做呢?将TextWrapping属性设置为Wrap,将AcceptsReturn属性设置为True就好咯. ...
- CSS 魔法系列:纯 CSS 绘制图形(心形、六边形等)
<CSS 魔法系列>继续给大家带来 CSS 在网页中以及图形绘制中的使用.这篇文章给大家带来的是纯 CSS 绘制五角星.六角形.五边形.六边形.心形等等. 我们的网页因为 CSS 而呈现千 ...
- html5 Canvas绘制图形入门详解
html5,这个应该就不需要多作介绍了,只要是开发人员应该都不会陌生.html5是「新兴」的网页技术标准,目前,除IE8及其以下版本的IE浏览器之外,几乎所有主流浏览器(FireFox.Chrome. ...
- vue前端开发那些事——vue组件开发
vue的学习曲线不是很陡(相比其它框架,如anglarjs),官方文档比较全面,分为基础篇和高级篇.我们刚开始学习的时候,肯定像引用jquery那样,先把vue的js引进来,然后学习基础内容.如果仅仅 ...
随机推荐
- firewalld dbus接口使用指南
firewalld,一个基于动态区的iptables/nftables守护程序,自2009年左右开始开发,最新版本 - 防火墙0.6.3 - 发布于2018年10月11日.主要的开发人员是托马斯·沃纳 ...
- 每日总结:charcter方法(2021.10.5)
\t 在文中该处插入一个tab键 \b在文中该处插入一个后退键 \n 换行 \r 在文中该处回车 \f 在文中该处插入换页符 方法: isLetter()是否是一个字母 isDigit()是否是一个 ...
- SpringCloud升级之路2020.0.x版-28.OpenFeign的生命周期-进行调用
本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 接下来,我们开始分析 OpenFeign 同步环境下的生命周期的第二部分,使用 Synch ...
- JVM详解(五)——运行时数据区-方法区
一.概述 1.介绍 <Java虚拟机规范>中明确说明:尽管所有的方法区在逻辑上属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩.但对于HotSpot JVM而言,方法 ...
- NX Open显示符号(UF_DISP_display_temporary_point)
UF_DISP_display_temporary_point 使用方法: 1 Dim x As Double = 0, y As Double = 0, z As Double = 0 2 3 Di ...
- javascript运算符和表达式
1.表达式的概念 由运算符连接操作组成的式子,不管式子有多长,最终都是一个值. 2.算术运算符 加+ 减- 乘* 除/ 取模% 负数- 自增++ 自减-- 3.比较运算符 等于== 严格等于=== ...
- 利用 pip 安装 Python 程序包到个人用户文件夹下
利用 --user 参数,即 pip install --user package_name 这样会将Python 程序包安装到 $HOME/.local 路径下,其中包含三个字文件夹:bin,lib ...
- 第一次Alpha Scrum Meeting
本次会议为Alpha阶段第一次Scrum Meeting会议 会议概要 会议时间:2021年4月22日 会议地点:北航Inspiration Space咖啡厅 会议时长:1小时 会议内容简介:本次会议 ...
- 5.27日Scrum Metting
日期:2021年5月27日 会议主要内容概述:确定账单数据格式,确定需要添加新的图表,确定模板分享功能任务量. 一.进度情况# 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 ...
- 计算机网络传输层之TCP协议(tcp协议特点、tcp报文段首部格式、tcp连接建立---三次握手、tcp连接释放---四次握手)
文章转自:https://blog.csdn.net/weixin_43914604/article/details/105516090 学习课程:<2019王道考研计算机网络> 学习目的 ...