const viewUtil = { /** * 添加发光墙体 * @param {*} source * @param {*} feature * @param {*} minimumHeight * @param {*} maximumHeight */ addWallByFeature(source,feature,colorStr,minimumHeight,maximumHeight){ let coords = feature.geometry.coordinates[0][0]; minimumHeight = minimumHeight?Number(minimumHeight):100, maximumHeight = maximumHeight?Number(maximumHeight):5000 colorStr = colorStr?colorStr:"rgb(255,255,0)" source.entities.add({ // name: "发光动态墙体", wall: { positions: Cesium.Cartesian3.fromDegreesArray(coords.flat(2)), material: new WallDiffuseMaterialProperty({ color: Cesium.Color.fromCssColorString(colorStr).withAlpha(0.7), duration: 3000, }), minimumHeights: Array(coords.length).fill(minimumHeight), maximumHeights: Array(coords.length).fill(maximumHeight), outline: false, }, }); }, /** * 创建轮廓线,使用Entity实现 * @param {*} source 数据源 * @param {*} geometry 要素的几何对象 * @param {*} colorStr 填充颜色 * @param {*} outlineColorStr 轮廓线颜色 * @param {*} outlineWidth 轮廓线宽度 * @param {*} isFill 是否填充 */ createOutlinePolygon(source,feature,colorStr,outlineColorStr,outlineWidth,isFill=true){ let geometryType = feature.geometry.type; let coords = feature.geometry.coordinates; let attr = feature.properties; // console.log(attr.name) if(geometryType == "MultiPolygon"){ coords.forEach((polygon,i)=>{ let polygonHierarchy = null; if(polygon.length>1){ let holesArr = [],rings = polygon.slice(1,polygon.length); rings.forEach(cd=>{ holesArr.push(new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(cd.flat(2)))) }) polygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2)),holesArr) }else{ polygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2))) } console.log(attr.name) let entity = source.entities.add({ id:JSON.stringify({...attr,index:i}),//多环的时候单纯用attr会ID重复,所以使用环的索引加以区分。 polygon: { hierarchy: polygonHierarchy, material: Cesium.Color.fromCssColorString(colorStr?colorStr:"red"), }, }); entity.polygon.fill = isFill; entity.polygon.outlineWidth = outlineWidth; entity.polygon.outline = false; entity.polygon.outlineColor = Cesium.Color.RED; entity.polyline = { positions: entity.polygon.hierarchy._value.positions, width: entity.polygon.outlineWidth, material: Cesium.Color.fromCssColorString(outlineColorStr?outlineColorStr:"red"), } }) } }, /** * 添加面要素 * @param {*} source 数据源 * @param {*} feature 要素 * @param {*} colorStr 填充颜色 */ addPolygonEntityByFeature(source,feature,colorStr){ let geometryType = feature.geometry.type; let coord = feature.geometry.coordinates; if(geometryType == "MultiPolygon"){ // let polygon = coord[0]; // let outBoundary = new Cesium.PolygonHierarchy( Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2))) // source.add(new Cesium.Primitive({ // geometryInstances : new Cesium.GeometryInstance({ // geometry: new Cesium.PolygonGeometry({ // polygonHierarchy : outBoundary // }), // id:id // }), // appearance : new Cesium.EllipsoidSurfaceAppearance({ // material: new Cesium.Material({ // fabric : { // type : 'Color', // uniforms : { // color : Cesium.Color.fromCssColorString(colorStr?colorStr:"red") // } // } // }), // faceForward : true // }) // })); coord.forEach(polygon=>{ let polygonHierarchy = null; if(polygon.length>1){ let holesArr = [],rings = polygon.slice(1,polygon.length); rings.forEach(cd=>{ holesArr.push(new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(cd.flat(2)))) }) polygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2)),holesArr) }else{ polygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2))) } source.entities.add({ polygon: { hierarchy: polygonHierarchy, material: Cesium.Color.fromCssColorString(colorStr?colorStr:"red"), }, }); }) } }, addPolygonPrimitiveByFeature(primitiveCollection,feature,colorStr){ let geometryType = feature.geometry.type; let coord = feature.geometry.coordinates; if(geometryType == "MultiPolygon"){ coord.forEach(polygon=>{ let polygonHierarchy = null; if(polygon.length>1){ let holesArr = [],rings = polygon.slice(1,polygon.length); rings.forEach(cd=>{ holesArr.push(new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(cd.flat(2)))) }) polygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2)),holesArr) }else{ polygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2))) } primitiveCollection.add(new Cesium.Primitive({ geometryInstances : new Cesium.GeometryInstance({ geometry: new Cesium.PolygonGeometry({ polygonHierarchy : polygonHierarchy }), id:JSON.stringify(feature.properties) }), appearance : new Cesium.EllipsoidSurfaceAppearance({ material: new Cesium.Material({ fabric : { type : 'Color', uniforms : { color : Cesium.Color.fromCssColorString(colorStr?colorStr:"red") } } }), faceForward : true }) })); }) } }, addGeoVisImagerLayer(viewer,type){ switch(type){ case "yingxiang":{ viewer.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({ url: "https://tiles{s}.geovisearth.com/base/v1/img/{z}/{x}/{y}?format=webp&tmsIds=w&token="+geovisearthConfig.token, subdomains:'123', tilingScheme: new Cesium.WebMercatorTilingScheme(), minimumLevel: 4, maximumLevel: 18, })) break; } case "shiliang":{ viewer.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({ url: "https://tiles{s}.geovisearth.com/base/v1/vec/{z}/{x}/{y}?format=png&tmsIds=w&token="+geovisearthConfig.token, subdomains:'123', tilingScheme: new Cesium.WebMercatorTilingScheme(), minimumLevel: 4, maximumLevel: 18, })) break; } } }, addWaterFeature(primitiveCollection,feature) { let geometryType = feature.geometry.type; let coord = feature.geometry.coordinates; let attr = feature.properties; if (geometryType == "MultiPolygon") { coord.forEach((polygon) => { let polygonHierarchy = null; if(polygon.length>1){ let holesArr = [],rings = polygon.slice(1,polygon.length); rings.forEach(cd=>{ holesArr.push(new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(cd.flat(2)))) }) polygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2)),holesArr) }else{ polygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2))) } primitiveCollection.add( new Cesium.GroundPrimitive({ geometryInstances: new Cesium.GeometryInstance({ geometry: new Cesium.PolygonGeometry({ polygonHierarchy: polygonHierarchy, }), attributes: { // 通过attributes属性统一指定线段颜色 color: Cesium.ColorGeometryInstanceAttribute.fromColor( new Cesium.Color(1.0, 0, 0, 1.0) ), }, id: attr, }), appearance: new Cesium.EllipsoidSurfaceAppearance({ material: new Cesium.Material({ fabric: { type: "Water", uniforms: { // 水的基本颜色 baseWaterColor: new Cesium.Color( 64 / 255.0, 157 / 255.0, 253 / 255.0, 0.5 ), // 水法向摄动的法线图 normalMap: "./Build/Cesium/Assets/Textures/waterNormals.jpg", // 波纹数量 frequency: 1000.0, // 动画速度 animationSpeed: 0.002, // 振动的幅度 amplitude: 150, // 镜面反射的强度 specularIntensity: 1, }, }, }), faceForward: true, }), }) ); }); } }, addWaterFeature1(primitiveCollection,feature) { let geometryType = feature.geometry.type; let coord = feature.geometry.coordinates; let attr = feature.properties; if (geometryType == "MultiPolygon") { coord.forEach((polygon) => { let polygonHierarchy = null; if(polygon.length>1){ let holesArr = [],rings = polygon.slice(1,polygon.length); rings.forEach(cd=>{ holesArr.push(new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(cd.flat(2)))) }) polygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2)),holesArr) }else{ polygonHierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2))) } primitiveCollection.add( new Cesium.Primitive({ geometryInstances: new Cesium.GeometryInstance({ geometry: new Cesium.PolygonGeometry({ polygonHierarchy: polygonHierarchy, }), attributes: { // 通过attributes属性统一指定线段颜色 color: Cesium.ColorGeometryInstanceAttribute.fromColor( new Cesium.Color(1.0, 0, 0, 1.0) ), }, id: attr, }), appearance: new Cesium.EllipsoidSurfaceAppearance({ material: new Cesium.Material({ fabric: { type: "Water", uniforms: { // 水的基本颜色 baseWaterColor: new Cesium.Color( 64 / 255.0, 157 / 255.0, 253 / 255.0, 0.5 ), // 水法向摄动的法线图 normalMap: "./Build/Cesium/Assets/Textures/waterNormals.jpg", // 波纹数量 frequency: 1000.0, // 动画速度 animationSpeed: 0.002, // 振动的幅度 amplitude: 150, // 镜面反射的强度 specularIntensity: 1, }, }, }), faceForward: true, }), }) ); }); } }, addEffect(type,result,color,visible){ switch(type){ case "polygon":{ const primitives = new Cesium.PrimitiveCollection({ show:!!visible }); result.features.forEach((feature) => { primitives.add(this.createPrimitiveByFeature1(feature, color)); }); viewer.scene.primitives.add(primitives);// 添加面 return primitives; break; } case "label":{ const labelCollection = new Cesium.LabelCollection({ show:!!visible }); result.features.forEach((feature) => { labelCollection.add(this.addLabel(feature)); }); viewer.scene.primitives.add(labelCollection); // 添加 label return labelCollection; break; } case "water":{ const waterPrimitives = new Cesium.PrimitiveCollection({ show:!!visible}); result.features.forEach((feature) => { this.addWaterFeature(waterPrimitives,feature); }); viewer.scene.primitives.add(waterPrimitives); // 添加 水面特效 return waterPrimitives; break; } case "glow":{ let tmpDataSource = new Cesium.CustomDataSource(); viewer.dataSources.add(tmpDataSource); result.features.forEach((feature) => { tmpDataSource.entities.add(this.addGlowFeature(feature,!!visible,color)) }) tmpDataSource.show = !!visible; return tmpDataSource; } case "dynamicLine":{ let dyDataSource = new Cesium.CustomDataSource(); viewer.dataSources.add(dyDataSource); result.features.forEach((feature) => { dyDataSource.entities.add(this.addDynamicLine(feature,!!visible,color)) }) dyDataSource.show = !!visible; return dyDataSource; } } }, createPrimitiveByFeature1(feature, rgba) { let coords = feature.geometry.coordinates; let color = rgba?rgba:"#c7d221"; let ground = new Cesium.GroundPrimitive({ geometryInstances: new Cesium.GeometryInstance({ geometry: new Cesium.PolygonGeometry({ polygonHierarchy: coords[0][0][0].length==3?new Cesium.PolygonHierarchy( Cesium.Cartesian3.fromDegreesArrayHeights(coords.flat(3)) ):new Cesium.PolygonHierarchy( Cesium.Cartesian3.fromDegreesArray(coords.flat(3)) ), }), id: feature.properties, attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString(color)) }, }), appearance : new Cesium.PerInstanceColorAppearance({ translucent : false }) }); return ground; }, addLabel(feature){ // 计算中心点 let polygon = feature.geometry.coordinates[0]; let points = []; polygon.forEach(ring=>{ ring.forEach(coord=>{ points.push([coord[0],coord[1]]); }) }) let pointss = turf.points(points); let centerResult = turf.center(pointss); let center = centerResult.geometry.coordinates return { position: Cesium.Cartesian3.fromDegrees(center[0],center[1],18), text: feature.properties["名称"]?feature.properties["名称"]:feature.properties["zldwmc"], font: "24px Helvetica", horizontalOrigin:Cesium.HorizontalOrigin.CENTER,// 水平对齐方式 verticalOrigin:Cesium.HorizontalOrigin.CENTER,// 垂直对齐方式 fillColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.BLACK, outlineWidth: 1, showBackground:false, selectionIndicator:false, style: Cesium.LabelStyle.FILL_AND_OUTLINE, scale:0.8, disableDepthTestDistance: 100.0, distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10.0, 30000.0),//根据到相机的距离确定可见性。 scaleByDistance: new Cesium.NearFarScalar(500, 1, 30000, 0.0), // translucencyByDistance: new Cesium.NearFarScalar(500, 1, 1400, 0.0) } }, addGlowFeature(feature,show,colorStr){ let geometryType = feature.geometry.type; let coord = feature.geometry.coordinates; if(geometryType == "MultiPolygon"){ let polygon = coord[0]; return { name: "具有发光效果的线", polyline: { positions: Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2)),// 只取外环,构造边界线 width: 4, material: new Cesium.PolylineGlowMaterialProperty({ glowPower: 0.2, color:Cesium.Color.fromCssColorString(colorStr?colorStr:"#242dc2"), }), followSurface: false, //是否贴着地表 }, }; } }, /** * 返回线 PolylineGraphics * @param {*} feature 线要素 * @param {*} color * @param {*} width * @returns */ addDynamicLine(feature,color,width=1){ if(feature.geometry.type == "MultiLineString"){ let coords = feature.geometry.coordinates[0]; let name = feature.properties.name; let colorStr = color?color:"#FF0"; if(name!=null&&name.includes("高速")){ color = Cesium.Color.WHITE ; width = 3; } return { id:JSON.stringify(feature.properties), polyline: { positions: Cesium.Cartesian3.fromDegreesArray(coords.flat(2)), width: width, material: new PolylineTrailMaterial({ color: Cesium.Color.fromCssColorString(colorStr), duration:5000 }), }, }; } }, loadTileset(viewer,tilesetUrl,deep=-45) { let vm = this; let tileset = new Cesium.Cesium3DTileset({ url: tilesetUrl, maximumScreenSpaceError:8, dynamicScreenSpaceError: true, dynamicScreenSpaceErrorDensity: 0.00278, dynamicScreenSpaceErrorFactor: 4.0, dynamicScreenSpaceErrorHeightFalloff: 0.25, }); viewer.scene.primitives.add(tileset); tileset.readyPromise.then(function (tileset_) { vm.setTilesetHeightAndOffset(tileset_, deep); }); return tileset; }, setTilesetHeightAndOffset(tileset, height, x, y) { x = x ? x : 0; y = y ? y : 0; let center; if (tileset.boundingSphere) { // 3dtiles center = tileset.boundingSphere.center; } else if ( tileset._boundingSpheres && tileset._boundingSpheres.length > 0 ) { // Primitive center = tileset._boundingSpheres[0].center; } const cartographic = Cesium.Cartographic.fromCartesian(center); const surface = Cesium.Cartesian3.fromRadians( cartographic.longitude, cartographic.latitude, 0.0 ); const offset = Cesium.Cartesian3.fromRadians( cartographic.longitude + x, cartographic.latitude + y, height ); const translation = Cesium.Cartesian3.subtract( offset, surface, new Cesium.Cartesian3() ); const modelMaxtrix = Cesium.Matrix4.fromTranslation(translation); tileset.modelMatrix = modelMaxtrix; }, } export default viewUtil;