learning_cesium/在线编辑-动态画线.html

481 lines
20 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<!-- Use correct character set. -->
<meta charset="utf-8" />
<!-- Tell IE to use the latest, best version. -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>
<title>Learning Cesium!</title>
<script src="./Build/Cesium/Cesium.js"></script>
<style>
@import url(./Build/Cesium/Widgets/widgets.css);
html,
body,
#app,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.menu-container {
position: absolute;
top: 30px;
left: 100px;
z-index: 9999;
}
</style>
<!-- 引入样式 -->
<link rel="stylesheet" href="./js/elementui/index.css" />
<!-- import Vue before Element -->
<script src="./js/vue2710.js"></script>
<!-- import JavaScript -->
<script src="./js/elementui/index.js"></script>
</head>
<body>
<div id="app">
<div class="menu-container">
<el-row type="flex" :gutter="20">
<el-col :span="24">
<div class="grid-content bg-purple">
<el-breadcrumb separator="/">
<el-breadcrumb-item>cesium</el-breadcrumb-item>
<el-breadcrumb-item>绘制功能</el-breadcrumb-item>
<el-breadcrumb-item>点、线、面</el-breadcrumb-item>
</el-breadcrumb>
</div>
</el-col>
</el-row>
<el-row type="flex" :gutter="20">
<el-col :span="24">
<div class="grid-content bg-purple">
<cesiumComponent id="cesium" ref="refCesium" />
</div>
</el-col>
</el-row>
<el-row type="flex" :gutter="20">
<el-col :span="24">
<div class="grid-content bg-purple">
<el-button type="primary" @click="addDem()">复位</el-button>
<el-button type="primary" @click="draw('point')"
>绘制点</el-button
>
<el-button type="primary" @click="draw('polyline')"
>绘制线</el-button
>
<el-button type="primary" @click="draw('polygon')"
>绘制面</el-button
>
<el-button type="primary" @click="clearDrawEntities"
>清空</el-button
>
</div>
</el-col>
</el-row>
</div>
<div
id="tooltip"
style="
position: absolute;
z-index: 999;
background: rgba(0, 0, 0, 0.3);
color: rgb(255, 255, 255);
font-size: 12px;
padding: 5px;
border-radius: 5px;
"
>
左键点击选点,右键确定
</div>
<div id="cesiumContainer"></div>
</div>
<script type="module">
Cesium.Ion.defaultAccessToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5ZjRjNTZkNC01NDYxLTRhMjQtOGEwZC1kZjA3YzQ5YTJlZDkiLCJpZCI6MjYwODQsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODcxOTMwODN9.prGsSKyAW_9Ow5zHYPhbm3LsQL-ApQw5-5PNJkDaHi8";
new Vue({
el: "#app",
data() {
return {
polygonPointsEntities: [], // 区域的点位集合
polygonPointsEntitiesLine: [], // 连线的多点
polygonPointsEntitiesEntity: [], // 区域查询所画线实体
pointPositionList: [], // 画点的经纬度集合
editPoints: [], // 编辑时编辑点集合,删除点用
isAddStatus: false, // 是否是添加区域
isEditStatus: false, // 是否是编辑区域
isAddPoint: false, //是否新添加了点
spaceArea: "", // 区域范围坐标
polygonEntity: null, // 区域面实体
isSaved: false, // 保存状态
viewer: null, // 地图实例化
curBillboard: null, // 当前高亮的广告牌
entityMarkerList: [], // 地图上点的资源实体对象集合
companyPoint: [], // 企业上点数据
// 标注图层
tdtImgAnnoLayerProvider:
new Cesium.WebMapTileServiceImageryProvider({
url: "http://t6.tianditu.com/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=b6b320a7ccfabfdc30536330efc07f3e",
layer: "tdtImgAnnoLayer",
style: "default",
format: "image/jpeg",
tileMatrixSetID: "GoogleMapsCompatible",
}),
_viewer: undefined,
tempEntities: [],
};
},
mounted() {
this.initMap(119.666612, 34.249119, 40000);
// if (this.parentRow.id) {
// this.getGridDetail();
// }
},
methods: {
// 初始化地图(根据当前企业所在位置初始化中心位置)
initMap(longitude, latitude, height) {
Cesium.Ion.defaultAccessToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNjJkN2ZjNC04OTYxLTQyZmItYmM5Mi0yOTgyMzQxMjEzZGQiLCJpZCI6MTg5NTIsInNjb3BlcyI6WyJhc2wiLCJhc3IiLCJhc3ciLCJnYyIsInByIl0sImlhdCI6MTU4OTYyODkwMn0.ibuCu13_8ksLkyimUHR4e1LrWRb-_sfZrPMhSWSzJBg";
let viewer = new Cesium.Viewer("cesiumContainer", {
baseLayerPicker: false,
geocoder: false, // 是否显示地名查找控件
homeButton: false,
sceneModePicker: false, // 是否显示投影方式控件
selectionIndicator: false,
baseLayerPicker: false, // 是否显示图层选择控件
navigationHelpButton: false, // 是否显示帮助信息控件
animation: false, // 是否显示动画控件
// creditContainer: "credit",
timeline: false, // 是否显示时间线控件
fullscreenButton: false,
vrButton: false,
infoBox: false, // 是否显示点击要素之后显示的信息
// requestRenderMode: true, // 启用请求渲染模式
scene3DOnly: true, // 每个几何实例将只能以3D渲染以节省GPU内存
sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式 Cesium.SceneMode
imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
url: "http://t0.tianditu.gov.cn/img_w/wmts?tk=b6b320a7ccfabfdc30536330efc07f3e",
layer: "img",
style: "default",
tileMatrixSetID: "w",
format: "tiles",
maximumLevel: 18,
}),
});
this._viewer = viewer;
viewer._cesiumWidget._creditContainer.style.display = "none";
viewer.scene.globe.depthTestAgainstTerrain = false; // 图标被遮挡
viewer.scene.fxaa = false;
// 设置后当相机高度达到设置的最大和最小高度时将不再放大和缩小
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 0; // 相机的高度的最小值
viewer.scene.screenSpaceCameraController.maximumZoomDistance = 20000000; // 相机高度的最大值
// 天地图矢量标注图层
this.tdtImgAnnoLayer = viewer.imageryLayers.addImageryProvider(
this.tdtImgAnnoLayerProvider
);
viewer.imageryLayers.raiseToTop(this.tdtImgAnnoLayer);
// 定位到中心点
// this.flyTo([Number(longitude), Number(latitude)], height,0);
// 关闭双击事件
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
);
// this.addMouseListener(); // 地图鼠标移动事件
// this.addMouseClick(); // 地图鼠标左键单击事件
// this.addMouseRightClick(); // 地图鼠标右键点击事件
// this.addMouseLeftDown(); // 地图鼠标左键压下事件
viewer.camera.setView({
destination : new Cesium.Cartesian3(-2356756.15965061, 5772015.66176657, 3168029.199415899),
orientation: {
heading : 0.01658837002956659, // east, default value is 0.0 (north)
pitch : -1.0356538269507363, // default value (looking down)
roll : 6.283178308645091 // default value
}
});
},
/**
* 根据类型绘制对象
* @param type point、polyline、polygon
*/
draw(type) {
//绘制点
let that = this;
let viewer = this._viewer;
let tempEntities = this.tempEntities;
let position = [];
let tempPoints = [];
// 开启深度检测
viewer.scene.globe.depthTestAgainstTerrain = false;
let handler = new Cesium.ScreenSpaceEventHandler(
viewer.scene.canvas
);
document.getElementsByTagName("body").item(0).style.cursor =
"crosshair";
switch (type) {
case "point":
//鼠标移动事件
handler.setInputAction(function (movement) {
let tooltip = document.getElementById("tooltip");
tooltip.style.display = "none";
tooltip.style.left = movement.endPosition.x + 15 + "px";
tooltip.style.top = movement.endPosition.y + 5 + "px";
if (window.pt) {
let cartesian3 = viewer.scene.pickPosition(
movement.endPosition
);
window.pt._position = new Cesium.CallbackProperty(
function () {
return cartesian3;
},
false
);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 监听鼠标左键
handler.setInputAction(function (movement) {
// 从相机位置通过windowPosition 世界坐标中的像素创建一条射线。返回Cartesian3射线的位置和方向。
let ray = viewer.camera.getPickRay(movement.position);
// 查找射线与渲染的地球表面之间的交点。射线必须以世界坐标给出。返回Cartesian3对象
position = viewer.scene.globe.pick(ray, viewer.scene);
let point = that.drawPoint(position);
window.pt = point;
tempEntities.push(point);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// 左键双击停止绘制
handler.setInputAction(function () {
handler.destroy(); //关闭事件句柄
handler = null;
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
// 右击单击停止绘制
handler.setInputAction(function () {
handler.destroy(); //关闭事件句柄
handler = null;
document.getElementsByTagName("body").item(0).style.cursor =
"default";
let tooltip = document.getElementById("tooltip");
tooltip.style.display = "none";
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
break;
case "polyline":
//鼠标移动事件
handler.setInputAction(function (movement) {
let tooltip = document.getElementById("tooltip");
tooltip.style.display = "block";
tooltip.style.left = movement.endPosition.x + 15 + "px";
tooltip.style.top = movement.endPosition.y + "px";
let car3 = viewer.scene.pickPosition(movement.endPosition);
//当鼠标在一些Entity上时car3会是undefined
if (tempPoints.length > 0 && Cesium.defined(car3)) {
if (!window.lineEntity || that.isAddPoint) {
window.lineEntity = that.drawPolyline([
...tempPoints,
car3,
]);
that.isAddPoint = false;
}
let positions =
window.lineEntity.polyline.positions.getValue();
positions[positions.length - 1].x = car3.x;
positions[positions.length - 1].y = car3.y;
positions[positions.length - 1].z = car3.z;
window.lineEntity.polyline.positions =
new Cesium.CallbackProperty(function () {
return positions;
}, false);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//左键点击操作
handler.setInputAction(function (click) {
that.isAddPoint = true;
//调用获取位置信息的接口
let ray = viewer.camera.getPickRay(click.position);
position = viewer.scene.globe.pick(ray, viewer.scene);
tempPoints.push(position);
let tempLength = tempPoints.length;
//调用绘制点的接口
let point = that.drawPoint(tempPoints[tempPoints.length - 1]);
tempEntities.push(point);
if (tempLength > 1) {
let pointline = that.drawPolyline([
tempPoints[tempPoints.length - 2],
tempPoints[tempPoints.length - 1],
]);
tempEntities.push(pointline);
} else {
// tooltip.innerHTML = "请绘制下一个点,右键结束";
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
//右键点击操作
handler.setInputAction(function (click) {
tempPoints = [];
handler.destroy(); //关闭事件句柄
handler = null;
viewer.entities.remove(window.lineEntity);
window.lineEntity = null;
let tooltip = document.getElementById("tooltip");
tooltip.style.display = "none";
document.getElementsByTagName("body").item(0).style.cursor =
"default";
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
break;
case "polygon":
//鼠标移动事件
handler.setInputAction(function (movement) {},
Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//左键点击操作
handler.setInputAction(function (click) {
//调用获取位置信息的接口
let ray = viewer.camera.getPickRay(click.position);
position = viewer.scene.globe.pick(ray, viewer.scene);
tempPoints.push(position);
let tempLength = tempPoints.length;
//调用绘制点的接口
let point = that.drawPoint(position);
tempEntities.push(point);
if (tempLength > 1) {
let pointline = that.drawPolyline([
tempPoints[tempPoints.length - 2],
tempPoints[tempPoints.length - 1],
]);
tempEntities.push(pointline);
} else {
// tooltip.innerHTML = "请绘制下一个点,右键结束";
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
//右键点击操作
handler.setInputAction(function (click) {
let cartesian = viewer.camera.pickEllipsoid(
click.position,
viewer.scene.globe.ellipsoid
);
if (cartesian) {
let tempLength = tempPoints.length;
if (tempLength < 3) {
alert("请选择3个以上的点再执行闭合操作命令");
} else {
//闭合最后一条线
let pointline = that.drawPolyline([
tempPoints[tempPoints.length - 1],
tempPoints[0],
]);
tempEntities.push(pointline);
that.drawPolygon(tempPoints);
tempEntities.push(tempPoints);
handler.destroy(); //关闭事件句柄
handler = null;
}
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
break;
}
},
drawPoint(position, config) {
let viewer = this._viewer;
let config_ = config ? config : {};
return viewer.entities.add({
name: "点几何对象",
position: position,
point: {
color: Cesium.Color.SKYBLUE,
pixelSize: 10,
outlineColor: Cesium.Color.YELLOW,
outlineWidth: 3,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
});
},
drawPolyline(positions, config_) {
let viewer = this._viewer;
if (positions.length < 1) return;
let config = config_ ? config_ : {};
return viewer.entities.add({
name: "线几何对象",
polyline: {
// positions: positions,
positions: new Cesium.CallbackProperty(function () {
return positions;
}, false),
width: config.width ? config.width : 5.0,
material: new Cesium.PolylineGlowMaterialProperty({
color: config.color
? new Cesium.Color.fromCssColorString(config.color)
: Cesium.Color.GOLD,
}),
depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
color: config.color
? new Cesium.Color.fromCssColorString(config.color)
: Cesium.Color.GOLD,
}),
clampToGround: true,
},
});
},
drawPolygon(positions, config_) {
let viewer = this._viewer;
if (positions.length < 2) return;
let config = config_ ? config_ : {};
return viewer.entities.add({
name: "面几何对象",
polygon: {
hierarchy: positions,
material: config.color
? new Cesium.Color.fromCssColorString(config.color).withAlpha(
0.2
)
: new Cesium.Color.fromCssColorString("#FFD700").withAlpha(
0.2
),
},
});
},
/**
* 清除实体
*/
clearDrawEntities() {
let viewer = this._viewer;
this.tempEntities = [];
// 清除之前的实体
const entitys = viewer.entities._entities._array;
let length = entitys.length;
// 倒叙遍历防止实体减少之后entitys[f]不存在
for (let f = length - 1; f >= 0; f--) {
if (
entitys[f]._name &&
(entitys[f]._name === "点几何对象" ||
entitys[f]._name === "线几何对象" ||
entitys[f]._name === "面几何对象")
) {
viewer.entities.remove(entitys[f]);
}
}
},
},
});
</script>
</body>
</html>