# 矢量图层 v-vector

矢量数据在客户端呈现为矢量。即使在动画期间,这种图层类型也能提供最准确的渲染。点和标签在旋转视图上保持直立。对于非常大量的矢量数据,在平移和缩放动画期间性能可能会受到影响。在这种情况下,请尝试 module:ol/layer/VectorImage~VectorImageLayer (opens new window) --- 对应v-graphic组件

import { VVector } from 'v-ol-map'

# 参数 props

继承参数查看

参数 类型 默认值 描述
layerId String vector-layer-${uuid()} 图层id
source Object / undefined undefined 资源。数据结构参考:ol/source/Vector (opens new window)
features Array [] 图层中的要素集合,单个要素参数参考:feature
FeatureStyle Object / null / undefined undefined 图层样式。当设置为 时null,只有具有自己风格的特征才会被渲染。module:ol/style/Style~Style (opens new window)如果未设置,请参阅将使用的默认样式。
modify Object / Boolean false 是否开启编辑,参数:modify
cluster Object / Boolean false 是否开启聚合,参数:ol/source/Cluster (opens new window)

# 编辑 modify

modify.style 参考:style

# 可调用方法 methods

方法名 说明 参数
updateFeatureById 有些时候不想改动原始数据来改变图层中要素属性,可以使用此方法。在使用此方法前需保证生成的要素带有id属性。 (id, update) 接收两个参数,1. 要素id。2. 要素更新内容(key,value)。可选key:positionstyle
getFeatureById 根据要素ID获取当前图层上的要素 (id) 要素id

# updateFeatureById

update.poition更新要素位置。值为经纬度数组。

update.style更新要素样式。值为样式对象。

this.$refs.layer.updateFeatureById(feature.id, { position: position })

# getFeatureById

const feature = this.$refs.layer.getFeatureById(id)

# 事件 events

事件名称 说明 会调参数
load 图层加载完成回调 -
modifyStart 开始编辑的回调 (evt,map)
modifyEnd 编辑结束时的回调 (evt,map)
modifyChange 编辑进行时的回调 (evt,map,feature)
singleclick 点击事件 (evt,feature)
pointermove 鼠标悬浮事件 (evt,feature)

# 示例

# 加载矢量图层、在该图层上生成点、线、面 use

<template>
  <v-map :view="view">
    <v-vector v-for="layer in layers" :key="layer.id" :ref="layer.id" :layer-id="layer.id"  :visible="layer.visible" :features="layer.features"></v-vector>
  </v-map>
</template>
<script>
export default {
  data(){
    return {
      view: {
        center: [118.045456, 24.567489],
        zoom: 10
      },
       layers: [
        {
          id: 'layer1',
          visible: true,
          features: [
            {
              id: 'point1',
              coordinates: [118.140448, 24.512917],
              convert: 'bd-84', // 特殊属性,经纬度转化。支持:百度(bd)、高德(gd)、wgs84(84)互转
              style: {
                icon: {
                  scale: 0.6,
                  src: require('@/assets/img/point_6.png')
                },
                text: {
                  text: '百度转84',
                  font: '13px sans-serif',
                  fill: {
                    color: '#3d73e8'
                  },
                  backgroundFill: {
                    color: '#ffffff'
                  },
                  stroke: {
                    color: '#ffffff',
                    width: 1
                  },
                  backgroundStroke: {
                    color: '#000000',
                    width: 1
                  },
                  offsetX: 0,
                  offsetY: 30
                },
                styleFunction: function (feature, resolution, map, style) {
                  const viewZoom = map.getView().getZoom()
                  const minZoom = 12
                  const maxZoom = 16
                  const textStyle = style.getText()
                  if (viewZoom >= 14) {
                    textStyle.setText('百度转84')
                  }
                  if (viewZoom >= 15) {
                    textStyle.setText('根据层级显示不同内容')
                  }
                  style.setText(textStyle)
                  return minZoom <= viewZoom && viewZoom <= maxZoom ? style : null
                }
              },
              properties: {
                name: 'feature1'
              }
            }
          ]
        },
        {
          id: 'layer2',
          visible: true,
          features: []
        },
        {
          id: 'polygon',
          visible: true,
          features: [
            {
              type: 'polygon', // 除了普通icon点位,其他元素需注明元素类型
              style: {
                fill: {
                  color: 'rgba(67,126,152,0.15)'
                },
                stroke: {
                  color: 'rgba(67,126,255,1)',
                  width: 1,
                  lineDash: [20, 10, 20, 10]
                },
                text: {
                  text: '多边形',
                  font: '13px sans-serif',
                  fill: {
                    color: '#3d73e8'
                  }
                }
              },
              updateStyle: {
                fill: {
                  color: 'rgba(4,3,43,0.5)'
                }
              },
              coordinates: [
                [118.23048075355373, 24.587052571002776], [118.25051461705989, 24.592192894082423],
                [118.24383041710121, 24.561810933485354], [118.23048075355373, 24.587052571002776]
              ]
            },
            {
              type: 'polyline',
              style: {
                stroke: {
                  color: 'rgba(220,171,119,1)',
                  width: 2
                  // lineDash: [20, 10, 20, 10]
                },
                text: {
                  text: 'line'
                }
              },
              coordinates: [[118.20513460817911, 24.6005204040184], [118.22511304202654, 24.607323827184675], [118.22998527470209, 24.627570481933592]]
            },
            {
              type: 'circle',
              center: [118.25945470514871, 24.608883531726836],
              radius: 500,
              style: {
                text: {
                  text: '圆形'
                }
              }
            }
          ]
        }
      ]
    }
  }
}
</script>	

# 编辑要素

<template>
<div class="home">
  <button class="btn-modify" @click="modify = !modify">{{ modify?'取消编辑':'激活编辑' }}</button>
  <v-map ref="map" :view="view" default-tile="BD">
    <!-- 弹框初始化位置在圆形边界,需要layer图层加载完成后获取要素信息 -->
    <v-vector v-if="overlayLoad" ref="layer" :modify="modify?modifyOptions:false" :features="features" @load="load" @modifyChange="change"></v-vector>
    <!-- 先生成弹框再加载图层 -->
    <v-overlay class="overlay" :position="position" @load="onOverlayLoad">
      半径:{{radius}}米
    </v-overlay>
  </v-map>
</div>
</template>

<script>
export default {
  name: 'modify',
  data () {
    return {
      view: {
        city: 'xiamen',
        zoom: 12
      },
      modify: true,
      modifyOptions: {
        style: {
          stroke: {
            color: 'yellow'
          },
          fill: {
            color: 'black'
          }
        }
      },
      features: [
        {
          id: 'circle',
          type: 'circle',
          center: [118.11921478793144, 24.49890150072479],
          radius: 500,
          style: {
            stroke: {
              color: 'red'
            },
            fill: {
              color: 'green'
            }
          }
        }
      ],
      position: undefined,
      radius: 0,
      overlayLoad: false
    }
  },
  methods: {
    load (layer, map) {
      const circle = this.$refs.layer.getFeatureById('circle')
      const geometry = circle.getGeometry()
      const radius = geometry.getRadius() // 半径
      const metersPerUnit = map.getView().getProjection().getMetersPerUnit() // 半径以米为单位
      const extent = geometry.getExtent()
      this.position = [extent[2], (extent[3] + extent[1]) / 2]
      this.radius = (radius * metersPerUnit).toFixed(2)
    },
    onOverlayLoad () {
      this.overlayLoad = true
    },
    change (evt, map) {
      const geometry = evt.target
      this.setPosition(geometry, map)
    },
    setPosition (geometry, map) {
      const radius = geometry.getRadius() // 半径
      const metersPerUnit = map.getView().getProjection().getMetersPerUnit() // 半径以米为单位
      const extent = geometry.getExtent()
      this.position = [extent[2], (extent[3] + extent[1]) / 2]
      this.radius = (radius * metersPerUnit).toFixed(2)
    }
  }
}
</script>

<style lang="scss">
.btn-modify{
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 9;
}
.overlay{
  background: white;
  color: black;
  border: 1px solid blue;
  display: inline;
  padding: 2px;
}
</style>

Last Updated: 6/1/2023, 1:32:46 PM