# vue+openlayers离线地图 **Repository Path**: jacky11/vue-openlayers-offline-map ## Basic Information - **Project Name**: vue+openlayers离线地图 - **Description**: 以vue2为例 通过openlayers实现离线卫星地图 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2024-02-04 - **Last Updated**: 2024-02-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vue+openlayers离线卫星地图 1.首先通过MapTileDownloader下载离线瓦片地图(高德); 链接: https://pan.baidu.com/s/1IpUrLrd2hDk1W89LxHvDNg 提取码: 3395 下载完成后进入下载资源文件夹(MapDownload),发现下载的资源都在mapabc文件夹中 在该文件夹通过npm 下载 http-server,对该文件夹的图片资源搭一个服务 npm i http-server 再通过powershell(或其他终端) 运行http-server(直接输入命令http-server) 终端上会显示该服务在内网中的地址 2.以vue2项目为例,通过脚手架快速搭建一个vue2项目,并安装openlayers npm i openlayers 3.创建地图容器 ``` ``` 4.引入ol ```javascript import 'ol/ol.css' import { Tile as TileLayer } from 'ol/layer' import XYZ from 'ol/source/XYZ' import VectorLayer from "ol/layer/Vector"; import VectorSource from "ol/source/Vector"; import { Map, View, Feature } from "ol"; import { Style, Icon } from "ol/style"; import { Point } from "ol/geom"; import Overlay from "ol/Overlay"; ``` 5.进行map配置和覆盖物配置 ```javascript export default { name: 'HomeView', components: {}, data() { return { mapObj: null, mapDom: null, pointLayer: {}, markerList: [ [100.84, 36.85], [100.88, 36.67] ], } }, mounted() { this.initMap(); // this.clickMap(); this.markerList.forEach((v, index) => { this.addPoints(v, index); }) // 73.20139986752463, 55.71183382086091 // 140.59154463897022,16.722475512185397 // this.clickOverLay(); }, methods: { markerClick(e) { console.log(1); console.log(e); }, // 清除地图;某些情况下地图容器会存在两个,导致地图无法正常显示。 // 找了半天官方貌似也没有提供对应的api,自己动手了。 mapClear() { if (this.mapDom) { this.mapDom.innerHTML = '' this.mapDom = null } }, // 初始化地图 initMap() { // 先尝试清除 // this.mapClear() // 获取地图容器 this.mapDom = document.getElementById('map') // 初始化地图配置 this.mapObj = new Map({ target: this.mapDom, // 地图容器 view: new View({ center: [101.01791, 36.93013], // 地图中心点 zoom: 6, // 缩放 minZoom: 6, // 设置最小缩放级别 maxZoom: 11, // 设置最大缩放级别 // doubleClickZoom: false, //屏蔽双击放大事件 (失效) projection: 'EPSG:4326', // 坐标系 extent: [73.1339870718837, 16.722475512185397, 140.59154463897022, 55.75498452724199], // 73.1339870718837, 55.75498452724199 // 140.59154463897022,16.722475512185397 }), }) // 添加一个使用离线瓦片地图的层 const offlineMapLayer = new TileLayer({ source: new XYZ({ // url:'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}' url: 'http://192.168.0.122:8081' + '/{z}/{x}/{y}.jpg', // 设置本地离线瓦片所在路径,前面的地址是你输入http-server之后的服务地址 // tileLoadFunction: (imageTile, src)=> { // console.log(imageTile,src) // // 使用滤镜 将白色修改为深色 // let img = new Image() // // img.crossOrigin = '' // // 设置图片不从缓存取,从缓存取可能会出现跨域,导致加载失败 // img.setAttribute('crossOrigin', 'anonymous') // img.onload = ()=> { // let canvas = document.createElement('canvas') // let w = img.width // let h = img.height // canvas.width = w // canvas.height = h // let context = canvas.getContext('2d') // context.filter = 'grayscale(98%) invert(100%) sepia(20%) hue-rotate(180deg) saturate(1600%) brightness(80%) contrast(90%)' // context.drawImage(img, 0, 0, w, h, 0, 0, w, h) // imageTile.getImage().src = canvas.toDataURL('image/png') // }, // img.onerror = ()=>{ // imageTile.getImage().src = require('@/assets/logo.png') // } // img.src = src // }, }), }) this.mapObj.on('singleclick', event => { console.log(event.coordinate); let pixel = event.pixel //pixel:点击的像素点 //forEachFeatureAtPixel:map对象上的通过像素点获取标注点 let feature = this.mapObj.forEachFeatureAtPixel(pixel, feature => feature); if (feature) { console.log('当前为标记点,id为:' + feature.values_.id + ',坐标为:' + event.coordinate); console.log(feature); // console.log(event); //如果feature存在,表示点击的是标注点 //可以通过feature.get(属性值)来获取标注点自定义的一些属性,这些属性是在new Feature构造函数中设置的属性值 } else { //如果feature不存在,表示点击的是地图的空白部分 let coordinate = event.coordinate //通过event.coordiante属性获取点击的地方的经纬度 console.log('当前为空白处,坐标为:' + event.coordinate); } }) // 将图层添加到地图 this.mapObj.addLayer(offlineMapLayer) // 加载地理坐标 // this.addPoint() }, clickMap() { this.mapObj.on("click", (e) => { // this.addPoints(e.coordinate); console.log(e.coordinate); }) }, clickOverLay() { this.mapObj.on('click', function (event) { const feature = this.mapObj.forEachFeatureAtPixel(event.pixel, function (feature, layer) { return feature; }); if (feature) { // 在这里执行您的回调函数,例如弹出一个信息框 console.log('Feature clicked:', feature.get('name')); } }) }, /** * 根据经纬度坐标添加覆盖物 */ addPoints(coordinate, index) { if (Object.keys(this.pointLayer).length == 0) { // 创建图层 this.pointLayer = new VectorLayer({ source: new VectorSource(), }); // 图层添加到地图上 this.mapObj.addLayer(this.pointLayer); } // 创建feature要素,一个feature就是一个点坐标信息 const feature = new Feature({ geometry: new Point(coordinate), id: index, }); // 设置要素的图标 feature.setStyle( new Style({ // 设置图片效果 image: new Icon({ src: "http://192.168.0.122:8081/project.png", // anchor: [0.5, 0.5], scale: 0.2, }), }) ); // 要素添加到地图图层上 // this.pointLayer.getSource().addFeatures([feature]); this.pointLayer.getSource().addFeature(feature); // 设置文字信息 this.addText(coordinate); }, addText(coordinate) { const overlayBox = document.getElementById("map"); //获取一个div const oSpan = document.createElement("span"); //创建一个span oSpan.contentEditable = false; //设置文字是否可编辑 oSpan.id = coordinate[0]; //创建一个id let pText = document.createTextNode("项目" + `(${coordinate[0].toFixed(2)},${coordinate[1].toFixed(2)})`); //创建span的文本信息 oSpan.appendChild(pText); //将文本信息添加到span overlayBox.appendChild(oSpan); //将span添加到div中 let textInfo = new Overlay({ position: coordinate, //设置位置 element: document.getElementById(coordinate[0]), offset: [-70, 30], //设置偏移 }); this.mapObj.addOverlay(textInfo); }, }, beforeDestroy() { this.mapClear() }, } ```