cesium方法整理
一、安装依赖
// 安装cesium
npm install cesium --save
// 安装turf工具
npm install @truf/turf --save
// 安装cesium vite插件
npm install vite-plugin-cesim --save
二、项目中引用
import * as Cesium from 'cesium'
import 'cesium/Build/Cesium/Widgets/widgets.css'
import * as turf from '@turf/turf'// 配置地图根目录
window.CESIUM_BASE_URL = '../Cesium'
三、具体方法介绍总结
1,生成地图电子底图(new Cesium.UrlTemplateImageryProvider({}))
let electronic = new Cesium.UrlTemplateImageryProvider({url: 'url', // url 地址fileExtension: "jpg" // 类型
})
2,生成地图卫星底图( new Cesium.ArcGisMapServerImageryProvider({}) )
let satellite = new Cesium.ArcGisMapServerImageryProvider({url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
})
3,初始实例化及相关配置( new Cesium.Viewer(id, {}) )
let viewer = new Cesium.Viewer(id, {//需要进行可视化的数据源的集合animation: false, //是否显示动画控件selectionIndicator: false,shouldAnimate: true, // 是否使用动画homeButton: false, //是否显示Home按钮fullscreenButton: false, //是否显示全屏按钮baseLayerPicker: false, //是否显示图层选择控件geocoder: false, //是否显示地名查找控件timeline: false, //是否显示时间线控件sceneModePicker: false, //是否显示投影方式控件navigationHelpButton: false, //是否显示帮助信息控件infoBox: false, //是否显示点击要素之后显示的信息requestRenderMode: true, //启用请求渲染模式scene3DOnly: false, //每个几何实例将只能以3D渲染以节省GPU内存sceneMode: (config.mode == 'earth' && Cesium.SceneMode.SCENE3D) || (config.mode == '3D' && Cesium.SceneMode.COLUMBUS_VIEW) || Cesium.SceneMode.SCENE2D, //初始场景模式 1 2D模式 2 2D循环模式 3 3D模式 Cesium.SceneModefullscreenElement: document.body, //全屏时渲染的HTML元素 暂时没发现用处imageryProvider: (config.baseLayer == 'satellite' && config.satellite) || config.electronic
});//隐藏cesium左下角logo
viewer._cesiumWidget._creditContainer.style.display = 'none';
// 开启抗锯齿
viewer.scene.postProcessStages.fxaa.enabled = true
// 相机高度最大值,限制缩小级别
let cameraHeight = 1.1e7
viewer.scene.screenSpaceCameraController.maximumZoomDistance = cameraHeight * 3;// 深度开启或关闭
viewer.scene.globe.depthTestAgainstTerrain = false;// 取消默认的双击放大时间
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);// 引起事件监听的相机变化幅度
viewer.camera.percentageChanged = 0.02;
4, 注册地图事件(new Cesium.ScreenSpaceEventHandler())
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 监听地图鼠标左击
handler.setInputAction((click) => leftClickEvent(click), Cesium.ScreenSpaceEventType.LEFT_DOWN)
function leftClickEvent(click) {// 鼠标左击回调函数
}
// 监听地图鼠标右击
handler.setInputAction((click) => rightClickEvent(click), Cesium.ScreenSpaceEventType.RIGHT_CLICK)
function rightClickEvent(click) {// 鼠标右击回调函数
}// 销毁句柄
handler.destroy()
5,获取鼠标点击位置(世界坐标系) (viewer.camera.getPickRay())
1、获取椭球上的点的经纬度(椭球上的点)
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function(event) {// 世界坐标、笛卡尔坐标// enent.position 为屏幕坐标let cartesian = viewer.camera.pickEllipsoid(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; // 高度,椭球面height永远等于0let coordinate = {longitude: Number(lng.toFixed(6)),latitude: Number(lat.toFixed(6)),altitude: Number(alt.toFixed(2))};console.log(coordinate);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);2、获取地表面的点的经纬度(地形上的点)
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function(event){// 笛卡尔3 射线的位置和方向 // event.position 屏幕坐标let ray = viewer.camera.getPickRay(event.position);// 射线与渲染的地球表面之间的交点 世界坐标、笛卡尔坐标let cartesian = viewer.scene.globe.pick(ray, viewer.scene);// 地理坐标 弧度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))};}, Cesium.ScreenSpaceEventType.LEFT_CLICK);3、获取场景里的点的经纬度(模型上的点)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);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
6,点击获取实体对象(viewer.scene.pick(position))
// 点击获取实体对象
// e.position 屏幕坐标
let pickedObject = viewer.scene.pick(e.position)
7,点击获取entity实体( viewer.entities.getById() )
let entity = viewer.entities.getById(id)
8.弧度角度转换
// 将角度转成弧度
Cesium.Math.toRadians(degrees)
// 将弧度转成角度
Cesium.Math.toDegrees(radians)
// 将笛卡尔坐标系中的点转换为地理坐标系中的点。
Cesium.Ellipsoid.cartesianToCartographic(cartesian)
// 将地理坐标系中的点转换为笛卡尔坐标系中的点。
Cesium.Ellipsoid.cartographicToCartesian(cartographic)
9.移动视图,设置相机飞行( viewer.camera.flyTo({}) )
// 将经纬度转成笛卡尔坐标
Cesium.Cartesian3.fromDegrees()
// 将经纬度坐标数组转成笛卡尔坐标数组
Cesium.Cartesian3.fromDegreesArray(degreesArray)viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(119.36401386990066, 31.18535721814696, 120000),orientation: {heading: Cesium.Math.toRadians(345.0),pitch: Cesium.Math.toRadians(-60.0),roll: Cesium.Math.toRadians(0.0)}
})
10. 获取实体 具体 数据( entity.properties.data.getValue() )
// 获取实体具体数据
let data = entity.properties.data.getValue()
11.地图模式改变
// 切换到2D模式
viewer.scene.morphTo2D(1)
// 切换到3D模式
viewer.scene.morphTo3D()
// 切换到哥伦布模式
viewer.scene.morphToColumbusView()// 获取中心视图 2D 3D
let centerPosition = getCenterPosition(),
// 哥伦布模式 记录之前的变化矩阵和距离
let originalView = getViewTransform(viewer)/*** @description: 获取变换矩阵和到中心点的距离* @param {*} viewObj 地图对象* @return {transform, distance} 变换矩阵,距离*/
function getViewTransform(viewObj) {let position = getCenterPosition()if (!position) return// 中心点var centerPosition = Cesium.Cartesian3.fromDegrees(position.lon, position.lat, 0)// 相机点var endLat = Cesium.Math.toDegrees(viewObj.camera.positionCartographic.latitude)var endlng = Cesium.Math.toDegrees(viewObj.camera.positionCartographic.longitude)var height = viewObj.camera.positionCartographic.height;var endPosition = Cesium.Cartesian3.fromDegrees(endlng, endLat, height)// 距离var distance = Cesium.Cartesian3.distance(centerPosition, endPosition)// 矩阵var transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(position.lon, position.lat));return {transform: transform,distance: distance}
}/*** @description:获取地图中心点* @return {lon, lat, height} 经度,纬度,高度*/
function getCenterPosition() {let centerResult = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(viewer.canvas.clientWidth / 2,viewer.canvas.clientHeight / 2,),)let height = viewer.camera.positionCartographic.height || 10000;if (!Cesium.defined(centerResult)) return falselet curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(centerResult);let curLongitude = (curPosition.longitude * 180) / Math.PI;let curLatitude = (curPosition.latitude * 180) / Math.PI;return {lon: curLongitude,lat: curLatitude,height: height}
}// 监听场景转换完成事件
viewer.scene.morphComplete.addEventListener(() =>{// 延迟相机转场let timeout = setTimeout(() => {if (config.mode == '2D' || config.mode == 'earth') {if (!centerPosition) returnlet position = Cesium.Cartesian3.fromDegrees(centerPosition.lon, centerPosition.lat, centerPosition.height)viewer.camera.flyTo({destination: position,});} else {if (!originalView) returnvar heading = viewer.camera.heading;var pitch = viewer.camera.pitch;viewer.camera.lookAtTransform(originalView.transform, new Cesium.HeadingPitchRange(heading, pitch, originalView.distance));}// 解除lookAtTransform的锁定viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)clearTimeout(timeout)}, 1000)
})
12.cesium 是否定义了对象( Cesium.defined(对象) )
Cesium.defined(对象)
13.移除所有地图底图图层,添加地图底图( viewer.imageryLayers.removeAll(), viewer.imageryLayers.addImageryProvider() )
// 移除所有图层
viewer.imageryLayers.removeAll()
// 添加底图
viewer.imageryLayers.addImageryProvider(electronic)
14.卷帘图,把视图分割成两部分,每部分加载不同的底图
/*** @description: 卷帘图:把视图分割成两部分,每部分加载不同的底图*/
function initJuanlian() {// 添加卷帘对比图let layers = viewer.imageryLayers;let leftMap = layers.addImageryProvider(config.electronic)let rightMap = layers.addImageryProvider(config.satellite);// 设置位置左右放置leftMap.splitDirection = Cesium.SplitDirection.LEFT;rightMap.splitDirection = Cesium.SplitDirection.RIGHT// 分割占比let slider = document.getElementById('juanlian');slider.style.display = 'block';viewer.scene.splitPosition = (slider.offsetLeft) / (slider.parentElement.offsetWidth);// 事件let handler = new Cesium.ScreenSpaceEventHandler(slider);let moveActive = false;handler.setInputAction(function () {moveActive = true;}, Cesium.ScreenSpaceEventType.LEFT_DOWN);handler.setInputAction(function () {moveActive = true;}, Cesium.ScreenSpaceEventType.PINCH_START);handler.setInputAction((e) => sliderMove(e, moveActive), Cesium.ScreenSpaceEventType.MOUSE_MOVE);handler.setInputAction((e) => sliderMove(e, moveActive), Cesium.ScreenSpaceEventType.PINCH_MOVE);handler.setInputAction(function () {moveActive = false;}, Cesium.ScreenSpaceEventType.LEFT_UP);handler.setInputAction(function () {moveActive = false;}, Cesium.ScreenSpaceEventType.PINCH_END);
}/*** @description: 分割线移动* @param {*} movement * @param {*} moveActive */
function sliderMove(movement, moveActive) {if (!moveActive) {return;}let slider = document.getElementById('juanlian');let relativeOffset = movement.endPosition.x;let splitPosition = (slider.offsetLeft + relativeOffset) / slider.parentElement.offsetWidth;slider.style.left = 100.0 * splitPosition + '%';viewer.scene.splitPosition = splitPosition;
}
15.视图放大
/*** @description: 视图放大*/
function zoomInView() {var position = viewer.camera.positionCartographic;viewer.camera.moveForward(position.height * 0.5)
}
16.视图缩小
/*** @description: 视图缩小*/
function zoomOutView() {var position = viewer.camera.positionCartographic;viewer.camera.moveBackward(position.height * 0.5)
}
17.移除实体(viewer.entities.remove(entity))
// 移除实体
viewer.entities.remove(entity)
18.创建CustomDataSource集合( new Cesium.CustomDataSource(name) )
// 创建 CustomDataSource 集合
let drawCollection = new Cesium.CustomDataSource(name)
// viewer.dataSources添加集合
viewer.dataSources.add(drawCollection)
19.添加线
/*** @description: 添加线* @param {*} positions */
function addLine(positions) {let line = new Cesium.Entity({name: '直线',type: 'polyline',polyline: {positions: new Cesium.CallbackProperty(() => positions, false),width: 2,material: Cesium.Color.fromCssColorString("#1565c2").withAlpha(1),clampToGround: true,classificationType: Cesium.ClassificationType.BOTH},})// 添加到集合let _line = drawCollection.entities.add(line);return _line
}
20.两点之间的距离( Cesium.Cartesian3.distance( points, points ) )
// 两点间的距离
// points 笛卡尔坐标
// distance 单位为米
let distance = Cesium.Cartesian3.distance(points,points)
21.算法 计算一个点是否在多边形里
/**
* 计算一个点是否在多边形里
* @param {Object} pt 标注点
* @param {Object} poly 多边形数组
*/
function isInsidePolygon(pt, poly) {for (var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)((poly[i].lat <= pt.lat && pt.lat < poly[j].lat) || (poly[j].lat <= pt.lat && pt.lat < poly[i].lat)) &&(pt.lng < (poly[j].lng - poly[i].lng) * (pt.lat - poly[i].lat) / (poly[j].lat - poly[i].lat) + poly[i].lng) &&(c = !c);return c;
}
22.经纬度转屏幕坐标
/*** 经纬度转屏幕坐标* @param {*} latlng 经纬度* @return cartesian2-屏幕坐标*/
function latlngToWindowCoordinates(latlng) {let cartesian3 = Cesium.Cartesian3.fromDegrees(latlng.lon, latlng.lat, 0)let cartesian2 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, cartesian3);return cartesian2
}