254 lines
8.9 KiB
JavaScript
254 lines
8.9 KiB
JavaScript
|
/**
|
||
|
* 等高线
|
||
|
*/
|
||
|
import Dialog from "../../Obj/Element/Dialog";
|
||
|
import Tools from "../../Tools";
|
||
|
|
||
|
let _DialogObject = null;
|
||
|
let material = null;
|
||
|
let handler = null;
|
||
|
let activeHeightElm = null;
|
||
|
let tools
|
||
|
activeHeightElm = document.createElement('div')
|
||
|
activeHeightElm.className = 'YJ-customize-active-height-elm'
|
||
|
activeHeightElm.style.position = 'absolute'
|
||
|
activeHeightElm.style.left = '10px'
|
||
|
activeHeightElm.style.top = '10px'
|
||
|
activeHeightElm.style.width = '100px'
|
||
|
// activeHeightElm.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'
|
||
|
activeHeightElm.style.textAlign = 'center'
|
||
|
activeHeightElm.style.pointerEvents = 'none'
|
||
|
activeHeightElm.style.color = '#ff0000'
|
||
|
activeHeightElm.style.display = 'none'
|
||
|
async function dialog(sdk) {
|
||
|
if (!sdk || _DialogObject) {
|
||
|
return
|
||
|
}
|
||
|
if (!material) {
|
||
|
createMaterial()
|
||
|
}
|
||
|
if (!tools) {
|
||
|
tools = new Tools()
|
||
|
}
|
||
|
|
||
|
_DialogObject = await new Dialog(sdk, {}, {
|
||
|
title: "等高线", left: '180px',
|
||
|
top: '100px',
|
||
|
confirmCallBack: options => { },
|
||
|
closeCallBack: () => {
|
||
|
_DialogObject = null
|
||
|
}
|
||
|
});
|
||
|
|
||
|
_DialogObject._element.body.className =
|
||
|
_DialogObject._element.body.className + ' contour'
|
||
|
let contentElm = document.createElement('div')
|
||
|
contentElm.innerHTML = `
|
||
|
<span class="custom-divider"></span>
|
||
|
<div class="div-item">
|
||
|
<div class="row">
|
||
|
<div class="col input-select-unit-box">
|
||
|
<span class="label">高差</span>
|
||
|
<div class="input-number input-number-unit-1">
|
||
|
<input class="input gap" type="number" title="" min="0" max="1000">
|
||
|
<span class="unit">m</span>
|
||
|
<span class="arrow"></span>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="col input-select-unit-box" style="flex: 0 0 120px;">
|
||
|
<span class="label">主线颜色</span>
|
||
|
<div class="primary-lice-color"></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="row">
|
||
|
<div class="col input-select-unit-box">
|
||
|
<span class="label">次线条数</span>
|
||
|
<div class="input-number input-number-unit-1">
|
||
|
<input class="input gap2" type="number" title="" min="0" max="10">
|
||
|
<span class="unit"></span>
|
||
|
<span class="arrow"></span>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="col input-select-unit-box" style="flex: 0 0 120px;">
|
||
|
<span class="label">次线颜色</span>
|
||
|
<div class="secondary-lice-color"></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="row" style="align-items: flex-start;">
|
||
|
<div class="col">
|
||
|
</div>
|
||
|
<div class="col" style="flex: 0 0 120px;">
|
||
|
<span class="label">开关</span>
|
||
|
<input class="btn-switch" type="checkbox">
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<span class="custom-divider"></span>
|
||
|
`
|
||
|
contentElm.innerHTML = `
|
||
|
<span class="custom-divider"></span>
|
||
|
<div class="div-item">
|
||
|
<div class="row" style="align-items: flex-start;">
|
||
|
<div class="col" style="flex: 0 0 120px;">
|
||
|
<span class="label">开关</span>
|
||
|
<input class="btn-switch" type="checkbox">
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
`
|
||
|
_DialogObject.contentAppChild(contentElm)
|
||
|
|
||
|
contentElm.getElementsByClassName('btn-switch')[0].addEventListener('change', (e) => {
|
||
|
if (e.target.checked) {
|
||
|
if (handler) {
|
||
|
handler.destroy()
|
||
|
}
|
||
|
if (!sdk.viewer.container.getElementsByClassName('YJ-customize-active-height-elm')[0]) {
|
||
|
sdk.viewer.container.appendChild(activeHeightElm)
|
||
|
}
|
||
|
|
||
|
handler = new Cesium.ScreenSpaceEventHandler(
|
||
|
sdk.viewer.canvas
|
||
|
)
|
||
|
handler.setInputAction((movement) => {
|
||
|
let cartesian = sdk.viewer.scene.pickPosition(movement.endPosition)
|
||
|
if (cartesian) {
|
||
|
let top = 0
|
||
|
let left = 0
|
||
|
if (sdk.viewer && sdk.viewer._element) {
|
||
|
let element = sdk.viewer._element.getElementsByClassName('cesium-widget')[0].getElementsByTagName('canvas')[0]
|
||
|
top = element.getBoundingClientRect().top + window.scrollY
|
||
|
left = element.getBoundingClientRect().left + window.scrollX
|
||
|
}
|
||
|
activeHeightElm.style.left = movement.endPosition.x - 50 + left + 'px'
|
||
|
activeHeightElm.style.top = movement.endPosition.y - 40 + top + 'px'
|
||
|
activeHeightElm.style.display = 'block'
|
||
|
let pos84 = tools.cartesian3Towgs84(cartesian, sdk.viewer)
|
||
|
let mainContourHeight = Math.floor(pos84.alt / material.uniforms.spacing) * material.uniforms.spacing
|
||
|
let gap = pos84.alt - mainContourHeight
|
||
|
let gap2 = material.uniforms.spacing / (material.uniforms.secondaryLinesCount + 1)
|
||
|
let activeHeight = Math.floor(gap / gap2) * gap2 + mainContourHeight
|
||
|
if ((pos84.alt - activeHeight) > gap2 / 2) {
|
||
|
activeHeight = activeHeight + gap2
|
||
|
}
|
||
|
material.uniforms.mouseHeight = pos84.alt
|
||
|
material.uniforms.mousePosition = cartesian
|
||
|
activeHeightElm.innerHTML = `${activeHeight.toFixed(0)}`
|
||
|
}
|
||
|
else {
|
||
|
activeHeightElm.style.display = 'none'
|
||
|
}
|
||
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
||
|
sdk.viewer.scene.globe.material = material;
|
||
|
} else {
|
||
|
if (handler) {
|
||
|
handler.destroy()
|
||
|
handler = null
|
||
|
}
|
||
|
if (sdk.viewer.container.getElementsByClassName('YJ-customize-active-height-elm')[0]) {
|
||
|
activeHeightElm.style.display = 'none'
|
||
|
sdk.viewer.container.removeChild(activeHeightElm)
|
||
|
}
|
||
|
sdk.viewer.scene.globe.material = null;
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function createMaterial() {
|
||
|
Cesium.Material._materialCache._materials.ElevationContour.fabric.source = `
|
||
|
uniform vec4 color;
|
||
|
uniform vec4 secondaryLinesColor;
|
||
|
uniform float spacing;
|
||
|
uniform float width;
|
||
|
uniform float secondaryLinesWidth;
|
||
|
uniform float mouseHeight;
|
||
|
uniform float secondaryLinesCount; // 0=无次线, 1=1条次线, 2=2条次线...
|
||
|
|
||
|
czm_material czm_getMaterial(czm_materialInput materialInput)
|
||
|
{
|
||
|
czm_material material = czm_getDefaultMaterial(materialInput);
|
||
|
|
||
|
// 主等高线计算
|
||
|
float distanceToMainContour = mod(materialInput.height, spacing);
|
||
|
|
||
|
// 抗锯齿计算
|
||
|
#if (__VERSION__ == 300 || defined(GL_OES_standard_derivatives))
|
||
|
float dxc = abs(dFdx(materialInput.height));
|
||
|
float dyc = abs(dFdy(materialInput.height));
|
||
|
float dFMain = max(dxc, dyc) * czm_pixelRatio * width;
|
||
|
#else
|
||
|
float dFMain = czm_pixelRatio * width;
|
||
|
#endif
|
||
|
|
||
|
bool isMainContour = distanceToMainContour < dFMain;
|
||
|
bool isSecondaryContour = false;
|
||
|
float dFSecondary = 0.0;
|
||
|
float secondarySpacing = 0.0;
|
||
|
|
||
|
// 只有当存在次线时才计算次线
|
||
|
if(secondaryLinesCount > 0.0) {
|
||
|
secondarySpacing = spacing / (secondaryLinesCount + 1.0);
|
||
|
float distanceToSecondaryContour = mod(materialInput.height, secondarySpacing);
|
||
|
|
||
|
// 确保次线不会与主线重叠
|
||
|
float minDistanceToMain = min(distanceToMainContour, spacing - distanceToMainContour);
|
||
|
bool notCloseToMain = minDistanceToMain > dFMain * 2.0; // 2倍线宽缓冲
|
||
|
|
||
|
#if (__VERSION__ == 300 || defined(GL_OES_standard_derivatives))
|
||
|
dFSecondary = max(dxc, dyc) * czm_pixelRatio * secondaryLinesWidth;
|
||
|
#else
|
||
|
dFSecondary = czm_pixelRatio * secondaryLinesWidth;
|
||
|
#endif
|
||
|
|
||
|
isSecondaryContour = (distanceToSecondaryContour < dFSecondary) && notCloseToMain;
|
||
|
}
|
||
|
|
||
|
// 计算当前高度所属的等高线高度
|
||
|
float mainContourHeight = floor(materialInput.height / spacing) * spacing;
|
||
|
float secondaryContourHeight = floor(materialInput.height / spacing * (secondaryLinesCount + 1.0)) * spacing / (secondaryLinesCount + 1.0);
|
||
|
|
||
|
// 高亮判断
|
||
|
bool shouldHighlight = false;
|
||
|
if(isMainContour && abs(mainContourHeight - mouseHeight) < 0.5 * (spacing/(secondaryLinesCount+1.0))) {
|
||
|
shouldHighlight = true;
|
||
|
} else if(isSecondaryContour && abs(secondaryContourHeight - mouseHeight) < 0.5 * (spacing/(secondaryLinesCount+1.0))) {
|
||
|
shouldHighlight = true;
|
||
|
}
|
||
|
|
||
|
// 颜色输出
|
||
|
vec4 outColor;
|
||
|
if(shouldHighlight) {
|
||
|
outColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||
|
} else if(isMainContour) {
|
||
|
outColor = czm_gammaCorrect(vec4(color.rgb, color.a));
|
||
|
} else if(isSecondaryContour) {
|
||
|
outColor = czm_gammaCorrect(vec4(secondaryLinesColor.rgb, secondaryLinesColor.a));
|
||
|
} else {
|
||
|
outColor = vec4(0.0);
|
||
|
}
|
||
|
|
||
|
material.diffuse = outColor.rgb;
|
||
|
material.alpha = outColor.a;
|
||
|
return material;
|
||
|
}
|
||
|
`
|
||
|
|
||
|
material = new Cesium.Material({
|
||
|
fabric: {
|
||
|
type: "ElevationContour",
|
||
|
uniforms: {
|
||
|
width: 2,
|
||
|
secondaryLinesWidth: 1, // 次级线宽度
|
||
|
spacing: 200,
|
||
|
color: Cesium.Color.fromCssColorString('#ffd000'),
|
||
|
secondaryLinesColor: Cesium.Color.fromCssColorString('#0dff00').withAlpha(0.5),
|
||
|
mouseHeight: -100000,
|
||
|
mousePosition: new Cesium.Cartesian3(0, 0, 0),
|
||
|
secondaryLinesCount: 3
|
||
|
},
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
export { dialog }
|