tilestrata-blend插件可以将多个栅格瓦片图层合并成一个 png 图层,并且支持透明度、混合模式、图层过滤等选项。使用这个插件必须安装依赖node-mapnik。这个插件依然是一个利用 mapnik 强大的功能的Provider
类型的插件,甚至可以基于 mapnik 增强它已有的功能。
demo 项目可以参考tilestrata-sample-code
1. 安装
$ npm install tilestrata-blend --save
|
2. 使用
const tilestrata = require('tilestrata') const mapnik = require('tilestrata-mapnik') const blend = require('tilestrata-blend') const server = tilestrata()
server .layer('world_merc') .route('tile.png') .use(disk.cache({ dir: 'tilecache' })) .use( mapnik({ pathname: 'style/world.xml' }) )
server .layer('province') .route('tile.png') .use( mapnik({ pathname: 'style/province.xml' }) )
server .layer('blend_layer') .route('combined.png') .use( blend( [ ['world_merc', 'tile.png'], [ 'province', 'tile.png', { opacity: 0.5, comp_op: 'multiply', image_filters: 'agg-stack-blur(10,10)' } ] ], { matte: 'ffffff' } ) )
server.listen(9527)
|
3. 效果
demo 项目可以参考tilestrata-sample-code
可以在同一张瓦片上看到黄色的中国省界图层和世界边界图层,下图是没有配置仍和options
:
下图是像上面演示的那样,给省界图层加入了一些options
,例如 image_filters 和 opacity:
4. 代码浅析
这个插件在背后依赖了tilestrata-dependency,所以配置里面的['world_merc', 'tile.png']
实际上是通过执行了.use(dependency('world_merc_png', 'tile.png'))
操作来获取数据源:
var layers = layers.map(function(pair) { var layer = pair[0] var filename = pair[1] var comp_options = pair[2] || {} return [dependency(layer, filename), comp_options] })
|
当请求某个瓦片时候,对每个layers
依次执行fetchTile
获取对应图片和prepareImage
预处理图片
async.series( [ function fetchTile(callback) { callback(err) }, function prepareImage(callback) { generateMatte(noop) } ], function(err) { callback(err, image ? [image, options] : null) } )
|
完成每个数据源的单独处理后就是合并操作了,利用 mapnik 的omposite方法来依次合并创建的每个mapnik.Image
对象,最后再利用demultiply解构为 buffer 返回给 tilestrata 就好了。
async.eachSeries(images, function(res, callback) { intermediate.composite(image, res[1], callback); }, function(err) { intermediate.demultiply(function(err) { callback(null, buffer, {'Content-Type': 'image/png'}); }); }); });
|