Skip to content

压平

压平面的保存和标绘、单体化相同,都是使用 togeojson()的方式直接转换为 json 格式数据上传保存,但是压平需要额外调用压平接口

压平绘制

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

//根据辅助面中的点来获取需要压平的模型
var myPolygon = new LSGlobe.PolygonGeometry({
    polygonHierarchy: new LSGlobe.PolygonHierarchy(pos),
    perPositionHeight: true
});

viewer.scene.pageLODLayers.addFlattenPolygon(myPolygon);

//可以选择让辅助面是否显示
pushDataSource.entities.getById(id).show = false;

//获取当前压平的模型对象函数
function whichTileset(x, y) {
    var returnValue = [];
    for (var i = 0; i < viewer.scene.pageLODLayers._pageLODs.length; i++) {
        var aTileSet = viewer.scene.pageLODLayers._pageLODs[i];
        var oCenter = aTileSet.tileBoundingSphere.center;
        var ellipsoid = viewer.scene.globe.ellipsoid;
        var cartesian3 = new LSGlobe.Cartesian3(oCenter.x, oCenter.y, oCenter.z);
        var cartographic = ellipsoid.cartesianToCartographic(cartesian3);
        //ellipsoid表示球对象
        var lat = LSGlobe.Math.toDegrees(cartographic.latitude);
        var lng = LSGlobe.Math.toDegrees(cartographic.longitude);
        var position = {
            x: lng,
            y: lat,
            z: cartographic.height
        };
        var distance = getDistance(position, x, y);
        if (distance < aTileSet.tileBoundingSphere.radius) {
            returnValue.push(aTileSet);
        }
    }
    return returnValue;
}
//获取两个经纬度之间的距离函数
function getDistance(position, x, y) {
    var radLatA = position.y * 0.0174532925199432957692369077;
    var radLatB = y * 0.0174532925199432957692369077;
    var radLonA = position.x * 0.0174532925199432957692369077;
    var radLonB = x * 0.0174532925199432957692369077;
    return Math.acos(Math.cos(radLatA) * Math.cos(radLatB) * Math.cos(radLonA - radLonB) + Math.sin(radLatA) * Math.sin(radLatB)) * 6378137;
}

压平面的编辑

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

// 清空所有压平面和辅助面
viewer.scene.pageLODLayers.removeAllFlattenPolygons();
//重新压平
var aPushEntities = pushDataSource.entities.values;
for (var i = 0; i < aPushEntities.length; i++) {
    if (aPushEntities[i].show) {
        var aTileset = [];
        var pos = aPushEntities[i].polygon.hierarchy.getValue().positions;

        //使用辅助面的点集合绘制一个面对象
        var myPolygon = new LSGlobe.PolygonGeometry({
            polygonHierarchy: new LSGlobe.PolygonHierarchy(pos),
            perPositionHeight: true
        });
       viewer.scene.pageLODLayers.addFlattenPolygon(myPolygon);
    }
}

//2).设置名称
entity.name = "修改后的名称";

压平面的飞行

JavaScript
//压平面的飞行借助了压平辅助面
var entity = pushDataSource.entities.getById(id);
//粗略定位
viewer.flyTo(entity);

//精准定位(参考单体化定位)
var entity = pushDataSource.entities.getById(id);
    var entityPosition = getRealPosition(entity);
    viewer.camera.flyTo({
        destination: LSGlobe.Cartesian3.fromDegrees(entityPosition.lng,entityPosition.lat,entityPosition.alt),
        duration: 3
    })

设置显示隐藏

JavaScript

//对应的实景三维模型
tileset._flattenPolygons[0].show=true;//true显示,false:影藏
tileset.updateFlatten();
//对应的entity也要做对应同步
entity.show=true;//true显示,false:影藏

压平面的删除

JavaScript

//删除对应的entity
pushDataSource.entities.removeById(id);
//删除所有压平
viewer.scene.pageLODLayers.removeAllFlattenPolygons();
//重新压所有
//参照编辑里面的重新压平

压平存储

压平的存储是以 json 格式保存的,直接赋值给 oSubSceneData.push,然后随场景保存接口一并提交保存

JavaScript
oSubSceneData.push = pushDataSource.toGeoJson()

压平面的重载

压平获取接口,参数 jsonType 为 4

//localhost:8000/wish3dearth/api/scene/v1.0.0/getSceneJsonInfo

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++) {
            if(aPushEntities[i].id.indexOf("common") < 0){
                aPushEntities[i].polygon.perPositionHeight=false;
            }
            if (aPushEntities[i].show && aPushEntities[i].id.indexOf("common") < 0) {
                var aPushPos=aPushEntities[i].polygon.hierarchy.getValue().positions?aPushEntities[i].polygon.hierarchy.getValue().positions:aPushEntities[i].polygon.hierarchy.getValue();
                var oDegree = fnCartesian2Degreen(aPushPos[0]);
                var mtileset = whichTileset(oDegree.lng, oDegree.lat);
                var myPolygon = new LSGlobe.PolygonGeometry({
                        polygonHierarchy: new LSGlobe.PolygonHierarchy(aPushPos),
                        perPositionHeight: true
                    });
                    for (var j = 0; j < mtileset.length; j++) {
                        mtileset[j]._flattenPolygons.push(myPolygon);
                        mtileset[j].updateFlatten();
                    }
            }
        }
}).otherwise(function(error) {
    console.log(error);
});

Released under the MIT License.