基于 Vue 和 OpenLayers 的地理可视化应用搭建全解析

455 阅读4分钟

一、下载安装node.js

进入官网地址下载安装包

详细操作:

  1. 到官方网站下面下载(展示的为nodejs16版本,按照自己需求来进行安装) image.png
  2. 下载完成后,双击安装包,开始安装Node.js image.png image.png
  3. 直接点【Next】按钮,此处可根据个人需求修改安装路径,修改完毕后继续点击【Next】按钮 image.png
  4. 此处选择默认安装,可根据自身需求进行调整,继续点击【Next】按钮,Node.js runtime表示运行环境,npm package manager表示npm包管理器,online documentation shortcuts在线文档快捷方式,Add to PATH添加到环境变量 image.png
  5. 不选中,直接点击【Next】按钮 image.png
  6. 点击【Install】按钮进行安装 image.png
  7.  安装完毕,点击【Finish】按钮 image.png

测试安装是否成功

按下【win+R】键,输入cmd,打开cmd窗口,输入:node-v查看node.js版本,npm-v查看npm版本

image.png

命令如下: node -v npm -v

二、创建vue项目并在项目中搭建openlayers

npm install --global @vue-cli 是 vue 3.x及更高版本的 手脚架
npm install --global vue-cli 是 vue 2.x 的 手脚架(此文使用这个, 命令中的–global 可以更改成为–g) npm install --global vue-cli

74c53a3f01158ee53e486566ce615a38.png

注释:

Vue build ==> 打包方式,回车即可;

Install vue-router ==>是否要安装 vue-router,项目中肯定要使用到 所以Y 回车;

Use ESLint to lint your code ==>是否需要 js 语法检测 目前我们不需要 所以 n 回车;

Set up unit tests ==> 是否安装 单元测试工具 目前我们不需要 所以 n 回车;

Setup e2e tests with Nightwatch ==> 是否需要 端到端测试工具 目前我们不需要 所以 n 回车;

运行项目(npm run dev

创建vue-openlayers项目

在项目文件夹中打开cmd窗口,使用 npm install ol-save进行创建openlayers组件

三、安装一些常见的组件库(例如:elemenUl )

四、openlayers中文文档

9b5f73136d4424122f69453e68b1d39.png

五、示例代码

API_KEY替换自己天地图申请到的API Key(代码中可以切换三种地图类型,详细可以看天地图的文档)

<template>
    <!-- 基础图层组件的根容器 -->
    <div class="baseLayerRoot">
        <!-- Element UI 的弹出框组件,位置在右侧,宽度为 250px,触发方式为点击 -->
        <el-popover placement="right" :width="250" trigger="click">
            <!-- 弹出框的触发按钮,通过 isActive 控制按钮的样式 -->
            <el-button slot="reference" :class="{ 'popoverActive': isActive }" class="myPopover"></el-button>
            <!-- 弹出框的内容 -->
            <div>
                <!-- 地图选择项,点击触发 changeMap 方法,传入参数 1 -->
                <div class="mapSelect bottomMap" @click="changeMap(1)">
                    <div class="mapSelect bottomMapText">地图</div>
                </div>
                <!-- 影像选择项,点击触发 changeMap 方法,传入参数 2 -->
                <div class="mapSelect bottomImage" @click="changeMap(2)">
                    <div class="mapSelect bottomMapText">影像</div>
                </div>
                <!-- 地形选择项,点击触发 changeMap 方法,传入参数 3 -->
                <div class="mapSelect bottomTerrain" @click="changeMap(3)">
                    <div class="mapSelect bottomMapText">地形</div>
                </div>
            </div>
        </el-popover>
    </div>
</template>
<script>
// 注释掉的导入语句,可能用于移除和添加专业图层
//import {removeZhuanYeLayer,addZhuanYeLayer } from '@/assets/mapjs/delOrAddLayer';
// 导入 Vuex 存储
import store from "@/store";

export default {
    // 组件名称
    name: 'baseLayer',
    // 接收的属性,isActive 用于控制按钮样式
    props: ['isActive'],
    data() {
        return {
            // 地图对象,初始化为 null
            map: null, 
            // 检查列表,目前未使用
            checkList: [],
            // 图层映射,目前未使用
            layers: new Map(),
            // 基础图层对象,包含路网、影像和地形图层
            baseLayers: {
                路网: new ol.layer.Tile({
                    // 天地图路网图层的数据源
                    source: new ol.source.XYZ({
                        url: `http://t1.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=API_KEY`,
                        wrapX: false
                    }),
                }),
                影像: new ol.layer.Tile({
                    // 天地图影像图层的数据源
                    source: new ol.source.XYZ({
                        url: `http://t2.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=API_KEY`,
                        wrapX: false,
                    }),
                }),
                地形: new ol.layer.Tile({
                    // 天地图地形图层的数据源
                    source: new ol.source.XYZ({
                        url: `http://t3.tianditu.com/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=API_KEY`,
                        wrapX: false,
                    }),
                }),
            },
        }
    },
    mounted() {
        // 检查 store 中是否已经存在地图对象
        if (store.state.map.mapObj) {
            // 如果存在,将地图对象赋值给 this.map
            this.map = store.state.map.mapObj;
        } else {
            // 如果不存在,使用 watch 监听 store 中地图对象的变化
            const watcher = this.$watch(() => store.state.map.mapObj, (newValue) => {
                if (newValue) {
                    // 当地图对象有值时,将其赋值给 this.map
                    this.map = newValue;
                    // 停止监听
                    watcher(); 
                }
            });
        }
    },
    methods: {
        // 切换地图图层的方法,根据传入的 type 参数进行不同操作
        changeMap(type) {
            // 检查地图对象是否已经初始化
            if (!this.map) {
                console.error('地图对象未初始化');
                return;
            }
            if (type === 1) {
                // 当 type 为 1 时,移除影像和地形图层
                this.map.removeLayer(this.baseLayers.影像);
                this.map.removeLayer(this.baseLayers.地形);
            } else if (type === 2) {
                // 当 type 为 2 时,添加影像图层,移除地形图层
                this.map.addLayer(this.baseLayers.影像)
                this.map.removeLayer(this.baseLayers.地形);
            } else {
                // 当 type 为 3 时,移除影像图层,添加地形图层
                this.map.removeLayer(this.baseLayers.影像);
                this.map.addLayer(this.baseLayers.地形)
            }
        },
    },
}
</script>
<style scoped lang="scss">
.baseLayerRoot {
    position: absolute;
    bottom: 5px;
    left: 315px;

    .myPopover {
        max-height: 600px;
        overflow-x: hidden;
        position: absolute;
        background-position: 50% 50%;
        background-repeat: no-repeat;
        display: block;
        background-image: url("../../assets/images/u106.svg");
        width: 40px;
        height: 40px;
        bottom: 20px;
        -webkit-transition: 0.2s;
        transition: 0.2s;
        // left: 10px;
        // padding: 0px;
    }

    .el-popover {
        position: absolute;
        bottom: 10px;
        left: 10px;
        z-index: 1000;
        padding: 0px;

    }
}

.mapSelect {
    position: relative;
    width: 68px;
    height: 63px;
    display: inline-block;
    margin-left: 5px;
    margin-top: 5px;
    cursor: pointer;
}

.bottomMapText {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 68px;
    height: 18px;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    text-align: center;
    z-index: 1002;
    font-size: 12px;
    line-height: 18px;
    margin: 0;
}

.bottomMap {
//本地照片
    background: url("../../assets/images/map.png");
}

.bottomImage {
//本地照片
    background: url("../../assets/images/image.png");
}

.bottomTerrain {
//本地照片
    background: url("../../assets/images/terrain.png");
}

.popoverActive {
    //建议用js控制
    left: -306px;
}
</style>