880 lines
34 KiB
Vue
880 lines
34 KiB
Vue
<template>
|
||
<div>
|
||
<div id="over-viewer"></div>
|
||
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
class PolylineTrailMaterial {
|
||
constructor(option = {}) {
|
||
this._definitionChanged = new Cesium.Event()
|
||
this._color = undefined
|
||
this._colorSubscription = undefined
|
||
this._time = (new Date()).getTime()
|
||
|
||
this.color = option.color ? option.color : Cesium.Color.fromCssColorString('rgba(90,90,255, 1)');
|
||
|
||
this.duration = option.duration ? option.duration : 5000
|
||
// this.img = option.img ? option.img :'/images/colors2.png'
|
||
this.img = this.createMaterialImage()
|
||
// 类型(会自动加载到cesium中)
|
||
this.type = option.type ? option.type : 'PolylineTrail'
|
||
|
||
// 着色器
|
||
this.source = option.source ? option.source : 'czm_material czm_getMaterial(czm_materialInput materialInput)' +
|
||
'{' +
|
||
'czm_material material = czm_getDefaultMaterial(materialInput);' +
|
||
'vec2 st = materialInput.st;' +
|
||
'vec4 colorImage = texture2D(image, vec2(fract(st.s - time), st.t));' +
|
||
'material.alpha = colorImage.a * color.a;' +
|
||
'material.diffuse = (colorImage.rgb+color.rgb)/2.0;' +
|
||
'return material;' +
|
||
'}'
|
||
|
||
this.addMaterial()
|
||
}
|
||
createMaterialImage(){
|
||
var c = document.createElement("canvas");
|
||
c.width = 512;
|
||
c.height = 32;
|
||
var ctx = c.getContext("2d");
|
||
var colorstr = this.color.toCssColorString().replace("rgb(","").replace(")","");
|
||
var my_gradient = ctx.createLinearGradient(0, 0, c.width, 0);
|
||
my_gradient.addColorStop(0, "rgba("+colorstr+", 1)");
|
||
my_gradient.addColorStop(1, "rgba("+colorstr+", 0)");
|
||
ctx.fillStyle = my_gradient;
|
||
ctx.fillRect(0, 0, c.width, c.height);
|
||
return c.toDataURL('image/png');
|
||
}
|
||
getType() {
|
||
return 'PolylineTrail'
|
||
}
|
||
getValue(time, result) {
|
||
if (!Cesium.defined(result)) {
|
||
result = {}
|
||
}
|
||
|
||
result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color)
|
||
result.image = this.img
|
||
result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration
|
||
|
||
return result
|
||
}
|
||
equals(other) {
|
||
return this === other || (other instanceof PolylineTrailMaterial && Cesium.Property.equals(this._color, other._color))
|
||
}
|
||
addMaterial() {
|
||
Cesium.Material._materialCache.addMaterial(this.type, {
|
||
fabric: {
|
||
type: this.type,
|
||
uniforms: {
|
||
color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
|
||
image: this.img,
|
||
time: 100
|
||
},
|
||
source: this.source
|
||
},
|
||
|
||
translucent: (material) => {
|
||
return true
|
||
}
|
||
})
|
||
|
||
// 注意Cesium.defineProperties会报错,需要改为Object
|
||
Object.defineProperties(PolylineTrailMaterial.prototype, {
|
||
isConstant: {
|
||
get: () => {
|
||
return false
|
||
},
|
||
configurable: true
|
||
},
|
||
definitionChanged: {
|
||
get: () => {
|
||
return this._definitionChanged
|
||
},
|
||
configurable: true
|
||
},
|
||
color: {
|
||
value: Cesium.createPropertyDescriptor('color'),
|
||
configurable: true,
|
||
writable: true
|
||
}
|
||
})
|
||
}
|
||
}
|
||
class Bubble {
|
||
constructor(val) {
|
||
this.viewer = val.viewer;
|
||
this.div = document.createElement("div");
|
||
}
|
||
addDynamicLabel(data,cartesian3) {
|
||
let div = this.div;
|
||
div.id = data.id;
|
||
// div.style.display="inline"
|
||
div.style.position = "absolute";
|
||
div.style.minWidth = "380px";
|
||
div.style.height = "auto";
|
||
let keys = Object.keys(data);
|
||
// 构建属性面板
|
||
let HTMLTable = `
|
||
<div class="bubble-box">
|
||
|
||
<div class="box-wrap" id="bubbleContent">
|
||
<div class="pine"></div>
|
||
<div class="bubble-close" id="popupClose">x</div>
|
||
<div class="area">
|
||
<div class="area-title fontColor">${ data['name']?data['name']:data['名称'] }</div>
|
||
</div>
|
||
<div class="content" >
|
||
${keys.map(item=>{
|
||
return `<div class="data-li">
|
||
<div class="data-label textColor">${item}:</div>
|
||
<div class="data-value">
|
||
<span class="label-num yellowColor">${data[item]}</span>
|
||
</div>
|
||
</div>`
|
||
}).join('')}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- <img src="./layer_border.png" alt="Norway"> -->
|
||
</div>
|
||
`;
|
||
div.innerHTML = HTMLTable;
|
||
this.viewer.cesiumWidget.container.appendChild(div);
|
||
document
|
||
.getElementById("popupClose")
|
||
.addEventListener("click", () => {
|
||
this.clearDiv();
|
||
});
|
||
let gisPosition = cartesian3;
|
||
this.handler = this.viewer.scene.postRender.addEventListener(() => {
|
||
const canvasHeight = this.viewer.scene.canvas.height;
|
||
const windowPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
|
||
this.viewer.scene,
|
||
gisPosition
|
||
);
|
||
let content = document.getElementById("bubbleContent");
|
||
let height = content?content.clientHeight:220;
|
||
div.style.bottom = canvasHeight - windowPosition.y + height + Math.sin(Math.PI/180*45)*60+ "px";
|
||
const elWidth = div.offsetWidth;
|
||
div.style.left = windowPosition.x - elWidth / 2 + 190 + "px";
|
||
}, this);
|
||
}
|
||
clearDiv() {
|
||
if (this.div && this.div.parentElement) {
|
||
var parent = this.div.parentElement;
|
||
parent.removeChild(this.div);
|
||
this.handler&&this.handler();
|
||
}
|
||
}
|
||
}
|
||
|
||
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:
|
||
"/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;
|
||
},
|
||
}
|
||
// import { cartesianToLnglat, uuid } from "./js/cUtils";
|
||
// import viewUtil from "./js/viewUtil.js";
|
||
// import Bubble from "./js/Bubble.js";
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
|
||
};
|
||
},
|
||
mounted() {
|
||
this.initCesium();
|
||
},
|
||
methods: {
|
||
initCesium() {
|
||
|
||
let box = document.getElementsByClassName("content__default")[0];
|
||
box.style.maxWidth = "100%";
|
||
box.style.paddingTop = 0;
|
||
let Cesium = this.$cesium;
|
||
window.CESIUM_BASE_URL = "/cesium";
|
||
Cesium.Ion.defaultAccessToken =
|
||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5ZjRjNTZkNC01NDYxLTRhMjQtOGEwZC1kZjA3YzQ5YTJlZDkiLCJpZCI6MjYwODQsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODcxOTMwODN9.prGsSKyAW_9Ow5zHYPhbm3LsQL-ApQw5-5PNJkDaHi8";
|
||
// 添加 Mapbox tile provider
|
||
const mapboxAccess =
|
||
"pk.eyJ1IjoicWl1c2hpamllIiwiYSI6ImNsMDNvdDRybDEyc2YzZG9kbWZoY2FuOW0ifQ.4FH-BUupi46Z0zQ-CEm_Ig";
|
||
|
||
var customMapboxIamgery = new Cesium.MapboxStyleImageryProvider({
|
||
// url: "https://api.mapbox.com/styles/v1",
|
||
username: "qiushijie",
|
||
styleId: "clboooor3000714mi15y9j6ba",
|
||
accessToken: mapboxAccess,
|
||
scaleFactor: true,
|
||
});
|
||
|
||
var viewer = new Cesium.Viewer("over-viewer", {
|
||
geocoder: false, //位置查找
|
||
homeButton: false, //视图返回初始位置
|
||
sceneModePicker: false, //视角选择器
|
||
baseLayerPicker:false,//底图选择器
|
||
navigationHelpButton: false, //导航帮助按钮
|
||
animation: false, //动画控制器
|
||
creditContainer: document.createElement("div"),//版权显示
|
||
timeline: false, //时间线
|
||
fullscreenButton: false, //全屏控件
|
||
vrButton: false,
|
||
infoBox: false,
|
||
selectionIndicator: false,
|
||
imageryProvider:customMapboxIamgery
|
||
});
|
||
window.Cesium = Cesium;
|
||
window.viewer = viewer;
|
||
window.bubble = new Bubble({
|
||
viewer:viewer
|
||
});
|
||
this.initEvent();
|
||
this.setExtent(viewer);
|
||
this.riverPrimitives = viewer.scene.primitives.add(// 创建primitive集合,存储水系图元对象
|
||
new Cesium.PrimitiveCollection()
|
||
);
|
||
this.addWaterPrimitive(this.riverPrimitives);
|
||
|
||
// 加载动态路网
|
||
this.rdSource = new Cesium.CustomDataSource("dynamicRoad");// 创建自定义数据源,存放动态墙体的Entity
|
||
viewer.dataSources.add(this.rdSource);
|
||
let roadUrl = "/data/licheng_road.geojson"
|
||
fetch(roadUrl).then(res=>res.json()).then(result=>{
|
||
result.features.forEach(feature=>{
|
||
this.rdSource.entities.add(viewUtil.addDynamicLine(feature,"#fff",1))
|
||
})
|
||
})
|
||
// 加载白模
|
||
let whiteUrl = "/data/licheng/tileset.json"
|
||
let whiteTileset = viewUtil.loadTileset(viewer,whiteUrl,0)
|
||
},
|
||
setExtent(viewer){
|
||
viewer.camera.setView({
|
||
// destination : Cesium.Cartesian3.fromDegrees(113.9044,23.3215,1000000),
|
||
destination: new Cesium.Cartesian3(-2368517.8753985167, 5368259.496963671, 2498952.3392142765),
|
||
orientation: {
|
||
heading :0.21256304726696484, //Cesium.Math.toRadians(0.0), // east, default value is 0.0 (north)
|
||
pitch :-0.3255554838380681, //Cesium.Math.toRadians(-90), // default value (looking down)
|
||
roll : 0.0000316945339733 // default value
|
||
}
|
||
});
|
||
|
||
},
|
||
addWaterPrimitive(riverPrimitives){
|
||
// 加水纹
|
||
let waterUrl = "/data/licheng_water.geojson"
|
||
fetch(waterUrl).then(res=>res.json()).then(result=>{
|
||
result.features.forEach(feature=>{
|
||
viewUtil.addWaterFeature1(riverPrimitives,feature);
|
||
})
|
||
})
|
||
},
|
||
initEvent(){
|
||
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
|
||
let vm = this;
|
||
handler.setInputAction(function (evt) {
|
||
// 获取该位置的所有primitive集合
|
||
let picks = viewer.scene.drillPick(evt.position);
|
||
viewer.scene.render();
|
||
let isOn3dtiles = false;
|
||
let pickPrimitive = [];
|
||
let pickEntity =[];
|
||
let pickTileFeature =[];
|
||
for (var i = 0; i < picks.length; i++) {
|
||
if (picks[i] && picks[i] instanceof Cesium.Cesium3DTileFeature) {
|
||
//模型上拾取
|
||
isOn3dtiles = true;
|
||
pickTileFeature.push(picks[i]);
|
||
}
|
||
if(picks[i].primitive && picks[i].primitive instanceof Cesium.GroundPrimitive){
|
||
pickPrimitive.push(picks[i])
|
||
}
|
||
if(picks[i].id instanceof Cesium.Entity){
|
||
pickEntity.push(picks[i].id)
|
||
}
|
||
}
|
||
if(window.selectPrimitive){
|
||
// viewer.scene.primitives.remove(window.selectPrimitive);
|
||
// window.selectPrimitive=null;
|
||
let comp = window.selectPrimitive;
|
||
let attr = comp.primitive.getGeometryInstanceAttributes(comp.id);
|
||
attr.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromBytes(comp.color[0],comp.color[1],comp.color[2],comp.color[3]));
|
||
window.selectPrimitive=null;
|
||
}
|
||
|
||
let currCartesian3 = viewer.scene.globe.pick(viewer.camera.getPickRay(evt.position),viewer.scene)
|
||
|
||
|
||
if (pickPrimitive.length>0||pickEntity.length>0) {
|
||
// 设置选中高亮primitive
|
||
if(pickPrimitive.length&&pickPrimitive[0].id){
|
||
var attributes = pickPrimitive[0].primitive.getGeometryInstanceAttributes(pickPrimitive[0].id);
|
||
window.selectPrimitive = {
|
||
id:pickPrimitive[0].id,
|
||
primitive:pickPrimitive[0].primitive,
|
||
color:{...attributes.color}
|
||
}
|
||
attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({
|
||
alpha: 0.5
|
||
}));
|
||
}
|
||
//坐标转换
|
||
// let currCartesian3 = viewer.scene.pickPosition(evt.position);
|
||
// let pickobject = viewer.scene.pick(evt.position); //取最上面的primitive对象
|
||
let fields = {};
|
||
if (pickEntity.length) {
|
||
fields = JSON.parse(pickEntity[0].id);
|
||
}else if(pickPrimitive.length){
|
||
fields = pickPrimitive[0].id;
|
||
}
|
||
window.bubble.clearDiv()
|
||
window.bubble.addDynamicLabel(fields,currCartesian3)
|
||
} else if(pickTileFeature.length){
|
||
let fields = {};
|
||
const feature = pickTileFeature[0];
|
||
const propertyNames = feature.getPropertyNames();
|
||
const length = propertyNames.length;
|
||
for (let i = 0; i < length; ++i) {
|
||
const propertyName = propertyNames[i];
|
||
if(propertyName == "采集时间"){
|
||
fields["测试的时间"] = feature.getProperty(propertyName);
|
||
}else{
|
||
fields[propertyName] = feature.getProperty(propertyName);
|
||
}
|
||
|
||
}
|
||
window.bubble.clearDiv()
|
||
window.bubble.addDynamicLabel(fields,currCartesian3)
|
||
}
|
||
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||
}
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang='stylus' scoped>
|
||
#over-viewer {
|
||
height: 80vh;
|
||
width: 100%;
|
||
}
|
||
|
||
.path-container {
|
||
position: absolute;
|
||
top: 75px;
|
||
left: 70px;
|
||
}
|
||
</style> |