当前位置: 首页 > article >正文

SuperMap iClient3D for Cesium立体地图选中+下钻特效

在大屏展示系统中,对行政区划数据制作了立体效果,如果希望选中某一行政区划进行重点介绍,目前常见的方式是通过修改选中对象色彩、边线等方式进行实现;这里提供另外一种偏移动效的思路,提供功能让地图选中效果更加炫酷,一起开看看如何实现吧!

立体地图选中+下钻特效

一、数据制作

对于上述视频中的立体地图制作,此处讲述,如有需要可访问:Online 开发者中心

可视化案例中提供了详细的代码、数据下载链接及数据制作过程。

二、实现思路

选中抬升效果的实现思路如下图所示

点击下钻效果的实现思路如下图所示

三、关键代码

数据抬升关键代码如下:

handlerPoint.setInputAction(function(event) {
					var result = viewer.scene.pick(event.endPosition)
					var layertop = scene.layers.find('sichuan432602');
					var selection = layertop.getSelection();
					if (selection.length > 0) {			
						var selectedId = Number(selection[selection.length - 1]);
						if (!offsetList[selectedId]) {
							offsetList[selectedId] = {
								"isoffset": true,
								"offsetZ": 0
							};
						} else {
							for (let key in offsetList) {
								offsetList[key].isoffset = false;
							}
							offsetList[selectedId].isoffset = true;
						}
					} else {
						for (let key in offsetList) {
							offsetList[key].isoffset = false;
						}
					}
				}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
				setInterval(function() {
					var layertop = scene.layers.find('sichuan432602');
					for (let key in offsetList) {
						if (offsetList[key].isoffset) {
							if (offsetList[key].offsetZ < 20000) {
								offsetList[key].offsetZ = offsetList[key].offsetZ + 1000;
								layertop.setObjsTranslate([key], new Cesium.Cartesian3(0, 0, offsetList[key].offsetZ))
							}


						} else {
							if (offsetList[key].offsetZ > 0) {
								offsetList[key].offsetZ = offsetList[key].offsetZ - 500;
								layertop.setObjsTranslate([key], new Cesium.Cartesian3(0, 0, offsetList[key].offsetZ))
							}
						}
					}

				}, 20)

下钻关键代码如下:

let handlerPoint = new Cesium.ScreenSpaceEventHandler(window.viewer.scene.canvas);
				handlerPoint.setInputAction(function(event){
					viewer.entities.removeById("selectedId");
					
					var layertop = scene.layers.find('sichuan432602');
					var selection = layertop.getSelection();
					if (selection.length > 0) {
						var selectedId = Number(selection[selection.length - 1]);
						// layertop.setObjsVisible([selectedId], true)
						provinceEntity.show = false;
						$("#echarts").hide();
						cityEntity.entities.removeAll();
						cityEntity.show = true;
						layertop.releaseSelection();
						$.ajax({
							url: './images/cbg/sichuancitys4326.json',
							success: function(data) {
								var geometrys = data.features;
								for (var i = 0; i < geometrys.length; i++) {
									if (geometrys[i].properties.cityid != selectedId) {
										continue;
									}
									var geometry = geometrys[i].geometry;
									var coordinates = geometry.coordinates;
									var pipeLinePts = [];
									var polygon;
									if (geometry.type == "MultiLineString") {
										debugger;
									} else {
										for (var j = 0; j < coordinates[0].length; j++) {
											
											var pos = new Cesium.Cartesian3.fromDegrees(Number(coordinates[0][j][0]),
												Number(coordinates[0][j][1]), 20000);
											pipeLinePts.push(pos);
					
										}
										polygon = new Cesium.PolygonHierarchy(pipeLinePts)
									}
					
									cityEntity.entities.add({
										polygon: {
											hierarchy: polygon,
											// outlineWidth: 1/window.devicePixelRatio,
											material: new Cesium.Color(255 / 255, 0 / 255, 0 / 255,
												0),
											outline: true,
											height: 20000,
											outlineWidth: 5 / window.devicePixelRatio,
											outlineColor: new Cesium.Color(170 / 255, 170 / 255,
												170 / 255, 1)
										}
									})
									var position = new Cesium.Cartesian3.fromDegrees(geometrys[i].properties.Center_X,
										geometrys[i].properties.Center_Y, 500);
									cityEntity.entities.add({
										// id: name,
										position: position,
										label: {
											text: geometrys[i].properties.name,
											outlineWidth: 3,
											style: Cesium.LabelStyle.FILL_AND_OUTLINE,
											fillColor: new Cesium.Color(255 / 255, 255 / 255, 255 /
												255, 0.9),
											outlineColor: new Cesium.Color(0 / 255, 18 / 255, 4 /
												255, 1.0),
											disableDepthTestDistance: Number.POSITIVE_INFINITY,
											font: 14 - Math.pow(window.devicePixelRatio, 2) +
												'px Arial bold',
											pixelOffset: new window.Cesium.Cartesian2(15 * name
												.length + 15, 0)
										}
									})
								}
								viewer.flyTo(cityEntity, {
									duration: 1.5,
									offset: {
										heading: 0.04200358377266422, // 以弧度为单位的航向角。
										pitch: -0.6718486685836051, // 以弧度为单位的俯仰角。
										range: 0 // 到中心的距离,以米为单位。								
									}
								});
					
							}
						});
					
					} else {
						provinceEntity.show = true;
						cityEntity.show = false;
						$("#echarts").show();
					}
				},Cesium.ScreenSpaceEventType.LEFT_CLICK)

四、示例完整代码

示例完整代码如下:

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
		<meta name="viewport"
			content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
		<title>四川省蓝色风格影像地图</title>
		<link href="../../Build/Cesium/Widgets/widgets.css" rel="stylesheet">
		<link href="./css/pretty.css" rel="stylesheet">
		<script type="text/javascript" src="./js/bubble/popup.js"></script>
		<script src="./js/jquery.min.js"></script>
		<script src="./js/config.js"></script>
		<script src="./js/echarts.min.js"></script>
		<script src="./js/EchartsLayer.js"></script>
		<script type="text/javascript" src="../../Build/Cesium/Cesium.js"></script>
		<style>
			#test3 .divpoint {
				background: url(./images/qipao2.png) no-repeat;
				background-size: cover;
				width: 230px;
				height: 150px;
			}

			#test3 .label-wrap {
				padding-left: 100px;
				padding-top: 8px;
				box-sizing: border-box;
			}

			#test3 .data-li {
				font-size: 14px;
				margin-top: 6px;
			}

			.sm-div-graphic {
				position: absolute;
				color: #fff;
				font-size: 14px;
			}
		</style>
	</head>
	<body>
		<div id="cesiumContainer">
		</div>
		<div id='loadingbar' class="spinner">
			<div class="spinner-container container1">
				<div class="circle1"></div>
				<div class="circle2"></div>
				<div class="circle3"></div>
				<div class="circle4"></div>
			</div>
			<div class="spinner-container container2">
				<div class="circle1"></div>
				<div class="circle2"></div>
				<div class="circle3"></div>
				<div class="circle4"></div>
			</div>
			<div class="spinner-container container3">
				<div class="circle1"></div>
				<div class="circle2"></div>
				<div class="circle3"></div>
				<div class="circle4"></div>
			</div>
		</div>
		<!-- <div id="test3" class="sm-div-graphic" style="pointer-events: all; display: block;  z-index: 8920788;">
			<div class="divpoint divpoint-theme-29baf1">
				<div class="label-wrap">
					<div id="name" class="pop-title">移动的弹窗</div>
					<div class="label-content">
						<div class="data-li">
							<div id="renkou" class="data-label">速度:10km/h</div>
						</div>
						<div class="data-li">
							<div id="gdp" class="data-label">目的地:xxxx</div>
						</div>
					</div>
				</div>
			</div>
		</div> -->
		<script type="text/javascript">
			function onload(Cesium) {
				var sichuanGDP = {};
				//初始化viewer部件,并添加天地图服务
				var xres = parseInt(window.screen.width * window.devicePixelRatio);
				var yres = parseInt(window.screen.height * window.devicePixelRatio);
				viewer = new Cesium.Viewer('cesiumContainer', {
					baseLayerPicker: false,
					orderIndependentTranslucency: false,
					shouldAnimate: true,
					infoBox: false,
					contextOptions: {
						webgl: {
							alpha: true
						},
						maxDrawingBufferWidth: xres,
						maxDrawingBufferHeight: yres
					},
				});
				var provinceEntity = new window.Cesium.CustomDataSource("provinceEntity");
				viewer.dataSources.add(provinceEntity);
				var cityEntity = new window.Cesium.CustomDataSource("cityEntity");
				viewer.dataSources.add(cityEntity);
				cityEntity.show = false;
				var echartsLayer;
				viewer.imageryLayers.addImageryProvider(new Cesium.SingleTileImageryProvider({
					url: './images/cbg/world06.jpg',
				}));
				viewer.resolutionScale = window.devicePixelRatio;
				viewer.useBrowserRecommendedResolution = true;
				viewer.scene.globe.depthTestAgainstTerrain = false;
				viewer.scene.terrainProvider.isCreateSkirt = false;
				var scene = viewer.scene;
				scene.screenSpaceCameraController.zoomFactor = 5.0;
				scene.lightSource.ambientLightColor = new Cesium.Color(0.5, 0.5, 0.5, 1);
				var widget = viewer.cesiumWidget;
				$('#loadingbar').remove();
				try {
					var promise = viewer.scene.open("http://localhost:8090/iserver/services/3D-sichuanblue/rest/realspace")

				} catch (e) {
					if (widget._showRenderLoopErrors) {
						var title = '渲染时发生错误,已停止渲染。';
						widget.showErrorPanel(title, undefined, e);
					}
				}
				$.ajax({
					url: './images/cbg/sichuanfenjie4326.json',
					success: function(data) {
						var geometrys = data.features;
						for (var i = 0; i < geometrys.length; i++) {
							var geometry = geometrys[i].geometry;
							var coordinates = geometry.coordinates;
							var pipeLinePts = [];
							for (var j = 0; j < coordinates.length; j++) {
								var convertPos = new Cesium.Cartesian3.fromDegrees(coordinates[j][0], coordinates[j][
									1
								], 500);
								pipeLinePts.push(convertPos);
							}
							provinceEntity.entities.add({
								polyline: {
									positions: pipeLinePts,
									width: 2 / window.devicePixelRatio,
									material: new Cesium.Color(94 / 255, 213 / 255, 245 / 255, 0.5),
									arcType: Cesium.ArcType.RHUMB,
									clampToGround: true
								}
							})
						}
					}
				});
				$.ajax({
					url: './images/cbg/sichuanbounds4326.json',
					success: function(data) {
						var geometrys = data.features;
						for (var i = 0; i < geometrys.length; i++) {
							var geometry = geometrys[i].geometry;
							var coordinates = geometry.coordinates;
							var pipeLinePts = [];
							for (var j = 0; j < coordinates.length; j++) {

								var convertPos = new Cesium.Cartesian3.fromDegrees(coordinates[j][0], coordinates[j][
									1
								], 500);
								pipeLinePts.push(convertPos);
							}
							provinceEntity.entities.add({
								polyline: {
									positions: pipeLinePts,
									width: 2.5,
									material: new Cesium.Color(94 / 255, 213 / 255, 245 / 255, 1)
								}
							})
						}
					}
				});
				var position = new Cesium.Cartesian3.fromDegrees(109.40543308511627, 26.993328925156895, -50000);


				var targetPosition = new Cesium.Cartesian3.fromDegrees(101.98226836938083, 24.519626362055106, -50000);


				var options_n = {
					targetPosition: targetPosition,
					color: new Cesium.Color(255 / 255, 255 / 255, 255 / 255, 1),
					intensity: 3,
				};
				var directionalLight_n = new Cesium.DirectionalLight(position, options_n);
				// viewer.scene.addLightSource(directionalLight_n);
				addPOIeChart();

				function addPOIeChart() {
					var data = [];
					var geoCoordMap = {};
					$.ajax({
						url: './images/cbg/sichuan_city_name_P_2.json',
						success: function(datas) {
							let realtimeDataEntities = []
							var geometrys = datas.features;
							for (var i = 0; i < geometrys.length; i++) {
								var geometry = geometrys[i].geometry;
								var coordinates = geometry.coordinates;
								var name = geometrys[i].properties.name;
								if (name.length > 4) {
									var tempname = "";
									for (var k = 0; k < name.length; k++) {
										tempname = tempname + name[k] + "\n"
									}
									name = tempname;
								}
								var level = Number(geometrys[i].properties.level) - 1;

								data.push({
									'name': name,
									'value': 220 + level * 150
								})
								geoCoordMap[name] = [coordinates[0], coordinates[1]];;
								var convertposition = new Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[
									1], 500);
								sichuanGDP[geometrys[i].properties.UserID] = {
									"coordinates": convertposition,
									"name": geometrys[i].properties.name2,
									"renkou": geometrys[i].properties.renkou,
									"gdp": geometrys[i].properties.gdp,

								}
								provinceEntity.entities.add({
									// id: name,
									position: convertposition,
									label: {
										text: name,
										outlineWidth: 3,
										style: Cesium.LabelStyle.FILL_AND_OUTLINE,
										fillColor: name === "成都市" ? new Cesium.Color(240 / 255, 255 / 255,
											0 /
											255, 1) : new Cesium.Color(255 / 255, 255 / 255, 255 / 255,
											0.9),
										outlineColor: name === "成都市" ? new Cesium.Color(0 / 255, 18 / 255,
											4 /
											255, 1) : new Cesium.Color(79 / 255, 128 / 255, 169 / 255,
											0.9),
										disableDepthTestDistance: Number.POSITIVE_INFINITY,
										font: 14 + level * 8 - Math.pow(window.devicePixelRatio, 2) +
											'px Arial bold',
										pixelOffset: name.length > 4 ? new window.Cesium.Cartesian2(-25, 0) :
											new window.Cesium.Cartesian2(40 + level * 15, 0)
									}
								})


							}
							const convertData = function(data) {
								const res = [];
								for (let i = 0; i < data.length; i++) {
									const geoCoord = geoCoordMap[data[i].name];
									if (geoCoord) {
										res.push({
											name: data[i].name,
											value: geoCoord.concat(data[i].value)
										});
									}
								}
								return res;
							};
							const options = {
								animation: !1,
								GLMap: {},
								series: [{
									name: '前5',
									type: 'effectScatter',
									coordinateSystem: 'GLMap',
									data: convertData(data.sort(function(a, b) {
										return b.value - a.value;
									}).slice(0, 50)),
									symbolSize: function(val) {
										return val[2] / 20;
									},
									showEffectOn: 'render',
									rippleEffect: {
										brushType: 'stroke',
										period: 1.5,
										scale: 3.5
									},
									hoverAnimation: true,
									itemStyle: {
										normal: {
											color: '#FFFFFF',
											shadowBlur: 20,
											shadowColor: '#333'
										}
									},
									zlevel: 1
								}]
							};
							echartsLayer = new EchartsLayer(viewer);
							echartsLayer.chart.setOption(options);
						}
					});
				}
				let handlerPoint = new Cesium.ScreenSpaceEventHandler(window.viewer.scene.canvas);
				handlerPoint.setInputAction(function(event){
					viewer.entities.removeById("selectedId");
					
					var layertop = scene.layers.find('sichuan432602');
					var selection = layertop.getSelection();
					if (selection.length > 0) {
						var selectedId = Number(selection[selection.length - 1]);
						// layertop.setObjsVisible([selectedId], true)
						provinceEntity.show = false;
						$("#echarts").hide();
						cityEntity.entities.removeAll();
						cityEntity.show = true;
						layertop.releaseSelection();
						$.ajax({
							url: './images/cbg/sichuancitys4326.json',
							success: function(data) {
								var geometrys = data.features;
								for (var i = 0; i < geometrys.length; i++) {
									if (geometrys[i].properties.cityid != selectedId) {
										continue;
									}
									var geometry = geometrys[i].geometry;
									var coordinates = geometry.coordinates;
									var pipeLinePts = [];
									var polygon;
									if (geometry.type == "MultiLineString") {
										debugger;
									} else {
										for (var j = 0; j < coordinates[0].length; j++) {
											
											var pos = new Cesium.Cartesian3.fromDegrees(Number(coordinates[0][j][0]),
												Number(coordinates[0][j][1]), 20000);
											pipeLinePts.push(pos);
					
										}
										polygon = new Cesium.PolygonHierarchy(pipeLinePts)
									}
					
									cityEntity.entities.add({
										polygon: {
											hierarchy: polygon,
											// outlineWidth: 1/window.devicePixelRatio,
											material: new Cesium.Color(255 / 255, 0 / 255, 0 / 255,
												0),
											outline: true,
											height: 20000,
											outlineWidth: 5 / window.devicePixelRatio,
											outlineColor: new Cesium.Color(170 / 255, 170 / 255,
												170 / 255, 1)
										}
									})
									var position = new Cesium.Cartesian3.fromDegrees(geometrys[i].properties.Center_X,
										geometrys[i].properties.Center_Y, 500);
									cityEntity.entities.add({
										// id: name,
										position: position,
										label: {
											text: geometrys[i].properties.name,
											outlineWidth: 3,
											style: Cesium.LabelStyle.FILL_AND_OUTLINE,
											fillColor: new Cesium.Color(255 / 255, 255 / 255, 255 /
												255, 0.9),
											outlineColor: new Cesium.Color(0 / 255, 18 / 255, 4 /
												255, 1.0),
											disableDepthTestDistance: Number.POSITIVE_INFINITY,
											font: 14 - Math.pow(window.devicePixelRatio, 2) +
												'px Arial bold',
											pixelOffset: new window.Cesium.Cartesian2(15 * name
												.length + 15, 0)
										}
									})
								}
								viewer.flyTo(cityEntity, {
									duration: 1.5,
									offset: {
										heading: 0.04200358377266422, // 以弧度为单位的航向角。
										pitch: -0.6718486685836051, // 以弧度为单位的俯仰角。
										range: 0 // 到中心的距离,以米为单位。								
									}
								});
					
							}
						});
					
					} else {
						provinceEntity.show = true;
						cityEntity.show = false;
						$("#echarts").show();
					}
				},Cesium.ScreenSpaceEventType.LEFT_CLICK)
				
				
				var offsetList = {};
				handlerPoint.setInputAction(function(event) {
					var result = viewer.scene.pick(event.endPosition)
					var layertop = scene.layers.find('sichuan432602');
					var selection = layertop.getSelection();
					if (selection.length > 0) {			
						var selectedId = Number(selection[selection.length - 1]);
						if (!offsetList[selectedId]) {
							offsetList[selectedId] = {
								"isoffset": true,
								"offsetZ": 0
							};
						} else {
							for (let key in offsetList) {
								offsetList[key].isoffset = false;
							}
							offsetList[selectedId].isoffset = true;
						}
					} else {
						for (let key in offsetList) {
							offsetList[key].isoffset = false;
						}
					}
				}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
				setInterval(function() {
					var layertop = scene.layers.find('sichuan432602');
					for (let key in offsetList) {
						if (offsetList[key].isoffset) {
							if (offsetList[key].offsetZ < 20000) {
								offsetList[key].offsetZ = offsetList[key].offsetZ + 1000;
								layertop.setObjsTranslate([key], new Cesium.Cartesian3(0, 0, offsetList[key].offsetZ))
							}


						} else {
							if (offsetList[key].offsetZ > 0) {
								offsetList[key].offsetZ = offsetList[key].offsetZ - 500;
								layertop.setObjsTranslate([key], new Cesium.Cartesian3(0, 0, offsetList[key].offsetZ))
							}
						}
					}

				}, 20)

			}
			if (typeof Cesium !== 'undefined') {
				window.startupCalled = true;
				onload(Cesium);
			}
		</script>
	</body>
</html>


http://www.kler.cn/a/506669.html

相关文章:

  • 《Keras 3 在 TPU 上的肺炎分类》
  • “扣子”开发之四:与千帆AppBuilder比较
  • 2Spark Core
  • 【学习笔记】Macbook管理多个不同的Python版本
  • LabVIEW光流算法的应用
  • Js:正则表达式及正则表达式方法
  • 【Docker】使用Dev Container进行开发
  • HTML 中的 Window 和 Document 介绍
  • 【Uniapp-Vue3】manifest.json配置
  • 前后端分离开发心得
  • 十分钟带汝入门大数据开发语言Scala
  • 序列化和反序列化 Json 字符串 @JSONField
  • XML在线格式化 - 加菲工具
  • Flurl:一个Star 3.9K的链式RESTful风格HTTP开源.Net库
  • 【Linux】13.Linux进程概念(2)
  • OSPF的LSA的学习研究
  • leetcode 3095. 或值至少 K 的最短子数组 I
  • PHP xml 常用函数整理
  • Web前端------HTML表格
  • ThinkPHP 8的一对一关联
  • centos安装golang
  • javascript基础从小白到高手系列一:使用cookie 的注意事项
  • 【编译构建】用cmake编译libjpeg动态库并实现转灰度图片
  • AST抽象语法树
  • Vue 和 uniApp 中 CSS 样式差别
  • Dart语言的多线程编程