Vue3+OpenLayers的简单使用详解

 更新时间:2025年12月04日 08:49:35   作者:竭点  
本文介绍了如何在Vue3项目中使用OpenLayers实现地图展示功能,包括安装OpenLayers、创建地图组件、添加图层、修改地图样式以及实现地图点击等功能,通过完整的代码示例,展示了如何在地图上添加标注和连线,OpenLayers提供了丰富的API和组件,可以满足各种地图展示需求

在前端开发中,地图展示是一个常见的需求。OpenLayers 是一个功能强大的开源地图库,可以帮助我们在 Web 应用程序中展示地图并且进行交互。

本文将介绍如何在 Vue 3 项目中使用 OpenLayers,让您能够轻松实现地图展示功能

步骤一:安装 OpenLayers

首先,我们需要在 Vue 3 项目中安装 OpenLayers:

npm install ol

步骤二:创建地图组件

在 Vue 3 项目中创建一个地图组件,例如Map.vue

在vue文件中创建两个图层,显示地图和地点

const tdtVectorLayer = new TileLayer({
        title: "天地图矢量图层",
        source: new XYZ({
          url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=天地图申请的key",
        })
      });
      const tdtVectorLabelLayer = new TileLayer({
        title: "天地图矢量注记图层",
        source: new XYZ({
          url: "http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=天地图申请的key",
        })
      });

然后将图层添加到openlayers提供map方法中

map = new Map({
        layers: [tdtVectorLayer,tdtVectorLabelLayer],
        target: mapCon.value,
        view: new View({
          center: beijing,
          minZoom: 4,
          zoom: 8,
        }),
      });

openlayers提供有修改地图样式的方法:

geoMarker.setStyle(styles.geoMarker)
      const iconFeature = new Feature({
        geometry: new Point(beijing),
      });
      iconFeature.setStyle(createLabelStyle(iconFeature));

完整的代码:

<template>
  <div ref="mapCon" id="mapCon"></div>
</template>

<script>
import "ol/ol.css";
import { ref, onMounted } from "vue";
import { Map, View } from "ol";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import { fromLonLat } from "ol/proj";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import Feature from "ol/Feature";
import {LineString,Point } from 'ol/geom';
import { Icon, Style,Stroke,Circle,Fill } from "ol/style";
import yzm from '@/assets/stationicon.png'

export default {
  setup() {
    const mapCon = ref(null);
    const speed = ref(null);
    const animating = ref(false);
    let routeCoords;
    let routeLength;

    const beijing = fromLonLat([116.28, 39.54]);
    let map;
    let clickedPoints = [fromLonLat([116.28, 39.54])];
    const styles = {
        geoMarker: new Style({
          image: new Circle({
            radius: 7,
            snapToPixel: false,
            fill: new Fill({ color: 'black' }),
            stroke: new Stroke({
              color: 'white',
              width: 2
            })
          })
        }),
      };
    const geoMarker = new Feature({
      type: 'geoMarker',
      geometry: new Point(beijing)
    });

    onMounted(() => {
      const tdtVectorLayer = new TileLayer({
        title: "天地图矢量图层",
        source: new XYZ({
          url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=天地图申请的key",
        })
      });
      const tdtVectorLabelLayer = new TileLayer({
        title: "天地图矢量注记图层",
        source: new XYZ({
          url: "http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=天地图申请的key",
        })
      });
      map = new Map({
        layers: [tdtVectorLayer,tdtVectorLabelLayer],
        target: mapCon.value,
        view: new View({
          center: beijing,
          minZoom: 4,
          zoom: 8,
        }),
      });

      const createLabelStyle = function (feature) {
        return new Style({
          image: new Icon({
            anchor: [0.5, 60],
            anchorOrigin: "top-right",
            anchorXUnits: "fraction",
            anchorYUnits: "pixels",
            offsetOrigin: "top-right",
            opacity: 0.75,
            src: yzm,
          }),
        });
      };
      geoMarker.setStyle(styles.geoMarker)
      const iconFeature = new Feature({
        geometry: new Point(beijing),
      });
      iconFeature.setStyle(createLabelStyle(iconFeature));

      const vectorSource = new VectorSource({
        features: [iconFeature,geoMarker],
      });

      const vectorLayer = new VectorLayer({
        source: vectorSource,
      });
      map.addLayer(vectorLayer);

      map.on("click", function (evt) {
        const point = evt.coordinate;
        addVectorLabel(point);
      });

      function addVectorLabel(coordinate) {
        const newFeature = new Feature({
          geometry: new Point(coordinate),
        });
        newFeature.setStyle(createLabelStyle(newFeature));
        vectorSource.addFeature(newFeature);
        clickedPoints.push(coordinate);
        const route = new LineString([clickedPoints[clickedPoints.length - 2], coordinate]);
        routeCoords = route.getCoordinates();
        routeLength = routeCoords.length;
        if (clickedPoints.length > 1) {
          // 创建折线特征,连接点击的点
          const lineStyle = new Style({
            stroke: new Stroke({
              width: 6,
              color: [237, 212, 0, 0.8]
            }),
          });
          const lineFeature = new Feature({
            geometry: route,
          });
          lineFeature.setStyle(lineStyle);
          vectorSource.addFeature(lineFeature);
        }
      }
    });
    
    


   

    return { mapCon,animating,startAnimation };
  },
};
</script>

<style>
  #menu{
    margin-bottom: 20px;
  }
 
  #mapCon {
    width: 70vw;
    height: 500px;
  }

  
</style>

本段代码主要实现在地图点击时,添加标注并给两点间连线

总结

通过以上步骤,我们成功地在 Vue 3 项目中使用 OpenLayers 来展示地图。

您也可以根据自己的需求来配置地图的样式和功能,OpenLayers 提供了丰富的 API 和组件来满足各种地图展示的需求。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue中的slot封装组件弹窗

    vue中的slot封装组件弹窗

    这篇文章主要介绍了vue中的slot封装组件弹窗,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • vue使用自定义指令实现拖拽

    vue使用自定义指令实现拖拽

    这篇文章主要为大家详细介绍了vue使用自定义指令实现拖拽,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • Vue如何处理Axios多次请求数据显示问题

    Vue如何处理Axios多次请求数据显示问题

    这篇文章主要介绍了Vue如何处理Axios多次请求数据显示问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • 在Vue3中使用EasyPlayer.js播放器的具体流程

    在Vue3中使用EasyPlayer.js播放器的具体流程

    EasyPlayer.js是一款强大的H5播放器,专为现代网页设计,提供对多种视频流协议的支持,这篇文章主要介绍了在Vue3中使用EasyPlayer.js播放器的具体流程,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-04-04
  • vue实现数字变换动画的示例代码

    vue实现数字变换动画的示例代码

    本文主要介绍了vue实现数字变换动画的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • vue.js框架实现表单排序和分页效果

    vue.js框架实现表单排序和分页效果

    这篇文章主要为大家详细介绍了vue.js框架实现表单排序和分页效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • 解决vue bus.$emit触发第一次$on监听不到问题

    解决vue bus.$emit触发第一次$on监听不到问题

    这篇文章主要介绍了解决vue bus.$emit触发第一次$on监听不到问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • Vue+element 解决浏览器自动填充记住的账号密码问题

    Vue+element 解决浏览器自动填充记住的账号密码问题

    我们在做form表单的时候,会发现,浏览器会自动的将我们之前保存的密码,自动的填充到表单中input 为 type="password" 的框中,如何实现此功能呢,下面小编给大家介绍下,感兴趣的朋友一起看看吧
    2019-06-06
  • vue 本地环境跨域请求proxyTable的方法

    vue 本地环境跨域请求proxyTable的方法

    今天小编就为大家分享一篇vue 本地环境跨域请求proxyTable的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • Vue+Element实现封装抽屉弹框

    Vue+Element实现封装抽屉弹框

    这篇文章主要为大家详细介绍了如何利用Vue和Element实现简单的抽屉弹框效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-06-06

最新评论