從自己的角度,簡(jiǎn)單的二次封裝了一下openlayer,在這里提供一下我的思路!
1.添加一個(gè)底圖對(duì)象 map
2.向底圖對(duì)象上添加線層或者點(diǎn)層 line-map與 point-map
效果圖
image.png
前端組件引用
<div style="height:500px">
<map :baseMap="baseMap" @handleDownEvent="handleDownEvent" ref="map">
<template slot="yl-map-layers">
<line-map :lineData="lineData" :fun="lineFun"></line-map>
<point-map :pointData="pointData" :fun="pointFun"></point-map>
</template>
<template slot="map-overlay" slot-scope="scope">
{{scope.content}}
</template>
</map>
</div>
<script>
// 注意:
// 1.傳入地圖地圖需引用 :
// import TileLayer from "ol/layer/Tile";
// import XYZ from "ol/source/XYZ";
//todo:1.其它地圖交互事件暴露
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
export default {
name: "yl-map-sam",
data() {
return {
pointFun:(e)=>{
return {
src:null,
scale:null
}
},//點(diǎn)樣式
lineFun:(e)=>{
return {
color:null,
width:null
}
},//線樣式
lineData:[
{
data:[
[[104,30],[106,28]],//路段1
[[108,22],[105,33]],//路段2
],
info:'路線1'
}
],//線性數(shù)據(jù)結(jié)構(gòu)
pointData:[
{lng:104,lat:30,info:'點(diǎn)1'},//點(diǎn)1
{lng:108,lat:24,info:'點(diǎn)2'}//點(diǎn)2
],//點(diǎn)數(shù)據(jù)結(jié)構(gòu)
baseMap:new TileLayer({
source: new XYZ({
projection: "EPSG:3857",
url:
"https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}"
}),
name: "底圖"
})
}
},
methods:{
//地圖元素點(diǎn)擊事件
handleDownEvent(feature){
//點(diǎn)擊后將對(duì)應(yīng)元素移動(dòng)至地圖中間
this.fitView(feature);
},
//注意:closeOverlay()吆你、refMapData()胧后、fitView()使用: 給地圖添加ref
//關(guān)閉彈框
closeOverlay(){
this.$refs.map.close();
},
//刷新地圖疊加層數(shù)據(jù)
refMapData(){
this.$bus.$emit(this.$refs.map.mapId + "ready", {});
},
//移動(dòng)焦點(diǎn)位置 傳入值features:Array
fitView(feature){
this.$refs.map.fitViewfeatures([feature]);
}
}
}
</script>
地圖組件層 map
<template>
<div class="wapper">
<div :id="mapId" :ref="mapId" style="height:100%;width:100%;">
<slot name="yl-map-layers"></slot>
<div id="popup" class="ol-popup" v-show="content!=null">
<span class="popup-close" @click="close">
<i class="el-icon-close" />
</span>
<div id="popup-content">
<slot name="yl-map-overlay" :content="content"></slot>
</div>
</div>
</div>
</div>
</template>
<script>
import "ol/ol.css";
import { Map, View } from "ol";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import { Cluster, OSM, Vector as VectorSource } from "ol/source";
import Feature from "ol/Feature";
import VectorLayer from "ol/layer/Vector";
import Icon from "ol/style/Icon";
import GeoJSON from "ol/format/GeoJSON";
import { Circle as CircleStyle, Fill, Stroke, Style, Text } from "ol/style";
import * as olSize from "ol/size";
import request from "@/utils/request";
//彈框
import Overlay from "ol/Overlay";
//自定義事件方法
import {
defaults as defaultInteractions,
Pointer as PointerInteraction,
} from "ol/interaction";
export default {
name: "yl-map",
props: {
baseMap: {
type: Object,
default: function () {
return new TileLayer({
source: new XYZ({
projection: "EPSG:3857",
url:
"https://mt1.google.cn/vt/lyrs=y@113&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}&s=",
}),
name: "底圖",
});
},
},
},
data() {
return {
timeout: null,
content: null, //內(nèi)容
mapId: null, //地圖id
map: null, //地圖
view: null,
overlay: null, //彈框
};
},
methods: {
close() {
//彈窗關(guān)閉方法(防止外部調(diào)用此方法——所以先要判斷是否為空)
this.overlay ? this.overlay.setPosition(undefined) : "";
},
},
created() {
console.info("map-created");
this.mapId = "map" + new Date().getTime();
},
mounted() {
console.info("地圖組件掛載,id:" + this.mapId);
let view = new View({
center: [104.06, 30.67],
projection: "EPSG:4326",
zoom: 8,
minZoom: 6,
maxZoom: 20,
});
this.view = view;
const map = new Map({
target: this.$refs[this.mapId],
layers: [this.baseMap],
view: view,
});
this.map = map;
this.$bus.$emit(this.mapId + "ready", {});
},
};
</script>
<style lang="scss" scoped>
.wapper {
position: relative;
width: 100%;
height: 100%;
font-size: 80%;
font-family: Source Han Sans CN;
font-weight: 400;
}
.popup-close {
position: absolute;
right: 5px;
top: 5px;
cursor: pointer;
}
.ol-popup {
background-color: #fff;
padding: 10px;
border-radius: 5px;
}
</style>
線性層 line-map
<template></template>
<script>
/**
* 線
*/
import "ol/ol.css";
import { Map, View } from "ol";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import VectorSource from "ol/source/Vector";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import VectorLayer from "ol/layer/Vector";
import Icon from "ol/style/Icon";
import GeoJSON from "ol/format/GeoJSON";
import { Circle as CircleStyle, Fill, Stroke, Style, Text } from "ol/style";
import * as olSize from "ol/size";
//線性
import LineString from "ol/geom/LineString";
import { getSessionMotif, getUserInfo } from "@/utils/auth";
import { localConvertArray } from "./../../../../../examples/utils/gps";
export default {
name: "yl-line-map",
props: {
lineData: {
type: Array,
default: function () {
return [];
},
},
fun: {
type: Function,
default: function (data) {
return (e) => {
return {
color: null,
width: null,
};
};
},
},
},
watch: {
lineData(val) {
if (this.map == null) {
this.map = this.$parent.map;
}
if (this.mapLayers.length > 0) {
for (let i in this.mapLayers) {
this.map.removeLayer(this.mapLayers[i]);
}
this.mapLayers = [];
}
this.addLineLayer();
},
},
data() {
return {
mapLayers: [],
map: null,
};
},
methods: {
setLineStyle(info) {
if (this.fun(info).color && this.fun(info).width) {
let lintStyle = new Style({
stroke: new Stroke({
//地圖連線的樣式
color: this.fun(info).color,
width: this.fun(info).width,
}),
});
return lintStyle;
} else {
return null;
}
},
addLineLayer() {
let featureLines = [];
if (this.lineData && this.lineData.length > 0) {
for (let i in this.lineData) {
if (this.lineData[i].data.length > 0) {
for (let x in this.lineData[i].data) {
if (this.lineData[i].data[x].length > 1) {
// 設(shè)置 feature
let featureLine = new Feature({
geometry: new LineString(
localConvertArray(this.lineData[i].data[x])
),
_md_: this.lineData[i].info,
});
featureLine.setStyle(this.setLineStyle(this.lineData[i].info));
featureLines.push(featureLine);
}
}
}
}
if (featureLines.length > 0) {
// 設(shè)置 線性數(shù)據(jù)源
let LineSource = new VectorSource({
features: featureLines,
});
// 設(shè)置 線性圖層
let LineLayer = new VectorLayer({
source: LineSource,
style: new Style({
stroke: new Stroke({
width: 6,
}),
}),
type: "Line",
});
//添加 線性圖層
this.map.addLayer(LineLayer);
this.mapLayers.push(LineLayer);
}
}
},
},
beforeCreate() {},
created() {
this.$bus.$on(this.$parent.mapId + "ready", () => {
if (this.map == null) {
this.map = this.$parent.map;
}
if (this.mapLayers.length > 0) {
for (let i in this.mapLayers) {
this.map.removeLayer(this.mapLayers[i]);
}
this.mapLayers = [];
}
this.addLineLayer();
});
},
beforeMount() {},
mounted() {},
};
</script>
<style lang="scss" scoped>
</style>