压平
压平面的保存和标绘、单体化相同,都是压平面要素统一保存在 pushDataSource(GeoJsonDataSource)中, 然后利用GeoJsonDataSource
的toGeoJson
方法导出提交。
上述是数据存储,但是压平需要额外调用压平接口
压平绘制
JavaScript
var pushDataSource;
//存储压平绘制的面要素会保存到该对象中
var promise = viewer.dataSources.add(new LSGlobe.GeoJsonDataSource("pushDataSource"));
promise.then(function(dataSource) {
pushDataSource = dataSource;
}).otherwise(function(error) {
});
//压平面的绘制
var pushHandler = new LSGlobe.ScreenSpaceEventHandler(viewer.scene.canvas);
pushHandler.setInputAction(function(movement) {
//获取的坐标上添加标绘点,具体的坐标获取参照坐标转换
var Pos = scene.pickGlobe(movement.position);
},
LSGlobe.ScreenSpaceEventType.LEFT_CLICK);
//根据上面获取到的点集合经过处理后达到新的数据
var oValuePoint = ChangePolygonPosition(event.positions);
//该面是辅助设置压平面的面,最后压平的高度和范围是该面显示的高度和范围(该面用于保存,存储于pushDataSource.entities,如果需要对比高度效果可以多创建一个面)
pushDataSource.entities.add({
name: '压平面',//压平面名称
id: id,
polygon: {
hierarchy: {
positions:LSGlobe.Cartesian3.fromDegreesArrayHeights(oValuePoint)
},
material: new LSGlobe.Color(0.5, 1.0, 1.0, 0.7),
fill: true,
//显示填充
outline: false,
outlineColor: LSGlobe.Color.YELLOW,
perPositionHeight: true
}
});
//坐标转换函数
function ChangePolygonPosition(oPositions) {
var oValuePoint = [];
//所有点统一高度,使压平面在同一水平面(此处计算所有点的平均高度)
var fSumHeight = 0;
for (var a = 0; a < oPositions.length; a++) {
var cartographic = LSGlobe.Cartographic.fromCartesian(oPositions[a]);
fSumHeight = fSumHeight + cartographic.height;
}
var Height = fSumHeight / oPositions.length;
for (var a = 0; a < oPositions.length; a++) {
var CurrentPoint = oPositions[a];
var cartographic = LSGlobe.Cartographic.fromCartesian(CurrentPoint);
var currentClickLon = LSGlobe.Math.toDegrees(cartographic.longitude);
var currentClickLat = LSGlobe.Math.toDegrees(cartographic.latitude);
oValuePoint.push(currentClickLon);
oValuePoint.push(currentClickLat);
oValuePoint.push(Height);
}
return oValuePoint;
};
//模型的压平
var pos = oValuePoint;//同上面oValuePoint
//根据辅助面中的点来获取需要压平的模型
for (var j = 0; j < viewer.scene.primitives.length; j++) {
var oTileSet = viewer.scene.primitives.get(j)
if (oTileSet.name && oTileSet.name.bizType == 3) {
var polygon = new LSGlobe.PolygonHierarchy(
pos
)
var flattenRegion = new LSGlobe.FlattenRegion({
polygon: polygon,
show: true,
})
try {
if (oTileSet.flattenRegions) {
oTileSet.flattenRegions.add(flattenRegion)
} else {
const flattenRegionCollection =
new LSGlobe.FlattenRegionCollection({
flattenRegions: [flattenRegion], // 传入的坑对象数组
enabled: true, // 是否启用,设为false不显示;默认值为true。
numberOfCascades: 4, // 级联数量,设为1或4:1——性能高;4——精度高;默认值为4。
// 距离相机的最远作用距离,超过此距离后模型没有效果。距离越大精度越低,默认值为5000,最大距离限制为20000。
maximumDistance: 8000,
// 使用的映射纹理尺寸。数值越大性能越低占用显存越高但精度高;默认值为2048。
size: 2048,
// 可见映射范围的延伸长度,降低不在视景体内的顶点对压平效果的影响。值越大影响越小,但是精度越低。
visibleOverlayExtension: 10,
// 是否对被压物体进行压平测试。压平测试可以减少被压对象的数量,从而提升渲染性能;但压平测试需要被压物体与每个压平面进行相交判断,在压平面较多时此测试本身对性能影响较大。
flattenTest: false
})
oTileSet.flattenRegions = flattenRegionCollection
}
} catch (e) {
console.error(e)
}
}
}
//可以选择让辅助面是否显示
pushDataSource.entities.getById(id).show = false;
压平面的修改
JavaScript
//1).设置高度
//获取对应参考面
var entity = pushDataSource.entities.getById(id);
//获取压平点坐标
var aFlatArray = ChangePolygonPosition(entity.polygon.hierarchy.getValue().positions);
for (var i = 2; i < aFlatArray.length; i = i + 3) {
aFlatArray[i] = height; //height 改变后的高度值
}
//删除原参考面,新增参考面
pushDataSource.entities.remove(entity);
pushDataSource.entities.add({
name: '压平面',
//压平面名称
id: id,
polygon: {
hierarchy: {
positions: LSGlobe.Cartesian3.fromDegreesArrayHeights(aFlatArray)
},
material: new LSGlobe.Color(0.5, 1.0, 1.0, 0.7),
fill: true,
//显示填充
outline: false,
outlineColor: LSGlobe.Color.YELLOW,
perPositionHeight: true
}
});
// 清空所有压平面和辅助面
// 清除所有倾斜上面的压平
for (var i = 0; i < viewer.scene.primitives.length; i++) {
var oTileSet = viewer.scene.primitives.get(i)
// 倾斜
if (oTileSet.name && oTileSet.name.bizType == 3) {
try {
if (oTileSet.flattenRegions) {
oTileSet.flattenRegions.removeAll()
}
} catch (e) {
console.error(e)
}
}
}
//重新压平
var aPushEntities = pushDataSource.entities.values;
for (var i = 0; i < aPushEntities.length; i++) {
if (aPushEntities[i].show) {
for (var j = 0; j < viewer.scene.primitives.length; j++) {
var oTileSet = viewer.scene.primitives.get(j)
if (oTileSet.name && oTileSet.name.bizType == 3) {
var polygon = new LSGlobe.PolygonHierarchy(
aPushEntities[i].polygon.hierarchy.getValue().positions
)
var flattenRegion = new LSGlobe.FlattenRegion({
polygon: polygon,
show: true,
})
try {
if (oTileSet.flattenRegions) {
oTileSet.flattenRegions.add(flattenRegion)
} else {
const flattenRegionCollection =
new LSGlobe.FlattenRegionCollection({
flattenRegions: [flattenRegion], // 传入的坑对象数组
enabled: true, // 是否启用,设为false不显示;默认值为true。
numberOfCascades: 4, // 级联数量,设为1或4:1——性能高;4——精度高;默认值为4。
// 距离相机的最远作用距离,超过此距离后模型没有效果。距离越大精度越低,默认值为5000,最大距离限制为20000。
maximumDistance: 8000,
// 使用的映射纹理尺寸。数值越大性能越低占用显存越高但精度高;默认值为2048。
size: 2048,
// 可见映射范围的延伸长度,降低不在视景体内的顶点对压平效果的影响。值越大影响越小,但是精度越低。
visibleOverlayExtension: 10,
// 是否对被压物体进行压平测试。压平测试可以减少被压对象的数量,从而提升渲染性能;但压平测试需要被压物体与每个压平面进行相交判断,在压平面较多时此测试本身对性能影响较大。
flattenTest: false
})
oTileSet.flattenRegions = flattenRegionCollection
}
} catch (e) {
console.error(e)
}
}
}
}
}
//2).设置名称
entity.name = "修改后的名称";
压平面的定位
提示
压平面定位可以参照视角定位中的flyToBoundingSphere
定位方法,
JavaScript
//压平面的飞行借助了压平辅助面
var entity = pushDataSource.entities.getById(id);
//方法1
viewer.flyto(entity)
//方法2
// 利用点集合定位,positions世界坐标数组
const boundingSphere = LSGlobe.BoundingSphere.fromPoints(entity.polygon.hierarchy.getValue().positions);
viewer.camera.flyToBoundingSphere(boundingSphere, {
offset: new LSGlobe.HeadingPitchRange(0, -LSGlobe.Math.PI_OVER_TWO, 0)
});
设置显示隐藏
JavaScript
//对应的实景三维模型删除
tileset.flattenRegions.removeAll()
//再构建压平面重新压平
oTileSet.flattenRegions=FlattenRegionCollection//压平面集合
压平面的删除
JavaScript
//删除对应的entity
pushDataSource.entities.removeById(id);
//删除所有压平
//对应的实景三维模型删除
tileset.flattenRegions.removeAll()
//重新压所有
//参照编辑里面的重新压平
压平存储
压平的存储是以 json 格式保存的,直接赋值给 oSubSceneData.push,然后随场景保存接口一并提交保存
JavaScript
oSubSceneData.push = pushDataSource.toGeoJson()
从场景数据中加载压平面
压平面数据获取接口查询场景压平面信息,参数 jsonType 为 4;
JavaScript
var oGeoJson = result.data;
//result.data前面获取的标绘数据json
var promise = LSGlobe.GeoJsonDataSource.load(oGeoJson, {});
promise.then(function(dataSource) {
//将数据再次加载到初始化存储压平的对象中
pushDataSource = dataSource;
//添加到球中
viewer.dataSources.add(dataSource);
var aPagelodLayers = viewer.scene.pageLODLayers._pageLODs;
for (var i = 0; i < aPagelodLayers.length; i++) {
try {
aPagelodLayers[i].cleanflattenPolygon();
} catch(e) {}
}
//重新压平
var aPushEntities = pushDataSource.entities.values;
for (var i = 0; i < aPushEntities.length; i++) {
// 降低透明度(entity只是存储数据用不用显示出来)
aPushEntities[i].polygon.material = LSGlobe.Color.fromRandom({
red: aPushEntities[i].polygon.material.color._value.red,
green: aPushEntities[i].polygon.material.color._value.green,
blue: aPushEntities[i].polygon.material.color._value.blue,
alpha: 0.01
})
if (aPushEntities[i].show) {
for (var j = 0; j < viewer.scene.primitives.length; j++) {
var oTileSet = viewer.scene.primitives.get(j) if (oTileSet.name && oTileSet.name.bizType == 3) {
var polygon = new LSGlobe.PolygonHierarchy(aPushEntities[i].polygon.hierarchy.getValue().positions) var flattenRegion = new LSGlobe.FlattenRegion({
polygon: polygon,
show: true,
}) try {
if (oTileSet.flattenRegions) {
oTileSet.flattenRegions.add(flattenRegion)
} else {
const flattenRegionCollection = new LSGlobe.FlattenRegionCollection({
flattenRegions: [flattenRegion],
// 传入的坑对象数组
enabled: true,
// 是否启用,设为false不显示;默认值为true。
numberOfCascades: 4,
// 级联数量,设为1或4:1——性能高;4——精度高;默认值为4。
// 距离相机的最远作用距离,超过此距离后模型没有效果。距离越大精度越低,默认值为5000,最大距离限制为20000。
maximumDistance: 8000,
// 使用的映射纹理尺寸。数值越大性能越低占用显存越高但精度高;默认值为2048。
size: 2048,
// 可见映射范围的延伸长度,降低不在视景体内的顶点对压平效果的影响。值越大影响越小,但是精度越低。
visibleOverlayExtension: 10,
// 是否对被压物体进行压平测试。压平测试可以减少被压对象的数量,从而提升渲染性能;但压平测试需要被压物体与每个压平面进行相交判断,在压平面较多时此测试本身对性能影响较大。
flattenTest: false
}) oTileSet.flattenRegions = flattenRegionCollection
}
} catch(e) {
console.error(e)
}
}
}
}
}
}).otherwise(function(error) {
console.log(error);
});