Vue项目-OpenLayers地图初始化
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
一、安装
1、官网
(1)官网文档
(2)参考文档
http://linwei.xyz/ol3-primer/ch01/index.html
(3)参考示例
http://develop.smaryun.com:81/API/JS/OL3InterfaceDemo/index.htm
2、安装openlayers
// 安装最新版本
npm i ol
// 安装指定版本,例如7.0.0
npm i ol@7.0.0
// 注意:如果npm无法正常安装,使用cnpm安装
// 安装最新版本
cnpm i ol
// 安装指定版本,例如7.0.0
cnpm i ol@7.0.0
二、配置
1、模块引入
创建一个名为ol.js的文件,引入ol中需要使用的模块
// ----------------<<CSS文件>>----------------
import "ol/ol.css";
// ----------------<<常用模块>>----------------
import Map from "ol/Map.js";
// import { XYZ } from "ol/source.js";
import XYZ from "ol/source/XYZ";
import View from "ol/View.js";
import Fill from 'ol/style/Fill.js'
import Point from 'ol/geom/Point.js';
import Style from 'ol/style/Style.js';
import Circle from 'ol/style/Circle.js';
import Stroke from 'ol/style/Stroke.js';
import Feature from 'ol/Feature.js';
import TileLayer from "ol/layer/Tile.js";
import LineString from 'ol/geom/LineString.js';
import VectorLayer from 'ol/layer/Vector.js';
import VectorSource from 'ol/source/Vector.js';
import { DoubleClickZoom } from 'ol/interaction.js';
// ----------------<<其他模块>>----------------
import OSM from "ol/source/OSM.js";
import WFS from 'ol/format/WFS.js';
import Icon from 'ol/style/Icon.js';
import Tile from 'ol/layer/Tile.js';
import WMTS from 'ol/source/WMTS.js';
import Image from 'ol/layer/Image.js';
import { buffer } from 'ol/extent.js';
import Overlay from 'ol/Overlay.js';
import GeoJSON from 'ol/format/GeoJSON.js';
import TileWMS from 'ol/source/TileWMS.js';
import ImageWMS from 'ol/source/ImageWMS.js';
import ImageStyle from 'ol/style/Image.js';
import ZoomToExtent from 'ol/control/ZoomToExtent.js';
import { transform, fromLonLat, toLonLat } from 'ol/proj.js'
const ols = {
Map: Map,
XYZ: XYZ,
View: View,
OSM: OSM,
WFS: WFS,
Icon: Icon,
Tile: Tile,
WMTS: WMTS,
Fill: Fill,
Point: Point,
Style: Style,
Image: Image,
buffer: buffer,
Circle: Circle,
Stroke: Stroke,
Feature: Feature,
Overlay: Overlay,
GeoJSON: GeoJSON,
TileWMS: TileWMS,
ImageWMS: ImageWMS,
toLonLat: toLonLat,
TileLayer: TileLayer,
transform: transform,
fromLonLat: fromLonLat,
ImageStyle: ImageStyle,
LineString: LineString,
VectorLayer: VectorLayer,
VectorSource: VectorSource,
ZoomToExtent: ZoomToExtent,
DoubleClickZoom: DoubleClickZoom,
}
export default ols
三、地图渲染 & 模型添加
1、初始化地图
<template>
<div id="openLayers">
<!-- map -->
<div id="openLayerContainer"></div>
</div>
</template>
<script>
// 引入模块文件
import ols from "../js/ol";
export default {
name: "",
components: {},
props: {},
data() {
return {
// 点位ID
pointId:0,
// 所有点位坐标集合
pointCoord:[],
// 所有点位图层集合-清除使用
pointVector:[],
// 线条ID
lineId:0,
// 所有线条图层集合-清除使用
lineVector:[],
}
},
computed: {},
created() {},
mounted() {
this.initMap();
},
methods: {
// 初始化地图
initMap() {
const tileMap = new ols.TileLayer({
source: new ols.XYZ({
// 官网在线地图(可以添加在线和离线地图)
url: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
}),
});
// 初始化地图
window.openLayers = new ols.Map({
layers: [tileMap], // 直接在配置上加载
target: "openLayerContainer", // 地图容器
view: new ols.View({
projection: "EPSG:4326", // 坐标系
center: [110, 30], // 地图中心点
zoom: 6, // 默认缩放比例
minZoom: 2, // 缩放最小级别 2
maxZoom: 20, // 缩放最大级别 20
}),
});
// 清除默认的左键双击缩放
const dblClickInteraction = openLayers
.getInteractions()
.getArray()
.find((interaction) => {
return interaction instanceof ols.DoubleClickZoom;
});
openLayers.removeInteraction(dblClickInteraction);
// 左键双击
openLayers.on("dblclick", (e) => {
// 添加点位
this.addPoint(e.coordinate);
// 保存点位坐标位置
this.pointCoord.push(e.coordinate);
});
},
},
};
</script>
<style lang="less" scoped>
#openLayers {
width: 100%;
height: 100vh;
#openLayerContainer {
width: 100%;
height: 100%;
}
}
</style>
2、添加模型
(1)官网示例
每一个点位和线条都会创建一个图层
① 添加、清除点位
// 添加点位
addPoint(coordinate) {
// 创建点位
const point = new ols.Feature({
geometry: new ols.Point([coordinate[0], coordinate[1]]),
});
// 设置点位id
point.setId(this.pointId);
// 设置点位样式
point.setStyle(
new ols.Style({
// 形状
image: new ols.Circle({
radius: 3,
fill: new ols.Fill({
color: "rgba(255,0,0,1)",
}),
}),
})
);
//实例化一个矢量图层Vector作为绘制层
const source = new ols.VectorSource({
features: [point],
});
//创建一个图层
const vector = new ols.VectorLayer({
source: source,
});
//将绘制层添加到地图容器中
openLayers.addLayer(vector);
// 图层中添加点
vector.getSource().addFeature(point);
//存储图层
this.pointVector.push(vector);
// 点位id加1,下次创建点位使用
this.pointId++;
},
// 清除点位
clearPoint() {
// 移除点位
this.pointCoord.forEach((item) => {
item
.getSource()
.getFeatures()
.forEach((feature) => {
item.getSource().removeFeature(feature);
});
// 从地图容器重删除绘制层
openLayers.removeLayer(item);
});
// 点位ID
this.pointId = 0;
// 所有点位坐标集合
this.pointCoord = [];
// 所有点位图层集合-清除使用
this.pointVector = [];
},
② 添加、清除线条
// 添加线条
addLine() {
if (!this.pointCoord || this.pointCoord.length < 2) {
this.$message.warning("至少需要2个点");
} else {
// 创建线条
const line = new ols.Feature({
geometry: new ols.LineString(this.pointCoord),
});
// 设置线条id
line.setId(this.lineId);
// 设置线条样式
line.setStyle(
new ols.Style({
// 边线
stroke: new ols.Stroke({
color: "#ffffff",
width: 2,
}),
})
);
// 实例化一个矢量图层Vector作为绘制层
const source = new ols.VectorSource({
features: [line],
});
// 创建一个图层
const vector = new ols.VectorLayer({
source: source,
});
// 将绘制图层添加到地图容器中
openLayers.addLayer(vector);
// 图层中添加线
vector.getSource().addFeature(line);
// 存储图层
this.lineVector.push(vector);
// 线条id加1,下次创建线条使用
this.lineId++;
}
},
// 清除线条
clearLine() {
// 移除线条
this.lineVector.forEach((item) => {
item
.getSource()
.getFeatures()
.forEach((feature) => {
item.getSource().removeFeature(feature);
});
// 从地图容器重删除绘制层
openLayers.removeLayer(item);
});
// 线条ID
this.lineId = 0;
// 所有线条图层集合-清除使用
this.lineVector = [];
},
(2)个人示例
点位和线条各一个图层
① 添加、清除点位
// 添加点位
addPoint(coordinate) {
if (!this.pointVector) {
//实例化一个矢量图层Vector作为绘制层
const source = new ols.VectorSource();
this.pointVector = new ols.VectorLayer({
source: source,
});
}
// 创建点位
const point = new ols.Feature({
geometry: new ols.Point([coordinate[0], coordinate[1]]),
});
// 设置点位id
point.setId(this.pointId);
// 设置点位样式
point.setStyle(
new ols.Style({
// 形状
image: new ols.Circle({
radius: 3,
fill: new ols.Fill({
color: "rgba(255,0,0,1)",
}),
}),
})
);
//将绘制层从地图容器中移除
openLayers.removeLayer(this.pointVector);
//将绘制层添加到地图容器中
openLayers.addLayer(this.pointVector);
//更新地图
openLayers.updateSize();
// 图层中添加点位
this.pointVector.getSource().addFeature(point);
// 存储点位
this.pointArr.push(point);
// 点位id加1,下次创建点位使用
this.pointId++;
},
// 清除点位
clearPoint() {
// 移除点位
this.pointArr.forEach((item) => {
this.pointVector.getSource().removeFeature(item);
});
// 从地图容器中删除绘制层
openLayers.removeLayer(this.pointVector);
// 点位ID
(this.pointId = 0),
// 所有点位坐标集合
(this.pointCoord = []);
// 所有点位图层集合-清除使用
this.pointVector = [];
},
② 添加、清除线条
// 添加线条
addLine() {
if (!this.pointCoord || this.pointCoord.length < 2) {
this.$message.warning("至少需要2个点");
} else {
//实例化一个矢量图层Vector作为绘制层
if (!this.lineVector) {
const source = new ols.VectorSource();
this.lineVector = new ols.VectorLayer({
source: source,
});
}
// 创建线条
const line = new ols.Feature({
geometry: new ols.LineString(this.pointCoord),
});
// 设置线条id
line.setId(this.lineId);
// 设置线条样式
line.setStyle(
new ols.Style({
// 边线
stroke: new ols.Stroke({
color: "#ffffff",
width: 2,
}),
})
);
//将绘制层从地图容器中移除
openLayers.removeLayer(this.lineVector);
//将绘制层添加到地图容器中
openLayers.addLayer(this.lineVector);
//更新地图
openLayers.updateSize();
// 图层中添加线
this.lineVector.getSource().addFeature(line);
// 存储线条
this.lineArr.push(line);
// 线条id加1,下次创建线条使用
this.lineId++;
}
},
// 清除线条
clearLine() {
// 移除线条
this.lineArr.forEach((item) => {
this.lineVector.getSource().removeFeature(item);
});
// 从地图容器中删除绘制层
openLayers.removeLayer(this.lineVector);
// 线条ID
this.lineId = 0;
// 所有线条图层集合-清除使用
this.lineVector = [];
},
四、其他操作
1、鼠标事件
// 清除默认的左键双击缩放
const dblClickInteraction = openLayers
.getInteractions()
.getArray()
.find((interaction) => {
return interaction instanceof ols.DoubleClickZoom;
});
openLayers.removeInteraction(dblClickInteraction);
//左键单击
openLayers.on("singleclick", (e) => {
console.log("左键单击", e);
});
// 左键双击
openLayers.on("dblclick", (e) => {
console.log("左键双击", e);
});
// 单击(左右键)
openLayers.on("click", (e) => {
console.log("单击", e);
});
// 鼠标移动
openLayers.on("pointermove", (e) => {
console.log("鼠标移动", e);
});
// 鼠标拖拽
openLayers.on("pointerdrag", (e) => {
console.log("鼠标拖拽", e);
});
// 地图移动事件
openLayers.on("moveend", (e) => {
console.log("地图移动事件", e);
});
五、完整案例
1、代码(ol@6.15.1)
<template>
<div class="openLayers">
<!-- map -->
<div id="openLayerContainer"></div>
</div>
</template>
<script>
// ----------------<<CSS文件>>----------------
import "ol/ol.css";
import imgUrl from "@assets/img/car.png"; // 引入图片
// ----------------<<常用模块>>----------------
import Map from "ol/Map.js";
import XYZ from "ol/source/XYZ.js";
import View from "ol/View.js";
import TileLayer from "ol/layer/Tile.js";
import { fromLonLat, transform } from "ol/proj.js";
import styleCircle from "ol/style/Circle.js";
import Style from "ol/style/Style.js";
import Icon from "ol/style/Icon.js";
import Stroke from "ol/style/Stroke.js"; // 线条颜色
import Fill from "ol/style/Fill.js"; // 填充色
import Feature from "ol/Feature.js";
import VectorSource from "ol/source/Vector.js";
import VectorLayer from "ol/layer/Vector.js";
import { LineString, Point, Circle, LinearRing, Polygon } from "ol/geom";
export default {
name: "",
components: {},
props: {},
data() {
return {
// 地图对象
openLayers: null,
// 绘制层
sourceVector: null,
// 图层
layerVector: null,
// 位置信息
position: {
localDoa: 0, // 方位
localROA: 30, // 夹角
localHeight: 0, // 高度
localLon: 130, // 经度
localLat: 30, // 纬度
},
// timer
timer: null,
};
},
computed: {},
created() {},
mounted() {
this.queryLocalPos(); // 获取实时位置
this.initMap();
this.changeTowardParams();
},
methods: {
// ---------------------<<请求>>---------------------
queryLocalPos() {
this.$API.queryLocalPosRequest().then((res) => {
if (res.code == 1000) {
this.position = res.data;
// this.initMap();
}
});
},
// ---------------------<<地图>>---------------------
// 初始化地图
initMap() {
const tileMap = new TileLayer({
source: new XYZ({
// 官网在线地图(可以添加在线和离线地图)
// url: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
url: "https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
}),
});
// 初始化地图;
window.openLayers = new Map({
target: "openLayerContainer", // 地图容器
layers: [tileMap], // 直接在配置上加载
view: new View({
projection: "EPSG:3857", // 坐标系
center: fromLonLat([this.position.localLon, this.position.localLat]),
zoom: 9, // 默认缩放比例
minZoom: 5, // 缩放最小级别 1
maxZoom: 10, // 缩放最大级别 20
}),
});
// 画圆
this.drawCircle(this.position, 50000);
// 设置地图中心点-定位功能
// openLayers.getView().setCenter(fromLonLat([this.position.localLon, this.position.localLat]));
// openLayers.on("pointerdrag", function (e) {
// console.log("鼠标拖拽", e);
// });
// openLayers.on("singleclick", function (e) {
// console.log("左键单击", e);
// // const coordinate = transform(e.coordinate, "EPSG:3857", "EPSG:4326");
// });
// openLayers.on("click", function (e) {
// console.log("鼠标点击", e);
// // const coordinate = transform(e.coordinate, "EPSG:3857", "EPSG:4326");
// });
// // 清除默认的左键双击缩放
// const dblClickInteraction = openLayers
// .getInteractions()
// .getArray()
// .find((interaction) => {
// return interaction instanceof ols.DoubleClickZoom;
// });
// openLayers.removeInteraction(dblClickInteraction);
// openLayers.on("dblclick", function (e) {
// console.log("左键双击", e);
// // const coordinate = transform(e.coordinate, "EPSG:3857", "EPSG:4326");
// });
},
// 画圆
drawCircle(ps, range) {
var newCircle = new Feature({
geometry: new Circle(fromLonLat([ps.localLon, ps.localLat]), range),
});
// 设置id
newCircle.setId("newCircle");
newCircle.setStyle(
new Style({
//填充色
fill: new Fill({
color: "rgba(255,228,181,0.5)",
}),
//边线颜色
stroke: new Stroke({
color: "#FE9E28",
width: 3,
}),
//形状
image: new styleCircle({
radius: 7,
fill: new Fill({
color: "rgba(255,228,181,0.5)",
}),
}),
})
);
//实例化一个矢量图层Vector作为绘制层
this.sourceVector = new VectorSource({
features: [newCircle],
});
//创建一个图层
this.layerVector = new VectorLayer({
source: this.sourceVector,
});
//将图层添加到地图容器中
openLayers.addLayer(this.layerVector);
// 添加中心点
this.drawPoint({
lon: ps.localLon,
lat: ps.localLat,
angle: ps.localDoa,
});
// 添加扇形
this.drawCurve(
fromLonLat([ps.localLon, ps.localLat]),
range,
ps.localDoa,
ps.localROA
);
},
// 位置:origin
// 范围:radius
// 朝向:angle
// 角度:range
drawCurve(origin, radius, angle, range) {
const feature = new Feature({
geometry: new Polygon([this.addCurve(origin, radius, angle, range)]),
});
// 设置id
feature.setId("myCurve");
feature.setStyle(
new Style({
//填充色
fill: new Fill({
color: "rgba(255,0,0,.5)",
}),
//边线颜色
stroke: new Stroke({
color: "#FF0000",
width: 1,
}),
})
);
this.layerVector.getSource().addFeatures([feature]);
},
addCurve(origin, radius, angle, range) {
let pointList = [];
/**
* 添加起始点位
*/
pointList.push(origin);
/**
* 开始角度
*/
let startAngle = angle - range / 2 + 90;
/**
* 根据传进来的角度范围绘制
*/
for (let i = 0; i < range; i++) {
startAngle += 1;
/**
* 利用余弦计算出维度,因为在二维地图中正北方向是朝上的,同理经度有正弦可以计算出来
*/
let lon = Math.cos((startAngle * Math.PI) / 180) * radius + origin[0];
let lat = Math.sin((startAngle * Math.PI) / 180) * radius + origin[1];
/**
* 添加进数组中
*/
pointList.push([lon, lat]);
}
return pointList;
},
// 画点
drawPoint(ps) {
// 创建点位
const point = new Feature({
geometry: new Point(fromLonLat([ps.lon, ps.lat])),
});
// 设置id
point.setId("myPoint");
// 设置点位样式
point.setStyle(
new Style({
image: new Icon({
src: imgUrl,
scale: 0.1,
rotation: -(ps.angle * (6.3 / 360)),
}),
})
);
// 添加到图层
this.layerVector.getSource().addFeatures([point]);
},
// 重新添加所有实体
addAll() {
// 清除所有实体
this.clearAll();
// 添加所有实体
this.drawCircle(this.position, 50000);
// 设置地图中心点
openLayers
.getView()
.setCenter(
fromLonLat([this.position.localLon, this.position.localLat])
);
},
// 清除所有
clearAll() {
// 删除所有feature
this.layerVector
.getSource()
.getFeatures()
.forEach((feature) => {
this.layerVector.getSource().removeFeature(feature);
});
// 删除图层
openLayers.removeLayer(this.layerVector);
},
// 调整方位
changeToward(ps, range) {
this.addAll();
},
// 调整方位参数
changeTowardParams() {
// 自动调整方位
if (this.timer) {
clearInterval(this.timer);
}
this.timer = setInterval(() => {
if (this.position.localDoa == 360) {
this.position.localDoa = 0;
}
this.position.localDoa -= 6;
}, 500);
},
},
watch: {
position: {
handler(newVal, oldVal) {
this.changeToward(newVal, 50000);
},
deep: true,
},
},
beforeDestroy() {
clearInterval(this.timer);
},
};
</script>
<style lang="less" scoped>
.openLayers {
width: 100%;
height: 100%;
#openLayerContainer {
width: 100%;
height: 100%;
background-color: #2f4f4f;
}
}
</style>
GitHub 加速计划 / vu / vue
80
16
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:4 个月前 )
9e887079
[skip ci] 2 个月前
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 6 个月前
更多推荐
已为社区贡献5条内容
所有评论(0)