Vue3+Cesium开发教程(23)——Cesium动态标绘和编辑文字、图标(图片)、glb模型

61 阅读3分钟

本学习系列以Cesium + Vue3 +Typescript+elementplus作为主要技术栈。详情请查阅原文Vue3+Cesium学习教程系列(23)——Cesium动态标绘和编辑文字、图标(图片)、glb模型

以下便是在Cesium中实现文字、图标(图片)、模型标绘与编辑的步骤。首先新建文字类(CommonLabel)、图标类(CommonBillboard)、模型类(CommonModel)。三个类均继承BaseDraw即可。具体代码如下

import { CallbackPositionProperty, Cartesian2, Cartesian3, Color, Entity, HeightReference, HorizontalOrigin, LabelGraphics, LabelStyle, VerticalOrigin, Viewer } from "cesium";
import { BaseDraw, GeometryType } from "../BaseDraw";
import EventDispatcher from "@/system/EventDispatcher/EventDispatcher";
export default class CommonLabel extends BaseDraw {
    private labelOption: LabelGraphics.ConstructorOptions
    constructor(viewer: Viewer, dispatcher: EventDispatcher) {
        super(viewer, dispatcher);
        this.geometryType = GeometryType.COMMON_LABEL;
        this.labelOption = {
            text: '测试名称xttx110',
            font: '14pt Source Han Sans CN',
            fillColor: Color.BLUE,
            backgroundColor: Color.YELLOW,
            showBackground: true,
            scale: 1.0,
            style: LabelStyle.FILL_AND_OUTLINE,
            // 相对于坐标的水平位置
            verticalOrigin: VerticalOrigin.CENTER,
            // 相对于坐标的水平位置
            horizontalOrigin: HorizontalOrigin.LEFT,
            // 该属性指定标签在屏幕空间中距此标签原点的像素偏移量
            pixelOffset: new Cartesian2(10, 0),
            // 关闭深度测试,避免被地形遮挡
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
            // 贴地显示(与 point 保持一致)
            heightReference: HeightReference.CLAMP_TO_GROUND,
            // 是否显示
            show: true
        }
    }
    protected buildFinalEntity(): Entity {
        const pos = this.getPositions()[0];
        return this.viewer.entities.add({
            position: pos,
            point: { pixelSize: 12, color: Color.RED, heightReference: HeightReference.CLAMP_TO_GROUND, disableDepthTestDistance: Number.POSITIVE_INFINITY },
            label: this.labelOption
        });
    }
    protected buildTempEntity(): Entity | undefined {
        return this.viewer.entities.add({
            position: new CallbackPositionProperty(() => this.tempCursor || new Cartesian3(), false),
            point: { pixelSize: 12, color: Color.RED, heightReference: HeightReference.CLAMP_TO_GROUND, disableDepthTestDistance: Number.POSITIVE_INFINITY },
            label: this.labelOption
        });
    }
    protected onLeftClick(e: any) {
        super.onLeftClick(e);
        // 点只需要 1 次点击即可结束
        this.finish();
    }
}
import { BillboardGraphics, CallbackPositionProperty, Cartesian3,  Entity, HeightReference, HorizontalOrigin,  VerticalOrigin, Viewer } from "cesium";
import { BaseDraw, GeometryType } from "../BaseDraw";
import EventDispatcher from "@/system/EventDispatcher/EventDispatcher";
export default class CommonBillboard extends BaseDraw {
    private billboardOption:BillboardGraphics.ConstructorOptions
    constructor(viewer: Viewer, dispatcher: EventDispatcher) {
        super(viewer, dispatcher);
        this.geometryType = GeometryType.COMMON_LABEL;
        this.billboardOption={
            // 图像地址,URI或Canvas的属性
                image: '/testdata/images/mark1.png',
                // 高度(以像素为单位)
                height: 50,
                // 宽度(以像素为单位)
                width: 50,               
                // 相对于坐标的垂直位置
                verticalOrigin: VerticalOrigin.BOTTOM,
                // 相对于坐标的水平位置
                horizontalOrigin: HorizontalOrigin.CENTER,                
                // 关闭深度测试,避免被地形遮挡
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
                // 贴地显示(与 point 保持一致)
                heightReference: HeightReference.CLAMP_TO_GROUND,
                // 应用于图像的统一比例。比例大于会1.0放大标签,而比例小于会1.0缩小标签。
                scale: 1.0,
                // 是否显示
                show: true
        }
    }
    protected buildFinalEntity(): Entity {
        const pos = this.getPositions()[0];
        return this.viewer.entities.add({
            position: pos,
            // point: { pixelSize: 12, color: Color.RED, heightReference: HeightReference.CLAMP_TO_GROUND, disableDepthTestDistance: Number.POSITIVE_INFINITY },
            billboard: this.billboardOption
        });
    }
    protected buildTempEntity(): Entity | undefined {
        return this.viewer.entities.add({
            position: new CallbackPositionProperty(() => this.tempCursor || new Cartesian3(), false),
            billboard: this.billboardOption
        });
    }
    protected onLeftClick(e: any) {
        super.onLeftClick(e);
        // 点只需要 1 次点击即可结束
        this.finish();
    }
}
import { CallbackPositionProperty, Cartesian3, Cartographic, Entity, HeightReference, ModelGraphics, Viewer } from "cesium";
import { BaseDraw, GeometryType } from "../BaseDraw";
import EventDispatcher from "@/system/EventDispatcher/EventDispatcher";
export default class CommonModel extends BaseDraw {
    private modelOption: ModelGraphics.ConstructorOptions;
    constructor(viewer: Viewer, dispatcher: EventDispatcher) {
        super(viewer, dispatcher);
        this.geometryType = GeometryType.COMMON_MODEL;
        this.modelOption = {
            // 引入模型
            uri: '/testdata/CesiumBalloon.glb',
            // 模型的近似最小像素大小,而不考虑缩放。
            minimumPixelSize: 150,
            // 是否执行模型动画
            runAnimations: true,
            // 应用于图像的统一比例。比例大于会1.0放大标签,而比例小于会1.0缩小标签。
            scale: 1.0,
            // 贴地显示(与 point 保持一致)
            heightReference: HeightReference.CLAMP_TO_GROUND,
            // 是否显示
            show: true
        }
    }
    protected buildFinalEntity(): Entity {
        const pos = this.getPositions()[0];
        // 把模型抬高一小段,避免被地形遮挡
        const carto = Cartographic.fromCartesian(pos);
        const raised = Cartesian3.fromRadians(carto.longitude, carto.latitude, carto.height + 2);
        return this.viewer.entities.add({
            position: raised,
            model: this.modelOption,
           
        });
    }
    protected buildTempEntity(): Entity | undefined {
        return this.viewer.entities.add({
            position: new CallbackPositionProperty(() => {
                const p = this.tempCursor || new Cartesian3();
                const c = Cartographic.fromCartesian(p);
                return Cartesian3.fromRadians(c.longitude, c.latitude, c.height + 2);
            }, false),
            model: this.modelOption,           
        });
    }
    protected onLeftClick(e: any) {
        super.onLeftClick(e);
        // 点只需要 1 次点击即可结束
        this.finish();
    }
}

然后将新添加的文字类、图表类和模型类添加到EditHelper中完成编辑功能。

case GeometryType.COMMON_LABEL:
case GeometryType.COMMON_BILLBOARD:
case GeometryType.COMMON_MODEL:
     this.shapeEntity.position = new ConstantPositionProperty(this.positions[this.positions.length - 1]);
     break;

来看看效果:

更多代码请查阅原文Vue3+Cesium学习教程系列(23)——Cesium动态标绘和编辑文字、图标(图片)、glb模型