OpenLayers实操Vue3(点线面文字标注热力图聚合点地图打印等等...)
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
1.OpenLayers简介
OpenLayers是一个用于开发WebGIS客户端的JavaScript包,为互联网客户端提供强大的地图展示功能,包括地图数据显示与相关操作,主要还是以面向对象进行开发的。
2.初始化地图
(1)安装
npm install ol
(2)实例化地图
要显示一个基本的地图首先需要提供一个容器,设置好宽高,然后引入OpenLayers,添加一个地图图层,地图服务可以使用内置的一个开源地图OSM,也可以使用其他的在线瓦片服务,比如:百度、高德、天地图、必应、谷歌等,具体服务地址可以自行百度,本文使用的是高德的服务
<template>
<div class="ol-map" id="olMap"></div>
</template>
引入这模块和组件
import { ref, reactive, toRefs, onMounted, nextTick } from 'vue'
import Map from 'ol/Map' // OpenLayers的主要类,用于创建和管理地图
import View from 'ol/View' // OpenLayers的视图类,定义地图的视图属性
import { Tile as TileLayer } from 'ol/layer' // OpenLayers的瓦片图层类
import { XYZ, OSM } from 'ol/source' // OpenLayers的瓦片数据源,包括XYZ格式和OpenStreetMap专用的数据源
import { fromLonLat, toLonLat } from 'ol/proj' // OpenLayers的投影转换函数,用于经纬度坐标和投影坐标之间的转换
初始化地图函数
onMounted(() => {
// 地图初始化
initOLMap()
})
let map: any = null
/**
* Date:2024/3/26
* Author:zx
* Function:【初始化地图】
* @param 无
*/
function initOLMap() {
// 创造地图实例
map = new Map({
// 设置地图容器的ID
target: 'olMap',
// 定义地图的图层列表,用于显示特定的地理信息。
layers: [
// 高德地图
// TileLayer表示一个瓦片图层,它由一系列瓦片(通常是图片)组成,用于在地图上显示地理数据。
new TileLayer({
// 设置图层的数据源为XYZ类型。XYZ是一个通用的瓦片图层源,它允许你通过URL模板来获取瓦片
source: new XYZ({
url: 'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
})
})
],
// 设置地图的视图参数
// View表示地图的视图,它定义了地图的中心点、缩放级别、旋转角度等参数。
view: new View({
// fromLonLat是一个函数,用于将经纬度坐标转换为地图的坐标系统。
center: fromLonLat([108.924652, 34.208527]),//地图中心点
zoom: 15,// 缩放级别
minZoom: 0,// 最小缩放级别
maxZoom: 18,// 最大缩放级别
constrainResolution: true// 因为存在非整数的缩放级别,所以设置该参数为true来让每次缩放结束后自动缩放到距离最近的一个整数级别,这个必须要设置,当缩放在非整数级别时地图会糊
})
})
}
一个基本地图就出来了
添加了地图的旋转效果,包括一些控件以及一些常用的事件,完整代码如下
<template>
<div class="ol-map" id="olMap"></div>
</template>
<script lang='ts' setup>
import { ref, reactive, toRefs, onMounted, nextTick } from 'vue'
import Map from 'ol/Map' // OpenLayers的主要类,用于创建和管理地图
import View from 'ol/View' // OpenLayers的视图类,定义地图的视图属性
import { Tile as TileLayer } from 'ol/layer' // OpenLayers的瓦片图层类
import { XYZ, OSM } from 'ol/source' // OpenLayers的瓦片数据源,包括XYZ格式和OpenStreetMap专用的数据源
import { fromLonLat, toLonLat } from 'ol/proj' // OpenLayers的投影转换函数,用于经纬度坐标和投影坐标之间的转换
import {
defaults as defaultInteractions,
DragRotateAndZoom,
} from 'ol/interaction' // OpenLayers的交互类,包括默认的交互集合和特定的旋转缩放交互
import { defaults, FullScreen, MousePosition, ScaleLine } from 'ol/control' // OpenLayers的控件类,包括默认的控件集合和特定的全屏、鼠标位置、比例尺控件
import Feature from 'ol/Feature' // OpenLayers的要素类,表示地图上的一个对象或实体
import Point from 'ol/geom/Point' // OpenLayers的点几何类,用于表示点状的地理数据
import { Vector as VectorLayer } from 'ol/layer' // OpenLayers的矢量图层类,用于显示矢量数据
import { Vector as VectorSource } from 'ol/source' // OpenLayers的矢量数据源类,用于管理和提供矢量数据
import { Circle as CircleStyle, Style, Stroke, Fill, Icon } from "ol/style" // OpenLayers的样式类,用于定义图层的样式,包括圆形样式、基本样式、边框、填充和图标
import LineString from 'ol/geom/LineString' // OpenLayers的线几何类,用于表示线状的地理数据
import tb from '@/assets/image/hyfw.png' // 导入一个图片资源
import Polygon from "ol/geom/Polygon" // OpenLayers的多边形几何类,用于表示面状的地理数据
onMounted(() => {
// 地图初始化
initOLMap()
})
let map: any = null
/**
* Date:2024/3/26
* Author:zx
* Function:【初始化地图】
* @param 无
*/
function initOLMap() {
// 创造地图实例
map = new Map({
// 设置地图容器的ID
target: 'olMap',
// 定义地图的图层列表,用于显示特定的地理信息。
layers: [
// 高德地图
// TileLayer表示一个瓦片图层,它由一系列瓦片(通常是图片)组成,用于在地图上显示地理数据。
new TileLayer({
// 设置图层的数据源为XYZ类型。XYZ是一个通用的瓦片图层源,它允许你通过URL模板来获取瓦片
source: new XYZ({
url: 'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
})
})
],
// 设置地图的视图参数
// View表示地图的视图,它定义了地图的中心点、缩放级别、旋转角度等参数。
view: new View({
// fromLonLat是一个函数,用于将经纬度坐标转换为地图的坐标系统。
center: fromLonLat([108.924652, 34.208527]),//地图中心点
zoom: 15,// 缩放级别
minZoom: 0,// 最小缩放级别
maxZoom: 18,// 最大缩放级别
constrainResolution: true// 因为存在非整数的缩放级别,所以设置该参数为true来让每次缩放结束后自动缩放到距离最近的一个整数级别,这个必须要设置,当缩放在非整数级别时地图会糊
}),
// 按住shift进行旋转
interactions: defaultInteractions().extend([new DragRotateAndZoom()]),
// 控件
controls: defaults().extend([
new FullScreen(), // 全屏
new MousePosition(), // 显示鼠标当前位置的地图坐标
new ScaleLine()// 显示比例尺
])
})
// 事件
map.on('moveend', (e:any) => {
console.log('地图移动', e)
// 获取当前缩放级别
var zoomLevel = map.getView().getZoom();
console.log('当前缩放级别:', zoomLevel);
})
map.on('rendercomplete', () => {
console.log('渲染完成')
})
map.on('click', (e:any) => {
console.log('地图点击', e)
var coordinate = e.coordinate;
// 将投影坐标转换为经纬度坐标
var lonLatCoordinate = toLonLat(coordinate);
// 输出转换后的经纬度坐标
console.log('经纬度坐标:', lonLatCoordinate);
})
}
3.openlayers实战
(1)openlayers添加点
自己设置点位或者添加图片都可
/**
* Date:2024/3/26
* Author:zx
* Function:【点】
* @param 无
*/
const dotMethod = () => {
// 创建点特征(Feature):
let feature = new Feature({
title: 'xian',
geometry: new Point(fromLonLat([108.924652, 34.208527])) // 转换坐标
})
// 设置特征样式(Style):
feature.setStyle(
new Style({
// 使用 CircleStyle 创建一个圆形的点
image: new CircleStyle({
fill: new Fill({
color: 'red',
}),
radius: 7,
}),
})
);
// 创建和添加特征到源(Source)
// VectorSource表示一个矢量要素源,它用于存储和显示地理数据。
let source = new VectorSource()
source.addFeature(feature)
// 创建图层并设置源(Layer)
// VectorLayer表示一个矢量图层,它由一系列矢量要素(Feature)组成,用于在地图上显示地理数据。
let layer = new VectorLayer()
layer.setSource(source)
map.addLayer(layer)
}
(2)鼠标点击生成点
/**
* Date:2024/3/26
* Author:zx
* Function:【鼠标点击生成点】
* @param 无
*/
const DrawMethod = () => {
// 创建一个绘制交互(Draw)
// 监听地图上的鼠标点击事件
map.on('click', function (event: any) {
// 获取点击位置的坐标
let coordinate = event.coordinate;
// 创建点特征(Feature)
let pointFeature = new Feature({
geometry: new Point(coordinate)
});
// 设置点特征的样式(Style)
pointFeature.setStyle(
new Style({
image: new CircleStyle({
fill: new Fill({
color: 'red' // 点的填充颜色为红色
}),
radius: 7, // 点的半径
stroke: new Stroke({
color: 'black', // 点的边界颜色为黑色
width: 2 // 点的边界宽度
})
})
})
);
// 创建和添加特征到源(Source)
let source = new VectorSource();
source.addFeature(pointFeature);
// 创建图层并设置源(Layer)
let layer = new VectorLayer();
layer.setSource(source);
// 将图层添加到地图上
map.addLayer(layer);
});
}
(3)openlayers添加线
/**
* Date:2024/3/26
* Author:zx
* Function:【线】
* @param 无
*/
const lineMethod = () => {
// 创建线特征(Feature):
let lineFeature = new Feature({
geometry: new LineString([
fromLonLat([108.924652, 34.208527]), // 起点经纬度坐标
fromLonLat([108.92314996295164, 34.220681741967226]), // 终点经纬度坐标
// 你可以在这里添加更多的坐标点,以绘制更复杂的线
])
});
// 设置线特征的样式(Style):
lineFeature.setStyle(
new Style({
stroke: new Stroke({
color: 'red', // 线的颜色
width: 2 // 线的宽度
})
})
);
// 创建和添加特征到源(Source)
let source = new VectorSource();
source.addFeature(lineFeature);
// 创建图层并设置源(Layer)
let layer = new VectorLayer();
layer.setSource(source);
// 将图层添加到地图上
map.addLayer(layer);
}
(4)openlayers添加面
/**
* Date:2024/3/26
* Author:zx
* Function:【面】
* @param 无
*/
const faceMethod = () => {
// 定义多边形的坐标数组,这里使用一个简单的正方形作为示例
let coordinates = [
[
fromLonLat([108.924652, 34.208527]),
fromLonLat([108.925652, 34.208527]),
fromLonLat([108.925652, 34.209527]),
fromLonLat([108.924652, 34.209527]),
fromLonLat([108.924652, 34.208527])
]
];
// 创建多边形的几何对象
let polygon = new Polygon(coordinates);
// 创建特征(Feature)
let polygonFeature = new Feature({
geometry: polygon
});
// 设置多边形的样式(Style)
polygonFeature.setStyle(
new Style({
stroke: new Stroke({
color: 'red', // 多边形边界线的颜色
width: 2 // 多边形边界线的宽度
}),
fill: new Fill({
color: 'rgba(255, 0, 0, 0.5)' // 多边形填充颜色,这里设置为半透明红色
})
})
);
// 创建和添加特征到源(Source)
let source = new VectorSource();
source.addFeature(polygonFeature);
// 创建图层并设置源(Layer)
let layer = new VectorLayer();
layer.setSource(source);
// 将图层添加到地图上
map.addLayer(layer);
}
(5)openlayers添加图片
const dotMethod = () => {
// 创建点特征(Feature):
let feature = new Feature({
title: 'xian',
geometry: new Point(fromLonLat([108.924652, 34.208527])) // 转换坐标
})
// 设置特征样式(Style):
feature.setStyle(
new Style({
// 自定义图片
image: new Icon({
// anchor: [1, 1],// 显示位置
//图标缩放比例
// scale:0.5,
//透明度
opacity: 0.75,
src: zq// 图片url
})
})
);
// 创建和添加特征到源(Source)
// VectorSource表示一个矢量要素源,它用于存储和显示地理数据。
let source = new VectorSource()
source.addFeature(feature)
// 创建图层并设置源(Layer)
// VectorLayer表示一个矢量图层,它由一系列矢量要素(Feature)组成,用于在地图上显示地理数据。
let layer = new VectorLayer()
layer.setSource(source)
map.addLayer(layer)
}
(6)openlayers添加文字标注
/**
* Date:2024/3/26
* Author:zx
* Function:【文字标注】
* @param 无
*/
const addTextAnnotation = (text:any, coordinates:any) => {
// 创建一个点特征(Feature)作为文本标注的位置
let pointFeature = new Feature({
geometry: new Point(coordinates) // 设置点的坐标
});
// 创建一个带有文本的样式(Style)
let textStyle = new Style({
text: new Text({
text: text, // 文本内容
font: '28px Arial, sans-serif', // 字体样式
fill: new Fill({ color: 'red' }), // 文本填充颜色
stroke: new Stroke({ color: 'white', width: 5 }), // 文本边框样式
offsetX: 0, // 文本水平偏移量
offsetY: -10, // 文本垂直偏移量
textAlign: 'center' // 文本水平对齐方式
})
});
pointFeature.setStyle(textStyle);
// 创建一个特征源(Source)并添加点特征
let source = new VectorSource();
source.addFeature(pointFeature);
// 创建一个矢量图层(Layer)并设置特征源
let layer = new VectorLayer({
source: source
});
// 将图层添加到地图上
map.addLayer(layer);
};
注:在需要的地方引用
addTextAnnotation('你好呀', fromLonLat([108.924652, 34.208527]));
(7)openlayers添加popup
注:引入Text
import { Circle as CircleStyle, Style, Text,Stroke, Fill, Icon } from "ol/style" // OpenLayers的样式类,用于定义图层的样式,包括圆形样式、基本样式、边框、填充和图标
/**
* Date:2024/3/26
* Author:zx
* Function:【添加popup】
* @param 无
*/
const createPopup = () => {
// 创建一个弹出窗口容器元素
const popupContainer = document.createElement('div');
popupContainer.setAttribute('id', 'popup');
popupContainer.innerHTML = '<p>Your Popup Content Here</p>';
popupContainer.style.height = '50px';
popupContainer.style.backgroundColor = 'rgba(255, 255, 255, 0.8)'; // 设置背景颜色,这里使用了半透明白色
popupContainer.style.textAlign = 'center';
popupContainer.style.padding = '10px';
popupContainer.style.border = '1px solid #ccc';
popupContainer.style.color = 'red';
// 创建一个 Overlay 实例,将弹出窗口容器元素添加到 Overlay 中
const popupOverlay = new Overlay({
element: popupContainer,
autoPan: {
animation: {
duration: 250 // 设置自动平移动画的持续时间,单位为毫秒
}
}
});
// 将 Overlay 添加到地图上
map.addOverlay(popupOverlay);
// 设置弹出窗口的位置(示例位置)
const popupPosition = fromLonLat([108.924652, 34.208527]); // 替换 longitude 和 latitude 为实际的经纬度值
popupOverlay.setPosition(popupPosition);
// 显示弹出窗口
popupContainer.style.display = 'block';
}
(8)openlayers添加热力图
注:引入热力图库
import HeatmapLayer from 'ol/layer/Heatmap';
/**
* Date:2024/3/26
* Author:zx
* Function:【热力图】
* @param 无
*/
const heatMap = ()=>{
// 添加随机点数据
const heatmapData = [];
for (let i = 0; i < 100; i++) {
const randomLon = 108.924652 + (Math.random() - 0.5) * 0.2; // 在中心经度附近随机生成经度
const randomLat = 34.208527 + (Math.random() - 0.5) * 0.2; // 在中心纬度附近随机生成纬度
heatmapData.push(fromLonLat([randomLon, randomLat]));
}
// 创建一个矢量数据源,并添加随机点数据
const vectorSource = new VectorSource({
features: heatmapData.map(coord => new Feature(new Point(coord)))
});
// 创建一个热力图层
const heatmapLayer = new HeatmapLayer({
source: vectorSource,
blur: 15, // 设置模糊半径
radius: 20 // 设置热力点半径
});
// 将热力图层添加到地图中
map.addLayer(heatmapLayer);
}
(9)openlayers添加聚合点
创建聚合点(Cluster)的逻辑通常用于在地图上显示大量的点数据,当点过于密集时,它们会被聚合到一个表示多个点的单个聚合点中。在OpenLayers等地图库中,你可以使用特定的聚合图层来实现这一功能。
/**
* Date: 2024/3/27
* Author: zx
* Function: 【聚合点图层】
* @param 无
*/
const createClusterLayer = () => {
// 添加随机点数据
const clusterData = [];
for (let i = 0; i < 1000; i++) { // 假设有1000个随机点
const randomLon = 108.924652 + (Math.random() - 0.5) * 0.2; // 在中心经度附近随机生成经度
const randomLat = 34.208527 + (Math.random() - 0.5) * 0.2; // 在中心纬度附近随机生成纬度
clusterData.push(fromLonLat([randomLon, randomLat]));
}
// 创建一个矢量数据源,并添加随机点数据
const vectorSource = new VectorSource({
features: clusterData.map(coord => new Feature(new Point(coord)))
});
// 创建一个聚合图层
const clusterLayer = new VectorLayer({
source: new Cluster({
distance: 40, // 设置聚合的距离阈值
source: vectorSource
}),
style: function(feature) {
// 根据聚合点的数量设置不同的样式
const size = feature.get('features').length;
return new Style({
image: new CircleStyle({
radius: 10 + size / 10, // 半径根据聚合点数量进行调整
stroke: new Stroke({ color: 'white', width: 2 }),
fill: new Fill({ color: getColor(size) }) // 通过数量获取颜色
}),
text: new Text({
text: size.toString(),
fill: new Fill({ color: '#fff' }),
stroke: new Stroke({ color: '#000', width: 3 })
})
});
}
});
// 辅助函数:根据聚合点的数量获取不同的颜色
function getColor(size: number) {
let color = 'blue';
if (size > 100) color = 'red';
else if (size > 50) color = 'orange';
else if (size > 20) color = 'yellow';
return color;
}
// 将聚合图层添加到地图中
map.addLayer(clusterLayer);
};
4.地图打印
(1)引入
先引入一个打印模块,一个样式文件
import OlExtPrintDialog from 'ol-ext/control/PrintDialog'; //地图打印
import 'ol-ext/dist/ol-ext.min.css'; //样式文件
(2)配置
配置打印控件
let printControl = new OlExtPrintDialog({
lang: "zh", // 设置语言为中文
pdf: true, // 允许生成PDF文件
openWindow: false, // 不在新的浏览器窗口中打开打印对话框,而是在当前页面的某个元素中打开
title: '打印地图' // 打印对话框的标题
});
(3)添加
添加到 OpenLayers 地图实例中
//new Map完成之后
map.addControl(printControl);
(4)打印
点击地图左上角打印按钮,实现地图打印功能
注:打印预览的一切样式都建立在地图中
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支: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> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献3条内容
所有评论(0)