vue+supermap iclient for mapboxgl 降雨分布展示的webgis项目:3

目录

 一、降雨数据

二、时间轴控件

1、时间轴样式设置

2、获取时间轴节点数组

5、时间轴控件的完整代码

二、市州降雨统计组件


本节主要完成时间轴和市州降雨统计两个控件。

时间轴控件用于切换降雨数据,实现大屏内部降雨数据动态展示,而市州降雨统计组件则是根据读取的降雨数据,显示当天对应雨量最大最小值出现的市州。

 一、降雨数据

在开始之前,需要先将降雨数据读取。在实际的开发应用中,数据应由后端人员从数据库或其他途径读取之后,通过接口返回给前端人员。由于本项目只是个人学习使用,数据量较小,故直接前端读取使用。

本项目使用的数据可在github中直接下载https://github.com/mosuiqin/weather/tree/main/src/data

其中,d开头的数据为完整的降雨数据,例如:d013008.json;city开头的数据为市州降雨量统计数据,例如:city013008.json;qx开头的数据为市州各区县降雨量统计数据,例如:qx013008.json。

二、时间轴控件

时间轴控件分为三种形式,分别为点,段,条

时间轴(点):时间轴(点) | Vue-iClient-MapboxGL

<SmTimeLine :data="data" style="width:100%" @timelinechanged="changed" @timelineplaychanged="playChanged"></SmTimeLine>

时间轴(段):时间轴(段) | Vue-iClient-MapboxGL

<SmTimeRange :data="data" style="width:100%" @datazoom="changed"></SmTimeRange>

 时间轴(条):时间轴(条) | Vue-iClient-MapboxGL

<SmTimeSlider :data="data" style="width:100%" @timeplayerchanged="changed" @timeplayerplaychanged="playChanged"></SmTimeSlider>

 

 本文采用时间轴(点)的方式来显示时间轴。

<sm-time-line
      v-bind="timeLineProps" //时间轴样式设置
      :data="data"  //时间轴节点数组
      style="width: 100%" //控件宽度
      @timelinechanged="changed"//时间轴中的时间点改变后的事件
      @timelineplaychanged="changed" //时间轴中播放状态的切换事件
      background="rgba(138, 134, 134, 0.8)"//背景色
    ></sm-time-line>
1、时间轴样式设置
 timeLineProps: {
        autoPlay: true, //动态播放
        playInterval: 3000,  //节点间隔
        lineStyle: {  
          color: '#8C8C8C',  
          width: 2,
          type: 'solid',
        },          //轴线样式设置  
        label: {
          color: 'white',
        },
      },
2、获取时间轴节点数组

采用vuex来存储时间轴节点,在store文件夹中新建index.js文件,用于存储项目数据。本项目将时间点变化存储在timeInfo中。

Vuex是一个用于Vue.js应用程序的状态管理模式和库。它可以帮助我们在Vue组件之间共享和管理应用程序的状态。

Vuex的核心概念包括:

①State(状态):应用程序的状态存储在一个单一的状态树中,即`state`。可以通过在组件中使用`this.$store.state`来访问状态。

②Mutations(变更):状态的变更通过提交一个`mutation`来进行。`mutation`是一个包含`type`和`payload`的对象,用于描述状态的变更操作。通过定义`mutations`,我们可以明确地追踪和记录状态的变化。

③Actions(动作):`actions`用于处理异步操作和复杂的逻辑。它们可以包含多个`mutation`的提交,并可以通过`commit`方法来触发`mutation`。在组件中,可以通过`this.$store.dispatch`来触发`actions`。

④Getters(获取器):`getters`用于从状态中派生出新的数据,类似于计算属性。它们可以接收状态作为第一个参数,并可以在组件中通过`this.$store.getters`来访问。

⑤Modules(模块):当应用程序变得复杂时,可以将`state`、`mutations`、`actions`和`getters`划分为模块。每个模块都有自己的`state`、`mutations`、`actions`和`getters`,并可以嵌套在其他模块中。

使用Vuex可以帮助我们更好地组织和管理应用程序的状态,并使不同组件之间的状态共享更加简单和可维护。它特别适用于大型应用程序或需要在多个组件之间共享状态的场景。

                                                                    index.js
import Vue from 'vue';
import Vuex from 'vuex';


Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        timeInfo: [],
        currentTime: {
            dataset: "d013008",
            time: " 01-30 08:00"
        },
    },
    mutations: {
        getTimeInfo(state) {
            const dataInfo = ['d013008', 'd020108', 'd020120', 'd020208', 'd020220', 'd020308', 'd020320', 'd020408', 'd020420']

            if (state.timeInfo.length === 0) {
                for (let i = 0; i < dataInfo.length; i++) {
                    const time = ` ${dataInfo[i].slice(1,3)}-${dataInfo[i].slice(3,5)} ${dataInfo[i].slice(5,7)}:00`
                    const timeDate = {
                        dataset: dataInfo[i],
                        time: time
                    }
                    state.timeInfo.push(timeDate)
                }
            }

        },

    },
});

export default store;

3、时间点改变后的事件changed

将对应的时间点传递给store,便于其他组件灵活读取

changed(e) {
      // 获取当前日期
      const currentTime = this.timeInfo[e.currentIndex]
      this.$store.commit('changeCurrentTime', currentTime)
      // 加载雨量图
      changeRainPointMap(this.map, currentTime.dataset)
    },

4、加载雨量图

changeRainPointMap的作用为判断当前地图中是否有雨量数据加载,若有则移除。需注意移除数据,要先removeLayer,再removeSource。

如果不需要移除数据,但又不希望在地图中显示,可设置图层的可见性,使其不可见,例如map.setLayoutProperty(layerId, 'visibility', 'none');

                                                      changeRainPointMap.js
import {
  loadRainData
} from './rainPontMap'
export const changeRainPointMap = (map, dataset) => {
  const layer = map.getStyle().layers
  let flag = 0
  let mapId
  for (let item of layer) {
    if (item.id.slice(0, 1) === 'd') {
      flag = 1
      mapId = item.id
    }
  }
  if (flag === 1) {
    map.removeLayer(mapId)
    map.removeSource(mapId)

  }
  loadRainData(map, dataset)
}

loadRainData的作用为读取对应时间的降雨数据,并将其添加到地图中

                                                            rainPointMap.js
export const loadRainData = (map,dataset) => {
    import(`../data/${dataset}.json`).then((res) => {
        const geojson = res.default
        map.addLayer({
            id: dataset,
            type: 'circle',
            source: {
                type: 'geojson',
                data: geojson,
            },
            paint: {
                'circle-color': {
                    property: dataset,
                    type: 'exponential',
                    stops: [
                        [0, 'rgba(0,0,0,0)'],
                        [0.5, '#9ecae1'],
                        [1, '#08306b'],
                    ],//设置色带
                },
                // 'circle-opacity':0.2
            },
        })
    })

}
5、时间轴控件的完整代码
                                                            mapTimeLine.vue
<template>
  <div class="smTime">
    <sm-time-line
      v-bind="timeLineProps"
      :data="data"
      style="width: 100%"
      @timelinechanged="changed"
      @timelineplaychanged="changed"
      background="rgba(138, 134, 134, 0.8)"
    ></sm-time-line>
  </div>
</template>

<script>
import { changeRainPointMap } from '../components/changeRainPointMap'
export default {
  name: 'mapTimeLine',
  props: ['timeInfo', 'map'],
  data() {
    return {
      timeLineProps: {
        // 动态播放
        autoPlay: true,
        playInterval: 3000,
        lineStyle: {
          color: '#8C8C8C',
          width: 2,
          type: 'solid',
        },
        label: {
          color: 'white',
        },
      },
    }
  },
  computed: {
    data() {
      return this.timeInfo.map((item) => item.time)
    },
  },
  methods: {
    changed(e) {
      // 获取当前日期
      const currentTime = this.timeInfo[e.currentIndex]
      this.$store.commit('changeCurrentTime', currentTime)
      // 加载雨量图
      changeRainPointMap(this.map, currentTime.dataset)
    },
  },
  mounted() {},
}
</script>

<style scoped>
.smTime {
  position: absolute;
  bottom: 0.1rem;
  left: 0.1rem;
  width: 98%;
}
</style>
二、市州降雨统计组件

市州降雨统计组件由三部分组成,对应时间,雨量最大值,雨量最小值,而这三个值由时间轴切换的时间点来动态控制,所以需要先从store中获取最新的时间值timeInfo,再根据timeInfo读取对应的市州降雨量统计数据

完整代码:

<template>
  <div class="mapContent">
    <div class="mapContent_time">{{ timeInfo.time }}</div>
    <div class="mapContent_maxmin">
      <div class="mapContent_max">
        <img src="../image/green.png" class="mapContent_max_img" />
        <div class="mapContent_max_city">{{ maxCity.slice(0, 2) }}</div>
        <div class="mapContent_max_value">{{ maxvalue.toFixed(2) }}</div>
      </div>

      <div class="mapContent_min">
        <img src="../image/red.png" class="mapContent_min_img" />
        <div class="mapContent_min_city">{{ minCity.slice(0, 2) }}</div>
        <div class="mapContent_min_value">{{ minvalue.toFixed(2) }}</div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'mapContent',
  data() {
    return {
      maxCity: '成都市',
      maxvalue: 0.17,
      minCity: '甘孜藏族自治州',
      minvalue: 0,
    }
  },
  computed: {
    timeInfo() {
      return this.$store.state.currentTime
    },
  },
  watch: {
//监听时间变化,若发生变化,则调用函数,读取新的统计数据
    'timeInfo.dataset'() {
      this.getData()
    },
  },
  methods: {
//读取市州降雨统计数据
    getData() {
      const dataset = this.timeInfo.dataset
      import(`../data/city${dataset.slice(1, 7)}.json`).then((res) => {
        const avgData = res.default.map((item)=>item.avg)

        //查询雨量最大值
        this.maxvalue = Math.max(...avgData)
        //查询雨量最大值对应的索引
        let maxindex = avgData.findIndex((item) => {
          return this.maxvalue == item
        })
        //查询雨量最大值对应的市州
        this.maxCity = res.default[maxindex].city

        //查询雨量最小值
        this.minvalue = Math.min(...avgData)
        //查询雨量最小值对应的索引
        let minindex = avgData.findIndex((item) => {
          return this.minvalue == item
        })
        //查询雨量最小值对应的市州
        this.minCity = res.default[minindex].city
      })
    },
  },
  mounted() {},
}
</script>

<style scoped>
.mapContent {
  position: absolute;
  top: 1rem;
  right: 0.2rem;
  background-color: rgba(138, 134, 134, 0.8);
  border-radius: 0.1rem;
  color: rgb(243, 240, 240);
  text-align: center;
  font-size: 0.15rem;
  padding: 0.05rem;
}
.mapContent_time {
  font-size: 0.15rem;
  text-align: left;
  font-weight: lighter;
}
.mapContent_maxmin {
  display: flex;
}
.mapContent_max {
  margin-right: 0.1rem;
}
.mapContent_max_img,
.mapContent_min_img {
  height: 0.15rem;
  width: .7rem;
}
.mapContent_max_city,
.mapContent_min_city {
  font-weight: bold;
}
.mapContent_max_value {
  color: rgb(134, 221, 134);
}
.mapContent_min_value {
  color: rgb(224, 142, 142);
}
</style>

完整项目代码可在github上获取:GitHub - mosuiqin/weather: 利用supermap iclient for mapboxgl 完成简单的气象可视化

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值