[关闭]
@liruiyi962464 2025-01-01T22:17:11.000000Z 字数 4985 阅读 99

vue+openlayers离线卫星地图

前端


1.首先通过MapTileDownloader下载离线瓦片地图(高德);

链接: https://pan.baidu.com/s/1BBlcuR2wef7a_e9YOtHZ0w 提取码: 1030

下载完成后进入下载资源文件夹(MapDownload),发现下载的资源都在mapabc文件夹中

在该文件夹通过npm 下载 http-server,对该文件夹的图片资源搭一个服务

  1. npm i http-server
  2. 再通过powershell(或其他终端) 运行http-server(直接输入命令http-server)

终端上会显示该服务在内网中的地址

2.以vue2项目为例,通过脚手架快速搭建一个vue2项目,并安装openlayers

  1. npm i openlayers

3.创建地图容器

  1. <template>
  2. <div class="home">
  3. <div style="width: 100%; height: 100%">
  4. <div class="map" id="map"></div>
  5. </div>
  6. </div>
  7. </template>
  8. <style lang="scss">
  9. .home {
  10. height: 100vh;
  11. overflow: hidden;
  12. }
  13. .map {
  14. width: 100%;
  15. height: 100%;
  16. pointer-events: auto
  17. }
  18. </style>

4.引入ol

  1. import 'ol/ol.css'
  2. import { Tile as TileLayer } from 'ol/layer'
  3. import XYZ from 'ol/source/XYZ'
  4. import VectorLayer from "ol/layer/Vector";
  5. import VectorSource from "ol/source/Vector";
  6. import { Map, View, Feature } from "ol";
  7. import { Style, Icon } from "ol/style";
  8. import { Point } from "ol/geom";
  9. import Overlay from "ol/Overlay";

5.进行map配置和覆盖物配置

  1. export default {
  2. name: 'HomeView',
  3. components: {},
  4. data() {
  5. return {
  6. mapObj: null,
  7. mapDom: null,
  8. pointLayer: {},
  9. markerList: [
  10. [100.84, 36.85],
  11. [100.88, 36.67]
  12. ],
  13. }
  14. },
  15. mounted() {
  16. this.initMap();
  17. // this.clickMap();
  18. this.markerList.forEach((v, index) => {
  19. this.addPoints(v, index);
  20. })
  21. // 73.20139986752463, 55.71183382086091
  22. // 140.59154463897022,16.722475512185397
  23. // this.clickOverLay();
  24. },
  25. methods: {
  26. markerClick(e) {
  27. console.log(1);
  28. console.log(e);
  29. },
  30. // 清除地图;某些情况下地图容器会存在两个,导致地图无法正常显示。
  31. // 找了半天官方貌似也没有提供对应的api,自己动手了。
  32. mapClear() {
  33. if (this.mapDom) {
  34. this.mapDom.innerHTML = ''
  35. this.mapDom = null
  36. }
  37. },
  38. // 初始化地图
  39. initMap() {
  40. // 先尝试清除
  41. // this.mapClear()
  42. // 获取地图容器
  43. this.mapDom = document.getElementById('map')
  44. // 初始化地图配置
  45. this.mapObj = new Map({
  46. target: this.mapDom, // 地图容器
  47. view: new View({
  48. center: [101.01791, 36.93013], // 地图中心点
  49. zoom: 6, // 缩放
  50. minZoom: 6, // 设置最小缩放级别
  51. maxZoom: 11, // 设置最大缩放级别
  52. // doubleClickZoom: false, //屏蔽双击放大事件 (失效)
  53. projection: 'EPSG:4326', // 坐标系
  54. extent: [73.1339870718837, 16.722475512185397, 140.59154463897022, 55.75498452724199],
  55. // 73.1339870718837, 55.75498452724199
  56. // 140.59154463897022,16.722475512185397
  57. }),
  58. })
  59. // 添加一个使用离线瓦片地图的层
  60. const offlineMapLayer = new TileLayer({
  61. source: new XYZ({
  62. // url:'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
  63. url: 'http://192.168.0.122:8081' + '/{z}/{x}/{y}.jpg', // 设置本地离线瓦片所在路径,前面的地址是你输入http-server之后的服务地址
  64. // tileLoadFunction: (imageTile, src)=> {
  65. // console.log(imageTile,src)
  66. // // 使用滤镜 将白色修改为深色
  67. // let img = new Image()
  68. // // img.crossOrigin = ''
  69. // // 设置图片不从缓存取,从缓存取可能会出现跨域,导致加载失败
  70. // img.setAttribute('crossOrigin', 'anonymous')
  71. // img.onload = ()=> {
  72. // let canvas = document.createElement('canvas')
  73. // let w = img.width
  74. // let h = img.height
  75. // canvas.width = w
  76. // canvas.height = h
  77. // let context = canvas.getContext('2d')
  78. // context.filter = 'grayscale(98%) invert(100%) sepia(20%) hue-rotate(180deg) saturate(1600%) brightness(80%) contrast(90%)'
  79. // context.drawImage(img, 0, 0, w, h, 0, 0, w, h)
  80. // imageTile.getImage().src = canvas.toDataURL('image/png')
  81. // },
  82. // img.onerror = ()=>{
  83. // imageTile.getImage().src = require('@/assets/logo.png')
  84. // }
  85. // img.src = src
  86. // },
  87. }),
  88. })
  89. this.mapObj.on('singleclick', event => {
  90. console.log(event.coordinate);
  91. let pixel = event.pixel //pixel:点击的像素点
  92. //forEachFeatureAtPixel:map对象上的通过像素点获取标注点
  93. let feature = this.mapObj.forEachFeatureAtPixel(pixel, feature => feature);
  94. if (feature) {
  95. console.log('当前为标记点,id为:' + feature.values_.id + ',坐标为:' + event.coordinate);
  96. console.log(feature);
  97. // console.log(event);
  98. //如果feature存在,表示点击的是标注点
  99. //可以通过feature.get(属性值)来获取标注点自定义的一些属性,这些属性是在new Feature构造函数中设置的属性值
  100. } else {
  101. //如果feature不存在,表示点击的是地图的空白部分
  102. let coordinate = event.coordinate //通过event.coordiante属性获取点击的地方的经纬度
  103. console.log('当前为空白处,坐标为:' + event.coordinate);
  104. }
  105. })
  106. // 将图层添加到地图
  107. this.mapObj.addLayer(offlineMapLayer)
  108. // 加载地理坐标
  109. // this.addPoint()
  110. },
  111. clickMap() {
  112. this.mapObj.on("click", (e) => {
  113. // this.addPoints(e.coordinate);
  114. console.log(e.coordinate);
  115. })
  116. },
  117. clickOverLay() {
  118. this.mapObj.on('click', function (event) {
  119. const feature = this.mapObj.forEachFeatureAtPixel(event.pixel, function (feature, layer) {
  120. return feature;
  121. });
  122. if (feature) {
  123. // 在这里执行您的回调函数,例如弹出一个信息框
  124. console.log('Feature clicked:', feature.get('name'));
  125. }
  126. })
  127. },
  128. /**
  129. * 根据经纬度坐标添加覆盖物
  130. */
  131. addPoints(coordinate, index) {
  132. if (Object.keys(this.pointLayer).length == 0) {
  133. // 创建图层
  134. this.pointLayer = new VectorLayer({
  135. source: new VectorSource(),
  136. });
  137. // 图层添加到地图上
  138. this.mapObj.addLayer(this.pointLayer);
  139. }
  140. // 创建feature要素,一个feature就是一个点坐标信息
  141. const feature = new Feature({
  142. geometry: new Point(coordinate),
  143. id: index,
  144. });
  145. // 设置要素的图标
  146. feature.setStyle(
  147. new Style({
  148. // 设置图片效果
  149. image: new Icon({
  150. src: "http://192.168.0.122:8081/project.png",
  151. // anchor: [0.5, 0.5],
  152. scale: 0.2,
  153. }),
  154. })
  155. );
  156. // 要素添加到地图图层上
  157. // this.pointLayer.getSource().addFeatures([feature]);
  158. this.pointLayer.getSource().addFeature(feature);
  159. // 设置文字信息
  160. this.addText(coordinate);
  161. },
  162. addText(coordinate) {
  163. const overlayBox = document.getElementById("map"); //获取一个div
  164. const oSpan = document.createElement("span"); //创建一个span
  165. oSpan.contentEditable = false; //设置文字是否可编辑
  166. oSpan.id = coordinate[0]; //创建一个id
  167. let pText = document.createTextNode("项目" + `(${coordinate[0].toFixed(2)},${coordinate[1].toFixed(2)})`); //创建span的文本信息
  168. oSpan.appendChild(pText); //将文本信息添加到span
  169. overlayBox.appendChild(oSpan); //将span添加到div中
  170. let textInfo = new Overlay({
  171. position: coordinate, //设置位置
  172. element: document.getElementById(coordinate[0]),
  173. offset: [-70, 30], //设置偏移
  174. });
  175. this.mapObj.addOverlay(textInfo);
  176. },
  177. },
  178. beforeDestroy() {
  179. this.mapClear()
  180. },
  181. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注