openlayers绘制地图并叠加标记点以及自定义图标
最近正在学习openlayers相关的东西,但是这东西实在有点复杂,但是他能使用的东西确实很酷炫,不得不说openlayers很强大。还在摸索之中。。。,说它复杂在于api该怎么去用,该怎么选择使用地图数据源等等,先把目前实现的效果做个笔记。
1.地图可缩放
2.地图悬停省份可即时改变效果,离开自动回复
3.鼠标点击可输出点击的省份位置
4.绘制了一个maker,金黄色的那个。。
5.四个自定义图片的要素
效果图
代码
复制粘贴即可使用
<template>
<div id="app">
<div id="Map" ref="map"></div>
<div id="marker"></div>
<div ref="tooltip" class="tooltip"></div>
</div>
</template>
<script>
import "ol/ol.css";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import XYZ from "ol/source/XYZ";
import { Map, View, Feature,interaction,events } from "ol";
import { Style, Stroke, Fill,Icon } from "ol/style";
import { Polygon, MultiPolygon } from "ol/geom";
import { defaults as defaultControls } from "ol/control";
import { fromLonLat } from "ol/proj";
import Graticule from 'ol/layer/Graticule'; //引入网格标尺图层
import {Heatmap as HeatmapLayer} from 'ol/layer';//热力图
import KML from 'ol/format/KML';//热力图
import areaGeo from "@/static/china.json";
import proGeo from "@/static/province.json";
import { Point } from "ol/geom";
import Overlay from "ol/Overlay";
import colorArr from './color'
export default {
data() {
return {
map: null,
areaLayer: null,
featuresArr:[],
selectedFeature:null,
tipName:undefined,
oldFeature:null, //记录上一个经过的feature
oldStyle:null,
tooltipWid :50,
};
},
methods: {
/**
* 初始化地图
*/
initMap() {
this.map = new Map({
target: "Map",
controls: defaultControls({
zoom: true
}).extend([]),
layers: [
// new TileLayer(
// {
// source: new XYZ({
// url:
// "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}"
// // "http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}"
// })
// },
// { zoomOffset: 1 }
// ),
// new Graticule({
// // the style to use for the lines, optional.
// strokeStyle: new Stroke({
// color: '#ff6767',
// width: 2,
// lineDash: [0.5, 4]
// }),
// showLabels: false, //是否展示刻度
// wrapX: true
// }),
// new HeatmapLayer({
// source: new VectorSource({
// url: 'data/kml/2012_Earthquakes_Mag5.kml',
// format: new KML({
// extractStyles: false
// })
// }),
// blur: parseInt(5, 10),
// radius: parseInt(15, 10),
// weight: function(feature) {
// var name = feature.get('name');
// var magnitude = parseFloat(name.substr(2));
// return magnitude - 5;
// }
// })
],
view: new View({
center: fromLonLat([108.522097, 37.272848]),
zoom: 4.7,
maxZoom: 7,
minZoom: 4
})
});
this.initMove()
this.initClick()
},
/**
* 设置区域
*/
addArea(geo = []) {
if (geo.length == 0) return false;
let areaFeature = null;
// 设置图层
this.areaLayer = new VectorLayer({
source: new VectorSource({
features: []
})
});
// // 添加全国图层
this.map.addLayer(this.areaLayer);
//画几个点
this.drawPoints(this.areaLayer)
// geo.forEach(g => {
// let lineData = g.features[0];
// if (lineData.geometry.type == "MultiPolygon") {
// areaFeature = new Feature({
// geometry: new MultiPolygon(
// lineData.geometry.coordinates
// ).transform("EPSG:4326", "EPSG:3857")
// });
// } else if (lineData.geometry.type == "Polygon") {
// areaFeature = new Feature({
// geometry: new Polygon(
// lineData.geometry.coordinates
// ).transform("EPSG:4326", "EPSG:3857")
// });
// }
// });
// areaFeature.setStyle(
// new Style({
// fill: new Fill({ color: "#4e98f444" }),
// stroke: new Stroke({
// width: 3,
// color: [71, 137, 227, 1]
// })
// })
// );
// this.areaLayer.getSource().addFeatures([areaFeature]);
//添加各个省图层
let provinceData = null
proGeo[0].features.forEach((item,idx)=>{
let lineData = item;
provinceData = new Feature({
geometry: new MultiPolygon(
lineData.geometry.coordinates
).transform("EPSG:4326", "EPSG:3857")
});
provinceData.setStyle(
new Style({
// fill: new Fill({ color: "rgba(32,73,157,0.5)" }),
fill: new Fill({color:colorArr[idx].areaColor}),
stroke: new Stroke({
width: 1,
color: '#1858ab'
})
})
);
//需要s设置属性进去,然后在需要的时候才可以get到
provinceData.set('name',lineData.properties.name)
this.areaLayer.getSource().addFeatures([provinceData]);
})
},
drawPoints(areaLayer){
let coordinates = [
{ x: "106.918082", y: "31.441314" },
{ x: "86.36158200334317", y: "41.42448570787448" },
{ x: "89.71757707811526", y: "31.02619817424643" },
{ x: "116.31694544853109", y: "39.868508850821115" },
{ x: "103.07940932026341", y: "30.438580338450862" }
];
// 循环添加feature
for (let i = 0; i < coordinates.length; i++) {
// 创建feature,一个feature就是一个点坐标信息
let feature = new Feature({
geometry: new Point(
fromLonLat([coordinates[i].x, coordinates[i].y])
)
});
//添加图片
let src = require("../../assets/img/titleIcon.png");
var styleIcon = new Style({
// 设置图片效果
image: new Icon({
src: src,
anchor: [1, 1]
}),
});
feature.setStyle(styleIcon);
this.featuresArr.push(feature);
} // for 结束
// 批量添加feature
areaLayer.getSource().addFeatures(this.featuresArr);
},
addMarker() {
var marker = new Overlay({
position: fromLonLat([114.043505, 30.58165]),
positioning: "center-center",
element: document.getElementById("marker"),
stopEvent: false //决定是否阻止鼠标在这个至上是否可以缩放地图
});
this.map.addOverlay(marker);
},
//移动事件
initMove(){
let that = this
let tooltip = this.$refs.tooltip
this.map.on("pointermove", function(event) {
this.selectedFeature = that.map.forEachFeatureAtPixel(event.pixel, function(feature, layer) {
return {
feature: feature,
layer: layer
};
});
if (this.selectedFeature && this.selectedFeature.feature.get('name')) {
if (this.oldFeature) {
this.oldFeature.setStyle(this.oldStyle); //恢复样式
}
this.oldStyle = this.selectedFeature.feature.getStyle(); //获取当前选中图层的样式 存储起来 用于离开图层恢复之用
this.oldFeature = this.selectedFeature.feature; //获取当前选中图层的样式 存储起来 用于离开图层恢复之用
let highlightStyle = new Style({
//填充
fill: new Fill({
color: 'rgb(13,179,247)'
}),
})
this.oldFeature.setStyle(highlightStyle) //设置高亮
this.tipName = this.selectedFeature.feature.get("name"); //获取name属性
tooltip.innerHTML = this.tipName;
tooltip.style.left = event.pixel_[0]-that.tooltipWid + 'px';
tooltip.style.top = event.pixel_[1]-that.tooltipWid+30 + 'px';
tooltip.style.display = 'block';
} else { //离开feature
if (this.oldFeature) {
this.oldFeature.setStyle(this.oldStyle); //恢复样式
this.tipName = "";
tooltip.style.display = 'none';
tooltip.innerHTML = this.tipName;
}
this.oldFeature = null;
}
})
},
//点击事件
initClick(){
let that = this
let currentFeature
//鼠标点击区域事件
this.map.on("click", function(event) {
currentFeature = that.map.forEachFeatureAtPixel(event.pixel, function(feature, layer) {
return {
feature: feature,
layer: layer
};
});
if(currentFeature){
console.log('地图被点击',currentFeature.feature.get('name'))
}
})
}
},
mounted() {
this.initMap();//初始化地图方法
this.addArea(areaGeo);//添加区域图层方法
this.addMarker()
}
};
</script>
<style lang="scss" scoped>
#Map{
width: 100vw;
height:100vh;
background: rgb(0,21,48);
}
#marker{
width: 20px;
height: 20px;
background: gold;
border-radius: 50%;
}
.tooltip {
display:none;
height: 25px;
min-width:50px;
line-height: 25px;
position:absolute;
font-size: 14px;
padding: 0 10px;
color:#fff;
background:#09142e;
border-radius:4px;
left:50%;
top:30%;
user-select: none;
&::before{
content:'';
position:absolute;
height:0;
width:0;
bottom:-12px;
left:48%;
border:6px solid transparent;
border-top-color: #c9a3a3;
}
&::after{
content:'';
position:absolute;
height:0;
width:0;
bottom:-10px;
left:48%;
border:6px solid transparent;
border-top-color: #09142e;
}
}
</style>