Skip to content

单体化

单体化原理:本质就是贴模型地表的标绘面,在默认 0.01 的透明度下,当鼠标移动到该面时候,改变面的材质的透明度为 1,当鼠标移出后透明度重新设置透明度为 0.01,从而实现高亮效果。

单体化绘制

JavaScript

//1).初始化单体化存储对象
var monomerDataSource;
var promise = viewer.dataSources.add(new LSGlobe.GeoJsonDataSource("monomerDataSource"));

promise.then(function(dataSource) {
   monomerDataSource = dataSource;
   monomerDataSource.name="monomerDataSource"
}).otherwise(function(error) {

});

//2).单体化绘制
monomerDataSource.entities.add({
   //特殊字段该字段会保存下来,可以是字符串也可以是个对象
   name: '单体化面',
   //面的唯一标识会存储下来,再次加载也不改变,用于查找
   id: id,
   polygon: {
       hierarchy: {
           //面的点集合
           positions: event.positions,
       },
       //面的材质
       material: LSGlobe.Color.fromCssColorString("rgb(0,186,255)").withAlpha('0.5');,
       //是否填充面
       fill: true,
       //是否显示面的外边框(仅空间面有效)
       outline: false,
       //面的类型
       classificationType: LSGlobe.ClassificationType.BOTH,
       perPositionHeight:false//是否绝对高度(当设置非空间面时候一定要设置false,空间面一定要设置true)
   }
});

单体化要素获取

JavaScript
//id 绘制单体化时加入的唯一标识
var entity = monomerDataSource.entities.getById(id)

单体化显示隐藏

JavaScript
//entity获取到的单体化对象
entity.show=true/false;

单体化飞行

JavaScript
//entity获取到的单体化对象
//单体化飞行(贴地,贴模型)
var entity = monomerDataSource.entities.getById(id);
if (entity) {
    entity.polygon.material = LSGlobe.Color.fromRandom({
        red: entity.polygon.material.color._value.red,
        green: entity.polygon.material.color._value.green,
        blue: entity.polygon.material.color._value.blue,
        alpha: 0.7
    });
    var entityPosition = getRealPosition(entity);
    //获取单体化真实飞行坐标
    viewer.camera.flyTo({
        destination: LSGlobe.Cartesian3.fromDegrees(entityPosition.lng, entityPosition.lat, entityPosition.alt),
        duration: 3
    })
}

function getRealPosition(Entities) {
    if (Entities._corridor) {
        var aPos = Entities._corridor.positions._value;
    } else {
        var aPos = Entities.polygon.hierarchy._value.positions || Entities.polygon.hierarchy._value;
    }
    var iX = 0,
    iY = 0,
    iZ = 0,
    maxX = 0,
    maxY = 0,
    minX, minY, realheight;
    for (var i = 0; i < aPos.length; i++) {
        iX = aPos[i].x + iX;
        iY = aPos[i].y + iY;
        iZ = aPos[i].z + iZ;
    }
    iX = iX / aPos.length;
    iY = iY / aPos.length;
    iZ = iZ / aPos.length;
    //中心点经纬度
    var WorlsPos = new LSGlobe.Cartesian3(iX, iY, iZ);
    var oDegree = ellipsoid.cartesianToCartographic(WorlsPos);
    var lng = LSGlobe.Math.toDegrees(oDegree.longitude);
    var lat = LSGlobe.Math.toDegrees(oDegree.latitude);
    for (var a = 0; a < aPos.length; a++) {
        //当前点的经纬度
        var sWorlsPos = new LSGlobe.Cartesian3(aPos[a].x, aPos[a].y, aPos[a].z);
        var sDegree = ellipsoid.cartesianToCartographic(sWorlsPos);
        var slng = LSGlobe.Math.toDegrees(sDegree.longitude);
        var slat = LSGlobe.Math.toDegrees(sDegree.latitude);
        //中心点经纬度
        var oPos = {
            "x": slng,
            "y": slat
        };
        var currentheight = getDistance(oPos, lng, lat);
        if (a == 0) {
            realheight = currentheight
        }
        if (realheight < currentheight) {
            realheight = currentheight
        }
    }
    var sTileset = whichTileset(lng, lat)[0];
    //获取单体化当前依附的模型
    if (sTileset) {
        var alt = realheight * 1.7320508075689 + 50 + sTileset._boundingSphere.center.z * 1 + sTileset.name.position.split(",")[2] * 1;
        return {
            "lat": lat,
            "lng": lng,
            "alt": alt
        };
    } else {
        return {
            "lat": lat,
            "lng": lng,
            "alt": realheight
        };
    }
    return {
        "lat": lat,
        "lng": lng,
        "alt": alt
    };
}
//根据经纬度获取当前经纬度下的模型集合
//x经度值 y维度值
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);
        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
//单个单体化删除
//id绘制时添加的唯一标识
monomerDataSource.entities.removeById(id)

//删除monomerDataSource对象中的所有单体化
monomerDataSource.entities.removeAll();

单体化编辑

JavaScript
//entity获取到的单体化要素对象
//1.编辑单体化样式
//编辑单体化的特殊字段
entity.name = '单体化面';
//编辑单体化材质(颜色)
entity.polygon.material = LSGlobe.Color.fromCssColorString('rgb(0,0,0)');
//编辑单体化的透明度
entity.polygon.material = LSGlobe.Color.fromCssColorString('rgb(0,0,0)').withAlpha('0.5')

//2.获取属性和属性值展示出来
var oEntityProperties = entity.properties.getValue();

for (var key in oEntityProperties) {
    console.log(key+":"+oEntityProperties.key);
}
//3.编辑单体化的属性属性值
//添加属性属性值
entity.properties.addProperty("属性","属性值");
//下面是整体属性替换(谨慎使用,会覆盖之前的属性)
entities.properties = {
    "属性":"属性值"
};
//删除属性属性值
entity.properties.removeProperty("属性");

单体化点击获取

JavaScript

//初始化一个鼠标事件
var handlerMonomer = new LSGlobe.ScreenSpaceEventHandler(viewer.scene.canvas);
handlerMonomer.setInputAction(function(movement) {
    var posit = viewer.scene.pick(movement.position);
    if (LSGlobe.defined(posit)) {
        //如果posit值存在说明鼠标点击的地方有内容
        //(该内容可以是标注,标绘,单体化,矢量数据等要素)需要判断该数据是什么类型需要根据该对象中的特殊字段来判断或者是否包含关系
        if ( !! posit.id && monomerDataSource.entities.contains(posit.id)) {
            //如果被monomerDataSource.entities包含则是单体化

        }
    }
},
LSGlobe.ScreenSpaceEventType.LEFT_CLICK);

单体化存储

单体化的存储是以 json 格式保存的,直接赋值给 oSubSceneData.monomer,然后随场景保存接口一并提交保存

JavaScript
oSubSceneData.monomer = monomerDataSource.toGeoJson()

单体化重载

标绘获取接口,参数 jsonType 为 3

//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) {
    //将数据再次加载到初始化存储标绘要素的对象中
    monomerDataSource = dataSource;
    //添加到球中
    viewer.dataSources.add(dataSource);
}).otherwise(function(error) {
    console.log(error);
});

Released under the MIT License.