Skip to content

压平

压平面的保存和标绘、单体化相同,都是压平面要素统一保存在 pushDataSource(GeoJsonDataSource)中, 然后利用GeoJsonDataSourcetoGeoJson方法导出提交。

上述是数据存储,但是压平需要额外调用压平接口

压平绘制

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);
});

Released under the MIT License.