我的个人博客

人生三境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。

Cesium实现文字、点、多段线、多边形的实时绘制

背景知识

点、线、面以及文字的实时绘制是GIS很重要的一个功能,是用户对感兴趣区域标注的业务需要。同时Cesium提供了点、线(多段线)、面及文字(label)绘制的接口绘制方式总共有两种,一种是通过Entity实体的方式,一种是通过Primitives的方式。第一种使用较为简单,是在Primitives基础上进行了封装;第二种则更加贴近WebGL底层,语法更复杂但是绘制效率更高效率。鉴于实时绘制数据量并不大,不需要使用复杂高效的方法,第一种方法完全适用。

Cesium通过ScreenSpaceEventHandler方法添加鼠标监听,包括鼠标的移动、点击等,同时会把鼠标的位置信息以回调函数方式返回。通过监听用户鼠标状态实现矢量图形及文字注记的位置记录。

CallbackProperty监听:当变量变化时触发该监听,通过监听鼠标拾取坐标的变化实现动态绘制。

代码实现

记录点位

var location = {
    latitude: 0,
    longitude: 0,
    height: 0,
    endPosition: null,
    cartesian : null
};
viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(movement) {
    //记录移动位置
    location.endPosition = viewer.scene.pickPosition(movement.endPosition);
},Cesium.ScreenSpaceEventType.MOUSE_MOVE);

viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) {
    var cartesian = viewer.scene.pickPosition(movement.position);
    //记录点击位置
    location.cartesian = cartesian;
    var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
    location.latitude = Cesium.Math.toDegrees(cartographic.latitude);
    location.longitude = Cesium.Math.toDegrees(cartographic.longitude);
    location.height = cartographic.height;
},Cesium.ScreenSpaceEventType.LEFT_CLICK);

绘制文字注记

var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    handler.setInputAction(function(movement) {
        var label = new Cesium.Entity({
            position : Cesium.Cartesian3.fromDegrees(location.longitude, location.latitude,location.height),
            name : 'label',
            label:{
                text: '文字',
                font: '24px Helvetica',
                fillColor: Cesium.Color.SKYBLUE,
                outlineColor: Cesium.Color.BLACK,
                outlineWidth: 2,
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                scaleByDistance: new Cesium.NearFarScalar(100, 1.0, 200, 0.4)
            }
        });
        viewer.entities.add(label);
        featureCollection.push(label);
        handler.destroy();
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
});

绘制点

document.getElementById('point').onclick = function () {
    var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    handler.setInputAction(function(movement) {
        var label = new Cesium.Entity({
            position : Cesium.Cartesian3.fromDegrees(location.longitude, location.latitude,location.height),
            name : 'point',
            point:{
                outlineColor: Cesium.Color.BLACK,
            }
        });
        viewer.entities.add(label);
        featureCollection.push(label);
        handler.destroy();
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};

绘制多段线

function drawPolyline() {
    var floatingPoint;
    var activePolyline;
    var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    handler.setInputAction(function(click) {
        //var position = viewer.scene.pickPosition(click.position);
        if(Cesium.defined(location.cartesian)){
            var cartesian = location.cartesian;
            if(activeShapePoints.length === 0){
                floatingPoint = creatPoint(cartesian);
                activeShapePoints.push(cartesian);
                var dynamicPositions = new Cesium.CallbackProperty(function() {
                    return activeShapePoints;
                },false);
                activePolyline = createPolyline(dynamicPositions);
            }
            activeShapePoints.push(cartesian);
            creatPoint(cartesian);
        }
    },Cesium.ScreenSpaceEventType.LEFT_CLICK);
    handler.setInputAction(function(movement) {
        if(Cesium.defined(floatingPoint)){
            if(Cesium.defined(location.endPosition)){
                floatingPoint.position.setValue(location.endPosition);
                activeShapePoints.pop();
                activeShapePoints.push(location.endPosition);
            }
        }
    },Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    handler.setInputAction(function(movement) {
        handler.destroy();
        for(var i=0;i<Points.length;i++){
            viewer.entities.remove(Points[i]);
        }
        Points = [];
    },Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

    function createPolyline(positionData) {
        var polyline;
        polyline = viewer.entities.add({
            name : 'polyline',
            polyline : {
                positions : positionData,
                //在地形上绘制多段线,但是在3dtilset模型上无效
                clampToGround : false,
                followSurface : false,
                material: Cesium.Color.RED,
                width : 3
            }
        });
        return polyline;
    }
}

绘制多边形

function drawPolygon() {
    var floatingPoint;
    var activePolygon;
    var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
    handler.setInputAction(function(click) {
        var position = viewer.scene.pickPosition(click.position);
        if(Cesium.defined(location.cartesian)){
            var cartesian = location.cartesian;
            if(activeShapePoints.length === 0){
                floatingPoint = creatPoint(cartesian);
                activeShapePoints.push(cartesian);
                var dynamicPositions = new Cesium.CallbackProperty(function() {
                    return activeShapePoints;
                },false);
                activePolygon = createPolygon(dynamicPositions);
            }
            activeShapePoints.push(cartesian);
            creatPoint(cartesian);
        }
    },Cesium.ScreenSpaceEventType.LEFT_CLICK);
    handler.setInputAction(function(movement) {
        if(Cesium.defined(floatingPoint)){
            if(Cesium.defined(location.endPosition)){
                floatingPoint.position.setValue(location.endPosition);
                activeShapePoints.pop();
                activeShapePoints.push(location.endPosition);
            }
        }
    },Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    handler.setInputAction(function(movement) {
        handler.destroy();
        for(var i=0;i<Points.length;i++){
            viewer.entities.remove(Points[i]);
        }
        Points = [];
    },Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
    function createPolygon(positionData) {
        var polygon;
        polygon = viewer.entities.add({
            name: 'polygon',
            positions : positionData,
            polygon:{
                hierarchy : positionData,
                perPositionHeight: true,
                material: Cesium.Color.RED.withAlpha(0.7),
                outline: true,
                outlineColor: Cesium.Color.YELLOW.withAlpha(1)
            }
        });
        return polygon;
    }
}

效果图

 

posted on 2018-11-24 21:41  把子肉爱上热干面  阅读(4133)  评论(1编辑  收藏  举报

导航