1. 程式人生 > >Cesium實現文字、點、多段線、多邊形的實時繪制

Cesium實現文字、點、多段線、多邊形的實時繪制

troy event pop rap 重要 矢量圖形 def 記錄 mov

背景知識

點、線、面以及文字的實時繪制是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;
    }
}

效果圖

技術分享圖片

Cesium實現文字、點、多段線、多邊形的實時繪制