做了大略三个月的基于 cesium 地图开发的利用场景和大屏;次要想从 cesium 根本的入门到一些简略的场景交互做一个代码分享。
Cesium 是三维地图开发的一个前端 gis 引擎;反对 wtms、影像、模型、地形、歪斜摄影的数据加载。并通过对点线面、材质、视角等图形学常识对它进行一个正式三维场景的一个复现。
包含一些最
- 根本的创立地图、创立点位、数据源组、创立图层、加载 gif,相机视角;
- 加载图层、绘制点、线、面,调节情景参数;
- 对接天地图、高德地图、百度地图;
- 事件:点击事件、移除事件、移除事件、拖拽事件
- 弹框:视频弹框、详情弹框、报警弹框
- 轨迹:动静轨迹、轨迹漫游
- 流线图:喷泉、流线图
- 场景:模仿下雪、下雨、雷达图
- 根本工具箱:放大、放大,定位、画线
- kml、geojson 文件转换和加载
- 性能优化
-
常用工具办法
1、根本的创立地图
viewer = new Cesium.Viewer('maps', {
animation: false, // 是否创立动画小器件,左下角仪表
baseLayerPicker: false, // 是否显示图层选择器
fullscreenButton: false, // 是否显示全屏按钮
geocoder: false, // 是否显示 geocoder 小器件,右上角查问按钮
homeButton: false, // 是否显示 Home 按钮
infoBox: false, // 是否显示信息框
sceneModePicker: false, // 是否显示 3D/2D 选择器
selectionIndicator: false, // 是否显示选取指示器组件
timeline: false, // 是否显示时间轴
sceneMode: Cesium.SceneMode.SCENE3D, // 设定 3 维地图的默认场景模式:Cesium.SceneMode.SCENE2D、Cesium.SceneMode.SCENE3D、Cesium.SceneMode.MORPHING
navigationHelpButton: false, // 是否显示右上角的帮忙按钮
scene3DOnly: true, // 如果设置为 true,则所有几何图形以 3D 模式绘制以节约 GPU 资源
navigationInstructionsInitiallyVisible: false,
showRenderLoopErrors: false, // 是否显示渲染谬误
shouldAnimate: true,// 容许动画 // 这个得必须有!})
- 创立的点位:
- layer && layer.entities.add({
id: item.id,
name: item.name,
type: "marker",
featureType: type,
feature: item.feature,
lon: item.lon,
lat: item.lat,
mapTools: tools,// 地图左边按钮
position: Cesium.Cartesian3.fromDegrees(parseFloat(lon), parseFloat(lat), height),
billboard: {image: new Cesium.CallbackProperty(() => {return _self.superGif.get_canvas().toDataURL("image/png");
}, false),
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
width: 60,
height: imageheight
},
label: {text: type == "wrj" ? `${item.name}` : "",
font: '14pt 微软雅黑',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
// backgroundColor: Cesium.Color.YELLOW,
// showBackground: true,
outlineColor: new Cesium.Color.fromCssColorString("tranparent"),
fillColor: new Cesium.Color.fromCssColorString("#fff"),
outlineWidth: 5,
verticalOrigin: Cesium.VerticalOrigin.CENTER,
pixelOffset: new Cesium.Cartesian2(-110, -25)
},
})
- 创立数据图层
- markersLayer = new Cesium.CustomDataSource('marker-layer')
- viewer.dataSources.add(markersLayer)
- 创立地图底图图层
viewer.imageryLayers.addImageryProvider(new Cesium.SingleTileImageryProvider({url: '/static/map/worldimage.jpg'}));
- 加载 gif 动静图片,须要引入 SuperGif 插件进行 gif 转换,再通过 Cesium.CallbackProperty 一帧帧获取,须要留神得加上 dom 元素
- <img src="/biz/alarm.gif" width="20px" height="20px" ref="gifRef" rel:auto_play="1" rel:rubbable="1"
style="position: absolute;z-index: -1;" />
_self.superGif = new SuperGif({gif: this.$refs.gifRef});
_self.superGif.load(function () {
layer && layer.entities.add({
id: item.id,
name: item.name,
type: "marker",
featureType: type,
feature: item.feature,
lon: item.lon,
lat: item.lat,
mapTools: tools,// 地图左边按钮
position: Cesium.Cartesian3.fromDegrees(parseFloat(lon), parseFloat(lat), height),
billboard: {image: new Cesium.CallbackProperty(() => {return _self.superGif.get_canvas().toDataURL("image/png");
}, false),
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
width: 60,
height: imageheight
},
label: {text: type == "wrj" ? `${item.name}` : "",
font: '14pt 微软雅黑',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
// backgroundColor: Cesium.Color.YELLOW,
// showBackground: true,
outlineColor: new Cesium.Color.fromCssColorString("tranparent"),
fillColor: new Cesium.Color.fromCssColorString("#fff"),
outlineWidth: 5,
verticalOrigin: Cesium.VerticalOrigin.CENTER,
pixelOffset: new Cesium.Cartesian2(-110, -25)
},
_lng: lon,
_lat: lat,
_obj: item
})
});
}
- 相机视角(有 entity 则用 viewer,坐标用 camera)
let heading = viewer.camera.heading, pitch = viewer.camera.pitch, roll = viewer.camera.roll;
viewer.flyTo(_self.pickValue, {
offset: {
heading: 2.990358455542995, // 方向
pitch: -0.5403975721607086,// 歪斜角度
range: 11100
}
// 定位
let lon = list[0].lon || list[0].longitude, lat = list[0].lat || list[0].latitude;
viewer.camera.flyTo(this.mapCenter, 5000);
2、加载图层、绘制点、线、面,调节情景参数
加载图层
天地图超图形式对接
let IMG_C = viewer.imageryLayers.addImageryProvider(new Cesium.TiandituImageryProvider({
mapStyle: Cesium.TiandituMapsStyle.IMG_C,
token: 'e8865a2cd69468263ca650b1c73ee698'
}))
IMG_C.show = true;
// let IMG_C = viewer.imageryLayers.addImageryProvider(new Cesium.TiandituImageryProvider({
// mapStyle: Cesium.TiandituMapsStyle.TER_C,
// token: 'e8865a2cd69468263ca650b1c73ee698'
// }))
// IMG_C.show = true;
viewer.imageryLayers.addImageryProvider(new Cesium.TiandituImageryProvider({mapStyle: Cesium.TiandituMapsStyle.CIA_C,// 天地图全球中文注记服务(经纬度)
token: 'xxx' // 由天地图官网申请的密钥
}))
- 原生对接
// 叠加影像服务
var imgMap = new Cesium.UrlTemplateImageryProvider({url: tdtUrl + 'DataServer?T=img_w&x={x}&y={y}&l={z}&tk=' + token,
subdomains: subdomains,
tilingScheme: new Cesium.WebMercatorTilingScheme(),
maximumLevel: 22
});
viewer.imageryLayers.addImageryProvider(imgMap);
- 绘制面
ttMaplayer.entities.add({position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
ellipse: {
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: 99000000,
outlineColor: Cesium.Color.YELLOW.withAlpha(0.5),
outline: true,
outlineWidth: 2,
semiMinorAxis: 5000.0,
semiMajorAxis: 5000.0,
fill: false,
}
});
- 绘制矩形
let east = points[0].split(','),west = points[1].split(',');
layer.entities.add({
type:"marker",
name: item.name,
_obj:item,
position: Cesium.Cartesian3.fromDegrees(parseFloat((+east[0]+(+west[0]))/2), parseFloat((+west[1]+(+east[1]))/2)),
rectangle: {coordinates: Cesium.Rectangle.fromDegrees(+east[0], +east[1],+west[0], +west[1]),
outlineColor:Cesium.Color.RED,
outlineWidth:24,
fill:true,
material: Cesium.Color.BLUE.withAlpha(0.6),
outline:true
}
})
- 绘制线段(能够设置线段宽度和材质)
_t.appendLayer.entities.add({
polyline: {positions: new Cesium.CallbackProperty(function() {return _t.routeList}, false),
width: 5,
material: Cesium.Color.RED,
depthFailMaterial: Cesium.Color.RED,
clampToGround: true
}
})
- 参数调节
let Options = function () {
this.contrast = 128;
this.brightness = -0.3;
this.delta = 1;
this.gamma = 3.5;
this.enabled = false;
this.highDynamicRange = true;
this.shadows = false;
}
let option = new Options();
let gui = new dat.GUI();
gui.__closeButton.innerHTML = "膨胀面板";
let bloom = viewer.scene.postProcessStages.bloom;
gui.add(option, 'highDynamicRange').name("高动静范畴").onChange(function (value) {viewer.scene.highDynamicRange = value;})
gui.add(option, 'gamma', 0, 5).name("伽马亮度").onChange(function (value) {viewer.scene.gamma = value;})
gui.add(option, 'enabled').name("启用含糊").onChange(function (value) {bloom.enabled = value;})
gui.add(option, 'contrast', -128, 128).name("对比度").onChange(function (value) {bloom.uniforms.contrast = value;})
gui.add(option, 'brightness', -2, 2).name("光泽亮度").onChange(function (value) {bloom.uniforms.brightness = value;})
gui.add(option, 'delta', -5, 5).name("因子(delta)").onChange(function (value) {bloom.uniforms.delta = value;})
gui.add(option, 'shadows').name("启用暗影").onChange(function (value) {viewer.shadows = value;})
$('.dg.ac').css('top', '10%');
事件
-
鼠标左键点击事件
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas), _self = this; let ellipsoid = viewer.scene.globe.ellipsoid; // 点击地图视频标记窗口弹窗 handler.setInputAction(async e => { let lng, lat, height var cartesian = viewer.scene.pickPosition(e.position); // 地图点位查问 let pick = viewer.scene.pick(e.position); if (Cesium.defined(pick) && pick.id && pick.id.type === "marker") {}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
- 鼠标移入事件
- // 鼠标移入事件
handler.setInputAction(async movement => {
let lng, lat, height;
if (viewer.scene.mode !== Cesium.SceneMode.MORPHING) {let pick = viewer.scene.pick(movement.endPosition);
if (Cesium.defined(pick) && pick.id)}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
鼠标移除事件
rectHandler && rectHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
rectHandler && rectHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
rectHandler && rectHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP);
弹框(生成弹框和弹框挪动)
生成:
dom 节点
<poiDetail ref="poiRef"></poiDetail>
positionPopUp(c) {
this.tempPostion = c;
var x = c.x - 290;
var y = c.y - 250
this.boxStyle = `left:${x}px;top:${y}px`
},
destroy() {this.options = {};
this.hide();},
hide() {
this.getActionFlg = false;
this.visible = false;
this.showPlayer = false;
this.tempPostion = null;
}
- js 形式管制 dom 节点
_self.$refs.poiRef.open({
position: changedC,
item: _self.pickValue,
removeHandler: () => {_self.removeHandler()
}
})
-
挪动:postRender 监听地位挪动扭转坐标
viewer.scene.postRender.addEventListener(function () {
})相干链接:
bigMap kml 和 geojson 转换
在线图层解决
罕用的地图 json 下载和 svg 下载
Ceisum 文档比官网快
github 代码:https://github.com/holidaying/Cesium/tree/master