集团网站建设特色,宝塔面板做网站,阿里巴巴国际站运营培训,海外推广专员问题背景 我们自己一直使用的openlayergeoserver自己发布的地图#xff0c;使用的是矢量地图。但是由于政府地图大都使用为天地图#xff0c;所以需要将geoserver的矢量地图更改为天地图#xff0c;并且依旧是搭配openlayers来使用。 解决步骤 一#xff1a;加载离线地图geoserver自己发布的地图使用的是矢量地图。但是由于政府地图大都使用为天地图所以需要将geoserver的矢量地图更改为天地图并且依旧是搭配openlayers来使用。 解决步骤 一加载离线地图参考了https://juejin.cn/post/7017301189406490655的文章 ● 获取离线地图瓦片 ● openlayers加载离线地图瓦片 ● 显示地理坐标 ● 显示地理坐标范围。 二颜色切换效果(参考https://www.cnblogs.com/m7777/p/16280817.html这篇文章) ● openlayers瓦片预处理 ● 出现的各种问题修复 这里的解决方案我也是查了很多的博客和技术文章看的但是其中的出现的问题真的很多很多啊。所以自己写一篇记录一下。
一加载离线地图
a.下载离线地图瓦片 首先需要做的是下载瓦片。 ● 下载离线地图瓦片网上有很多方法、大部分收费 找个合适的工具真的难找到一个能用的免费贡献出来了全能地图下载器 ● 链接https://pan.baidu.com/s/18LiUAh1-5CsVxzhX77ZReg 提取码yd88 ● 1.下载完成后打开这个
2.选择需要下载的离线地图的瓦片注意啊这里的地图只能选高德地图的瓦片其他地图的瓦片要么没有要么就对不上号会导致加载图片失败。很坑一开始我以为是我代码的问题结果并不是。这里我是先尝试所以先下一个高德地图的瓦片试试后面再用其他工具下天地图的瓦片把瓦片换成天地图的瓦片一样的
错误大概是这样子的不要怀疑自己那是因为下载的瓦片不对或者下载的瓦片不全导致的。如果是完全没出来那就是下载器的问题如果是部分没出来那就是没下全瓦片。
b.发布离线数据
● 地图离线瓦片肯定是要放在服务器上的放在项目里有点过于庞大了。 ● 本地测试的话本地起一个服务用来访问地图离线瓦片本文采用 http-server 猛击查看安装 一行命令。
步骤很简单就是1.找到你下载地图离线瓦片的目录然后npm i http-server。 2.然后再在那个目录上运行 http-server这样子你的静态瓦片就能被别人访问到了模拟了放在服务器上访问的效果。
c.openlayers 加载离线地图 本文以 vue2 项目为例 1.安装ol ● npm install ol 2.加载离线的瓦片 这里的注意点就是 a.盒子必须要有宽高 b.url请换成你起http-server的服务地址 c.地图坐标中心点必须换成你下载城市的那个坐标范围。
templatediv classhomediv stylewidth: 100%; height: 100%div classmap idmap/div/div/div
/templatescript
import ol/ol.css
import Map from ol/Map
import { Tile as TileLayer } from ol/layer
import View from ol/View
import XYZ from ol/source/XYZexport default {name: HomeView,components: {},data () {return {mapObj: null,mapDom: null,mapPointList: [],pointLayerSource: null,pointLayer: null,}},mounted () {this.initMap()},methods: {// 清除地图 某些情况 地图容器会存在两个 导致地图无法正常显示 这个问题折腾了我半天。// 找了半天官方貌似也没有提供 对应的 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: [112.475243, 23.077845], // 地图中心点zoom: 13, // 缩放projection: EPSG:4326, // 坐标系}),})// 添加一个使用离线瓦片地图的层const offlineMapLayer new TileLayer({source: new XYZ({url: http://169.254.231.19:8081 /{z}/{x}/{y}.png, // 设置本地离线瓦片所在路径,前面的地址是你输入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.addLayer(offlineMapLayer)// 加载地理坐标// this.addPoint()},},beforeDestroy () {this.mapClear()},
}
/script
style langless
.map {width: 1900px;height: 1000px;// background-color: red;
}
/style如果你进行到了这一步恭喜你你成功的利用openlayers加载了离线地图在你运行项目之后你应该能看到属于你的地图了
二颜色切换效果
思路参考https://blog.csdn.net/qq_32077521/article/details/123224974这边文章写的挺好的大概讲了怎么样去更改自己地图的主题的几种办法。我之前用的是第二种使用filter来直接变色。结果导致了只要是地图上的东西都会经过染色变成其他颜色很不好然后左思冥想想到能不能只让该地图图层加上filter来变色其他图层都不会有filter的变色效果找了很久找到了下面这个 实现参考https://www.cnblogs.com/m7777/p/16280817.html
a.openlayers瓦片预处理
利用openlayers中的tileLoadFunction 的函数回调进行变色结合css的filter属性来进行变色。 大概就是这一段
tileLoadFunction函数解释这个api大概就是让你在加载瓦片时进行操作。 css的filter属性解释大概就是改变你图片的色相饱和度黑白通透性等等来实现图片变色的效果。缺点不能让地图指定哪个颜色只能调个大概的好看的颜色。 下面我放完整的代码大家复制这个就行。因为上面参考的代码还有坑点
templatediv classhomediv stylewidth: 100%; height: 100%div classmap idmap/div/div/div
/templatescript
import ol/ol.css
import Map from ol/Map
import { Tile as TileLayer } from ol/layer
import View from ol/View
import XYZ from ol/source/XYZexport default {name: HomeView,components: {},data () {return {mapObj: null,mapDom: null,mapPointList: [],pointLayerSource: null,pointLayer: null,}},mounted () {this.initMap()},methods: {// 清除地图 某些情况 地图容器会存在两个 导致地图无法正常显示 这个问题折腾了我半天。// 找了半天官方貌似也没有提供 对应的 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: [112.475243, 23.077845], // 地图中心点zoom: 13, // 缩放projection: EPSG:4326, // 坐标系}),})// 添加一个使用离线瓦片地图的层const offlineMapLayer new TileLayer({source: new XYZ({url: http://169.254.231.19:8081 /{z}/{x}/{y}.png, // 设置本地离线瓦片所在路径,前面的地址是你输入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.widthlet h img.heightcanvas.width wcanvas.height hlet 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.addLayer(offlineMapLayer)// 加载地理坐标// this.addPoint()},},beforeDestroy () {this.mapClear()},
}
/script
style langless
.map {width: 1900px;height: 1000px;// background-color: red;
}
/styleb.出现的各种问题解决
1.如果你复制了上面的代码去运行。第一个发现的就是会跨域那么说明了我们的静态资源文件有跨域的限制虽然百度了说设置img.setAttribute(‘crossOrigin’, ‘anonymous’)这个有用但是经过实验其实没用。 所以第一步我们需要解决跨域的问题 如何解决将刚才启动的http-server命令换成http-server --cors学过node应该了解一点加上cors可以取消跨域再次运行你就会能运行上来了注意看这个cors已经加上了
2.到这里我本以为已经是大功告成但是远远没有这么简单。原因就是出bug了。由于我们添加了这个函数然后有些瓦片又不齐全导致了加载了404的瓦片再次缩放回来瓦片就没了这个我思考了很久才想到应该是这个问题导致的大概的效果就是如下图
解决办法添加图片的onerror事件把imageTile.getImage().src require(‘/assets/logo.png’)设置为一个图片出错时的替换图片就ok了。对于404的图片大家也可以这样子设置设置成需要替换的图片就行
总结 filteropenlayers的tileLoadFunction实现地图的变色但是只能配出大概的整体好看的颜色。不能一一自定义某个图层的颜色比如设置树的颜色设置海滩的颜色。这些是需要自己发布地图服务来弄的。但是对于目前的离线地图需求的来说实现业务需求已经可以了。毕竟我们自己搭的地图服务用的是Open Street Map ,可是业务觉得天地图是必须的深色也是必须的有利有弊可以抉择。 另外https://blog.csdn.net/qq_32077521/article/details/123224974这篇文章也说了怎么样自定义离线地图颜色的大家也可以参考下我觉得是挺不错的开阔自己的思路