Vue3 + Openlayers10示例 ol-wind风场


前言

假装已经完成了vue3和Openlayers10开发环境的搭建,如果有需要,可搜索vue+Openlayers环境搭建的相关文章。

本示例基于Vue3 和 Openlayers10 的环境,利用 ol-wind 插件实现风场效果。


一、安装插件

安装ol-wind插件。

//安装ol-wind插件
npm install ol-wind --save

安装成功后,在vue项目的package.json文件中会有ol-wind插件的依赖,如下图。

二、代码展示

项目中main.js的代码:

import { createApp } from "vue";
import App from "./App.vue";

createApp(App).mount("#app");

项目中App.vue的代码:

<template>
  <HomePage></HomePage>
</template>

<script>
  import HomePage from './views/HomePage.vue'

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

项目中.\views\HomePage.vue的代码:

<template>
	<div class="common-layout">
		<el-container>
			<el-aside width="200px">Vue+Openlayers 开发示例目录</el-aside>
			<el-container>
				<el-main>
					<OlWind></OlWind>
				</el-main>
				<!--<el-footer>@King空 @格子问道</el-footer>-->
			</el-container>
		</el-container>
	</div>
</template>
<script>
	/* eslint-disable */
	import OlWind from '../components/Ol_Wind.vue'

	export default {
		name: 'HomePage',
		components: {
			OlWind
		},
	}
</script>
<style scoped>
	.el-header {
		background-color: #B3C0D1;
		color: #333;
		text-align: center;
		text-size-adjust: 10px;
	}

	.el-footer {
		background-color: #B3C0D1;
		color: #333;
		text-align: center;
		line-height: 60px;
	}

	.el-aside {
		background-color: #D3DCE6;
		color: #333;
		text-align: center;
		line-height: 200px;
	}

	.el-main {
		background-color: #E9EEF3;
		color: #333;
		text-align: center;
	}

	body>.el-container {
		margin-bottom: 40px;
	}

	.el-container:nth-child(5) .el-aside,
	.el-container:nth-child(6) .el-aside {
		line-height: 260px;
	}

	.el-container:nth-child(7) .el-aside {
		line-height: 320px;
	}
</style>

提示:为了方便初始化地图对象和底图,我新建了一个继承至Map的BaseMap类,放在.\src\components\BaseMap.js里。

项目中.\src\components\BaseMap.js的代码如下:

/* eslint-disable */
import "ol/ol.css";
import * as olProj from "ol/proj";
import { Map, View } from "ol";
import Tile from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";

/**
 * @classdesc
 * The map is the core component of OpenLayers. For a map to render, a view,
 * one or more layers, and a target container are needed:
 *
 *     import Map from 'ol/Map.js';
 *     import View from 'ol/View.js';
 *     import TileLayer from 'ol/layer/Tile.js';
 *     import OSM from 'ol/source/OSM.js';
 *
 *     const map = new Map({
 *       view: new View({
 *         center: [0, 0],
 *         zoom: 1,
 *       }),
 *       layers: [
 *         new TileLayer({
 *           source: new OSM(),
 *         }),
 *       ],
 *       target: 'map',
 *     });
 *
 * The above snippet creates a map using a {@link module:ol/layer/Tile~TileLayer} to
 * display {@link module:ol/source/OSM~OSM} OSM data and render it to a DOM
 * element with the id `map`.
 *
 * The constructor places a viewport container (with CSS class name
 * `ol-viewport`) in the target element (see `getViewport()`), and then two
 * further elements within the viewport: one with CSS class name
 * `ol-overlaycontainer-stopevent` for controls and some overlays, and one with
 * CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`
 * option of {@link module:ol/Overlay~Overlay} for the difference). The map
 * itself is placed in a further element within the viewport.
 *
 * Layers are stored as a {@link module:ol/Collection~Collection} in
 * layerGroups. A top-level group is provided by the library. This is what is
 * accessed by `getLayerGroup` and `setLayerGroup`. Layers entered in the
 * options are added to this group, and `addLayer` and `removeLayer` change the
 * layer collection in the group. `getLayers` is a convenience function for
 * `getLayerGroup().getLayers()`. Note that {@link module:ol/layer/Group~LayerGroup}
 * is a subclass of {@link module:ol/layer/Base~BaseLayer}, so layers entered in the
 * options or added with `addLayer` can be groups, which can contain further
 * groups, and so on.
 *
 * @fires import("./MapBrowserEvent.js").MapBrowserEvent
 * @fires import("./MapEvent.js").MapEvent
 * @fires import("./render/Event.js").default#precompose
 * @fires import("./render/Event.js").default#postcompose
 * @fires import("./render/Event.js").default#rendercomplete
 * @api
 */
class BaseMap extends Map {
  /**
   * @param {MapOptions} [options] Map options.
   */
  constructor(options) {
    //console.log("BaseMap 构造函数");
    super(options);

    //添加基础底图图层
    this.addLayer(
      new Tile({
        source: new XYZ({
          //高德地图
          url: "https://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8",
        }),
      })
    );
    //设置View
    this.setView(
      new View({
        projection: "EPSG:3857",
        center: olProj.transform([110, 30], "EPSG:4326", "EPSG:3857"),
        zoom: 3,
      })
    );
  }
}
export default BaseMap;

至此,准备工作已完成,该示例中最主要的风场组件.\src\components\Ol_Wind.vue的代码如下:

<template>
    <div class="header">
        <h2>利用 ol-wind 实现风场效果</h2>
    </div>
    <div id="vue-openlayers"></div>
</template>
<script>
    /* eslint-disable */
    //导入自定义基础地图
    import BaseMap from './BaseMap.js';

    //导入ol-wind插件
    import { WindLayer } from "ol-wind"
    //本地风场数据Json文件
    import winddata from "../assets/wind.json"

    export default {
        name: 'Ol-Wind',
        data() {
            return {
                map: null,
                windLayer: null,
            }
        },
        methods: {
            initMap() {
                //创建基础地图
                this.map = new BaseMap({
                    target: "vue-openlayers",
                });

                //创建风场图层(添加风场数据)
                this.windLayer = new WindLayer(winddata, {
                    windOptions: {
                        velocityScale: 0.05,
                        paths: 3200,
                        // eslint-disable-next-line no-unused-vars
                        colorScale: [
                            "rgb(36,104, 180)",
                            "rgb(60,157, 194)",
                            "rgb(128,205,193 )",
                            "rgb(151,218,168 )",
                            "rgb(198,231,181)",
                            "rgb(238,247,217)",
                            "rgb(255,238,159)",
                            "rgb(252,217,125)",
                            "rgb(255,182,100)",
                            "rgb(252,150,75)",
                            "rgb(250,112,52)",
                            "rgb(245,64,32)",
                            "rgb(237,45,28)",
                            "rgb(220,24,32)",
                            "rgb(180,0,35)"
                        ],
                        lineWidth: 3,
                        generateParticleOption: false
                    },
                    fieldOptions: {
                        wrapX: false,
                    },
                });
                this.map.addLayer(this.windLayer);      //添加风场图层
            },
        },
        mounted() {
            this.initMap();
        },
    }
</script>

<style scoped>
    #vue-openlayers {
        width: auto;
        height: 800px;
        margin: auto;
        border: 2px solid #4845e490;
    }

    .header {
        width: auto;
        border: 2px solid #4845e490;
        margin: auto;
        text-align: center;
    }
</style>

提示:在Ol_Wind.vue代码里用到的风场数据文件已上传,可自行下载并放到相应目录,当前示例是放在了assets目录下,使用时通过import引入。

    //本地风场数据Json文件
    import winddata from "../assets/wind.json"

提示:ol-wind的WindLayer风场图层支持两种方式设置风场数据

方法1:利用构造函数的第一个参数data传入。

方法2:利用setData方法传入。

ol-wind中设置风场数据的相关源码如下:

//WindLayer类(data:风场Json数据,options:图层参数)
class WindLayer extends layer.Layer {
    constructor(data, options) {
      const opt = assign({}, _options, options);
      super(opt);
      this.options = opt;
      this.className_ = options.className !== void 0 ? options.className : "wind-layer";
      this.pickWindOptions();
      if (data) {
        this.setData(data, options.fieldOptions);
      }
    }


     /**
     * 设置风场图层数据
     * set layer data
     * @param data 风场数据
     * @param options
     * @returns {WindLayer}
     */
    setData(data, options = {}) {
      if (data && data.checkFields && data.checkFields()) {
        this.field = data;
      } else if (isArray(data)) {
        this.field = formatData(data, options);
      } else {
        console.error("Illegal data");
      }
      const renderer = this.getRenderer();
      if (renderer && this.field) {
        renderer.setData(this.field);
      }
      this.changed();
      return this;
    }

总结

本示例基于 Vue 3.5.3 和 Openlayers 10.1.0 开发,相关插件也均采用能够兼容的版本,可根据自身需要适当取舍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值