<template>
|
<div>
|
<div id='searchMap' style="height: 50vh; width: 100%" ref="MapContent">
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import {Feature, Map, View} from "ol";
|
import {Tile as TileLayer, Vector as VectorLayer} from "ol/layer";
|
import XYZ from "ol/source/XYZ";
|
import VectorSource from "ol/source/Vector";
|
import {Circle as StyleCircle, Fill as StyleFill, Stroke as StyleStroke, Style, Text as StyleText} from "ol/style";
|
import Point from "ol/geom/Point";
|
import Icon from "ol/style/Icon";
|
import Draw from "ol/interaction/Draw";
|
import {Circle as GeomCircle, LineString as GeomLineString, Point as GeomPoint, Polygon as GeomPolygon} from "ol/geom";
|
import Cluster from "ol/source/Cluster";
|
|
export default {
|
name: "searchMapBox",
|
props: ['routeRange'],
|
data() {
|
return {
|
map: null,
|
points: [],
|
featurePoint:null,
|
// 线条点数组
|
linePoints: [],
|
// 多边形数组
|
polygonPoints: [],
|
draw: null,
|
drawLayer: null,
|
pointVector: null,
|
coordinates: [],// 保存绘画坐标地址 [[115.90490549080435, 28.746101718722358],[115.93151300423209, 28.741123538790717]]
|
toData: null,// 保存数据库格式坐标地址
|
showTip: false,
|
tipTitle: null
|
}
|
},
|
methods: {
|
|
createMap() {
|
let _this = this
|
//初始化地图
|
_this.map = new Map({
|
target: 'searchMap',
|
layers: [
|
new TileLayer({
|
source: new XYZ({
|
url: "https://webmap-tile.sf-express.com/MapTileService/rt?fetchtype=static&x={x}&y={y}&z={z}&project=sfmap&pic_size=256&pic_type=png8&data_name=361100&data_format=merged-dat&data_type=normal", // 行政区划
|
})
|
}),
|
|
],
|
view: new View({
|
// 设置中心点
|
//117.951478782, 28.447896798, 5000
|
center: [117.951478782, 28.447896798],
|
projection: 'EPSG:4326',
|
// 设置缩放倍数
|
zoom: 13,
|
minZoom: 8,
|
maxZoom: 19
|
})
|
})
|
|
_this.pointVector = new VectorLayer({
|
//layer所对应的source
|
source: new VectorSource({
|
wrapX: false // 禁止横向无限重复(底图渲染的时候会横向无限重复),设置了这个属性,可以让绘制的图形不跟随底图横向无限重复
|
}),
|
style: new Style({
|
image: new Icon({
|
src: "/img/dwicon.jpeg",
|
anchor: [0.48, 1],
|
// imgSize: [250,320],
|
scale: 0.13
|
}),
|
})
|
})
|
_this.map.addLayer(_this.pointVector)
|
// 在地图上回显线或点
|
if (this.routeRange) {
|
_this.startAdd(_this.routeRange)
|
}
|
this.point()
|
},
|
// 绘画之后的样式
|
styleFunction() {
|
// 绘画之后的样式
|
let styles = [
|
new Style({
|
fill: new StyleFill({color: "rgba(255, 255, 255, 0.2)"}),
|
stroke: new StyleStroke({
|
color: 'rgb(252, 94, 32)',
|
width: 5
|
})
|
})
|
]
|
return styles
|
},
|
// 添加点
|
addPoint(pointLonLat) {
|
// pointLonLat = POINT(115.87531914674 28.8603307485585)
|
if (pointLonLat) {
|
let pointData = ""
|
let pointArray = []
|
pointData = pointLonLat.match(/\(([^)]*)\)/)
|
pointArray = pointData[1].split(" ")
|
//设置点
|
let feature_Point = new Feature({
|
geometry: new Point([Number(pointArray[0]), Number(pointArray[1])])
|
})
|
//点样式
|
let style = new Style({
|
image: new Icon({
|
src: "/img/dwicon.jpeg",
|
anchor: [0.48, 1],
|
// imgSize: [250,320],
|
scale: 0.13
|
}),
|
})
|
this.featurePoint = feature_Point
|
feature_Point.setStyle(style)
|
this.pointVector.getSource().addFeature(feature_Point)
|
let center = [Number(pointArray[0]), Number(pointArray[1])]
|
let view = this.map.getView()
|
view.setZoom(16)
|
view.animate({
|
center: center,
|
duration: 5,
|
})
|
}
|
},
|
// 将点坐标集合转换为数据库数据
|
doData(val) {
|
let str = "LINESTRING("
|
for (let k = 0; k < val.length; k++) {
|
str += `${val[k][0]} ${val[k][1]}`
|
if (k != val.length - 1) {
|
str += ","
|
}
|
}
|
str = str + "," + `${val[0][0]} ${val[0][1]}`
|
str += ")"
|
// console.log(str)
|
return '\'' + str + '\''
|
},
|
// 开始绘制
|
point() {
|
let _this = this
|
_this.coordinates = []
|
_this.map.removeInteraction(_this.draw)
|
// _this.pointVector.getSource().clear()
|
|
_this.draw = new Draw({
|
source: _this.pointVector.getSource(),
|
type: 'Point',
|
})
|
_this.map.addInteraction(_this.draw)
|
// 点击事件
|
_this.map.on('click', function (e) {
|
if (_this.featurePoint != null){
|
_this.pointVector.getSource().removeFeature(_this.featurePoint)
|
}
|
|
if (_this.coordinates.length > 0) {
|
let featureArray = _this.pointVector.getSource().getFeatures()
|
for (let i = 0; i < featureArray.length -1; i++) {
|
_this.pointVector.getSource().removeFeature(featureArray[i])
|
}
|
_this.coordinates = []
|
}
|
// 将点坐标保存集合
|
_this.coordinates.push(e.coordinate)
|
_this.$emit("getMapData", _this.coordinates)
|
})
|
|
},
|
// 设置统一控制点击事件,需要画图方式在此处切换
|
handleClick(point) {
|
// 绘制连线
|
this.drawLineString(point)
|
// 绘制点
|
// this.drawPoint(point)
|
// 绘制圆形
|
// this.drawCircle(point)
|
// 绘制多边形
|
// this.drawPolygon(point)
|
},
|
// 绘制点位
|
drawPoint(center) {
|
let vectorLayer = this.getLayer()
|
|
let point = new GeomPoint(center)
|
let feature = new Feature(point)
|
vectorLayer.getSource().addFeature(feature)
|
this.map.addLayer(vectorLayer)
|
},
|
// 绘制连线
|
drawLineString(point) {
|
this.linePoints.push(point)
|
let featureLine = new Feature({
|
geometry: new GeomLineString(this.linePoints),
|
})
|
|
// 添加线的样式
|
let lineStyle = new Style({
|
fill: new StyleFill({
|
color: 'rgba(1, 210, 241, 0.1)'
|
}),
|
stroke: new StyleStroke({
|
color: 'rgba(255, 0, 0)',
|
width: 4,
|
}),
|
})
|
featureLine.setStyle(lineStyle)
|
|
let source = new VectorSource()
|
source.addFeature(featureLine)
|
let layer = new VectorLayer()
|
layer.setSource(source)
|
this.map.addLayer(layer)
|
},
|
// 绘制区域圆形
|
drawCircle(center) {
|
let vectorLayer = this.getLayer()
|
|
// 设置半径
|
let circle = new GeomCircle(center, 0.003)// 新建圆对象
|
let feature = new Feature(circle)// 新建Feature对象 并将circle传入
|
vectorLayer.getSource().addFeature(feature)// 将Feature对象填入图层源
|
this.map.addLayer(vectorLayer) // 将图层添至地图对象
|
},
|
// 画多边形
|
drawPolygon(point) {
|
this.polygonPoints.push(point)
|
let feature = new Feature({
|
geometry: new GeomPolygon([this.polygonPoints]),
|
attributes: null
|
})
|
// 添加线的样式
|
let lineStyle = new Style({
|
fill: new StyleFill({
|
color: 'rgba(1, 210, 241, 0.1)'
|
}),
|
stroke: new StyleStroke({
|
color: 'rgba(255, 0, 0)',
|
width: 4,
|
}),
|
})
|
feature.setStyle(lineStyle)
|
let source = new VectorSource()
|
source.addFeature(feature)
|
let vectorLayer = new VectorLayer({
|
source: source
|
})
|
this.map.addLayer(vectorLayer)
|
},
|
// 设置聚合点
|
addMarker() {
|
let source = new VectorSource()
|
// 随机创建200个要素,后台点位取出后按此格式处理
|
for (let i = 1; i <= 200; i++) {
|
let coordinates = [115.90 + Math.random() * 0.05, 28.64 + Math.random() * 0.05]
|
let feature = new Feature(new GeomPoint(coordinates))
|
source.addFeature(feature)
|
}
|
|
// 聚合
|
let clusterSource = new Cluster({
|
source: source,
|
distance: 50
|
})
|
|
let clusters = new VectorLayer({
|
source: clusterSource,
|
style: function (feature) {
|
let size = feature.get('features').length
|
let style = new Style({
|
image: new StyleCircle({
|
radius: 20,
|
stroke: new StyleStroke({
|
color: 'white'
|
}),
|
fill: new StyleFill({
|
color: '#AAD3DF'
|
})
|
}),
|
text: new StyleText({
|
text: size.toString(),
|
fill: new StyleFill({
|
color: 'black'
|
})
|
})
|
})
|
return style
|
}
|
})
|
|
this.map.addLayer(clusters)
|
},
|
// 重置图层
|
clearDraw() {
|
let _this = this
|
_this.coordinates = []
|
_this.map.removeInteraction(_this.draw)
|
_this.pointVector.getSource().clear()
|
|
// 传值给父组件
|
_this.$emit('toData', "")
|
},
|
// 获取新的 layer 图层对象
|
getLayer() {
|
return new VectorLayer({
|
source: new VectorSource({
|
features: ''
|
}),
|
// 设置样式,但不完全兼容
|
// style: function (feature) {
|
// let style = new Style({
|
// stroke: new StyleStroke({
|
// color: '#E80000',
|
// width: 2
|
// }),
|
// fill: new StyleFill({
|
// color: 'rgba(0,0,0,0)'
|
// })
|
// })
|
// return style
|
// }
|
})
|
},
|
|
startAdd(routeRange) {
|
if (routeRange.startsWith("POINT")) {
|
this.addPoint(routeRange)
|
}
|
},
|
|
setView(point){
|
let view = this.map.getView()
|
let center = [point.lng,point.lat]
|
view.setZoom(20)
|
view.animate({
|
center: center,
|
duration: 5,
|
})
|
}
|
},
|
mounted() {
|
this.createMap()
|
}
|
}
|
</script>
|
|
<style scoped>
|
|
</style>
|