4. cesium1.95版本结合typescript搭建vue框架环境

  cesium1.95版本结合typescript整合vue版本配置搭建开发环境,开箱即用 

需要项目代码架子可以联系博主

vue.config.js

const {defineConfig} = require('@vue/cli-service')
const CopyWebpackPlugin = require("copy-webpack-plugin");
const webpack = require("webpack");
const path = require("path");

let cesiumSource = "./node_modules/cesium/Source";
let cesiumWorkers = "Workers";
module.exports = defineConfig({
    transpileDependencies: true,
    lintOnSave: false,
    configureWebpack: {
        externals: {
            'cesium': 'Cesium',
        },
        output: {
            sourcePrefix: " ", // 让webpack 正确处理多行字符串配置 amd参数
        },
        amd: {
            toUrlUndefined: true, // webpack在cesium中能友好的使用require
        },
        resolve: {
            extensions: ['.js', '.vue', '.json'],
            alias: {
                "@": path.resolve("src"),
                cesium: path.resolve(__dirname, cesiumSource),
            }
        },
        plugins: [
            new CopyWebpackPlugin({
                patterns: [
                    {from: path.join(cesiumSource, cesiumWorkers), to: "Workers"},
                    {from: path.join(cesiumSource, "Assets"), to: "Assets"},
                    {from: path.join(cesiumSource, "Widgets"), to: "Widgets"},
                    {from: path.join(cesiumSource, "ThirdParty/Workers"), to: "ThirdParty/Workers"}
                ]
            }),
            new webpack.DefinePlugin({
                CESIUM_BASE_URL: JSON.stringify("./"),
            }),
        ],
        module: {
            unknownContextCritical: false,
            unknownContextRegExp: /\/cesium\/cesium\/Source\/Core\/buildModuleUrl\.js/,
            rules: [
                {
                    test: /\.js$/,
                    use: {
                        loader: '@open-wc/webpack-import-meta-loader',
                    },
                },
            ]
        },
    },
    devServer: {
        hot: true,
        open: true,
        // 代理
        proxy: {
            '/api': {
                target: 'http://localhost:8080/',
                changeOrigin: true,
                ws: true,
                pathRewrite: {
                    '^/api': ''
                }
            }
        },
        port: 9999,
    }
})

main.ts

import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import 'cesium/Widgets/widgets.css';

Vue.config.productionTip = false
Vue.use(ElementUI);

new Vue({
    render: h => h(App),
}).$mount('#app')

helloworld.vue

<template>
    <div style="width: 100%;height: 100%;">
        <div id="cesiumContainer">
        </div>
    </div>
</template>

<script lang="ts">
    import {Component, Vue} from 'vue-property-decorator'; // ts装饰器
    import axios from 'axios';
    import FeatureSilhouette from '../FeatureSilhouette'
    import CustomBubbleWindow from './CustomBubbleWindow.vue'

    @Component({
        components: {CustomBubbleWindow},
    })
    export default class HelloWorld extends Vue {
        private options: any = {
            url: "/model/8564/tileset.json",
            maximumScreenSpaceError: 20,             //最大屏幕空间误差
            maximumNumberOfLoadedTiles: 10000,  //最大加载瓦片个数
        }
        private selectedFeature: any;
        private elementMap: any = {};
        public viewer: any = null;
        private params: any = {}
        private bathElements: any = [];//加载模型时使用的批量入库的
        private bathParams: any = [];
        private childThis: any = null;//子组件
        private keyword: any = null;//搜索的关键词
        private isSearch: boolean = false;
        private records: any = [];//搜索的记录

        mounted() {
            this.viewer = new Cesium.Viewer('cesiumContainer', {
                animation: false,    //左下角的动画仪表盘
                baseLayerPicker: false,  //右上角的图层选择按钮
                geocoder: false,  //搜索框
                homeButton: false,  //home按钮
                sceneModePicker: false, //模式切换按钮
                timeline: false,    //底部的时间轴
                navigationHelpButton: false,  //右上角的帮助按钮,
                fullscreenButton: false,   //右下角的全屏按钮
                infoBox: false
            })
            //	去除版权信息
            this.viewer._cesiumWidget._creditContainer.style.display = "none";
            //加载模型
            this.viewer.scene.primitives.add(new Cesium.Cesium3DTileset(this.options)).readyPromise.then((tileset: any) => {
                //监听加载与卸载bim
                tileset.tileLoad.addEventListener((tile: any) => {
                    this.processTileFeatures(tile, this.loadFeature);
                });
                //视口定位
                this.viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.0, -0.5, tileset.boundingSphere.radius * 4));
            })

            //描边
            let featureSilhouette = new FeatureSilhouette(this.viewer);
            featureSilhouette.initHighLightSilhouette(this.clickCallBack);
        }

        //接收子组件对象
        childThisReceive(childThis: any) {
            this.childThis = childThis
        }

        //选中回调函数
        private selectedCallBack(feature: any) {

        }

        //鼠标点击回调
        private clickCallBack(feature: any, position: any) {
            console.log(feature.getProperty("element"));
            console.log(position)
            //显示点击查询到的面板
            this.childThis.showInfo(position, feature, this.viewer);
        }

        //发送搜索请求,得到搜索结果
        private onSearch() {
            //之前选中的清理掉
            this.unselectFeature(this.selectedFeature)
            if (this.keyword) {
                //根据关键字查询bim
                this.searchFeature(this.keyword);
            }

        }

        //重置
        private onReset() {
            this.keyword = null;
            this.isSearch = false;
            this.records = [];
            this.unselectFeature(this.selectedFeature)
        }

        //处理搜索框选中高亮
        private handleSelectFeature(item: any) {
            console.log(item);
            if (item) {
                let element = item.element;
                //根据三维场景中加载好的object对象,和element,查找搜索到的bim
                let feature = this.elementMap[element][0];
                if (feature) {
                    //选择高亮
                    let  color = item.status==1?Cesium.Color.RED:item.status==2?Cesium.Color.YELLOW:Cesium.Color.BLUE;
                    this.selectFeature(feature,color);
                }
            }
        }

        private mouseSelectFeature() {
            let handler = this.viewer.screenSpaceEventHandler;
            handler.setInputAction((movement: any) => {
                const feature = this.viewer.scene.pick(movement.endPosition);
                this.unselectFeature(this.selectedFeature);
                if (feature instanceof Cesium.Cesium3DTileFeature) {
                    this.selectFeature(feature,null);
                }
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        }

        private selectFeature(feature: any,color:any) {
            const element = feature.getProperty("element");
            this.setElementColor(element, color);
            this.selectedFeature = feature;
        }

        private unselectFeature(feature: any) {
            if (!Cesium.defined(feature)) {
                return;
            }
            const element = feature.getProperty("element");
            this.setElementColor(element, Cesium.Color.WHITE);
            if (feature === this.selectedFeature) {
                this.selectedFeature = undefined;
            }
        }

        private setElementColor(element: any, color: any) {
            const featuresToColor = this.elementMap[element];
            const length = featuresToColor.length;
            for (let i = 0; i < length; ++i) {
                const feature = featuresToColor[i];
                feature.color = Cesium.Color.clone(color, feature.color);
            }
        }

        private getElement(feature: any) {
            return parseInt(feature.getProperty("element"), 10);
        }


        private unloadFeature(feature: any) {
            this.unselectFeature(feature);
            const element = this.getElement(feature);
            const features = this.elementMap[element];
            const index = features.indexOf(feature);
            if (index > -1) {
                features.splice(index, 1);
            }
        }

        private loadFeature(feature: any) {
            const element = this.getElement(feature);
            let features = this.elementMap[element];
            if (!Cesium.defined(features)) {
                features = [];
                this.elementMap[element] = features;
            }
            features.push(feature);
        }

        private processContentFeatures(content: any, callback: any) {
            const featuresLength = content.featuresLength;
            for (let i = 0; i < featuresLength; ++i) {
                const feature = content.getFeature(i);
                callback(feature);
            }
        }

        private processTileFeatures(tile: any, callback: any) {
            const content = tile.content;
            const innerContents = content.innerContents;
            if (Cesium.defined(innerContents)) {
                const length = innerContents.length;
                for (let i = 0; i < length; ++i) {
                    this.processContentFeatures(innerContents[i], callback);
                }
            } else {
                this.processContentFeatures(content, callback);
            }
        }

        //保存BIM模型属性信息到数据库
        private saveFeatureToDB(features: any) {
            for (const feature of features) {
                let center = feature.tileset.boundingSphere.center;
                this.params = {}
                if (center) {
                    this.params.x = center.x;//x坐标
                    this.params.y = center.y;//y坐标
                    this.params.z = center.z;//z坐标
                }
                var propertyNames = feature.getPropertyNames();
                var length = propertyNames.length;
                for (var i = 0; i < length; ++i) {
                    var propertyName = propertyNames[i];
                    console.log(propertyName + ': ' + feature.getProperty(propertyName));
                    this.params[propertyName] = feature.getProperty(propertyName)
                }
                this.bathParams.push(this.params)
            }

            axios.post('/api/bim/save', this.bathParams).then((response) => {
                console.log(response);
                this.bathElements = [];
            }).catch(function (error) {
                console.log(error);
            });
        }

        //查询BIM模型
        private searchFeature(keyword: string): any {
            //发送的ajax请求
            axios.get('/api/bim/list', {
                params: {
                    keyword: keyword
                }
            }).then((response) => {
                console.log(response.data.data.records);
                if (response.data && response.data.data && response.data.data.records) {
                    // todo 渲染列表
                    this.records = response.data.data.records;
                    this.isSearch = true;
                }

            }).catch(function (error) {
                console.log(error);
            });
        }
    }
</script>

<style lang="less" scoped>
    #cesiumContainer {
        width: 100%;
        height: 100%;
        overflow: hidden;
    }
</style>

App.vue

<template>
    <div id="app">
        <HelloWorld/>
    </div>
</template>

<script lang="ts">
    import {Component, Vue} from 'vue-property-decorator'; // ts装饰器
    import HelloWorld from './components/HelloWorld.vue'

    @Component({
        components: {
            HelloWorld
        }
    })
    export default class App extends Vue {

    }
</script>

<style>
    html, body, #app {
        padding: 0px;
        margin: 0px;
        width: 100%;
        height: 100%;
        overflow: hidden;
    }
</style>

shims-tsx.d.ts

import Vue, {VNode} from 'vue'

declare global {
    namespace JSX {
        // eslint-disable-next-line @typescript-eslint/no-empty-interface
        interface Element extends VNode {
        }
        // eslint-disable-next-line @typescript-eslint/no-empty-interface
        interface ElementClass extends Vue {
        }
        interface IntrinsicElements {
            [elem: string]: any;
        }
    }
    interface Window {
        __wxjs_environment: any;
        WebViewJavascriptBridge: any;
        _czc: any;
    }
}

shims-vue.d.ts

declare module '*.vue' {
    import Vue from 'vue'
    export default Vue
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小龙三维GIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值