目录

  • 1、开发环境介绍
  • 1.1 node.js
  • 1.2 vue
  • 1.3 vue-cli
  • 1.4 Cesium
  • 1.5 GeoServe
  • 1.6 vscode
  • 2、部署开发环境
  • 2.1 安装node.js
  • 2.2 安装vue.js
  • 2.3 安装vue脚手架
  • 2.4 创建项目
  • 2.5 配置cesium
  • 2.6 部署初始地图界面
  • 3、DEM地形加载
  • 3.1 cesium实验室安装
  • 3.2 DEM切片及服务发布
  • 3.3 在地图中添加地形图服务
  • 3.4 启动服务
  • 4、GeoServer服务发布、调用
  • 4.1 安装GeoServer
  • 4.2 发布地理数据服务
  • 4.3 解决跨域问题
  • 4.4 调用地图服务

1、开发环境介绍

1.1 node.js

版本:v14.17.3

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,而cesium必须要部署web服务器才可以运行,因此使用node.js作为开发服务器,node.js需要在网站上下载本地安装包进行安装并部署环境变量。

1.2 vue

版本:v2.6.11

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式javascript框架。笔者因为对本框架比较熟悉,因此使用本JS框架来搭建本次环境。

1.3 vue-cli

版本:v4.5.0

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供:

  • 通过 @vue/cli 实现的交互式的项目脚手架。
  • 通过 @vue/cli + @vue/cli-service-global 实现的零配置原型开发。
  • 一个运行时依赖 (@vue/cli-service)

1.4 Cesium

版本:v1.87.1

Cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎。Cesium支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区域,并提供良好的触摸支持,且支持绝大多数的浏览器和mobile。

1.5 GeoServe

版本:2.20.1

GeoServer是一个基于Java的软件服务器,允许用户查看和编辑地理空间数据。 类似于IIS和tomcat的作用,不过GeoServer是专门用于空间数据的服务器。GeoServer需要基于JAVA环境。

1.6 vscode

VSCode(全称:Visual Studio Code)是一款由微软开发且跨平台的免费源代码编辑器

2、部署开发环境

2.1 安装node.js

下载安装包后安装即可,略过。

2.2 安装vue.js

在vscode或cmd终端中。

npm install vue -g

2.3 安装vue脚手架

在vscode或cmd终端中。

npm install vue-cli -g

2.4 创建项目

  • npx vue create 项目名称
  • 选择vue2项目
  • 安装cesium至当前项目下
    npm install cesium --save

2.5 配置cesium

设置cesium相关的webpack配置:

  • 建立一个vue.config.js文件
const path = require("path");
const TerserPlugin = require('terser-webpack-plugin');
 
const CopyWebpackPlugin = require('copy-webpack-plugin');
const webpack = require('webpack');
const cesiumSource = './node_modules/cesium/Source'
 
function resolve(dir) {
  return path.join(__dirname, dir);
}
 
module.exports = {
  // 打包后运行环境目录
  publicPath: process.env.NODE_ENV === "production" ? "/projectName/" : "/",
 
  lintOnSave: true, // eslint-loader 是否在保存的时候检查
  productionSourceMap: false, // 生产环境是否生成 sourceMap 文件
  filenameHashing: true, // 文件hash
  /*
    配置vue-cli3项目,可以说是all in vue.config.js的。
    当然,封装、就一定会留个口给用户,去对底层进行自定义操作。
    vue.config.js的配置项中,有两个口,configureWebpack和chainWebpack。
    configureWebpack:
        是调整webpack配置最简单的一种方式,可以新增也可以覆盖cli中的配置。
    可以是一个对象:被 webpack-merge 合并到webpack 的设置中去
    也可以是一个函数:如果你需要基于环境有条件地配置行为,就可以进行一些逻辑处理,可以直接修改或
    新增配置,(该函数会在环境变量被设置之后懒执行)。该方法的第一个参数会收到已经解析好的配置。
    在函数内,你可以直接修改配置,或者返回一个将会被合并的对象。
    chainWebpack:
        这个库提供了一个 webpack 原始配置的上层抽象,使其可以定义具名的 loader 规则
    和具名插件,可以通过其提供的一些方法链式调用,在cli-service中就使用了这个插件
  */
  configureWebpack: {
    output: {
      sourcePrefix: ' ' // 1 让webpack 正确处理多行字符串配置 amd参数
    },
    amd: { // 2
      toUrlUndefined: true // webpack在cesium中能友好的使用require
    },
    resolve: {
      extensions: ['.js', '.vue', '.json'],
      alias: {
        'cesium': path.resolve(__dirname, cesiumSource) // 3 定义别名cesium后,cesium代表了cesiumSource的文件路径
      }
    },
    plugins: [ // 4、配置webpack直接复制
      new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Workers'), to: 'Workers' }]),
      new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Assets'), to: 'Assets' }]),
      new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' }]),
      new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'ThirdParty/Workers'), to: 'ThirdParty/Workers' }]),
      new webpack.DefinePlugin({ // 5
        CESIUM_BASE_URL: JSON.stringify('./')
      })
    ],
    // module: {
    //   unknownContextRegExp: /^.\/.*$/,
    //   unknownContextCritical: false // 6 不让webpack打印载入特定库时候的警告
    // }
    optimization: {
      minimizer: [
        new TerserPlugin({
          terserOptions: {
            ecma: undefined,
            warnings: false,
            parse: {},
            compress: {
              drop_console: true,
              drop_debugger: false,
              pure_funcs: ['console.log'] // 移除console
            }
          },
        }),
      ]
    },
  },
 
  chainWebpack: config => {
    // 配置import 和 require 等路径别名,webpack中是通过 resolve.alias 来实现此功能的,通过set方法添加修改想要的alias 配置
    config.resolve.alias
      .set("@", resolve("src"))
      .set("spatial", resolve("public/SpatialData"))
      .set("assets", resolve("src/assets"))
      .set("components", resolve("src/components"));
  },
 
  // 修改浏览中的标签logo
  pwa: {
    iconPaths: {
      favicon32: "favicon.ico",
      favicon16: "favicon.ico",
      appleTouchIcon: "favicon.ico",
      maskIcon: "favicon.ico",
      msTileImage: "favicon.ico"
    }
  },
 
  // 多页面方式
  // pages: {
  //   index: {
  //     entry: './src/main',
  //     template: './public/index.html',
  //     fileName: 'index.html',
  //   },
  //   weui: {
  //     entry: './src/wmain',
  //     template: './public/windex.html',
  //   }
  // },
 
  css: {
    loaderOptions: {
      sass: {
        // implementation: require('sass'), // This line must in sass option
        // prependData: `@import "@/assets/scss/mixin.scss";` //引入全局变量
      },
    },
  },
 
};
  • 由于在./node_modules/cesium/Source/ThirdParty/zip.js 文件中使用了 import.meta 语法,因此我们需要安装loader
    npm install @open-wc/webpack-import-meta-loader --save-dev安装好了以后继续在vue.config.js中添加(在plugins[…]后面)loader的相关配置。
module: {
      rules: [
      {
      test: /\.js$/,
      use: {
      loader: '@open-wc/webpack-import-meta-loader',
      },
      },
    ]}

2.6 部署初始地图界面

  • 完成cesium相关配置后,在mani.js中挂载cesium到vue.prototype上
import Vue from 'vue'
import App from './App.vue'

// 引入cesium相关文件
var cesium = require('cesium/Cesium.js');
var widgets = require('cesium//Widgets/widgets.css');

Vue.config.productionTip = false
//将cesium对象挂载到vue原型上
Vue.prototype.cesium = cesium
Vue.prototype.widgets = widgets

new Vue({
  render: h => h(App),
}).$mount('#app')
  • 在manin.JS挂载的APP.vue上导入HelloWord.vue组件并清空其他内容
<template>
  <div id="app">
    <HelloWorld />
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
  • 修改helloWord.Vue的代码
<template>
 <div id="container" class="box">
    <div id="cesiumContainer"></div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
   methods: {
    init () {
      const Cesium = this.cesium//获取原型中的Cesium对象
      const viewer = new Cesium.Viewer('cesiumContainer');//创建地图对象,挂载至模板中
      viewer._cesiumWidget._creditContainer.style.display = "none";// 隐藏版权
    }
  },
  mounted () {
    this.init()
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
html,
body,
#cesiumContainer {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
.box {
  height: 100%;
}
</style>
  • 使用npm dev serve在本地启动项目,效果如下。

3、DEM地形加载

3.1 cesium实验室安装

  • Cesiumlab是一款专为Cesium开源数字地球平台打造的免费数据处理工具集。我们可以使用它将DEM数据切片及发布服务,下载地址:http://www.cesiumlab.com/。
  • 安装完成后启动Cesiumlab,将会启动一个web服务器和一个可视化操作界面(网页)
    操作界面:

使用手机号码注册登录后即可进行数据切片及服务发布。

3.2 DEM切片及服务发布

  • 如下图,输入文件为TIF格式的DEM影像,输入前在ARCGIS中检查坐标系信息是否齐全,DEM是否正常显示。
  • 下图为切片过程进程,切片完成后将在web服务器自动发布该DEM切片服务。
  • 切片完成后进入服务列表查看:
  • 通过右侧的预览图标可进入cesium服务预览界面,影像服务的加载速度极大影响切片速度,建议将底图修改为arcgis在线影像或其他加载速度较快的影像。

3.3 在地图中添加地形图服务

  • cesium中管理地形服务的对象为:CesiumTerrainProvider,在应用创建的生命周期中通过该类创建地形对象(HelloWord.vue中)。
const terrainProvider = new Cesium.CesiumTerrainProvider({
      url: 'http://localhost:9003/terrain/GPFHT7F4/'
      });
      viewer.terrainProvider = terrainProvider;
  • 再通过之前创建的地图对象将地形挂载viewer.terrainProvider = terrainProvider;
  • 将相机位置控制到DEM所在位置
viewer.camera.flyTo({
          destination:Cesium.Cartesian3.fromDegrees(115.601, 29.105, 15000.0)
        });

整个HelloWord.vue代码如下:

<template>
 <div id="container" class="box">
    <div id="cesiumContainer"></div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
   data(){

   },
   methods: {
    init () {
      const Cesium = this.cesium
      const viewer = new Cesium.Viewer('cesiumContainer' );
      //CesiumTerrainProvider函数是cesium中地形图的函数
      const terrainProvider = new Cesium.CesiumTerrainProvider({
      url: 'http://localhost:9003/terrain/GPFHT7F4/'
      });
      viewer.terrainProvider = terrainProvider;
      //控制相机位置 
      viewer.camera.flyTo({
          destination:Cesium.Cartesian3.fromDegrees(115.601, 29.105, 15000.0)
        });

      viewer._cesiumWidget._creditContainer.style.display = "none";// 隐藏版权
    }
  },
  mounted () {
    this.init()
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
html,
body,
#cesiumContainer {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
.box {
  height: 100%;
}
</style>

3.4 启动服务

  • 使用npm run serve命令启动服务,在LOCALHOST:8080中打开,缩放至地形变化明显的地方即可看见DEM渲染。

4、GeoServer服务发布、调用

4.1 安装GeoServer

GeoServer基于Java开发,因此安装前必须确保安装了Java。

官网http://geoserver.org/download/下载稳定版,文中使用2.20.0。

除了端口号要单独设置,其他的设置都接受默认值即可。

安装完成后,在左下角程序中选择Start GeoServer即可启动服务,进入http://localhost:8010/geoserver(端口号按安装时选择变化)。

geoserver 修改javahome geoserver dem_ide

4.2 发布地理数据服务

首先创建一个工作区,并启用工作区。

geoserver 修改javahome geoserver dem_Vue_02

再选择数据源,添加一个新的数据源

geoserver 修改javahome geoserver dem_ico_03

选择shapefile矢量数据源:

geoserver 修改javahome geoserver dem_ico_04

选择数据路径并保存关闭:

geoserver 修改javahome geoserver dem_ide_05

再进入图层预览就能看见我们发布的数据图层了,由于GeoServer不支持WFS服务,因此我们使用WMS(选择png图片)先进行展示

geoserver 修改javahome geoserver dem_Vue_06

弹出的网页中,就是我们的服务地址了。

geoserver 修改javahome geoserver dem_ide_07

4.3 解决跨域问题

跨域问题的本质是现代浏览器对网站的一种保护,禁止在A处获取的HTML页面里去调取B处的资源,A和B是否一处的定义是http(协议)IP(或域名)端口号都完全一致,如下例:

在我们的GeoServer服务的搭建时,我们在cesium的页面中(http://localhost:8080/)获取地图数据(http://localhost:8091/geoserver/cite/wms)时,就面临了端口不一致的问题,但是端口又不能重复使用,因此必须跨域问题必须解决。

而通过cesium实验室发布的数据没有这个问题,应该是cesium实验室已经做过处理了。

我们通过打开cesium实验室的请求数据瓦片,看到Headers(请求头)中已经携带了Access-Control-Allow-Origin: *的信息,即声明本请求不需要受到保护。

geoserver 修改javahome geoserver dem_ide_08

解决这个问题的办法就是像cesium在请求B处资源时,带上请求头,而在geoServer中我们想要带上这个请求头需要去做如下处理:

  • 下载跨域jar包并将jar包放到Geoserver安装目录 \webapps\geoserver\WEBINF\lib文件夹下(GeoServer版本2.20.0,jar包版本对应v20180830)。
  • jar包链接:https://pan.baidu.com/s/1_t4yaCrVQxOyYmg2yFiyhQ 提取码:8888
  • 设置跨域配置。打开Geoserver安装目录 \webapps\geoserver\WEBINF\web.xml文件,找到文件中<!-- Uncomment following filter toenable CORS的位置,把跨域配置的注释放开。

geoserver 修改javahome geoserver dem_Vue_09

  • 重启GeoServe服务

4.4 调用地图服务

在地图组件的初始化方法中新建一个Cesium.WebMapServiceImageryProvider对象来对承载服务。

var imageryProvider1=new Cesium.WebMapServiceImageryProvider({
                url:'http://localhost:8010/geoserver/cite/wms',
                  //layers:['0','1'],
                 layers:'cite:S215',
                 parameters : {
                 service : 'WMS',
                 format: 'image/png',
                 transparent:true,
                 //show:false
                },
              });

在地图中添加本对象:

Viewer.imageryLayers.addImageryProvider(imageryProvider1);

再次进入工程后,效果如下:

geoserver 修改javahome geoserver dem_ide_10