htmledit_views">
在大屏展示系统中,对行政区划数据制作了立体效果,如果希望选中某一行政区划进行重点介绍,目前常见的方式是通过修改选中对象色彩、边线等方式进行实现;这里提供另外一种偏移动效的思路,并提供下钻功能,让地图选中效果更加炫酷,一起开看看如何实现吧!
立体地图选中+下钻特效
一、数据制作
对于上述视频中的立体地图制作,此处不做讲述,如有需要可访问: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>