如何通过Cesium创建一个地图:
1、npm安装(这里使用1.95.0版本)
npm i cesium@1.95.0 -s
或
yarn add cesium@1.95.0 -s
2、组件引入
import * as Cesium from "cesium/Cesium";
3、容器创建
<div id="cesiumContainer" />
4、核心类Viewer创建
在Cesium中Viewer
是一切的开端,通过newCesium.Viewer(container, options)
来创建一个Viewer
对象,可以把该对象理解为三维虚拟地球,在Viewer
对象上的所有操作,可以看作是对三维虚拟地球的操作。
const viewer = new Viewer("cesiumContainer", {
infoBox: false,
animation: false, // 是否显示动画控件
homeButton: false, // 是否显示home键
geocoder: false, // 是否显示地名查找控件
baseLayerPicker: false, // 是否显示图层选择控件
timeline: false, // 是否显示时间线控件
fullscreenButton: false, // 是否全屏显示
infoBox: false, // 是否显示点击要素之后显示的信息
sceneModePicker: false, // 是否显示投影方式控件 三维/二维
navigationInstructionsInitiallyVisible: false,
navigationHelpButton: false, // 是否显示帮助信息控件
orderIndependentTranslucency: false,
shouldAnimate: true,
scene3DOnly: false, // 每个几何实例将只能以3D渲染以节省GPU内存
selectionIndicator: false, // 取消点击有绿框
// imageryProvider: false, // 不提供地图
baseLayerPicker: true, //是否显示图层选择控件
});
5、 设置初始位置(经纬度、缩放比例)
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
113.764043,
34.005325,
8000000
),
});
此时,一个地球就出现了!!!
cesium内置了一些图层供我们切换。
还可以通过一些json数据给地图添加想要的区块图层
- 通过阿里云数据可视化平台拿到相应地区的json数据DataV.GeoAtlas地理小工具系列
- 使用Cesium.GeoJsondataSource.load添加
//阿里云地理信息工具 数据获取
viewer.dataSources.add(
Cesium.GeoJsonDataSource.load(
"https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json"
)
);
我们还可以通过cesium对一些建筑物进行观察
但需要申请Cesium的令牌(token)
如何申请?
通过以下官网地址申请
Cesium ion
使用:
Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNDVhMjQ0Yi05MDg4LTRlNDYtYTIxMi00YmI4ZWYxOWMyNTgiLCJpZCI6MTQ5MzYwLCJpYXQiOjE2ODc3ODQ0OTh9.KlhT_LCnsEtYyawpEmJ_wx44_qTUbgze-SxGMRavbAM";
之后就可以访问高清页面;
完整代码
<template>
<div id="cesiumContainer" @dragover="allowDrop" @drop="drop">
<nav>
<button @click="draw('point')">点绘制</button>
<button @click="draw('polyline')">线绘制</button>
<button @click="draw('polygon')">圆绘制</button>
<button @click="clearDrawEntities">清空</button>
</nav>
</div>
</template>
<script>
import * as Cesium from "cesium/Cesium";
import { Viewer } from "cesium/Cesium";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import { transform, getTransform } from "ol/proj";
// import { selectNodesForSpecifiedRegion } from "../../utils/gis/commonMethods";
export default {
name: "cesiumView",
data() {
return {
// map: null,
cesiumContainer: null,
mapViewer: null,
tempEntities: [],
activeNames: [],
};
},
mounted() {
this.initMap();
},
methods: {
handleChange() {},
//init
initMap() {
// 此应用程序正在使用 Cesium 的默认 ion 访问令牌,请在使用 Ceisum API 调用之前先注册一个你自己的 Cesium ion 访问令牌
Cesium.Ion.defaultAccessToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNDVhMjQ0Yi05MDg4LTRlNDYtYTIxMi00YmI4ZWYxOWMyNTgiLCJpZCI6MTQ5MzYwLCJpYXQiOjE2ODc3ODQ0OTh9.KlhT_LCnsEtYyawpEmJ_wx44_qTUbgze-SxGMRavbAM";
const viewer = new Viewer("cesiumContainer", {
infoBox: false,
animation: false, // 是否显示动画控件
homeButton: false, // 是否显示home键
geocoder: false, // 是否显示地名查找控件
baseLayerPicker: false, // 是否显示图层选择控件
timeline: false, // 是否显示时间线控件
fullscreenButton: false, // 是否全屏显示
infoBox: false, // 是否显示点击要素之后显示的信息
sceneModePicker: false, // 是否显示投影方式控件 三维/二维
navigationInstructionsInitiallyVisible: false,
navigationHelpButton: false, // 是否显示帮助信息控件
orderIndependentTranslucency: false,
shouldAnimate: true,
scene3DOnly: false, // 每个几何实例将只能以3D渲染以节省GPU内存
selectionIndicator: false, // 取消点击有绿框
// imageryProvider: false, // 不提供地图
baseLayerPicker: true, //是否显示图层选择控件
});
//设置初始位置
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
113.764043,
34.005325,
3000
),
});
// entities 默认点位
// const entity = viewer.entities.add({
// position: Cesium.Cartesian3.fromDegrees(116.39, 39.91, 400),
// point: {
// pixelSize: 50,
// color: new Cesium.Color(0, 1, 0, 1),
// },
// });
// //将摄像头设置到远点处
// viewer.trackedEntity = entity;
//阿里云地理信息工具 数据获取
// viewer.dataSources.add(
// Cesium.GeoJsonDataSource.load(
// "https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json"
// )
// );
// Viewer.scene.globe.show = false;
// logo去除
viewer.cesiumWidget.creditContainer.style.display = "none";
this.mapViewer = viewer;
window.viewer = viewer;
console.log(viewer, "viewer");
},
// deleteRectangle() {},
//获取经纬度
getPosition(viewer) {
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (event) {
let cartesian = viewer.scene.pickPosition(event.position);
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
let alt = cartographic.height; // 高度
let coordinate = {
longitude: Number(lng.toFixed(6)),
latitude: Number(lat.toFixed(6)),
altitude: Number(alt.toFixed(2)),
};
console.log(coordinate,'coordinate');
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
},
/**
* Role map drop
* Desc 元素拖入地图放置事件
*/
drop(e) {
e.preventDefault();
this.getPosition(window.viewer);
// console.log(e, "eeeeeeeeee");
// const pos = transform(this.map.getEventCoordinate(e), "EPSG:3857", "EPSG:4326");
// console.log(pos, "pos");
// const pos = ol.proj.transform(pos, 'EPSG:3857', 'EPSG:4326');
// const data = e.dataTransfer.getData("Text");
// console.log(data,'data')
},
//图标拖动效果
drag(event, item) {
console.log(event, item, "---------------");
},
/**
* Role dragover
* Desc 在可拖动的元素或者被选择的文本被拖进一个有效的放置目标时(每几百毫秒)触发,
* 允许元素拖入地图
*/
allowDrop(e) {
e.preventDefault();
// event.preventDefault
},
draw(type) {
//点绘制
let _this = this;
let viewer = this.mapViewer;
let tempEntities = this.tempEntities;
let position = [];
let tempPoints = [];
/**
* Role depthTestAgainstTerrain 开启地形深度检测
* desc 开启地形检测后,会计算其他地理要素和地形之间的遮挡关系。未开启时,将会出现场景变化时,地物位置显示不正确。
*/
viewer.scene.globe.depthTestAgainstTerrain = true;
/**
* Role ScreenSpaceEventHandler
* type => canvas
* default => Document
* desc 处理用户输入事件。可以添加自定义功能以在以下位置执行当用户输入输入时。
*/
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
switch (type) {
case "point":
//监听 鼠标左键
handler.setInputAction(function (movement) {
// 从相机位置通过windowPosition 世界坐标中的像素创建一条射线。返回Cartesian3射线的位置和方向。
let ray = viewer.camera.getPickRay(movement.position);
// 查找射线与渲染的地球表面之间的交点。射线必须以世界坐标给出。返回Cartesian3对象
position = viewer.scene.globe.pick(ray, viewer.scene);
let point = _this.drawPoint(position);
tempEntities.push(point);
/**
* Role ScreenSpaceEventType
* Desc 此枚举类型用于对鼠标事件进行分类:向下,向上,单击,双击,按住按钮时移动。
*/
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// 左键双击停止绘制
handler.setInputAction(function () {
handler.destroy(); //关闭事件句柄
handler = null;
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
// 右击单击停止绘制
handler.setInputAction(function () {
handler.destroy(); //关闭事件句柄
handler = null;
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
break;
case "polyline":
//鼠标移动事件
handler.setInputAction(function (movement) {},
Cesium.ScreenSpaceEventType.MIDDLE_CLICK);
//左键点击操作
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 = _this.drawPoint(tempPoints[tempPoints.length - 1]);
tempEntities.push(point);
if (tempLength > 1) {
let pointline = _this.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;
}, 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 = _this.drawPoint(position);
tempEntities.push(point);
if (tempLength > 1) {
let pointline = _this.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 = _this.drawPolyline([
tempPoints[tempPoints.length - 1],
tempPoints[0],
]);
tempEntities.push(pointline);
_this.drawPolygon(tempPoints);
tempEntities.push(tempPoints);
handler.destroy(); //关闭事件句柄
handler = null;
}
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
break;
}
},
drawPoint(position, config) {
let viewer = this.mapViewer;
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.mapViewer;
if (positions.length < 1) return;
let config = config_ ? config_ : {};
return viewer.entities.add({
name: "线几何对象",
polyline: {
positions: positions,
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.mapViewer;
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.mapViewer;
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>
<style lang="less" scoped>
#cesiumContainer {
width: 100vw;
height: 100vh;
position: relative;
header {
position: absolute;
top: 0;
width: 100%;
height: 50px;
background: rgba(0, 0, 0, 0.5);
}
.leftBar {
width: 250px;
height: 50%;
position: absolute;
top: 30%;
z-index: 999;
.el-collapse-item__content {
display: flex;
justify-content: space-between;
// flex-wrap: wrap;
}
.collapseItems {
// display: block;
width: 100%;
height: auto;
.ivu-icon {
display: block;
}
b {
display: block;
text-align: center;
}
}
}
nav {
position: absolute;
left: 20px;
top: 20px;
width: 150px;
height: 180px;
// background: rgba(0, 0, 0, 0.5);
z-index: 999;
display: flex;
flex-direction: column;
justify-content: space-between;
button {
width: 100%;
height: 30px;
cursor: pointer;
}
}
}
</style>