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>
|