参考文档
http://linwei.xyz/ol3-primer/ch05/05-03.html http://openlayers.vip/examples/line-arrows.html
项目需要使用内网环境,故无法使用百度地图等在线地图.采用openlayers实现构建离线地图
通过shp加载shp矢量地图文件
<template>
<view style="width: 100%;height:100%">
<view id="map" class="map"></view>
</view>
</template>
<script>
import "ol/ol.css";
import {Map, View, Feature} from "ol";
import {Style, Icon} from 'ol/style';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import Point from 'ol/geom/Point';
import {defaults as defaultControls, MousePosition} from 'ol/control';
import config from '@/tools/config'
import {mapState} from "vuex";
// 示例: http://linwei.xyz/ol3-primer/ch05/05-03.html
// http://openlayers.vip/examples/line-arrows.html
export default {
props:{
robot_id: {
type: Number,
default: 0
}
},
data() {
return {
map: null, // map地图
layer: null,
zoom: 18, //缩放级别,范围5-18,越小,范围越广
// 初始化中心点坐标
longitude: 113.28618608029409,
latitude: 23.376623652412462,
styles: null,
};
},
computed:{
...mapState([
// 设备列表
'robots',
// 处理后的设备covers
'covers',
]),
// 当前设备信息
robot: function(){
return this.robots.find(item => item.id === this.robot_id)
},
// 当前选中 marker 索引
cover_index: function(){
return this.covers.findIndex(item => item.id === this.robot_id)
},
cover: function(){
return this.covers.find(item => item.id === this.robot_id)
}
},
watch:{
// cover(newVal,oldVal){
// if (!newVal) return;
// // if(oldVal.length !== newVal.length){
// // // 设置中心坐标
// // if(this.map){
// // console.log(this.cover.lng, this.cover.lat)
// // this.map.getView().setCenter([this.cover.lng, this.cover.lat]);
// // this.map.getView().setZoom(18);
// // }
// // }
// },
covers: {
handler(newVal,oldVal) {
if(oldVal.length === newVal.length){
// console.log('covers改变但长度没有发生变化,执行平移标记', newVal,oldVal)
// 移动标记
this.moveMarkers();
}else{
// 长度改变了,执行重置marker
this.initMarkers();
}
},
deep: true
}
},
mounted() {
this.initMap();
},
methods: {
initMap() {
this.target = document.getElementById('map');
this.map = new Map({
// 地图容器DIV层ID
target: this.target,
// 地图容器加载的图层
// layers: [
// // 将瓦面图层Layer 添加到 Map 中
// // new TileLayer({
// // // 给图层添加具体的数据源(这个是加载在线地图)
// // source: new OSM({
// // wrapX: true
// // })
// // })
// ],
// 设置 Map 容器的视图
view: new View({
projection: "EPSG:4326", // 使用这个坐标系, WGS84坐标系
center: [this.longitude, this.latitude],
zoom: this.zoom
}),
// 加载控件
controls: defaultControls().extend([
// 加载鼠标位置控件
new MousePosition()
]),
});
this.handleShp()
},
handleShp(){
shp(config.baseURL+"/gz-shp.zip").then((data) => {
if (data && data.length > 0) {
data.map(item => {
// 构建矢量图层
let pointLayer = new VectorLayer({
// 设置图层的数据源
source: new VectorSource({
features: (new GeoJSON()).readFeatures(item)
}),
})
pointLayer.setZIndex(2);
pointLayer.set('layer_name','shp')
// 添加矢量图层到map
this.map.addLayer(pointLayer);
})
}
})
},
// 初始化makers
initMarkers(){
this.$nextTick(()=>{
// 删除之前的图层
if(this.layer){
this.map.removeLayer(this.layer)
}
// 创建一个新的存放图标的图层
this.layer = new VectorLayer({
source: new VectorSource(),
})
this.layer.set('layer_name','marker')
this.styles = {
// 默认样式
defaultStyle: new Style({
image: new Icon({
src: '/static/img/green_rob.png',
}),
zIndex: 1
}),
// 选中样式
selectStyle: new Style({
image: new Icon({
src: '/static/img/red_rob.png',
}),
zIndex: 10
})
}
this.covers.map(cover => {
// 创建一个数据源(特征),并设置好在地图上的位置
let feature = new Feature({
geometry: new Point([cover.lng, cover.lat])
});
if(cover.id === this.robot_id){
// 设置为选中样式
feature.setStyle(this.styles.selectStyle);
}else{
// 设置未选中样式
feature.setStyle(this.styles.defaultStyle);
}
// 设置ID
feature.setId(cover.id);
// 设置名称
feature.set('name',cover.name);
// 为feature注册自定义事件click的监听
feature.on('click', this.onClickMarker);
// 添加数据源到图层
this.layer.getSource().addFeature(feature);
})
// 添加图层到map
this.layer.setZIndex(3);
this.map.addLayer(this.layer);
// 添加自定义事件
// 为地图注册点击事件的监听
this.map.on('click', (event)=>{
this.map.forEachFeatureAtPixel(event.pixel, (feature,layer)=>{
// 给点击的marker触发事件
feature.dispatchEvent({type: 'click', event: event});
// 防止触发多个marker,需要返回值
return true;
},{
// 根据图层名称,进行过滤
layerFilter: (layer) => {
return layer.get('layer_name') === 'marker';
}
});
});
})
},
// 移动makers
moveMarkers(){
if(this.layer){
this.covers.map(cover => {
// 根据ID获取到对应的marker
const feature = this.layer.getSource().getFeatureById(cover.id);
// 获取上次的坐标位置
const oldPoint = feature.getGeometry().getCoordinates();
// 移动坐标
feature.getGeometry().translate(cover.lng - oldPoint[0],cover.lat - oldPoint[1])
})
}
},
// 点击选中
onClickMarker(evt){
const feature = evt.target
if(this.robot_id != feature.getId()){
// 选中当前设备
this.$emit('change',feature.getId())
// 设置当前marker样式为选中样式
feature.setStyle(this.styles.selectStyle)
// 设置之前选中的marker为默认样式
this.layer.getSource().getFeatureById(this.robot_id).setStyle(this.styles.defaultStyle);
}
},
// 移除地图
removeMarkers(){
// 删除之前的图层
if(this.layer){
this.map.removeLayer(this.layer)
}
}
},
};
</script>
<style scoped>
.map {
width: 100%;
height: 100%;
}
</style>