坡度分析
坡度分析是通过创建色彩渐变,使地形的坡度以色彩渐变的形式展示出来
地形加载
requestVertexNormals 设置为 true 时会计算法线,用于坡度坡向
Javascript
async loadTerrain() {
let terrainPath = '';
try{
//构建地形数据,参数requestVertexNormals为true时会计算法线,用于坡度坡向
let terrainLayer = await LSGlobe.LSTerrainProvider.fromUrl(terrainPath, {
requestVertexNormals: true,
});
this.viewer.terrainLayers.addTerrainProvider(terrainLayer);
//单个地形时
let rect = terrainLayer.rectangle; //地形范围
this.viewer.scene.globe.materialRectangle = rect; //设置坡度坡向分析的范围
//有多个地形时,合并多个地形
/*
let rect = this.viewer.terrainLayers.get(0).rectangle;
for (let i = 0; i < this.viewer.terrainLayers.length; i++) {
this.viewer.terrainLayers.get(i)._requestVertexNormals = true;
LSGlobe.Rectangle.union(rect, this.viewer.terrainLayers.get(i).rectangle, rect);
}
*/
this.#flyToRectBoundingSphere(rect);
} catch (error) {
console.log(`Error loading terrain: ${error}`);
}
}
创建色带
创建一个 canvas 容器,填充渐变色
javascript
getColorRamp() {
let ramp = document.createElement('canvas');
ramp.width = 100;
ramp.height = 1;
let ctx = ramp.getContext('2d');
let values;
let colors;
values = slopeAnalysis.colorLegends.map(
(item) => Math.floor((item.value / 90) * 100) / 100
);
colors = slopeAnalysis.colorLegends.map((item) => item.color);
var grd = ctx.createLinearGradient(0, 0, 100, 1);
values?.forEach((item, i) => {
grd.addColorStop(values[i], colors[i]);
});
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 100, 1);
return ramp;
}
启用坡度分析
javascript
enableAnalysis() {
//创建材质
let material = LSGlobe.Material.fromType('SlopeRamp');
// 采用临近采样 ***
material._minificationFilter = LSGlobe.TextureMinificationFilter.NEAREST;
material._magnificationFilter = LSGlobe.TextureMinificationFilter.NEAREST;
//加载色带
let shadingUniforms = material.uniforms;
shadingUniforms.image = this.#getColorRamp();
let globe = this.viewer.scene.globe;
//启用灯光
globe.enableLighting = true;
//应用材质
globe.material = material;
}
完整代码
Javascript
class wish3dEarth {
viewer = null;
constructor() {
if (!LSGlobe?.viewer) {
this.#initEarth();
} else {
this.viewer = LSGlobe.viewer;
}
//加载地形
this.#loadTerrain();
}
//初始化地球
#initEarth() {
let licenseCode = '';
let wish3DEarthLicenseUrl = '';
this.viewer = new LSGlobe.Viewer('lsGlobe', {
guid: licenseCode,
licenseUrl: wish3DEarthLicenseUrl,
});
}
//加载地形
#loadTerrain() {
let terrainPath = '';
try{
//构建地形数据,参数requestVertexNormals为true时会计算法线,用于坡度坡向
let terrainLayer = await LSGlobe.LSTerrainProvider.fromUrl(terrainPath, {
requestVertexNormals: true,
});
this.viewer.terrainLayers.addTerrainProvider(terrainLayer);
//单个地形时
let rect = terrainLayer.rectangle; //地形范围
this.viewer.scene.globe.materialRectangle = rect; //设置坡度坡向分析的范围
//有多个地形时,合并多个地形
/*
let rect = this.viewer.terrainLayers.get(0).rectangle;
for (let i = 0; i < this.viewer.terrainLayers.length; i++) {
this.viewer.terrainLayers.get(i)._requestVertexNormals = true;
LSGlobe.Rectangle.union(rect, this.viewer.terrainLayers.get(i).rectangle, rect);
}
*/
this.#flyToRectBoundingSphere(rect);
} catch (error) {
console.log(`Error loading terrain: ${error}`);
}
}
//飞行至rectangle
#flyToRectBoundingSphere(rect) {
let boundingSphere = LSGlobe.BoundingSphere.fromRectangle3D(rect);
const heading = LSGlobe.Math.toRadians(30.0);
const pitch = LSGlobe.Math.toRadians(-30.0);
const range = 1.4e4;
this.viewer.camera.flyToBoundingSphere(boundingSphere, {
offset: new LSGlobe.HeadingPitchRange(heading, pitch, range),
maximumHeight: 2e6,
pitchAdjustHeight: 2e6,
duration: 4,
complete: this.showPanel,
});
}
}
class slopeAnalysis extends wish3dEarth {
//色带分级
static colorLegends = [
{
value: 0,
color: '#ffffff00',
show: false,
},
{
value: 3, // todo 由于LSGlobe-2.0.0.612引擎是根据法线计算的值,精度不是很准确存在全球着色的问题,所以我们将3度以下的设置为透明的颜色(引擎的测试代码是设置效果限制范围:viewer.scene.globe.materialRectangle = rect)
color: '#95f20445',
show: false,
},
{
value: 15,
color: '#caf98245',
},
{
value: 30,
color: '#ffff8045',
},
{
value: 45,
color: '#ffff0045',
},
{
value: 60,
color: '#facd9145',
},
{
value: 75,
color: '#f59a2345',
},
{
value: 90,
color: '#ec808d45',
},
];
constructor() {
super();
}
//启用分析
enableAnalysis() {
let material = LSGlobe.Material.fromType('SlopeRamp');
// 采用临近采样 ***
material._minificationFilter = LSGlobe.TextureMinificationFilter.NEAREST;
material._magnificationFilter = LSGlobe.TextureMinificationFilter.NEAREST;
let shadingUniforms = material.uniforms;
shadingUniforms.image = this.#getColorRamp();
let globe = this.viewer.scene.globe;
globe.enableLighting = true;
globe.material = material;
}
//清除分析
clearAnalysis() {
this.viewer.scene.globe.enableLighting = false;
try {
if (this.viewer.scene.globe.material !== undefined) {
this.viewer.scene.globe.material = undefined;
}
} catch (error) {
console.error(error);
}
}
//生成色带
#getColorRamp() {
let ramp = document.createElement('canvas');
ramp.width = 100;
ramp.height = 1;
let ctx = ramp.getContext('2d');
let values;
let colors;
values = slopeAnalysis.colorLegends.map(
(item) => Math.floor((item.value / 90) * 100) / 100
);
colors = slopeAnalysis.colorLegends.map((item) => item.color);
var grd = ctx.createLinearGradient(0, 0, 100, 1);
values?.forEach((item, i) => {
grd.addColorStop(values[i], colors[i]);
});
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 100, 1);
return ramp;
}
}
let analysis = new slopeAnalysis();
analysis.enableAnalysis();
//删除分析
//analysis.clearAnalysis()