diff --git a/src/serve_rendered.js b/src/serve_rendered.js index 91af39f..513dc8d 100644 --- a/src/serve_rendered.js +++ b/src/serve_rendered.js @@ -6,8 +6,8 @@ import path from 'path'; import url from 'url'; import util from 'util'; import zlib from 'zlib'; -import { createCanvas, Image } from 'canvas'; import sharp from 'sharp'; // sharp has to be required before node-canvas on linux but after it on windows. see https://github.com/lovell/sharp/issues/371 +import { createCanvas, Image } from 'canvas'; import clone from 'clone'; import Color from 'color'; import express from 'express'; @@ -1470,141 +1470,134 @@ export const serve_rendered = { let source_type; let source = styleJSON.sources[name]; let url = source.url; - if (url) { - if (url.startsWith('{') && url.endsWith('}')) { - url = url.slice(1, -1); + if ( + url && + (url.startsWith('pmtiles://') || url.startsWith('mbtiles://')) + ) { + // found pmtiles or mbtiles source, replace with info from local file + delete source.url; + + let dataId = url.replace('pmtiles://', '').replace('mbtiles://', ''); + if (dataId.startsWith('{') && dataId.endsWith('}')) { + dataId = dataId.slice(1, -1); } - if (url.startsWith('pmtiles://') || url.startsWith('mbtiles://')) { - // found pmtiles or mbtiles source, replace with info from local file - delete source.url; - let dataId = url.replace('pmtiles://', '').replace('mbtiles://', ''); - if (dataId.startsWith('{') && dataId.endsWith('}')) { - dataId = dataId.slice(1, -1); + const mapsTo = (params.mapping || {})[dataId]; + if (mapsTo) { + dataId = mapsTo; + } + + let inputFile; + const DataInfo = dataResolver(dataId); + if (DataInfo.inputfile) { + inputFile = DataInfo.inputfile; + source_type = DataInfo.filetype; + } else { + console.error(`ERROR: data "${inputFile}" not found!`); + process.exit(1); + } + + if (!isValidHttpUrl(inputFile)) { + const inputFileStats = fs.statSync(inputFile); + if (!inputFileStats.isFile() || inputFileStats.size === 0) { + throw Error(`Not valid PMTiles file: "${inputFile}"`); + } + } + + if (source_type === 'pmtiles') { + map.sources[name] = PMtilesOpen(inputFile); + map.source_types[name] = 'pmtiles'; + const metadata = await GetPMtilesInfo(map.sources[name]); + + if (!repoobj.dataProjWGStoInternalWGS && metadata.proj4) { + // how to do this for multiple sources with different proj4 defs? + const to3857 = proj4('EPSG:3857'); + const toDataProj = proj4(metadata.proj4); + repoobj.dataProjWGStoInternalWGS = (xy) => + to3857.inverse(toDataProj.forward(xy)); } - const mapsTo = (params.mapping || {})[dataId]; - if (mapsTo) { - dataId = mapsTo; - } + const type = source.type; + metadata['extension'] = 'pmtiles'; + Object.assign(source, metadata); + source.type = type; + source.tiles = [ + // meta url which will be detected when requested + `pmtiles://${name}/{z}/{x}/{y}.${metadata.format || 'pbf'}`, + ]; + delete source.scheme; - let inputFile; - const DataInfo = dataResolver(dataId); - if (DataInfo.inputfile) { - inputFile = DataInfo.inputfile; - source_type = DataInfo.filetype; - } else { - console.error(`ERROR: data "${inputFile}" not found!`); - process.exit(1); - } - - if (!isValidHttpUrl(inputFile)) { - const inputFileStats = fs.statSync(inputFile); - if (!inputFileStats.isFile() || inputFileStats.size === 0) { - throw Error(`Not valid PMTiles file: "${inputFile}"`); - } - } - - if (source_type === 'pmtiles') { - map.sources[name] = PMtilesOpen(inputFile); - map.source_types[name] = 'pmtiles'; - const metadata = await GetPMtilesInfo(map.sources[name]); - - if (!repoobj.dataProjWGStoInternalWGS && metadata.proj4) { - // how to do this for multiple sources with different proj4 defs? - const to3857 = proj4('EPSG:3857'); - const toDataProj = proj4(metadata.proj4); - repoobj.dataProjWGStoInternalWGS = (xy) => - to3857.inverse(toDataProj.forward(xy)); - } - - const type = source.type; - metadata['extension'] = 'pmtiles'; - Object.assign(source, metadata); - source.type = type; - source.tiles = [ - // meta url which will be detected when requested - `pmtiles://${name}/{z}/{x}/{y}.${metadata.format || 'pbf'}`, - ]; - delete source.scheme; - - if ( - !attributionOverride && - source.attribution && - source.attribution.length > 0 - ) { - if (!tileJSON.attribution.includes(source.attribution)) { - if (tileJSON.attribution.length > 0) { - tileJSON.attribution += ' | '; - } - tileJSON.attribution += source.attribution; + if ( + !attributionOverride && + source.attribution && + source.attribution.length > 0 + ) { + if (!tileJSON.attribution.includes(source.attribution)) { + if (tileJSON.attribution.length > 0) { + tileJSON.attribution += ' | '; } + tileJSON.attribution += source.attribution; } - } else { - queue.push( - new Promise((resolve, reject) => { - inputFile = path.resolve(options.paths.mbtiles, inputFile); - const inputFileStats = fs.statSync(inputFile); - if (!inputFileStats.isFile() || inputFileStats.size === 0) { - throw Error(`Not valid MBTiles file: "${inputFile}"`); - } - map.sources[name] = new MBTiles( - inputFile + '?mode=ro', - (err) => { - map.sources[name].getInfo((err, info) => { - if (err) { - console.error(err); - return; - } - map.source_types[name] = 'mbtiles'; - - if (!repoobj.dataProjWGStoInternalWGS && info.proj4) { - // how to do this for multiple sources with different proj4 defs? - const to3857 = proj4('EPSG:3857'); - const toDataProj = proj4(info.proj4); - repoobj.dataProjWGStoInternalWGS = (xy) => - to3857.inverse(toDataProj.forward(xy)); - } - - const type = source.type; - info['extension'] = 'mbtiles'; - Object.assign(source, info); - source.type = type; - source.tiles = [ - // meta url which will be detected when requested - `mbtiles://${name}/{z}/{x}/{y}.${info.format || 'pbf'}`, - ]; - delete source.scheme; - - if (options.dataDecoratorFunc) { - source = options.dataDecoratorFunc( - name, - 'tilejson', - source, - ); - } - - if ( - !attributionOverride && - source.attribution && - source.attribution.length > 0 - ) { - if ( - !tileJSON.attribution.includes(source.attribution) - ) { - if (tileJSON.attribution.length > 0) { - tileJSON.attribution += ' | '; - } - tileJSON.attribution += source.attribution; - } - } - resolve(); - }); - }, - ); - }), - ); } + } else { + queue.push( + new Promise((resolve, reject) => { + inputFile = path.resolve(options.paths.mbtiles, inputFile); + const inputFileStats = fs.statSync(inputFile); + if (!inputFileStats.isFile() || inputFileStats.size === 0) { + throw Error(`Not valid MBTiles file: "${inputFile}"`); + } + map.sources[name] = new MBTiles(inputFile + '?mode=ro', (err) => { + map.sources[name].getInfo((err, info) => { + if (err) { + console.error(err); + return; + } + map.source_types[name] = 'mbtiles'; + + if (!repoobj.dataProjWGStoInternalWGS && info.proj4) { + // how to do this for multiple sources with different proj4 defs? + const to3857 = proj4('EPSG:3857'); + const toDataProj = proj4(info.proj4); + repoobj.dataProjWGStoInternalWGS = (xy) => + to3857.inverse(toDataProj.forward(xy)); + } + + const type = source.type; + info['extension'] = 'mbtiles'; + Object.assign(source, info); + source.type = type; + source.tiles = [ + // meta url which will be detected when requested + `mbtiles://${name}/{z}/{x}/{y}.${info.format || 'pbf'}`, + ]; + delete source.scheme; + + if (options.dataDecoratorFunc) { + source = options.dataDecoratorFunc( + name, + 'tilejson', + source, + ); + } + + if ( + !attributionOverride && + source.attribution && + source.attribution.length > 0 + ) { + if (!tileJSON.attribution.includes(source.attribution)) { + if (tileJSON.attribution.length > 0) { + tileJSON.attribution += ' | '; + } + tileJSON.attribution += source.attribution; + } + } + resolve(); + }); + }); + }), + ); } } } diff --git a/src/serve_style.js b/src/serve_style.js index 3c982f2..5f4e5ee 100644 --- a/src/serve_style.js +++ b/src/serve_style.js @@ -111,29 +111,27 @@ export const serve_style = { for (const name of Object.keys(styleJSON.sources)) { const source = styleJSON.sources[name]; let url = source.url; - if (url) { - if (url.startsWith('{') && url.endsWith('}')) { - url = url.slice(1, -1); + if ( + url && + (url.startsWith('pmtiles://') || url.startsWith('mbtiles://')) + ) { + const protocol = url.split(':')[0]; + + let dataId = url.replace('pmtiles://', '').replace('mbtiles://', ''); + if (dataId.startsWith('{') && dataId.endsWith('}')) { + dataId = dataId.slice(1, -1); } - if (url.startsWith('pmtiles://') || url.startsWith('mbtiles://')) { - const protocol = url.split(':')[0]; - let dataId = url.replace('pmtiles://', '').replace('mbtiles://', ''); - if (dataId.startsWith('{') && dataId.endsWith('}')) { - dataId = dataId.slice(1, -1); - } - - const mapsTo = (params.mapping || {})[dataId]; - if (mapsTo) { - dataId = mapsTo; - } - - const identifier = reportTiles(dataId, protocol); - if (!identifier) { - return false; - } - source.url = `local://data/${identifier}.json`; + const mapsTo = (params.mapping || {})[dataId]; + if (mapsTo) { + dataId = mapsTo; } + + const identifier = reportTiles(dataId, protocol); + if (!identifier) { + return false; + } + source.url = `local://data/${identifier}.json`; } }