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

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

效果圖