对于使用mapbox_gl_js来进行的前端地图页面的开发,通常我们可以直接调用在线的mapbox组件资源,轻易的使用mapbox_gl_js提供的前端开发框架,但是由于网络延迟等一些列网络上的不确定因素,在进行正式的开发任务以及后期部署到生产环境的过程中会带来太多的不稳定因素,所以为了保证开发后的系统在生成环境中稳定的运行我们通常需要将mapbox_gl_js的在线资源本地化,接下里本文将一步步的介绍如何完成mapbox_gl_js的本地化:
我们会用到以下工具来完成资源的本地化:
Tomcat用于提供本地化的资源服务
Geoserver用于提供本地化的地图资源服务
JRE用于为Tomcat、Geoserver提供运行所需的基本环境
第一步:我们先将官网上面的的Helloworld代码抄过来:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Display a map</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.54.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.54.0/mapbox-gl.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiYW56aGlodW4iLCJhIjoiY2lsdnhjdjN5MDFvMHVia3NpYTlnbmUzaSJ9.twlExCjpR7uwH2IiFC7aDA';
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/satellite-v9', // stylesheet location
center: [121.50, 39], // starting position [lng, lat]
zoom: 9 // starting zoom
});
</script>
</body>
</html>
使用chrome浏览器进行调试,我们可以看到在网页上加载出来的卫星地图,我们继续研究这个例子代码,可以发现mapbox_gl用到的JS和CSS文件我们可以直接拉下来保存到本地即可,于是我们在调试的网页中按F12选择source栏目,在mapbox资源站点下载过来的文件中找到了JS和CSS文件,先保存到本地电脑上。我们继续观察这个Helloworld代码,可以看到现在完成了JS文件和CSS文件的本地化,但还有一个地方是需要调用在线资源的,这就是
style: 'mapbox://styles/mapbox/satellite-v9'
于是本地化的任务就转为了如何将style里面的资源进行本地化的任务,helloworld代码这里已经不能看到关于style里面更多的内容了,于是我们前往mapbox的官网,查阅相关资料,在Style Specification里面找到了,style除了这个url声明之外,还可以通过如下的方式进行定义:
{
"version": 8,
"name": "Mapbox Streets",
"sprite": "mapbox://sprites/mapbox/streets-v8",
"glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
"sources": {...},
"layers": [...]
}
根据官网上面的对应文档介绍,参数说明如下:
-
version:样式版本,当前必须必须设置8。
-
name:样式名称,设置一个可读的名称描述即可。
-
sprite:mapbox地图使用的图标。
-
glyphs:mapbox地图使用的标注字体。
-
sources:mapbox地图使用的地图服务资源定义。
-
layers:mapbox地图使用的图层定义。
于是我们仔细研究这种Style的定义方式,很容易得知,在Style资源本地化的道路上,我们需要分别将“sprite”和“glyphs”资源本地化,而对“source”和“layers”我们只需要定义另外的地图资源即可,对“source”和“layers”定义另外的地图资源的具体规则在官方文档由详细的说明,在这里我们直接进行定义不作赘述:
"sources": {
"osm-tiles": {
"type": "raster",
"tiles": [
"http://c.tile.openstreetmap.org/{z}/{x}/{y}.png"
],
"tileSize": 256
}
},
"layers":[{
"id": "001",
"type": "raster",
"source": "osm-tiles",
"source-layer": "osmtiles"
}]
根据官方说明文档,这里对sources参数与layers参数进行简要的介绍:
sources参数说明:
-
sources是地图资源对象,以key,value组成,sources里的key不能重复,唯一声明一个地图资源的组成。
-
value里的type是资源的类型,必须是 vector, raster, raster-dem, geojson, image, video中的一种。当前声明是xyz的png图片组成的底图,所以声明类型是raster。
-
value里的tiles是xyz底图的url模板组合,tileSize声明一个切片宽高,一般切片都是是256*256的,所以此处声明256 。
layers参数说明:
-
layers是个数组,数组每一项代表一个图层。
-
id是每个图层的主键,每个图层的id必须不能重复。
-
type,声明一个图层的类型。
-
source,图层的地图数据来源,指向sources里的某个key的资源定义,比如sources里定义了一个osm-tiles的资源,该图层数据来源指向这个资源,即将key的值输入此处。
-
source-layer:图层的名称,可以当做是图层别名,用以描述图层的。
在这里我们也可以使用Mapbox加载Geoserver上发布的WMS、WMTS、
TMS等标准的地图服务,详细的操作与设置方法请移步至GS系列进行查看。
至此我们完成了地图服务的本地化任务。接下里我们进行图标的本地化以及字体的本地化。
我们从上面的代码中可以看到图标是这样定义的:
"sprite": "mapbox://sprites/mapbox/streets-v8",
通过百度sprite我们可以得知sprite是一种用于减少大量小图片引起高频次网络访问的图片,称之为精灵图也叫雪碧图,同样我们打开刚刚的页面在Network栏下面可以找到精灵图的文件:sprite@2x.json和sprite@2x.png,直接拉到本地保存即可。接下来是字体的本地化:
我们找到对应的字体同样保存到本地即可。
现在我们把JS、CSS文件和精灵图以及字体都保存到本地了,而地图服务使用在线的别的地图服务或者自己通过Geoserver发布的地图服务代替了,接下来我们就需要将JS、CSS文件和精灵图以及字体放到本地的服务器中来对我们的前端页面提供相应的mapbox_gl开发的资源服务,在这里我们就要用到Tomcat来提供这个服务了,首先我们在Tomcat官方网站现在最新版本的Tomcat服务器软件,按照Tomcat的readme.md文件中的说明下载好对应版本的JRE文件,安装好Tomcat后到tomcat根目录的bin文件夹下面点击startup.bat批处理文件(win版本)开启tomcat,在这个过程中可能出现windows命令行一闪而过的状态,这时首先需要考虑在下载了JDK或者JRE后是否去windows的环境变量处正确配置了java的系统变量路径,
在环境变量没有问题后如何还是出现一闪而过的状态的话,可以右键startup.bat找一个文本编辑器打开,然后在文本的最后敲上pause,保存后重新运行startup.bat,这时候窗口会就留在桌面上了。这时点击shutdown.bat来关闭tomcat服务,接下来我们对Tomcat进行一些关于mapbox资源本地化所要用到的一些服务进行配置,首先我们进入到tomcat/conf/server.xml中,找到如下这行代码:
<connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
将其中的服务端口定义port="80"修改为 8088端口,以防止和电脑上别的服务撞端口而无法启动服务。
然后我们去到tomcat/conf/logging.properties中,找到如下这行代码:
java.util.logging.ConsoleHandler.encoding = UTF-8
将其中的编码方式由UTF-8改为GBK,此修改是解决刚刚启动tomcat的时候命令行窗口中的乱码问题。
然后就是最重要的一步,解决运行是由于资源在Tomcat服务器上端口号为8088与代码运行的服务器端口号不一致,所带来的跨域请求不通过的问题。为解决此问题,我们去到tomcat/conf/web.xml文件中跳到500多行的位置,大概在这个位置你会看见有<filter>这样的标签,在这个标签后面加入如下的代码:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
好了到此Tomcat就配置完成了,接下来我们将刚刚在各个地方去找到的JS文件、CSS文件、精灵图、字体库文件统一放到tomcat/webapps的文件夹下面:(可以在这里再建立文件夹有条理的管理mapbox资源)
保存好后,回到tomcat/bin文件夹中点击startup.bat使用管理员身份运行,即刻开启了本地化mapbox地图服务,相应的再刚刚的helloworld代码中我们将相关的资源地址改为我们的tomcat服务器地址:
JS的:
http://localhost:8088/mapbox_resource/JS/mapbox-gl.js
CSS的:
http://localhost:8088/mapbox_resource/CSS/mapbox-gl.css
精灵图的:
http://localhost:8088/mapbox_resource/sprite/sprite
字体的:
http://localhost:8088/mapbox_resource/fonts/{fontstack}/{range}.pbf
而对于地图服务来说我们改为在线的别的地图服务地址为:
"http://c.tile.openstreetmap.org/{z}/{x}/{y}.png"
最后分别添加到原有的helloworld代码中后,完成mapbox本地化后的完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'/>
<title>Display a map</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no'/>
<script src='http://localhost:8088/mapbox_resource/JS/mapbox-gl.js'></script>
<link href='http://localhost:8088/mapbox_resource/CSS/mapbox-gl.css' rel='stylesheet'/>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id='map'></div>
<script>
var map = new mapboxgl.Map({
container: 'map', // container id
style: {
"version": 8,
"name": "Mapbox Streets",
"sprite": "http://localhost:8088/mapbox_resource/sprite/sprite",
"glyphs": "http://localhost:8088/mapbox_resource/fonts/{fontstack}/{range}.pbf",
"sources": {
"osm-tiles": {
"type": "raster",
"tiles": [
"http://c.tile.openstreetmap.org/{z}/{x}/{y}.png"
],
"tileSize": 256
}
},
"layers":[{
"id": "001",
"type": "raster",
"source": "osm-tiles",
"source-layer": "osmtiles",
}],
center: [119.857062, 38.669979], // starting position [lng, lat]
zoom: 9// starting zoom
}
})
map.on('load', function () {
map.addLayer({
"id": "points",
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [119.857062, 38.669979]
},
"properties": {
"title": "Mapbox DC",
"icon": "monument"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [119.9, 39]
},
"properties": {
"title": "Mapbox SF",
"icon": "harbor"
}
}]
}
},
"layout": {
"icon-image": "{icon}-15",//--矢量数据中properties的icon注入
"text-field": "{title}",//--矢量数据的properties中tile注入
"text-font": ["MicrosoftYaHei"], //--字体,fontstack占位符就是对应这个声明。
"text-offset": [0, 0.6],
"text-anchor": "top"
}
});
});
</script>
</body>
</html>
最后启动Tomcat 启动Geosever调试运行以上前端代码即可看到本地化后的MAPBOX
另外如果在运行Tomcat时发现提示找不到CATALINA的路径那么请到系统变量的设置处设置用户变量 将CATALINA的路径设置到Tomcat的根目录处入下图所示