一、添加标注功能方法封装
添加矢量标注所需依赖,并封装方法。
InitMap.vue
/* eslint-disable no-unused-vars */
import mapConfig from '@/mapConfig' // 地图配置
import "ol/ol.css"
import Map from "ol/Map"
import View from "ol/View"
import TileLayer from "ol/layer/Tile"
import TileWMS from "ol/source/TileWMS"
import OSM from "ol/source/OSM"
import { defaults as defaultControls } from 'ol/control'
import ZoomSlider from 'ol/control/ZoomSlider' // 缩放控制
import WMSGetFeatureInfo from 'ol/format/WMSGetFeatureInfo'
// 添加图标相关
import OlFeature from 'ol/Feature'
import OlGeomPoint from 'ol/geom/Point'
import OlLayerVector from 'ol/layer/Vector'
import OlSourceVector from 'ol/source/Vector'
import OlStyleStyle from 'ol/style/Style'
import OlStyleIcon from 'ol/style/Icon'
// 添加相关文字描述
import Text from 'ol/style/Text'
import Fill from 'ol/style/Fill'
import Stroke from 'ol/style/Stroke'
export default {
methods: {
// 移除自定义矢量标注图层
removeIconLayer(data) {
if (data.length) {
for (let i = 0; i < data.length; i++) {
this.map.removeLayer(this.getLayerByName(data[i].address))
}
} else {
this.map.removeLayer(this.getLayerByName(data.address))
}
},
// 添加自定义矢量标注图层
addIconLayer(data, ID) {
if (data.length) {
// 多个点
let nData = data.filter((item) => {
// 过滤出没有坐标信息的点
return item.x && item.y
})
for (let i = 0; i < nData.length; i++) {
if (nData[i].x && nData[i].y) {
this.addCustomPoniter(nData[i], ID)
}
}
} else {
// 单个点
if (data.x && data.y) {
this.addCustomPoniter(data, ID)
}
}
},
// 添加自定义矢量标注
addCustomPoniter(data, ID) {
let iconOption = {}
switch (ID) {
case '网格员':
iconOption = {
src: require('@/assets/icon02.png'),
scale: 1
}
break
default:
iconOption = {
src: require('@/assets/ico.png'),
scale: 1
}
}
let vectorLayer = null // 矢量图层
let startMarker = new OlFeature({
type: 'icon',
id: ID, // 通过指定的 ID 去查找对应图层的 layerName 做请求
geometry: new OlGeomPoint([data.x, data.y])
})
vectorLayer = new OlLayerVector({
source: new OlSourceVector({
features: [startMarker]
}),
style: new OlStyleStyle({
image: new OlStyleIcon({
// anchor: [0.5, 1],
src: iconOption.src,
scale: iconOption.scale || 1
}),
// 设置图片下面显示字体的样式和内容
text: new Text({
font: '14px sans-serif', // 设置字体
maxAngle: 30,
offsetx: 10, // 设置文字偏移量
offsetY: 10,
text: data.address,// 文字描述
fill: new Fill({ // 字体颜色
color: '#000'
}),
stroke: new Stroke({ // 文字描边
color: '#fff',
width: 5
})
})
}),
zIndex: 9,
name: data.address
})
this.map.removeLayer(this.getLayerByName(data.address)) // 先移除一次,防止多次点击图层覆盖
this.map.addLayer(vectorLayer)
},
// 根据 name 获取 mapConfig.js 中的 layerName,作为点击标注获取详细信息的请求条件
getLayerNameFromConf(name) {
let layers = mapConfig.map.layers
let nameArr = []
for (let i = 0; i < layers.length; i++) {
nameArr.push(layers[i].name)
}
let index = nameArr.indexOf(name)
return layers[index].layerName
},
// 地图单击事件
singleClickFun(view) {
this.map.on('singleclick', (event) => {
// 点击标注
if (this.map.hasFeatureAtPixel(event.pixel)) {
let feature = this.map.getFeaturesAtPixel(event.pixel)
let layerName = feature[0].values_.id
let LAYERS = this.getLayerNameFromConf(layerName)
let wmsSource = new TileWMS({
url: "geoserver/geoserver/DLQ/wms", // 跨域访问(获取点击的详细信息,出现跨域问题,本地测试做了代理)
params: { LAYERS: LAYERS, TILED: true },
serverType: "geoserver",
transition: 0,
})
let viewResolution = (view.getResolution())
let url = wmsSource.getFeatureInfoUrl(
event.coordinate, viewResolution, 'EPSG:4326',
{ 'INFO_FORMAT': 'application/json' })
if (url) {
fetch(url)
.then((response) => {
return response.json()
})
.then((data) => {
console.log(data)
})
}
}
else {
let wmsSource = new TileWMS({
// 怎么针对某个图层做点击事件?点击需要传对应图层的 name,如果有多个图层,怎么判断点击的是哪个图层?
url: "geoserver/geoserver/DLQ/wms", // 跨域访问(获取点击的详细信息,出现跨域问题,本地测试做了代理)
params: { LAYERS: 'DLQ:DLQFHR', TILED: true },
serverType: "geoserver",
transition: 0,
})
let viewResolution = (view.getResolution())
let url = wmsSource.getFeatureInfoUrl(
event.coordinate, viewResolution, 'EPSG:4326',
{ 'INFO_FORMAT': 'application/json' })
if (url) {
fetch(url)
.then((response) => {
return response.json()
})
.then((data) => {
console.log(data)
})
}
}
})
},
}
}
</script>
二、传递点位信息
模拟一些点位做测试。
MapMain.vue
data() {
return {
clickFlag: false,
fhrData: [
{
address: '昆俞北路明旭社区明盛园4号楼',
x: 117.29548,
y: 39.16232
},
{
address: '津北公路',
x: 117.432727,
y: 39.080622
},
{
address: '华明街弘顺道金泰丽湾嘉园7号楼',
x: 117.365064,
y: 39.163788
}
]
}
},
methods: {
// 添加自定义标注
addCustomPoniter() {
// 单个点
let point = {
x: 117.3671,
y: 39.17287,
name: 'test',
address: 'test'
}
this.$refs.InitMap.addIconLayer(point, '网格员')
// 多个点
this.$refs.InitMap.addIconLayer(this.fhrData, '房户人')
},
// 移除自定义标注
removeCustomPoniter() {
this.$refs.InitMap.removeIconLayer(this.buildingData)
},
}
三、完整的 InitMap.vue
<template>
<div></div>
</template>
<script>
/* eslint-disable no-unused-vars */
import mapConfig from '@/mapConfig' // 地图配置
import "ol/ol.css"
import Map from "ol/Map"
import View from "ol/View"
import TileLayer from "ol/layer/Tile"
import TileWMS from "ol/source/TileWMS"
import OSM from "ol/source/OSM"
import { defaults as defaultControls } from 'ol/control'
import ZoomSlider from 'ol/control/ZoomSlider' // 缩放控制
import WMSGetFeatureInfo from 'ol/format/WMSGetFeatureInfo'
// 添加图标相关
import OlFeature from 'ol/Feature'
import OlGeomPoint from 'ol/geom/Point'
import OlLayerVector from 'ol/layer/Vector'
import OlSourceVector from 'ol/source/Vector'
import OlStyleStyle from 'ol/style/Style'
import OlStyleIcon from 'ol/style/Icon'
// 添加相关文字描述
import Text from 'ol/style/Text'
import Fill from 'ol/style/Fill'
import Stroke from 'ol/style/Stroke'
export default {
name: 'InitMap',
data() {
return {
map: null
}
},
mounted() {
this.initMap()
// this.getAllFeaturesByXML()
},
methods: {
// 移除自定义矢量标注图层
removeIconLayer(data) {
if (data.length) {
for (let i = 0; i < data.length; i++) {
this.map.removeLayer(this.getLayerByName(data[i].address))
}
} else {
this.map.removeLayer(this.getLayerByName(data.address))
}
},
// 添加自定义矢量标注图层
addIconLayer(data, ID) {
if (data.length) {
// 多个点
let nData = data.filter((item) => {
// 过滤出没有坐标信息的点
return item.x && item.y
})
for (let i = 0; i < nData.length; i++) {
if (nData[i].x && nData[i].y) {
this.addCustomPoniter(nData[i], ID)
}
}
} else {
// 单个点
if (data.x && data.y) {
this.addCustomPoniter(data, ID)
}
}
},
// 添加自定义矢量标注
addCustomPoniter(data, ID) {
let iconOption = {}
switch (ID) {
case '网格员':
iconOption = {
src: require('@/assets/icon02.png'),
scale: 1
}
break
default:
iconOption = {
src: require('@/assets/ico.png'),
scale: 1
}
}
let vectorLayer = null // 矢量图层
let startMarker = new OlFeature({
type: 'icon',
id: ID, // 通过指定的 ID 去查找对应图层的 layerName 做请求
geometry: new OlGeomPoint([data.x, data.y])
})
vectorLayer = new OlLayerVector({
source: new OlSourceVector({
features: [startMarker]
}),
style: new OlStyleStyle({
image: new OlStyleIcon({
// anchor: [0.5, 1],
src: iconOption.src,
scale: iconOption.scale || 1
}),
// 设置图片下面显示字体的样式和内容
text: new Text({
font: '14px sans-serif', // 设置字体
maxAngle: 30,
offsetx: 10, // 设置文字偏移量
offsetY: 10,
text: data.address,// 文字描述
fill: new Fill({ // 字体颜色
color: '#000'
}),
stroke: new Stroke({ // 文字描边
color: '#fff',
width: 5
})
})
}),
zIndex: 9,
name: data.address
})
this.map.removeLayer(this.getLayerByName(data.address)) // 先移除一次,防止多次点击图层覆盖
this.map.addLayer(vectorLayer)
},
// 根据 name 获取 mapConfig.js 中的 layerName,作为点击标注获取详细信息的请求条件
getLayerNameFromConf(name) {
let layers = mapConfig.map.layers
let nameArr = []
for (let i = 0; i < layers.length; i++) {
nameArr.push(layers[i].name)
}
let index = nameArr.indexOf(name)
return layers[index].layerName
},
// 地图单击事件
singleClickFun(view) {
this.map.on('singleclick', (event) => {
// 点击标注
if (this.map.hasFeatureAtPixel(event.pixel)) {
let feature = this.map.getFeaturesAtPixel(event.pixel)
let layerName = feature[0].values_.id
let LAYERS = this.getLayerNameFromConf(layerName)
let wmsSource = new TileWMS({
url: "geoserver/geoserver/DLQ/wms", // 跨域访问(获取点击的详细信息,出现跨域问题,本地测试做了代理)
params: { LAYERS: LAYERS, TILED: true },
serverType: "geoserver",
transition: 0,
})
let viewResolution = (view.getResolution())
let url = wmsSource.getFeatureInfoUrl(
event.coordinate, viewResolution, 'EPSG:4326',
{ 'INFO_FORMAT': 'application/json' })
if (url) {
fetch(url)
.then((response) => {
return response.json()
})
.then((data) => {
console.log(data)
})
}
}
else {
let wmsSource = new TileWMS({
// 怎么针对某个图层做点击事件?点击需要传对应图层的 name,如果有多个图层,怎么判断点击的是哪个图层?
url: "geoserver/geoserver/DLQ/wms", // 跨域访问(获取点击的详细信息,出现跨域问题,本地测试做了代理)
params: { LAYERS: 'DLQ:DLQFHR', TILED: true },
serverType: "geoserver",
transition: 0,
})
let viewResolution = (view.getResolution())
let url = wmsSource.getFeatureInfoUrl(
event.coordinate, viewResolution, 'EPSG:4326',
{ 'INFO_FORMAT': 'application/json' })
if (url) {
fetch(url)
.then((response) => {
return response.json()
})
.then((data) => {
console.log(data)
})
}
}
})
},
// 切换图层
changeLayer(name, flag) {
let layer = this.getLayerByName(name)
this.setLayerVisible(layer, flag)
},
// 设置图层显隐
setLayerVisible(layer, flag) {
switch (flag) {
case true:
layer.setVisible(true)
break
case false:
layer.setVisible(false)
break
}
},
// 根据图层名称获取图层
getLayerByName(name) {
let layers = this.map.getLayers().array_
let nameArr = []
let targetIndex = -1
for (let i = 0; i < layers.length; i++) {
nameArr.push(layers[i].values_.name)
}
targetIndex = nameArr.indexOf(name)
return layers[targetIndex]
},
// 获取所有图层
getAllTileLayers() {
let allLayers = mapConfig.map.layers
for (let i = 0; i < allLayers.length; i++) {
if (!allLayers[i].layerName) {
// 没有 GeoServer 用的是 OSM
let layer = new TileLayer({
source: new OSM(),
visible: allLayers[i].visible,
zIndex: allLayers[i].zIndex,
name: allLayers[i].name
})
this.map.addLayer(layer)
} else {
let layer = new TileLayer({
source: new TileWMS({
url: mapConfig.map.geoserver,
params: { LAYERS: allLayers[i].layerName, TILED: true },
serverType: "geoserver",
transition: 0,
}),
visible: allLayers[i].visible,
zIndex: allLayers[i].zIndex,
name: allLayers[i].name
})
this.map.addLayer(layer)
}
}
},
// 初始化地图
initMap() {
let view = new View(mapConfig.map.view)
this.map = new Map({
layers: [],
target: "map",
view: view,
controls: defaultControls().extend([new ZoomSlider()]) // 缩放控制
})
this.getAllTileLayers() // 获取所有图层
this.singleClickFun(view) // 地图单击事件
}
}
}
</script>
网友评论