mapv+openlayers+vue

96 阅读1分钟

image.png

<template>
  <div
    id="supermap"
    ref="supermap"
    class="supermap"
    style="height: 100vh; width: calc(100% - 20px); margin: 0 14px 0 10px"
  ></div>
</template>
<script>
import { Mapv } from '@supermap/iclient-ol/overlay/Mapv'
import { Image as ImageLayer } from 'ol/layer'
import Map from 'ol/Map'
import View from 'ol/View'
import TileLayer from 'ol/layer/Tile'
import OSM from 'ol/source/OSM'
import { fromLonLat, transform } from 'ol/proj'
import * as mapv from 'mapv'

export default {
  name: 'map',

  mounted() {
    this.$nextTick(() => {
      const map = new Map({
        target: 'supermap',
        layers: [
          new TileLayer({
            source: new OSM()
          })
        ],
        view: new View({
          center: fromLonLat([116.404, 39.915]),
          zoom: 5
        })
      })

      var citys = [
        '北京',
        '天津',
        '上海',
        '重庆',
        '石家庄',
        '太原',
        '呼和浩特',
        '哈尔滨',
        '长春',
        '沈阳',
        '济南',
        '南京',
        '合肥',
        '杭州',
        '南昌',
        '福州',
        '郑州',
        '武汉',
        '长沙',
        '广州',
        '南宁',
        '西安',
        '银川',
        '兰州',
        '西宁',
        '乌鲁木齐',
        '成都',
        '贵阳',
        '昆明',
        '拉萨',
        '海口'
      ]
      const randomCount = 500
      const node_data = { 0: { x: 108.154518, y: 36.643346 }, 1: { x: 121.485124, y: 31.235317 } }
      const edge_data = [{ source: '1', target: '0' }]

      for (let i = 1; i < randomCount; i++) {
        const city = citys[Math.floor(Math.random() * citys.length)]
        const cityCenter = mapv.utilCityCenter.getCenterByCityName(city)
        node_data[i] = {
          x: cityCenter.lng - 5 + Math.random() * 10,
          y: cityCenter.lat - 5 + Math.random() * 10
        }
        edge_data.push({ source: Math.floor(i * Math.random()), target: '0' })
      }

      const fbundling = mapv.utilForceEdgeBundling().nodes(node_data).edges(edge_data)
      const results = fbundling()

      // 修正坐标转换
      const transformCoords = (coordinates) => coordinates.map((coord) => fromLonLat([coord[0], coord[1]]))

      const data = []
      const timeData = []

      results.forEach((line) => {
        const coordinates = line.map((point) => [point.x, point.y])
        data.push({
          geometry: {
            type: 'LineString',
            coordinates: transformCoords(coordinates)
          }
        })

        line.forEach((point, j) => {
          timeData.push({
            geometry: {
              type: 'Point',
              coordinates: fromLonLat([point.x, point.y])
            },
            count: 1,
            time: j
          })
        })
      })

      // 添加图层
      const dataSet = new mapv.DataSet(data)
      const options = {
        map: map,
        dataSet: dataSet,
        mapvOptions: {
          strokeStyle: 'rgba(55, 50, 250, 0.3)',
          globalCompositeOperation: 'lighter',
          shadowColor: 'rgba(55, 50, 250, 0.5)',
          shadowBlur: 10,
          lineWidth: 1.0,
          draw: 'simple'
        }
      }

      map.addLayer(
        new ImageLayer({
          source: new Mapv(options)
        })
      )

      // 添加动画点图层
      const dataSet2 = new mapv.DataSet(timeData)
      const options2 = {
        map: map,
        dataSet: dataSet2,
        mapvOptions: {
          fillStyle: 'rgba(255, 250, 250, 0.9)',
          globalCompositeOperation: 'lighter',
          size: 1.5,
          animation: {
            type: 'time',
            stepsRange: { start: 0, end: 100 },
            trails: 1,
            duration: 5
          },
          draw: 'simple'
        }
      }

      map.addLayer(
        new ImageLayer({
          source: new Mapv(options2)
        })
      )
    })
  }
}
</script>