const Nightscape = { GeoJsonLayerList: [], liudongGntities: [], routesGroupByAirline: {}, tiyuchangdg: [], tiyuchangdg1: [], tiyuchangdg2: [], tiyuchangdg3: [], dgdsq: null, tycindex: 0, t: 0, //打开夜景 openNightSwitch() { store.state.isNightSwitch = true; this.startNight(true); }, closNightSwitch() { store.state.isNightSwitch = false; this.startNight(false); }, //夜景开关 startNight(isNight) { let that = this; scene.globe.show = true; viewer.scene.hdrEnabled = isNight; viewer.scene.bloomEffect.show = false; // 是否开启夜景 if (!isNight) { if (this.dgdsq) { clearTimeout(this.dgdsq); } if (scene.layers.find("白天")) scene.layers.find("白天").visible = true; if (scene.layers.find("夜晚")) scene.layers.find("夜晚").visible = false; scene.sun.show = true; this.clearLightSource(true, true); scene.skyAtmosphere.show = true; this.switchLight(true); //白天 this.setHypsometric(false); //夜景材质 viewer.imageryLayers.remove(this.imageLayer); } else { scene.sun.show = false; if (scene.layers.find("白天")) scene.layers.find("白天").visible = false; if (scene.layers.find("夜晚")) scene.layers.find("夜晚").visible = true; // 泛光线底纹 let roadLine1 = Cesium.GeoJsonDataSource.load(window.NightLightUrl.csfgx); roadLine1 .then(function (dataSource) { viewer.dataSources.add(dataSource); that.GeoJsonLayerList.push(dataSource); let lines_1 = dataSource.entities.values; for (let i = 0; i < lines_1.length; i++) { let line = lines_1[i]; line.polyline.material = new Cesium.PolylineGlowMaterialProperty({ //设置Glow材质 glowPower: 0.005, color: Cesium.Color.ORANGE.withAlpha(0.9), }); line.polyline.width = 50; } }) .otherwise(function (error) { window.alert(error); }); let roadLine2 = Cesium.GeoJsonDataSource.load(window.NightLightUrl.csfgx); //泛光亮线 roadLine2 .then(function (dataSource) { viewer.dataSources.add(dataSource); that.GeoJsonLayerList.push(dataSource); let lines_1 = dataSource.entities.values; for (let i = 0; i < lines_1.length; i++) { let line = lines_1[i]; line.polyline.material = new Cesium.PolylineGlowMaterialProperty({ //设置Glow材质 glowPower: 0.001, color: Cesium.Color.white, }); line.polyline.width = 5; } }) .otherwise(function (error) { window.alert(error); }); //地标灯光 Cesium.loadJson(window.NightLightUrl.yshdg).then((response) => { let features = response.features; features.forEach((element) => { let p = element.geometry.coordinates; var SpotLightPos3 = new Cesium.Cartesian3.fromDegrees( p[0], p[1], p[2] + 20 ); // var SpotLightPos32 = new Cesium.Cartesian3.fromDegrees( // p[0], // p[1], // p[2] // ); var SpotLightOptions3 = { cutoffDistance: 100, color: new Cesium.Color(18 / 255, 80 / 255, 193 / 255, 1), decay: 2, intensity: 1, }; let SpotLight33 = new Cesium.PointLight( SpotLightPos3, // SpotLightPos32, SpotLightOptions3 ); scene.addLightSource(SpotLight33); }); }); // 体育场灯光 Cesium.loadJson(window.NightLightUrl.tycdg).then((response) => { let features = response.features; features.forEach((element, indx) => { let p = element.geometry.coordinates; var SpotLightPos3 = new Cesium.Cartesian3.fromDegrees( p[0], p[1], p[2] + 10 ); var SpotLightOptions3 = { cutoffDistance: 150, color: new Cesium.Color(245 / 255, 250 / 255, 216 / 255, 0.51), decay: 1, intensity: 1, }; let SpotLight33 = new Cesium.PointLight( SpotLightPos3, // SpotLightPos32, SpotLightOptions3 ); that.tiyuchangdg.push(SpotLight33); scene.addLightSource(SpotLight33); }); let sd = that.splitArray(that.tiyuchangdg); that.tiyuchangdg1 = sd[0]; that.tiyuchangdg2 = sd[1]; that.tiyuchangdg3 = sd[2]; }); // // 道路灯光 Cesium.loadJson(window.NightLightUrl.dldg).then((response) => { let features = response.features; features.forEach((element) => { let p = element.geometry.coordinates; var SpotLightPos3 = new Cesium.Cartesian3.fromDegrees( p[0], p[1], p[2] + 40 ); var SpotLightOptions3 = { cutoffDistance: 130, color: new Cesium.Color(209 / 255, 209 / 255, 147 / 255, 0.5), decay: 1, intensity: 1, }; let SpotLight33 = new Cesium.PointLight( SpotLightPos3, // SpotLightPos32, SpotLightOptions3 ); scene.addLightSource(SpotLight33); }); }); // 草坪灯光 Cesium.loadJson(window.NightLightUrl.cpdg).then((response) => { let features = response.features; features.forEach((element) => { let p = element.geometry.coordinates; var SpotLightPos3 = new Cesium.Cartesian3.fromDegrees( p[0], p[1], p[2] + 20 ); var SpotLightOptions3 = { cutoffDistance: 90, color: new Cesium.Color(209 / 255, 209 / 255, 147 / 255, 1), decay: 1, intensity: 1, }; let SpotLight33 = new Cesium.PointLight( SpotLightPos3, // SpotLightPos32, SpotLightOptions3 ); scene.addLightSource(SpotLight33); }); }); this.loadldx(); this.switchLight(false); scene.skyAtmosphere.show = false; this.setHypsometric(true); //夜景 this.imageLayer = viewer.imageryLayers.addImageryProvider( new Cesium.SingleTileImageryProvider({ url: "static/images/zt/Nightscape/BlackMarble_2016-1.jpg", }) ); this.imageLayer.alpha = 0.5; if (this.dgdsq) { clearTimeout(dgdsq); } this.dgdsq = setInterval(function () { that.tycindex += 1; that.t += 0.2; if (that.t > 1) { that.t = 0; } let rgb = that.lerpColor("5,33,232", "232,222,5", that.t); let isch = false; if (that.tiyuchangdg1.length > that.tycindex) { that.tiyuchangdg1[that.tycindex].color = new Cesium.Color( rgb.r / 255, rgb.g / 255, rgb.b / 255, 0.51 ); isch = true; } if (that.tiyuchangdg2.length > that.tycindex) { that.tiyuchangdg2[that.tycindex].color = new Cesium.Color( rgb.r / 255, rgb.g / 255, rgb.b / 255, 0.51 ); isch = true; } if (that.tiyuchangdg3.length > that.tycindex) { that.tiyuchangdg3[that.tycindex].color = new Cesium.Color( rgb.r / 255, rgb.g / 255, rgb.b / 255, 0.51 ); isch = true; } if (!isch) { that.tycindex = 0; } }, 1000 * 1); } }, //设置环境光 switchLight(isDayLight) { if (isDayLight) { //设置环境光(白天) scene.lightSource.ambientLightColor = new Cesium.Color( 0.65, 0.65, 0.65, 1 ); } else { //设置环境光(夜晚) // scene.lightSource.ambientLightColor = new Cesium.Color(0.3, 0.3, 0.3, 1); // 添加光源 // this.addLightSource({ // gyType: "点光源", // cartesian: new Cesium.Cartesian3.fromDegrees( // 109.51762123055649, // 18.308419781897452, // 20.784050116021502 // ), // gyDecay: 5, // gyDistance: 300, // gyColor: "rgba(255,255,255,1)", // gyIntensity: 5, // }); // this.addLightSource({ // gyType: "点光源", // cartesian: new Cesium.Cartesian3.fromDegrees( // 109.51604504373526, // 18.30819674716975, // 15.12013402227458 // ), // gyDecay: 1, // gyDistance: 200, // gyColor: "rgba(255,255,255,1)", // gyIntensity: 2, // }); // this.addLightSource({ // gyType: "点光源", // cartesian: new Cesium.Cartesian3.fromDegrees( // 109.51119765783854, // 18.311007882958762, // 15.514382420330742 // ), // gyDecay: 1, // gyDistance: 200, // gyColor: "rgba(255,255,255,1)", // gyIntensity: 2, // }); // this.addLightSource({ // gyType: "点光源", // cartesian: new Cesium.Cartesian3.fromDegrees( // 109.5109719906024, // 18.312138464239744, // 15.514382420330742 // ), // gyDecay: 1, // gyDistance: 200, // gyColor: "rgba(255,255,255,1)", // gyIntensity: 2, // }); // this.addLightSource({ // gyType: "点光源", // cartesian: new Cesium.Cartesian3.fromDegrees( // 109.5155257151904, // 18.312710967602822, // 15.0056539031313925 // ), // gyDecay: 1, // gyDistance: 200, // gyColor: "rgba(255,255,255,1)", // gyIntensity: 2, // }); // this.addLightSource({ // gyType: "点光源", // cartesian: new Cesium.Cartesian3.fromDegrees( // 109.51794125594411, // 18.310599330540743, // 14.172257598338254 // ), // gyDecay: 1, // gyDistance: 200, // gyColor: "rgba(255,255,255,1)", // gyIntensity: 2, // }); //操场光源 this.addLightSource({ gyType: "点光源", cartesian: new Cesium.Cartesian3.fromDegrees( 109.51144104226398, 18.311654492261003, 24.172257598338254 ), gyDecay: 2, gyDistance: 200, gyColor: "rgba(255,255,255,1)", gyIntensity: 2, }); // 新增直射光1--西南侧光 var position = new Cesium.Cartesian3.fromDegrees( 108.64028472779978, 17.253899597841926, 10 ); var targetPosition1 = new Cesium.Cartesian3.fromDegrees( 108.98714556856183, 17.660729210061046, 10 ); var dirLightOptions = { targetPosition: targetPosition1, color: new Cesium.Color(220 / 255, 230 / 255, 240 / 255, 0.5), intensity: 1, }; this.directionalLight_1 && scene.removeLightSource(this.directionalLight_1); this.directionalLight_1 = new Cesium.DirectionalLight( position, dirLightOptions ); scene.addLightSource(this.directionalLight_1); //新增直射光1--东北侧光 var position3 = new Cesium.Cartesian3.fromDegrees( 110.1833740842942, 19.23480287256715, 10 ); var targetPosition3 = new Cesium.Cartesian3.fromDegrees( 109.92243671490641, 18.823627245617516, 10 ); var dirLightOptions3 = { targetPosition: targetPosition3, color: new Cesium.Color(220 / 255, 223 / 255, 227 / 255, 0.5), intensity: 1.5, }; this.directionalLight_3 && scene.removeLightSource(this.directionalLight_3); this.directionalLight_3 = new Cesium.DirectionalLight( position3, dirLightOptions3 ); scene.addLightSource(this.directionalLight_3); //新增直射光1--顶光 var position4 = new Cesium.Cartesian3.fromDegrees( 109.5264539133307, 18.2736162462657, 500 ); var targetPosition4 = new Cesium.Cartesian3.fromDegrees( 109.5264539133307, 18.2736162462657, 400 ); var dirLightOptions4 = { targetPosition: targetPosition4, color: Cesium.Color.SILVER.withAlpha(0.5), intensity: 0.1, }; this.directionalLight_4 && scene.removeLightSource(this.directionalLight_4); this.directionalLight_4 = new Cesium.DirectionalLight( position4, dirLightOptions4 ); scene.addLightSource(this.directionalLight_4); } }, //设置白膜自发光纹理 setHypsometric(isShow = true) { if (isShow) { scene.layers.layerQueue.forEach((layer) => { let hyp = null; let LayerName = window.NightViewLayerName.find((c) => c == layer.name); if (LayerName) { // 关掉边框线 layer.style3D.fillStyle = Cesium.FillStyle.Fill; hyp = new Cesium.HypsometricSetting(); hyp.emissionTextureArray = [ { url: "static/images/zt/Nightscape/Texture05.jpg", USpeed: 0.5, VSpeed: 0, UTiling: 1, VTiling: 1, }, { url: "static/images/zt/Nightscape/Texture01.jpg", USpeed: 0.5, VSpeed: 0, UTiling: 1, VTiling: 1, }, { url: "static/images/zt/Nightscape/build008.JPG", USpeed: 0, VSpeed: 0, UTiling: 1, VTiling: 3, }, { url: "static/images/zt/Nightscape/build129.JPG", USpeed: 0, VSpeed: 0, UTiling: 1, VTiling: 3, }, { url: "static/images/zt/Nightscape/build216.JPG", USpeed: 0, VSpeed: 0, UTiling: 1, VTiling: 3, }, // { // url: "static/images/zt/Nightscape/HighRiseNight0008_4_S.jpg", // USpeed: 0, // VSpeed: 0, // UTiling: 1, // VTiling: 1, // }, // { // url: "static/images/zt/Nightscape/HighRiseNight0016_3_L.jpg", // USpeed: 0, // VSpeed: 0, // UTiling: 1, // VTiling: 1, // }, // { // url: "static/images/zt/Nightscape/HighRiseNight0020_L.jpg", // USpeed: 0, // VSpeed: 0, // UTiling: 1, // VTiling: 1, // }, ]; layer.hypsometricSetting = { hypsometricSetting: hyp, }; } }); } else { scene.layers.layerQueue.forEach((layer) => { layer.hypsometricSetting = { hypsometricSetting: undefined, }; layer.style3D.fillStyle = Cesium.FillStyle.Fill; // 刷新场景 // layer.refresh(); }); } }, /** * 流动线 */ loadldx() { let that = this; Cesium.loadJson(window.NightLightUrl.dlzxx).then((jsonData) => { debugger; jsonData.features.forEach((route) => { let list = route.geometry.coordinates.flat(Infinity); debugger; let dl = viewer.entities.add({ // 用于打底的线 polyline: { positions: Cesium.Cartesian3.fromDegreesArrayHeights(list), width: 5, // 线的宽度,像素为单位 material: Cesium.Color.BLACK.withAlpha(0.3), }, }); this.liudongGntities.push(dl); let dls = viewer.entities.add({ id: route.properties.OBJECTID, polyline: { positions: Cesium.Cartesian3.fromDegreesArrayHeights(list), width: 4.0, material: new Cesium.PolylineTrailMaterialProperty({ outlineColor: Cesium.Color.WHITE, outlineWidth: 3, color: Cesium.Color.fromCssColorString("rgba(127, 255, 0, 1)"), trailLength: 0.3, period: 4.0, }), }, }); this.liudongGntities.push(dls); }); }); }, /** * 添加光源 * @param {} gyData */ addLightSource(gyData) { switch (gyData.gyType) { case "点光源": let option = { color: Cesium.Color.fromCssColorString(gyData.gyColor), cutoffDistance: Number(gyData.gyDistance), decay: Number(gyData.gyDecay), intensity: Number(gyData.gyIntensity), }; let pointLight = new Cesium.PointLight(gyData.cartesian, option); scene.addLightSource(pointLight); break; case "聚光灯": let spotLightOptions = { color: Cesium.Color.fromCssColorString(gyData.gyColor), distance: Number(gyData.gyDistance), decay: Number(gyData.gyDecay), intensity: Number(gyData.gyIntensity), angle: Cesium.Math.toRadians(Number(gyData.gyangle)), }; let spotLight = new Cesium.SpotLight( gyData.cartesian[0], gyData.cartesian[1], spotLightOptions ); scene.addLightSource(spotLight); break; case "直射光": let directionalLightOptions = { targetPosition: gyData.cartesian[1], color: Cesium.Color.fromCssColorString(gyData.gyColor), intensity: Number(gyData.gyIntensity), }; let directionalLight = new Cesium.DirectionalLight( gyData.cartesian[0], directionalLightOptions ); scene.addLightSource(directionalLight); break; default: break; } }, /** * 删除灯光 * @param isAllRemoveLightSource 是否删除所有灯光 */ clearLightSource(isAllRemoveLightSource = false) { if (isAllRemoveLightSource) { while (scene.lightSource.pointLight.values.length > 0) { scene.removeLightSource(scene.lightSource.pointLight.values[0]); } while (scene.lightSource.spotLight.values.length > 0) { scene.removeLightSource(scene.lightSource.spotLight.values[0]); } while (scene.lightSource.directionalLight.values.length > 0) { scene.removeLightSource(scene.lightSource.directionalLight.values[0]); } this.GeoJsonLayerList.forEach((element) => { viewer.dataSources.remove(element); }); this.liudongGntities.forEach((element) => { viewer.entities.remove(element); }); } }, lerpColor(startColor, endColor, t) { // 解析颜色字符串为数组 let start = startColor.split(",").map(Number); let end = endColor.split(",").map(Number); // 计算渐变后的颜色值 let r = start[0] + (end[0] - start[0]) * t; let g = start[1] + (end[1] - start[1]) * t; let b = start[2] + (end[2] - start[2]) * t; // 返回结果为字符串格式 return { r, g, b }; }, splitArray(arr) { let chunkSize = Math.ceil(arr.length / 3); // 计算每个子数组应该有的元素数量 let result = []; for (let i = 0; i < arr.length; i += chunkSize) { let chunk = arr.slice(i, i + chunkSize); // 使用slice方法获取子数组 // 如果需要,可以将子数组中的元素按特定顺序重新排列 // 例如,如果你想保持每组的元素顺序与原始数组中的顺序相同,但分成三个子数组 // 则不需要额外的逻辑,因为slice已经按照顺序返回了元素 result.push(chunk); // 将子数组添加到结果数组中 } // 如果需要,你可以对结果数组中的每个子数组进行额外的处理 // 例如,按照你给出的例子,我们需要将每个子数组的元素重新排序 result = result.map((chunk, index) => { // 根据索引确定每个子数组中元素的最终位置 return chunk .map((value, i) => { // 使用模运算来确定元素在最终数组中的位置 let finalIndex = (i + index) % 3; // 如果最终索引小于子数组的长度,则返回当前值,否则返回undefined(但在这个例子中,不会有undefined) return finalIndex < chunkSize ? value : undefined; }) .filter((value) => value !== undefined); // 过滤掉undefined值(如果有的话) }); // 但是,在这个特定的例子中,我们不需要上面的重新排序步骤 // 因为我们只需要简单地按照原始数组的顺序将元素分配给三个子数组 return result; }, }; export default Nightscape;