openlayers三大核心Map,View,Layer
一、项目引入
npm install ol
二、准备工作
import "ol/ol.css";//样式
import Map from "ol/Map";//地图对象
import Feature from 'ol/Feature';//标记
import View from "ol/View";//视图
import { Point,LineString } from "ol/geom";//标点,画线
import { OSM, XYZ, TileArcGISRest, Vector as VectorSource, WMTS } from 'ol/source';//图源
import { Vector as VectorLayer, Tile as TileLayer } from "ol/layer";//图层
import { fromLonLat, transform } from "ol/proj";//坐标系维度转换
import {
Circle as CircleStyle,
Fill,
Icon,
Stroke,
Style,
RegularShape
} from 'ol/style';//填充图标描边等之类用来标记打点使用
data(){
return{
vectorSourceData: null,
vectorSource: new VectorSource(),
}
}
三、底图渲染
//地图瓦片
let tileLayer=new TileLayer({
source: new XYZ({
url: "获取瓦片的地址",
}),
})
// 绘制点
let featureLayer = new VectorLayer({
source: that.vectorSource,
});
// 绘制线
that.vectorSourceData = new VectorSource({ wrapX: false })
let featureLineLayer = new VectorLayer({
source: that.vectorSourceData,
});
this.map = new Map({
target: 'container',//container为map的地图容器
layers: [tileLayer,featureLayer,featureLineLayer], // 设置图层
// 设置显示地图的视图
view: new View({
// projection: 'EPSG:4326',地图坐标系默认3857
center: transform([122.20, 30.25],"EPSG:4326","EPSG:3857"), //地图中心点
//tranfotm根据坐标系不同转换经纬度
zoom: 12, // 显示层级
rotation: 0.26,//旋转
}),
});
四、打点(标点)
let feature = new Feature({
idName:item.id,//给点取得名字标识(任意)
geometry: new Point(transform([item.lon,item.lat],"EPSG:4326","EPSG:3857")),//标记的经纬度坐标
})
//标记点的图标
feature.setStyle(
new Style({
image: new Icon({
src: require('@/assets/images/seawarning/shipIcon.svg'),
scale:0.1,//缩放
rotation:(item.heading*Math.PI)/180,//图标方向已正北方为0,顺时针转,(这里转成弧度)
})
})
);
//标记点的图标(内置圆形)
feature.setStyle(
new Style({
image: new CircleStyle({
fill: new Fill({//填充颜色
color: 'red',
}),
stroke: new Stroke({//描边
color: "#000",
}),
radius: 5,//点的大小
})
})
);
this.vectorSource.addFeature(feature);(data声明 vectorSource: new VectorSource())
//更新标记的经纬度位置,不重绘
this.vectorSource.forEachFeature((f)=>{//循环所有点标记,找到自己所需要的进行更新
if(f.values_.idName==item.id){
f.setGeometry(new Point(transform([item.lon,item.lat],"EPSG:4326","EPSG:3857")))//跟新坐标位置
}
})
五、绘线
// 绘制连线
addLine() {
let featureLine = new Feature({
type: "lineStyle",
geometry: new LineString([
transform([122.203, 30.2245], "EPSG:4326", "EPSG:3857"),
transform([122.216588,30.228215], "EPSG:4326", "EPSG:3857")
]),
});
featureLine.setStyle(
new Style({
stroke: new Stroke({
color: 'red',
width: 5,
})
})
);
this.vectorSourceData.addFeature(featureLine);
},
六、自定义绘制多边形
// 开始绘制多边形
drawStart(type,id) {
let that = this;
this.draw = new Draw({
source: this.source,
type: type,
});
this.map.addInteraction(this.draw);
this.draw.on("drawend", function (evt) {
that.drawingEnd(evt,id);
});
// 监听开始绘制
this.draw.on("drawstart", (evt) => {
evt.feature.getGeometry().on("change", function (et) {
//设置测量提示框的内标签为最终输出结果
lastTooltipCoord = et.target.getLastCoordinate();
let coordinateLine = et.target.getFlatCoordinates();
//长度
lastLength = that.formatLength(et.target);
tooltipCoord = [
coordinateLine[coordinateLine.length - 4],
coordinateLine[coordinateLine.length - 3],
];
that.measureTooltipElement.innerHTML = length;
that.measureTooltipElement.className =
"ol-tooltip ol-tooltip-static draw_km";
//设置测量提示框的位置坐标
that.measureTooltip.setPosition(tooltipCoord);
});
});
// 监听结束绘制
this.draw.on("drawend", function (evt) {
that.measureTooltipElement.innerHTML = lastLength;
//设置测量提示框的位置坐标
that.measureTooltip.setPosition(lastTooltipCoord);
that.drawingEnd(evt, indexNum);
});
},
// 构建多边形结束
drawingEnd(evt,id) {
const geo = evt.feature.getGeometry();
const points = geo.getCoordinates();
this.map.removeInteraction(this.draw);
this.drawLine(points,id)
},
//删除图形/图层
delDrawLine(){
//判断id 删除指定的单个多边形
// this.featureList.forEach(item=>{
// if(item.id_==0){
// this.polygonLayer.getSource().removeFeature(item)
// }
// })
//删除polygonLayer图层上所有多边形
this.polygonLayer.getSource().clear()
},
/**
* 绘制多边形路径
*/
drawLine(points,id){
let feature = new Feature({
type:'Polygon',
geometry: new Polygon(points)
})
feature.setId(id)//设置id
this.indexNum++
feature.setStyle(
new Style({
fill: new Fill({//填充
color: 'rgba(1, 210, 241, 0.5)'
}),
stroke: new Stroke({//绘线
color: 'rgba(255, 0, 0)',
width: 1,
}),
})
)
this.featureList.push(feature)//用来保存页面上的多边形,可以后续增删操作
this.polygonSource.addFeature(feature)
},
//创建一个新的测距提示
createMeasureTooltip() {
let self = this;
//如果已经存在帮助提示框则移除
if (self.measureTooltipElement) {
self.measureTooltipElement.parentNode.removeChild(
self.measureTooltipElement
);
}
//创建帮助提示要素的div
self.measureTooltipElement = document.createElement("div");
//设置帮助提示要素的样式
self.measureTooltipElement.className = "ol-tooltip ol-tooltip-measure";
//创建一个帮助提示的覆盖标注
self.measureTooltip = new Overlay({
element: self.measureTooltipElement,
offset: [0, -15],
positioning: "bottom-center",
});
//将帮助提示的覆盖标注添加到地图中
self.map.addOverlay(self.measureTooltip);
},
// 测量距离
formatLength(line) {
//计算平面距离
var length = getLength(line);
//定义输出变量
var output;
//如果长度大于1000,则使用km单位,否则使用m单位
if (length > 1000) {
output = Math.round((length / 1000) * 100) / 100 + " " + "km";
} else {
output = Math.round(length * 100) / 100 + " " + "m";
}
return output;
},
七、点击标点事件
// 点击
const that=this
this.map.on("click", (e) => {
// 判断是否点击在点上
let feature = this.map.forEachFeatureAtPixel(//循环
e.pixel,
(feature) => feature
);
if (feature != null) {
let dataSingle=null
this.shipLayerArray.forEach((item,index)=>{
if(item.id==feature.values_.idName){//idName自定义的标点属性
dataSingle=this.shipLayerArray[index]
}
})
console.log(dataSingle)//打印出点位信息
}
});
八、成果