很多时候,我们不能将我们的数据托管到mapbox的在线服务。我们希望使用mapbox studio定制完地图样式后,将样式文件导出,然后将数据服务改成geoserver发布的矢量瓦片服务。实现这个目标,需要解决:
1、图标等静态资源的本地化。
2、字体文件本地化。
2、数据服务的本地化。
一、使用geoserver发布矢量瓦片服务
上一篇文章已经介绍了如何使用geoserver发布矢量瓦片服务(数据源使用的是wgs84坐标),前端使用mapbox-gl来绘制矢量瓦片服务。在这次测试实验中,我发布了包括建筑、路网、湖泊水系,公交站点等七个图层,并将这七个图层放在一个图层组里面。
二、使用mapbox studio定制地图样式
使用mapbox studio制作自定义地图可以到看一下这篇文章,这里我不写详细制作过程来,可以看看官网给出的文档。如果,你不想将你的所有数据上传到mapbox地图定制的在线平台,事实上mapbox会对上传数据存储空间的大小是有限制,你可以上传测试数据来定制地图样式。
为了测试需要,我添加了公交站点和路网的标注图层、公交站点图标图层。mapbox-gl要在前端绘制标注,需要获取所需要的字体文件;同样,在绘制图标的使用,也要从服务端获取静态的图标资源。
制作完成后如果你想发布在线的地图样式,可以点击右上角发布地图样式。拷贝样式地址至mapbox-gl示例中就可以了。
下载制作的样式文件可以点击【share】-->【下载】
icons中图标(svg格式)是我在制作地图时上传的。style.json是我们的地图样式配置文件。这里需要知道的是,Mapbox 样式文件定义的是地图所呈现的视觉外观,包括:需要绘制哪些数据、绘制的顺序、以及绘制数据时如何进行符号化。样式文档是以json对象中的属性字段进行组织的。
三、静态资源(图标)的本地化
先来看一下,mapbox-gl在线示例是如何加载静态的图标资源等。打开下载的样式文件style.json可以看到静态文件在线配置到地址。
mapbox通过使用精灵图来减少网络请求次数。sprite.png记录合并后图片资源,sprite.json是索引文件,通过索引文件可以访问具体一个图标的位置。
可以尝试将sprite设置为相对地址,如"./xxx/",我这里测试貌似不行,mapbox源码中好像用正则表达式验证如果设置相对路径会出错,这里把我们定制地图的sprite.png和sprie.json下载下来,放在本地。将样式配置文件中的sprite设置为服务器上绝对位置,就可以了。如下图配置。
sprite.json和sprite.png是从定制好的地图样式,在预览时直接下载下来的。也可以通过工具根据图标集合生城,这里我们有测试,可以看看这里。
四、字体文件的本地化处理
前端绘制示例瓦片时,如果绘制标注的话需要提供字体,英文字体文件相对较小,如果是中文字体的少则都十几兆。mapbox使用pbf格式分段的请求方式来请求字体文件。因此需要根据配置文件中使用到的字体来生成pbf格式字体文件。
Mapbox开源了一个工具node-fontnik,可以将ttf和otf格式字体转换成Mapbox GL渲染需要的字体。可以编写字体转换代码,将ttf和otf格式到字体转换为pbf格式。下图,转换结果。
var fontnik = require('fontnik');
var fs = require('fs');
var path = require('path');
var convert = function (fileName, outputDir) {
var font = fs.
readFileSync(path.resolve(__dirname + "/" + fileName));
output2pbf(font, 0, 255, outputDir);
}
function output2pbf(font, start, end, outputDir) {
if (start > 65535) {
console.log("done!");
return;
}
fontnik.range({
font: font,
start: start,
end: end
}, function (err, res) {
var outputFilePath = path.
resolve(__dirname + "/" + outputDir + start + "-" + end + ".pbf");
fs.writeFile(outputFilePath, res, function (err) {
if (err) {
console.error(err);
} else {
output2pbf(font, end + 1, end + 1 + 255, outputDir);
}
});
});
}
convert("./fonts/ARIALUNI.ttf", "./fonts/pbf/ARIALUNI/");
可以将转换后的字体文件夹拷贝到本地的工程目录中,然后修改glyphs的配置地址。占位符{fontstack}是字体类型,{range}是字体范围。下图,字体文件本地化配置。
这里面有个问题,mapbox studio在定制地图的时候,设置标注字体会给出一个fallback字体,当主要字体缺少字形时,文本将以后备字体当样式呈现。网络请求多个字体时,字体文件名用逗号隔开。但是当字体服务本地化时候,样式配置文件中text-font如果设置多个字体时,将无法根据地址找到字体文件。这里面猜测是否可以将字体合并,然后转换成pbf格式,但这样感觉不合理,没测试,知道当可以告知一下。我这里直接将后备字体注释掉了。
四、数据服务的本地化配置
可以看出上一篇文章。这里给出完整代码。style如果设置style.json的相对路径可能会出错,因为style的类型是一个对象。这里定义了一个style变量,存储我们的地图配置。完整代码看这里。
<!DOCTYPE html>