Skip to content

Commit

Permalink
feat: convert mbtiles to a styled map package file (#35)
Browse files Browse the repository at this point in the history
* feat: convert mbtiles to a styled map package file

* update package-lock

* address PR comments
  • Loading branch information
gmaclennan authored Nov 18, 2024
1 parent 51d5cc1 commit 18afee4
Show file tree
Hide file tree
Showing 8 changed files with 732 additions and 15 deletions.
21 changes: 21 additions & 0 deletions bin/smp-mbtiles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env node
import { Command } from 'commander'
import { pipeline } from 'stream/promises'

import fromMBTiles from '../lib/from-mbtiles.js'

const program = new Command()

program
.description('Convert a MBTiles file to a styled map package file')
.option('-o, --output <file>', 'output smp file')
.argument('<mbtiles>', 'MBTiles file to convert')
.action(async (mbtilesPath, { output }) => {
if (output) {
await fromMBTiles(mbtilesPath, output)
} else {
await pipeline(fromMBTiles(mbtilesPath), process.stdout)
}
})

program.parseAsync(process.argv)
1 change: 1 addition & 0 deletions bin/smp.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ program
.name('smp')
.command('download', 'Download a map style to a styled map package file')
.command('view', 'Preview a styled map package in a web browser')
.command('mbtiles', 'Convert a MBTiles file to a styled map package file')

program.parse(process.argv)
83 changes: 83 additions & 0 deletions lib/from-mbtiles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { MBTiles } from 'mbtiles-reader'
import SMPWriter from 'styled-map-package/writer'

import fs from 'node:fs'
import { Transform } from 'node:stream'
import { pipeline } from 'node:stream'
import { pipeline as pipelinePromise } from 'node:stream/promises'

const SOURCE_ID = 'mbtiles-source'

/**
* @overload
* @param {string} mbtilesPath
* @returns {import('stream').Readable}
*/

/**
* @overload
* @param {string} mbtilesPath
* @param {string} outputPath
* @returns {Promise<void>}
*/

/**
* @param {string} mbtilesPath
* @param {string} [outputPath]
* @returns {Promise<void> | import('stream').Readable}
*/
export default function fromMBTiles(mbtilesPath, outputPath) {
const reader = new MBTiles(mbtilesPath)
if (reader.metadata.format === 'pbf') {
throw new Error('Vector MBTiles are not yet supported')
}
const style = {
version: 8,
name: reader.metadata.name,
sources: {
[SOURCE_ID]: {
...reader.metadata,
type: 'raster',
},
},
layers: [
{
id: 'background',
type: 'background',
paint: {
'background-color': 'white',
},
},
{
id: 'raster',
type: 'raster',
source: SOURCE_ID,
paint: {
'raster-opacity': 1,
},
},
],
}

const writer = new SMPWriter(style)

const returnValue = outputPath
? pipelinePromise(writer.outputStream, fs.createWriteStream(outputPath))
: writer.outputStream

const tileWriteStream = writer.createTileWriteStream()

const transform = new Transform({
objectMode: true,
transform({ z, x, y, data, format }, encoding, callback) {
callback(null, [data, { z, x, y, format, sourceId: SOURCE_ID }])
},
})

pipeline(reader, transform, tileWriteStream, (err) => {
if (err) return writer.outputStream.destroy(err)
writer.finish()
})

return returnValue
}
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export { default as Server } from './server.js'
export { default as StyleDownloader } from './style-downloader.js'
export { downloadTiles } from './tile-downloader.js'
export { default as download } from './download.js'
export { default as fromMBTiles } from './from-mbtiles.js'
Loading

0 comments on commit 18afee4

Please sign in to comment.