OpenLayers实操Vue3(点线面文字标注热力图聚合点地图打印等等...)

本文介绍了用于开发WebGIS客户端的JavaScript包OpenLayers。涵盖初始化地图,可选用不同地图服务;openlayers实战包括添加点、线、面、图片、文字标注等;还介绍了地图打印功能,通过引入模块、配置控件等步骤实现地图打印。
该文章已生成可运行项目,

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)打印

点击地图左上角打印按钮,实现地图打印功能

注:打印预览的一切样式都建立在地图中

本文章已经生成可运行项目
<think>嗯,用户想在Vue3中使用OpenLayers现绘制点、线、面的功能按钮,并且集成高德地图作为栅格地图源。首先,我需要回忆一下OpenLayers的基本用法,以及如何在Vue3中集成它。对了,OpenLayers是一个开源的JavaScript库,用于在网页上显示地图,支持多种地图源,包括高德地图。 用户提到要使用高德地图作为栅格层,我记得高德地图的Web墨卡托投影是EPSG:3857,所以需要确保OpenLayers的视设置正确。高德的瓦片服务URL需要按照他们的格式来写,比如https://webrd0{1-4}.is.autonavi.com/appmaptile?参数。还要注意版权信息,可能需要添加attribution。 接下来是绘制功能。OpenLayers有交互式绘制的模块,比如Draw交互。用户需要点、线、面三种绘制类型,所以可能需要三个按钮,分别触发不同的绘制模式。在Vue中,可以使用ref来引用地图容器,然后在onMounted钩子中初始化地图层。 然后,组件的结构部分,需要一个地图容器div,设置好样式,比如宽度和高度。在脚本部分,引入必要的OpenLayers模块,如Map, View, TileLayer,以及Draw和VectorSource等。地图初始化时,创建高德的瓦片层,添加到地图例中。同时,需要一个矢量层来存储用户绘制的形。 对于绘制功能,需要为每个按钮绑定点击事件,切换不同的绘制类型。比如,点击点按钮时,创建Draw交互,设置type为&#39;Point&#39;,添加到地图中。完成绘制后,可能需要监听addfeature事件,将形添加到矢量层。同时,每次开始新的绘制前,需要移除之前的绘制交互,避免冲突。 另外,用户可能希望示例代码尽可能完整,所以需要包括引入的模块、地图初始化、绘制功能的现,以及清除所有绘制的功能。可能还需要注意Vue3的组合式API,使用setup函数和ref等响应式引用。 还有,测试时可能需要申请高德地图的key,但用户示例中可能不需要,直接使用公开的URL。但需要注意高德地图的服务条款,确保合法使用。 最后,整理代码结构,确保在Vue组件中正确初始化和销毁地图,避免内存泄漏。比如,在onUnmounted钩子中销毁地图例。可能还需要处理地图的缩放控件和默认交互,比如禁用旋转等。 总结一下,步骤应该是:安装依赖、创建组件、初始化地图、添加高德层、现绘制交互、绑定按钮事件、处理绘制结果和清除功能。然后,验证代码是否能在Vue3项目中正确运行,绘制点线面并显示在高德地图上。</think>在Vue3中集成OpenLayers地图绘制功能的完整现步骤如下: ### 一、环境准备 1. 安装依赖 ```bash npm install ol vue3-openlayers ``` ### 二、组件现 ```vue <template> <div class="map-container"> <div ref="mapContainer" class="map"></div> <div class="controls"> <button @click="startDrawing(&#39;Point&#39;)">绘制点</button> <button @click="startDrawing(&#39;LineString&#39;)">绘制线</button> <button @click="startDrawing(&#39;Polygon&#39;)">绘制面</button> <button @click="clearAll">清除全部</button> </div> </div> </template> <script setup> import { ref, onMounted, onUnmounted } from &#39;vue&#39; import Map from &#39;ol/Map&#39; import View from &#39;ol/View&#39; import TileLayer from &#39;ol/layer/Tile&#39; import XYZ from &#39;ol/source/XYZ&#39; import VectorLayer from &#39;ol/layer/Vector&#39; import VectorSource from &#39;ol/source/Vector&#39; import Draw from &#39;ol/interaction/Draw&#39; import { Style, Fill, Stroke, Circle } from &#39;ol/style&#39; const mapContainer = ref(null) let map = null let drawInteraction = null // 初始化矢量层 const vectorSource = new VectorSource() const vectorLayer = new VectorLayer({ source: vectorSource, style: new Style({ fill: new Fill({ color: &#39;rgba(255, 0, 0, 0.2)&#39; }), stroke: new Stroke({ color: &#39;#ff0000&#39;, width: 2 }), image: new Circle({ radius: 7, fill: new Fill({ color: &#39;#ff0000&#39; }) }) }) }) // 初始化高德地图层 const gaodeLayer = new TileLayer({ source: new XYZ({ url: &#39;https://webrd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}&#39;, attributions: &#39;高德地图提供&#39; }) }) onMounted(() => { // 初始化地图 map = new Map({ target: mapContainer.value, layers: [gaodeLayer, vectorLayer], view: new View({ center: [12600000, 2650000], // 高德坐标系坐标 zoom: 10, projection: &#39;EPSG:3857&#39; }) }) }) // 绘制功能 const startDrawing = (type) => { // 移除已有绘制交互 if (drawInteraction) { map.removeInteraction(drawInteraction) } // 创建新绘制交互 drawInteraction = new Draw({ source: vectorSource, type: type }) map.addInteraction(drawInteraction) } // 清除所有要素 const clearAll = () => { vectorSource.clear() } onUnmounted(() => { if (map) map.dispose() }) </script> <style> .map-container { position: relative; width: 100%; height: 600px; } .map { width: 100%; height: 100%; } .controls { position: absolute; top: 10px; left: 50px; z-index: 1000; background: rgba(255,255,255,0.8); padding: 10px; border-radius: 4px; } button { margin: 0 5px; padding: 5px 10px; } </style> ``` ### 三、关键技术解析 1. **坐标系适配**:高德地图采用Web墨卡托投影(EPSG:3857),需在View中显式声明坐标系[^2] 2. **瓦片加载**:通过XYZ源加载高德地图服务,使用模板URL中的{z}/{x}/{y}参数现动态瓦片请求 3. **绘制交互**: - 使用`ol/interaction/Draw`创建绘制交互 - 根据类型参数切换点/线/面模式 - 矢量要素存储在`VectorSource`中并通过`VectorLayer`渲染 4. **样式控制**:通过OpenLayers样式对象统一管理要素样式,支持动态样式调整 ### 四、优化建议 1. **坐标转换**:如需展示WGS84坐标,需使用`ol/proj`进行坐标转换 2. **绘制限制**:可添加拓扑校验、长度/面积计算等扩展功能 3. **性能优化**:对大量要素建议使用WebGL渲染器
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值