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

SuperMap iClient3D for WebGL选中抬升特效

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

立体地图选中+下钻特效

一、数据制作

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

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

二、实现思路

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

点击显示行政区效果的实现思路如下图所示

三、关键代码

数据抬升关键代码如下:

handlerPoint.setInputAction(function(event) {
				var result = viewer.scene.pick(event.endPosition)
				
				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;
					}
				}
			}, SuperMap3D.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 SuperMap3D.Cartesian3(0, 0, offsetList[key].offsetZ))
						}
			
			
					} else {
						if (offsetList[key].offsetZ > 0) {
							offsetList[key].offsetZ = offsetList[key].offsetZ - 500;
							layertop.setObjsTranslate([key], new SuperMap3D.Cartesian3(0, 0, offsetList[key].offsetZ))
						}
					}
				}
			
			}, 20)

点击显示行政区关键代码如下:

let handlerPoint = new SuperMap3D.ScreenSpaceEventHandler(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]);
					provinceEntity.show = false;
					$("#echarts").hide();
					cityEntity.entities.removeAll();
					cityEntity.show = true;
					layertop.releaseSelection();
					$.ajax({
						url: './data/sichuan/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 == "MultiPolygon") {
									coordinates=geometry.coordinates[0];
								} else {
									for (var j = 0; j < coordinates[0].length; j++) {
										
										var pos = new SuperMap3D.Cartesian3.fromDegrees(Number(coordinates[0][j][0]),
											Number(coordinates[0][j][1]), 20000);
										pipeLinePts.push(pos);
				
									}
									polygon = new SuperMap3D.PolygonHierarchy(pipeLinePts)
								}
				
								cityEntity.entities.add({
									polygon: {
										hierarchy: polygon,
										// outlineWidth: 1/window.devicePixelRatio,
										material: new SuperMap3D.Color(255 / 255, 0 / 255, 0 / 255,
											0),
										outline: true,
										height: 20000,
										outlineWidth: 5 / window.devicePixelRatio,
										outlineColor: new SuperMap3D.Color(170 / 255, 170 / 255,
											170 / 255, 1)
									}
								})
								var position = new SuperMap3D.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: SuperMap3D.LabelStyle.FILL_AND_OUTLINE,
										fillColor: new SuperMap3D.Color(255 / 255, 255 / 255, 255 /
											255, 0.9),
										outlineColor: new SuperMap3D.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.SuperMap3D.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();
				}
			},SuperMap3D.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/SuperMap3D/Widgets/widgets.css" rel="stylesheet">
    <link href="./css/pretty.css" rel="stylesheet">
    <link href="./style/S3MTiles_suofeiya.css" rel="stylesheet">
    <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 src="./js/slider.js"></script>
    <script type="text/javascript" src="../../Build/SuperMap3D/SuperMap3D.js"></script>
</head>
<body>
<div id="Container"></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>
<script type="text/javascript">
    function onload(SuperMap3D) {
        // 通过config.js中的getEngineType,获取引擎类型(EngineType)用于设置启动方式
        var EngineType = getEngineType();
		var xres = parseInt(window.screen.width * window.devicePixelRatio);
		var yres = parseInt(window.screen.height * window.devicePixelRatio);
        var viewer = new SuperMap3D.Viewer('Container', {
			baseLayerPicker: false,
			orderIndependentTranslucency: false,
			shouldAnimate: true,
			infoBox: false,
            contextOptions: {
                contextType: Number(EngineType), // Webgl2:2 ; WebGPU:3
				webgl: {
					alpha: true
				},
				maxDrawingBufferWidth: xres,
				maxDrawingBufferHeight: yres
            }
        });

        viewer.scenePromise.then(function(scene){
            init(SuperMap3D, scene, viewer);
        });
    }

    function init(SuperMap3D, scene, viewer) {
		var sichuanGDP = {};
        var provinceEntity = new window.SuperMap3D.CustomDataSource("provinceEntity");
        viewer.dataSources.add(provinceEntity);
        var cityEntity = new window.SuperMap3D.CustomDataSource("cityEntity");
        viewer.dataSources.add(cityEntity);
        cityEntity.show = false;
        var echartsLayer;
        viewer.imageryLayers.addImageryProvider(new SuperMap3D.SingleTileImageryProvider({
        	url: './images/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 SuperMap3D.Color(0.5, 0.5, 0.5, 1);
        var widget = viewer.cesiumWidget;

        try{
           var promise = scene.open("http://localhost:8090/iserver/services/3D-sichuanblue/rest/realspace");
		   var layertop
            SuperMap3D.when(promise,function(layers){
				layertop = scene.layers.find('sichuan432602');
            },function(){
                var title = '加载SCP失败,请检查网络连接状态或者url地址是否正确?';
                widget.showErrorPanel(title, undefined, e);
            });
			$.ajax({
				url: './data/sichuan/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 SuperMap3D.Cartesian3.fromDegrees(coordinates[j][0], coordinates[j][
								1
							], 500);
							pipeLinePts.push(convertPos);
						}
						provinceEntity.entities.add({
							polyline: {
								positions: pipeLinePts,
								width: 2 / window.devicePixelRatio,
								material: new SuperMap3D.Color(94 / 255, 213 / 255, 245 / 255, 0.5),
								arcType: SuperMap3D.ArcType.RHUMB,
								clampToGround: true
							}
						})
					}
				}
			});
			$.ajax({
				url: './data/sichuan/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 SuperMap3D.Cartesian3.fromDegrees(coordinates[j][0], coordinates[j][
								1
							], 500);
							pipeLinePts.push(convertPos);
						}
						provinceEntity.entities.add({
							polyline: {
								positions: pipeLinePts,
								width: 2.5,
								material: new SuperMap3D.Color(94 / 255, 213 / 255, 245 / 255, 1)
							}
						})
					}
				}
			});
			var position = new SuperMap3D.Cartesian3.fromDegrees(109.40543308511627, 26.993328925156895, -50000);
			
			
			var targetPosition = new SuperMap3D.Cartesian3.fromDegrees(101.98226836938083, 24.519626362055106, -50000);
			
			
			var options_n = {
				targetPosition: targetPosition,
				color: new SuperMap3D.Color(255 / 255, 255 / 255, 255 / 255, 1),
				intensity: 3,
			};
			var directionalLight_n = new SuperMap3D.DirectionalLight(position, options_n);
			addPOIeChart();
			function addPOIeChart() {
				var data = [];
				var geoCoordMap = {};
				$.ajax({
					url: './data/sichuan/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 SuperMap3D.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: SuperMap3D.LabelStyle.FILL_AND_OUTLINE,
									fillColor: name === "成都市" ? new SuperMap3D.Color(240 / 255, 255 / 255,
										0 /
										255, 1) : new SuperMap3D.Color(255 / 255, 255 / 255, 255 / 255,
										0.9),
									outlineColor: name === "成都市" ? new SuperMap3D.Color(0 / 255, 18 / 255,
										4 /
										255, 1) : new SuperMap3D.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.SuperMap3D.Cartesian2(-25, 0) :
										new window.SuperMap3D.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 SuperMap3D.ScreenSpaceEventHandler(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]);
					provinceEntity.show = false;
					$("#echarts").hide();
					cityEntity.entities.removeAll();
					cityEntity.show = true;
					layertop.releaseSelection();
					$.ajax({
						url: './data/sichuan/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 == "MultiPolygon") {
									coordinates=geometry.coordinates[0];
								} else {
									for (var j = 0; j < coordinates[0].length; j++) {
										
										var pos = new SuperMap3D.Cartesian3.fromDegrees(Number(coordinates[0][j][0]),
											Number(coordinates[0][j][1]), 20000);
										pipeLinePts.push(pos);
				
									}
									polygon = new SuperMap3D.PolygonHierarchy(pipeLinePts)
								}
				
								cityEntity.entities.add({
									polygon: {
										hierarchy: polygon,
										// outlineWidth: 1/window.devicePixelRatio,
										material: new SuperMap3D.Color(255 / 255, 0 / 255, 0 / 255,
											0),
										outline: true,
										height: 20000,
										outlineWidth: 5 / window.devicePixelRatio,
										outlineColor: new SuperMap3D.Color(170 / 255, 170 / 255,
											170 / 255, 1)
									}
								})
								var position = new SuperMap3D.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: SuperMap3D.LabelStyle.FILL_AND_OUTLINE,
										fillColor: new SuperMap3D.Color(255 / 255, 255 / 255, 255 /
											255, 0.9),
										outlineColor: new SuperMap3D.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.SuperMap3D.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();
				}
			},SuperMap3D.ScreenSpaceEventType.LEFT_CLICK)
			
			var offsetList = {};
			handlerPoint.setInputAction(function(event) {
				var result = viewer.scene.pick(event.endPosition)
				
				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;
					}
				}
			}, SuperMap3D.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 SuperMap3D.Cartesian3(0, 0, offsetList[key].offsetZ))
						}
			
			
					} else {
						if (offsetList[key].offsetZ > 0) {
							offsetList[key].offsetZ = offsetList[key].offsetZ - 500;
							layertop.setObjsTranslate([key], new SuperMap3D.Cartesian3(0, 0, offsetList[key].offsetZ))
						}
					}
				}
			
			}, 20)
        }
        catch(e){
            if (widget._showRenderLoopErrors) {
                var title = '渲染时发生错误,已停止渲染。';
                widget.showErrorPanel(title, undefined, e);
            }
        }
        $('#loadingbar').remove();
    }
    if (typeof SuperMap3D !== 'undefined') {
        window.startupCalled = true;
        onload(SuperMap3D);
    }
    </script>
</body>
</html>


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

相关文章:

  • QLineEdit 在文本发生变更时触发事件几种方式详细说明
  • Java 多态/向下转型/instanceof
  • SSM课设-学生管理系统
  • 数字艺术类专业人才供需数据获取和分析研究
  • 【k8s面试题2025】1、练气期
  • 解决 多层跳板机情况下,ssh可以成功连但是VSCode失败
  • oracle之行转列
  • 亲测有效!如何快速实现 PostgreSQL 数据迁移到 时序数据库TDengine
  • vue3+three.js加载glb模型
  • 基于SpringBoot + Mybatis Plus + SaToken + Thymeleaf + Layui的后台管理系统
  • Python基于Django的社区爱心养老管理系统设计与实现【附源码】
  • Cyber Security 101-Security Solutions-Firewall Fundamentals(防火墙基础)
  • Java Web开发高级——Spring Boot与Docker容器化部署
  • 电子电气架构 --- 车载通信诊断
  • 【开源免费】基于SpringBoot+Vue.JS密接者跟踪系统(JAVA毕业设计)
  • 大语言模型增强推荐系统:分类、趋势、应用与未来
  • c# PDF文件合并工具
  • python milvus及curl命令进行query请求
  • Java工程结构:服务器规约(JVM 碰到 OOM 场景时输出 dump 信息、设置tomcat的 JVM 的内存参数、了解服务平均耗时)
  • STM32更新程序OTA
  • 为AI聊天工具添加一个知识系统 之54 为事务处理 设计 基于DDD的一个 AI操作系统 来处理维度
  • npm配置electron专属的淘宝镜像进行安装
  • 2、ansible的playbook
  • MongoDB文档查询
  • PyTorch使用教程(11)-cuda的使用方法
  • Skeleton 骨架屏