|
|
|
@ -6,6 +6,7 @@
|
|
|
|
|
|
|
|
|
|
import {getDistance, getElevation} from "@/utils/map/geocomputation.ts";
|
|
|
|
|
import {Cartesian3, Viewer} from "cesium";
|
|
|
|
|
import * as echarts from "echarts";
|
|
|
|
|
type ProfileResult = {
|
|
|
|
|
distanceArray:number[],
|
|
|
|
|
elevationArray:number[],
|
|
|
|
@ -24,23 +25,29 @@ export function elevationProfile(viewer: Viewer, start:Cartesian3, end:Cartesian
|
|
|
|
|
let distanceFromStart:number[] = [] //断点至起点的距离m
|
|
|
|
|
// 计算首尾点距离 m
|
|
|
|
|
let totalLen = getDistance(start, end) * 1000
|
|
|
|
|
// 获取起点高度
|
|
|
|
|
breakPointsHeight.push(getElevation(viewer, start))
|
|
|
|
|
// 获取起点高度及其与起点的距离
|
|
|
|
|
breakPointsHeight.push(Math.round(getElevation(viewer, start)))
|
|
|
|
|
distanceFromStart.push(0)
|
|
|
|
|
|
|
|
|
|
//获取中间断点的高度及其与起点的距离
|
|
|
|
|
if(interval > 0){
|
|
|
|
|
//断点数量
|
|
|
|
|
let breakNum = Math.floor(totalLen/interval)
|
|
|
|
|
// 如果采样间隔小于首尾点距离,则获取每个断点的坐标 并获取其高度
|
|
|
|
|
if(breakNum>=1){
|
|
|
|
|
for (let i = 1; i <= breakNum; i++) {
|
|
|
|
|
for (let i = 1; i < breakNum; i++) {
|
|
|
|
|
let breakP = Cartesian3.lerp(start, end, i/breakNum, new Cartesian3())
|
|
|
|
|
breakPointsHeight.push(getElevation(viewer, breakP))
|
|
|
|
|
distanceFromStart.push(getDistance(start,breakP)*1000)
|
|
|
|
|
breakPointsHeight.push(Math.round(getElevation(viewer, breakP))) //单位 米
|
|
|
|
|
distanceFromStart.push(Math.round(getDistance(start,breakP)*1000)) //单位 米
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 获取终点高度
|
|
|
|
|
breakPointsHeight.push(getElevation(viewer, end))
|
|
|
|
|
distanceFromStart.push(totalLen)
|
|
|
|
|
return { distanceArray:distanceFromStart, elevationArray:breakPointsHeight }
|
|
|
|
|
|
|
|
|
|
// 获取终点高度及其与起点的距离
|
|
|
|
|
breakPointsHeight.push(Math.round(getElevation(viewer, end)))
|
|
|
|
|
distanceFromStart.push(Math.round(totalLen))
|
|
|
|
|
|
|
|
|
|
return { distanceArray: distanceFromStart, elevationArray: breakPointsHeight }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -50,12 +57,18 @@ export function elevationProfile(viewer: Viewer, start:Cartesian3, end:Cartesian
|
|
|
|
|
* @param interval 线段采样间隔 m为单位
|
|
|
|
|
* @return 从折线起点至终点剖面线的海拔高度数组
|
|
|
|
|
*/
|
|
|
|
|
export function profileAnalyse(viewer: Viewer, polyline:Cartesian3[],interval: number){
|
|
|
|
|
let result:ProfileResult = { distanceArray:[], elevationArray:[] }
|
|
|
|
|
for (let i = 0; i < polyline.length - 2; i++) {
|
|
|
|
|
let temp = elevationProfile(viewer,polyline[i],polyline[i+1],interval)
|
|
|
|
|
export function profileAnalyse(viewer: Viewer, polyline:Cartesian3[], interval: number){
|
|
|
|
|
let result: ProfileResult = { distanceArray:[], elevationArray:[] }
|
|
|
|
|
let temp_dis = 0 //每两点之间的距离
|
|
|
|
|
for (let i = 0; i <= polyline.length - 2; i++) {
|
|
|
|
|
let temp = elevationProfile(viewer, polyline[i], polyline[i+1], interval)
|
|
|
|
|
result.elevationArray = result.elevationArray.concat(temp.elevationArray)
|
|
|
|
|
result.distanceArray = result.distanceArray.concat(temp.distanceArray)
|
|
|
|
|
temp.distanceArray.forEach(distance => {
|
|
|
|
|
result.distanceArray.push(distance+temp_dis)
|
|
|
|
|
})
|
|
|
|
|
if(temp.distanceArray.length > 0){
|
|
|
|
|
temp_dis += temp.distanceArray[temp.distanceArray.length-1]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
@ -66,19 +79,21 @@ export function profileAnalyse(viewer: Viewer, polyline:Cartesian3[],interval: n
|
|
|
|
|
* @param viewer 地图
|
|
|
|
|
* @param viewpoint 视点
|
|
|
|
|
* @param target 目标点
|
|
|
|
|
* @param h 视点地面抬高,默认为1m
|
|
|
|
|
* @param h1 视点地面挂高 m
|
|
|
|
|
* @param h2 目标点地面挂高 m
|
|
|
|
|
* @param curvature 是否考虑地球曲率
|
|
|
|
|
* @param breakNum 采样间隔,默认为100个断点
|
|
|
|
|
*/
|
|
|
|
|
export function visibilityAnalyse(viewer: Viewer, viewpoint:Cartesian3, target:Cartesian3,
|
|
|
|
|
h= 1, breakNum = 100) {
|
|
|
|
|
h1:number, h2:number,curvature:boolean, breakNum = 100) {
|
|
|
|
|
// 获取视点高度和目标点高度
|
|
|
|
|
let viewpointH = getElevation(viewer, viewpoint) + h
|
|
|
|
|
let targetH = getElevation(viewer, target)
|
|
|
|
|
if (viewpointH === -9999.2024 + h ) {
|
|
|
|
|
let viewpointH = getElevation(viewer, viewpoint) + h1
|
|
|
|
|
let targetH = getElevation(viewer, target) + h2
|
|
|
|
|
if (viewpointH === -9999.2024 + h1 ) {
|
|
|
|
|
console.log("无法获取视点海拔高度!")
|
|
|
|
|
return undefined
|
|
|
|
|
}
|
|
|
|
|
if (targetH === -9999.2024 ) {
|
|
|
|
|
if (targetH === -9999.2024 + h2 ) {
|
|
|
|
|
console.log("无法获取目标点海拔高度!")
|
|
|
|
|
return undefined
|
|
|
|
|
}
|
|
|
|
@ -98,5 +113,350 @@ export function visibilityAnalyse(viewer: Viewer, viewpoint:Cartesian3, target:C
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(curvature){
|
|
|
|
|
let Rmax = 2.898 * (Math.sqrt(h1)+Math.sqrt(h2))
|
|
|
|
|
if (Rmax < totalLen/1000.0) return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 绘制地形剖面折线图
|
|
|
|
|
* @param xData x数组
|
|
|
|
|
* @param yData y数组,以面积线绘制
|
|
|
|
|
*/
|
|
|
|
|
export function drawEchartsProfileAnalyse(xData:number[], yData:number[]) {
|
|
|
|
|
let myChart = echarts.init(document.getElementById('profileEChart'))
|
|
|
|
|
// 绘制图表
|
|
|
|
|
myChart.setOption({
|
|
|
|
|
legend: {
|
|
|
|
|
show: true,
|
|
|
|
|
type: 'plain',
|
|
|
|
|
top: '5%',
|
|
|
|
|
data:[
|
|
|
|
|
{
|
|
|
|
|
name: 'groundLine',
|
|
|
|
|
itemStyle: 'inherit',
|
|
|
|
|
lineStyle: 'inherit',
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
tooltip: {
|
|
|
|
|
show: true,
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
axisPointer: {
|
|
|
|
|
type: 'cross'
|
|
|
|
|
},
|
|
|
|
|
formatter:'地表高度: {c0}'
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
data: xData,
|
|
|
|
|
name: '距离/米',
|
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontWeight:'bolder',
|
|
|
|
|
fontSize: 14
|
|
|
|
|
},
|
|
|
|
|
nameLocation: 'end',
|
|
|
|
|
axisLine:{
|
|
|
|
|
onZero: false,
|
|
|
|
|
show: true, // 是否显示坐标轴轴线
|
|
|
|
|
symbol: ['none', 'arrow'],
|
|
|
|
|
symbolSize: [7, 10]
|
|
|
|
|
},
|
|
|
|
|
axisLabel: {
|
|
|
|
|
formatter: '{value}',
|
|
|
|
|
margin: 5,
|
|
|
|
|
},
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: true, // 是否显示坐标轴刻度
|
|
|
|
|
inside: true, // 坐标轴刻度是否朝内,默认朝外
|
|
|
|
|
alignWithLabel: true,
|
|
|
|
|
lineStyle: {
|
|
|
|
|
color: '#000000', //刻度线的颜色
|
|
|
|
|
type: 'solid', //坐标轴线线的类型(solid实线类型;dashed虚线类型;dotted点状类型)
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
|
|
|
|
type: 'value',
|
|
|
|
|
name: '高度/米',
|
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontWeight:'bolder',
|
|
|
|
|
fontSize: 14
|
|
|
|
|
},
|
|
|
|
|
nameLocation: 'end',
|
|
|
|
|
position: 'left',
|
|
|
|
|
axisLabel: {
|
|
|
|
|
formatter: '{value}'
|
|
|
|
|
},
|
|
|
|
|
axisLine: {
|
|
|
|
|
show: true,
|
|
|
|
|
symbol: ['none', 'arrow'],
|
|
|
|
|
symbolSize: [7, 10]
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name:'groundLine',
|
|
|
|
|
type: 'line',
|
|
|
|
|
data: yData,
|
|
|
|
|
areaStyle: {
|
|
|
|
|
color: '#37a5fb',
|
|
|
|
|
opacity: 0.5
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 绘制折线图(航线碰撞检测)
|
|
|
|
|
* @param xData x数组
|
|
|
|
|
* @param yData y数组,以面积线绘制
|
|
|
|
|
* @param yData2 y数组,以折线绘制
|
|
|
|
|
*/
|
|
|
|
|
export const drawEchartsAirlineDetect = (xData:number[],yData:number[],yData2:number[]) => {
|
|
|
|
|
let myChart = echarts.init(document.getElementById('profileEChart'))
|
|
|
|
|
// 绘制图表
|
|
|
|
|
myChart.setOption({
|
|
|
|
|
legend:{
|
|
|
|
|
show: true,
|
|
|
|
|
type: 'plain',
|
|
|
|
|
top: '7%',
|
|
|
|
|
data:[
|
|
|
|
|
{
|
|
|
|
|
name: 'groundLine',
|
|
|
|
|
itemStyle: 'inherit',
|
|
|
|
|
lineStyle: 'inherit',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'airLine',
|
|
|
|
|
itemStyle: 'inherit',
|
|
|
|
|
lineStyle: 'inherit',
|
|
|
|
|
}]
|
|
|
|
|
},
|
|
|
|
|
tooltip: {
|
|
|
|
|
show: true,
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
axisPointer: {
|
|
|
|
|
type: 'cross'
|
|
|
|
|
},
|
|
|
|
|
formatter:'地表高度: {c0}<br>航线高度: {c1}'
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
data: xData,
|
|
|
|
|
name: '距离',
|
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontWeight:'bolder',
|
|
|
|
|
fontSize: 14
|
|
|
|
|
},
|
|
|
|
|
nameLocation: 'end',
|
|
|
|
|
axisLine:{
|
|
|
|
|
onZero: false,
|
|
|
|
|
show: true, // 是否显示坐标轴轴线
|
|
|
|
|
symbol: ['none', 'arrow'],
|
|
|
|
|
symbolSize: [7, 10]
|
|
|
|
|
},
|
|
|
|
|
axisLabel: {
|
|
|
|
|
formatter: '{value} m',
|
|
|
|
|
margin: 5,
|
|
|
|
|
},
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: true, // 是否显示坐标轴刻度
|
|
|
|
|
inside: true, // 坐标轴刻度是否朝内,默认朝外
|
|
|
|
|
alignWithLabel: true,
|
|
|
|
|
lineStyle: {
|
|
|
|
|
color: '#000000', //刻度线的颜色
|
|
|
|
|
type: 'solid', //坐标轴线线的类型(solid实线类型;dashed虚线类型;dotted点状类型)
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
|
|
|
|
type: 'value',
|
|
|
|
|
name: '高度',
|
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontWeight:'bolder',
|
|
|
|
|
fontSize: 14
|
|
|
|
|
},
|
|
|
|
|
nameLocation: 'end',
|
|
|
|
|
position: 'left',
|
|
|
|
|
axisLabel: {
|
|
|
|
|
formatter: '{value} m'
|
|
|
|
|
},
|
|
|
|
|
axisLine: {
|
|
|
|
|
show: true,
|
|
|
|
|
symbol: ['none', 'arrow'],
|
|
|
|
|
symbolSize: [7, 10]
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name:'groundLine',
|
|
|
|
|
type: 'line',
|
|
|
|
|
data: yData,
|
|
|
|
|
areaStyle: {
|
|
|
|
|
color: '#37a5fb',
|
|
|
|
|
opacity: 0.5
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name:'airLine',
|
|
|
|
|
type: 'line',
|
|
|
|
|
data: yData2,
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 绘制通视分析图 面积线和直线
|
|
|
|
|
* @param xData x数组,地面距离
|
|
|
|
|
* @param yData y数组,以面积线绘制
|
|
|
|
|
* @param startHeight 视线起始点高度(包含地面挂高)
|
|
|
|
|
* @param endHeight 视线终点高度(包含地面挂高)
|
|
|
|
|
*/
|
|
|
|
|
export const drawEchartsVisibility = (xData:number[], yData:number[],startHeight:number, endHeight:number) => {
|
|
|
|
|
console.group()
|
|
|
|
|
console.log(0, startHeight)
|
|
|
|
|
console.log(xData.at(-1), endHeight)
|
|
|
|
|
console.groupEnd()
|
|
|
|
|
console.log(xData)
|
|
|
|
|
let myChart = echarts.init(document.getElementById('profileEChart')) //Echarts-UnitTest
|
|
|
|
|
// 绘制图表
|
|
|
|
|
myChart.setOption({
|
|
|
|
|
legend: {
|
|
|
|
|
show: true,
|
|
|
|
|
type: 'plain',
|
|
|
|
|
top: '7%',
|
|
|
|
|
data: [
|
|
|
|
|
{ //地形剖面图例
|
|
|
|
|
name: '剖面线',
|
|
|
|
|
itemStyle: {
|
|
|
|
|
fontSize: 18
|
|
|
|
|
},
|
|
|
|
|
lineStyle: 'inherit',
|
|
|
|
|
},
|
|
|
|
|
{ //视线图例
|
|
|
|
|
name: '视线',
|
|
|
|
|
lineStyle: {
|
|
|
|
|
type: 'dotted',
|
|
|
|
|
width: 3,
|
|
|
|
|
color: '#f8364d'
|
|
|
|
|
},
|
|
|
|
|
itemStyle: {
|
|
|
|
|
fontSize: 18
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
selectedMode: false, //图例选择模式关闭
|
|
|
|
|
},
|
|
|
|
|
tooltip: {
|
|
|
|
|
show: true,
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
axisPointer: {
|
|
|
|
|
type: 'cross'
|
|
|
|
|
},
|
|
|
|
|
formatter:'地表高度: {c0}'
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
boundaryGap : false,
|
|
|
|
|
max: (value:any)=>{
|
|
|
|
|
return value.max * 1.01;
|
|
|
|
|
},
|
|
|
|
|
min: 0,
|
|
|
|
|
data: xData,
|
|
|
|
|
name: '距离/m',
|
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontWeight:'bolder',
|
|
|
|
|
fontSize: 14
|
|
|
|
|
},
|
|
|
|
|
nameLocation: 'end',
|
|
|
|
|
axisLine:{
|
|
|
|
|
onZero: false,
|
|
|
|
|
show: true, // 是否显示坐标轴轴线
|
|
|
|
|
symbol: ['none', 'arrow'],
|
|
|
|
|
symbolSize: [7, 10]
|
|
|
|
|
},
|
|
|
|
|
axisLabel: {
|
|
|
|
|
formatter: '{value}',
|
|
|
|
|
margin: 5,
|
|
|
|
|
},
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: true, // 是否显示坐标轴刻度
|
|
|
|
|
inside: true, // 坐标轴刻度是否朝内,默认朝外
|
|
|
|
|
alignWithLabel: true,
|
|
|
|
|
lineStyle: {
|
|
|
|
|
color: '#000000', //刻度线的颜色
|
|
|
|
|
type: 'solid', //坐标轴线线的类型(solid实线类型;dashed虚线类型;dotted点状类型)
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
|
|
|
|
max: (value:any)=>{
|
|
|
|
|
return Math.floor(Math.max(value.max,startHeight,endHeight)*1.01)
|
|
|
|
|
},
|
|
|
|
|
min: (value:any)=>{
|
|
|
|
|
return Math.floor(Math.min(value.min,startHeight,endHeight)*0.99)
|
|
|
|
|
},
|
|
|
|
|
type: 'value',
|
|
|
|
|
name: '高度/ m',
|
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontWeight:'bolder',
|
|
|
|
|
fontSize: 14
|
|
|
|
|
},
|
|
|
|
|
nameLocation: 'end',
|
|
|
|
|
position: 'left',
|
|
|
|
|
axisLabel: {
|
|
|
|
|
formatter: '{value}'
|
|
|
|
|
},
|
|
|
|
|
axisLine: {
|
|
|
|
|
show: true,
|
|
|
|
|
symbol: ['none', 'arrow'],
|
|
|
|
|
symbolSize: [7, 10]
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name:'剖面线',
|
|
|
|
|
type: 'line',
|
|
|
|
|
data: yData,
|
|
|
|
|
areaStyle: {
|
|
|
|
|
color: '#37a5fb',
|
|
|
|
|
opacity: 0.5
|
|
|
|
|
},
|
|
|
|
|
markLine: {
|
|
|
|
|
data: [
|
|
|
|
|
[
|
|
|
|
|
{coord: ['0', startHeight.toString()]},
|
|
|
|
|
{coord: [xData.at(-1)?.toString(), endHeight.toString()]}
|
|
|
|
|
// Markline中的坐标点必须为string,否则异常
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
symbol:['circle', 'arrow'],
|
|
|
|
|
label:{
|
|
|
|
|
formatter: "模 拟 视 线",
|
|
|
|
|
show: true,
|
|
|
|
|
position: 'middle',
|
|
|
|
|
fontSize: 15,
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
color: '#e73d3d',
|
|
|
|
|
},
|
|
|
|
|
lineStyle: { //标注线样式
|
|
|
|
|
type: 'dashed',
|
|
|
|
|
color: 'red',
|
|
|
|
|
with: 10
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{ /* 视线的series */
|
|
|
|
|
type: 'line',
|
|
|
|
|
symbol: 'none',
|
|
|
|
|
name: '视线',
|
|
|
|
|
color: 'transparent'
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|