首页 > 其他分享 >64.在Vue3中使用OpenLayers显示带箭头的线段,箭头居中

64.在Vue3中使用OpenLayers显示带箭头的线段,箭头居中

时间:2025-01-14 20:58:44浏览次数:3  
标签:ol const 线段 Vue3 箭头 OpenLayers new import

在 WebGIS 开发中,使用 OpenLayers 渲染地图和矢量图形是常见的需求。今天我们来实现一个效果:在 Vue 3 项目中,使用 OpenLayers 显示带箭头的线段,并让箭头居中。

项目环境和技术栈

  1. Vue 3 + Composition API
  2. OpenLayers
  3. Vite 构建工具

实现效果

我们将绘制一条由多个坐标点构成的线段,在每个线段的中点处显示一个箭头,指向线段的方向。

效果示例如下:


代码实现

1. 项目初始化

首先,使用 Vite 创建一个 Vue 3 项目:

npm create vite@latest vue-openlayers-demo --template 
vue cd vue-openlayers-demo npm install

安装 OpenLayers:

npm install ol

2. 编写代码

创建一个 MapWithArrow.vue 文件,编写以下内容:

<!--
 * @Author: 彭麒
 * @Date: 2025/1/14
 * @Email: 1062470959@qq.com
 * @Description: 此源码版权归吉檀迦俐所有,可供学习和借鉴或商用。
 -->
<template>
  <div class="container">
    <div class="w-full flex justify-center">
      <div class="font-bold text-[24px]">在Vue3中使用OpenLayers显示带箭头的线段,箭头居中</div></div>
    <div id="vue-openlayers" ref="mapRef" class="map-x"></div>
  </div>
</template>

<script setup>
import 'ol/ol.css';
import {ref, onMounted} from 'vue';
import {Map, View} from 'ol';
import Tile from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import {Style, Stroke, Icon} from 'ol/style';
import Feature from 'ol/Feature';
import {Point, LineString} from 'ol/geom';
import arrow from '@/assets/OpenLayers/arrow.png';

const map = ref(null);
const mapRef = ref(null);
const source = new VectorSource({wrapX: false});
const markersData = [
  [112.44837595417002, 23.186590101623924, 1604627953],
  [112.26981796722073, 22.48475773547695, 1604714353],
  [113.96115972956521, 22.25412016222777, 1604800753],
  [113.44837595417002, 23.186590101623924, 1604887153],
];
let fea = null;

const addLine = () => {
  const lineStringFeature = new Feature(new LineString(markersData));
  lineStringFeature.setStyle(
    new Style({
      stroke: new Stroke({
        color: '#00f',
        width: 2,
      }),
    })
  );

  fea = lineStringFeature;
  source.addFeature(lineStringFeature);
};

const arrowStyle = () => {
  const geometry = fea.getGeometry();
  const styles = [];
  geometry.forEachSegment((start, end) => {
    const dx = end[0] - start[0];
    const dy = end[1] - start[1];
    const rotation = Math.atan2(dy, dx);
    const kx = (end[0] + start[0]) / 2;
    const ky = (end[1] + start[1]) / 2;

    styles.push(
      new Style({
        geometry: new Point([kx, ky]),
        image: new Icon({
          src: arrow,
          anchor: [0.75, 0.5],
          rotateWithView: true,
          rotation: -rotation,
        }),
      })
    );
  });
  return styles;
};

const addPoint = () => {
  const features = markersData.map((data) => {
    const feature = new Feature({
      geometry: new Point([data[0], data[1]]),
    });
    feature.setStyle(arrowStyle());
    return feature;
  });
  source.addFeatures(features);
};

const initMap = () => {
  const raster = new Tile({
    source: new OSM(),
  });

  const vector = new VectorLayer({
    source: source,
  });

  map.value = new Map({
    target: mapRef.value,
    layers: [raster, vector],
    view: new View({
      projection: 'EPSG:4326',
      center: [113.243045, 22.16871],
      zoom: 7,
    }),
  });

  addLine();
  addPoint();
};

onMounted(() => {
  initMap();
});
</script>

<style scoped>
.container {
  width: 840px;
  height: 520px;
  margin: 0 auto;
  border: 1px solid #42B983;
}

#vue-openlayers {
  width: 800px;
  height: 400px;
  margin: 0 auto;
  border: 1px solid #42B983;
}
</style>

代码说明

  1. 地图初始化
    使用 OSM 作为地图底图,通过 VectorLayer 添加线段和箭头。

  2. 线段绘制
    通过 LineString 创建矢量线段,并设置样式。

  3. 箭头计算
    遍历每段线段的起点和终点,计算中点和角度,动态生成箭头样式。

  4. 动态样式
    箭头样式通过 Icon 图标实现,并通过 rotation 参数设置旋转角度。


总结

本文展示了如何在 Vue 3 中使用 OpenLayers 显示带箭头的线段,并详细介绍了实现细节。这种实现方法可以应用于各种地图展示需求,如路径规划、物流轨迹等场景。

如有问题,欢迎在评论区留言讨论!

标签:ol,const,线段,Vue3,箭头,OpenLayers,new,import
From: https://blog.csdn.net/Miller777_/article/details/145147427

相关文章

  • 源码分析之Openlayers中CanvasLineStringBuilder类
    访问Openlayers网站(https://jinuss.github.io/Openlayers_map_pages/,网站是基于Vue3+Openlayers,里面有大量的实践和案例。觉得还不错,可以给个小星星Star,鼓励一波https://github.com/Jinuss/OpenlayersMap哦~概述在Openlayers中,CanvasLineStringBuilder类用于构建......
  • qiankun微前端——接入子应用Vue3+vite实现
    qiankun:乾坤微前端框架什么是微前端Techniques,strategiesandrecipesforbuildingamodernwebappwithmultipleteamsthatcanshipfeaturesindependently.–MicroFrontends微前端是一种多个团队通过独立发布功能的方式来共同构建现代化web应用的技术......
  • vue3 + arcgis.js4.x---FeatureLayer(实现文本+图标)
    之前做arcgis.js开发的时候一直使用的是TextSymbol+SimpleMarkerSymbol实现的也就是一条数据打两个点(一个坐标点一个文本点)这种操作实在非常鸡肋;学会了FeatureLayer之后发现实现该功能非常简单constLayerView=newFeatureLayer({source:[newGraphic({......
  • vue3从入门到入坑-第1坑
    这是我2025年入门学习Vue的新年第一个坑啊。先看问题:<template><el-table:data="footerLinks"stripestyle="width:100%"><el-table-columnprop="linkName"label="链接名称"width="180"/><el-table-colu......
  • Vue2+OpenLayers调用WMTS服务初始化天地图示例
    目录一、案例截图二、安装OpenLayers库三、WMTS服务详解四、完整代码五、Gitee源码一、案例截图二、安装OpenLayers库npminstallol三、WMTS服务详解WMTS(WebMapTileService)是一种标准的网络地图服务协议,用于提供基于瓦片的地图数据。它允许客户端请求地图的具......
  • vue3 + arcgis.js4.x---导航箭头轨迹线
    onMounted(()=>{window.customMap=mapInit.initMap()constgraphicsLayer=newGraphicsLayer()//创建一个图层对象constpolyline=newPolyline({paths:[[117.227239,31.820586],[117.227239,33.820586],[119.227239,31......
  • vue3 + arcgis.js4.x---卷帘模式
    这里使用天地图的矢量图和影像图作为卷帘对比(tk自行申请)//初始化地图map:newMap({basemap:newBasemap({baseLayers:[newWebTileLayer('http://{subDomain}.tianditu.com/DataServer?T=vec_w&X={col}&Y={row}&L={level}&tk=',{......
  • 用Tauri2.0把Vite+Vue3项目打包成exe桌面程序
    前言最近有个需求是做一两个设备的配置页面,但需要在断网的笔记本上直接运行(笔记本用网线直连设备)。避免测试同事配置开发环境麻烦,想到了把这些前端配置页面打包成一个exe的安装包。到时候测试同事只需要双击运行安装,打开后就可以直接运行,比较方便。有这个打包需求后,首先想到的......
  • uniapp(vue3) -实现横向滚动选择日期组件,手势左右滑动选择日期,类似电影选票日期Tabs选
    效果图在uni-app手机h5网页网站/支付宝微信小程序/安卓app/苹果app/nvue等(全平台兼容)开发中,实现uniapp日历横向日期选择器可滑动可点击,自定义横向滑动选择日期周几,获取日历并列出当前月前几个月的日期,用户手势横向滑动日历选择器插件,支持自定义任意样式、自定义展示的日......
  • Vue3 改变
    1、全局apiVue.config.xxxapp.config.xxxVue.componentapp.componentVue.directiveapp.directiveVue.mixinapp.mixinVue.useapp.useVue.prototypeapp.config.globalProperties2、过度类名.v-enter-from,.v-leave-to{opacity:0;}.v-leave-f......