Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@ Node version: 18.17.0 or higher (Sharp requires this at minimum).
* `-b` or `--bounds`: Bounding box in WSEN format, comma separated (required)
* `-z` or `--minzoom`: Minimum zoom level (0 if not provided)
* `-Z` or `--maxzoom`: Maximum zoom level (required)
* `-i` or `--input`: Path where any source inputs (e.g. xyz, mbtiles, geojson) are located
* `-i` or `--input`: Path where any source inputs (e.g. mbtiles, xyz, geojson) are located
* `-o` or `--output`: Name of the output mbtiles file

## Example usage

```bash
$ node src/cli.js --style tests/fixtures/alert/style-with-tiles.json --bounds "-54.28772,3.11460,-54.03630,3.35025" -Z 14 --tilepath tests/fixtures/alert/tiles --output alert
$ node src/cli.js --style tests/fixtures/alert/style-with-geojson.json --bounds "-54.28772,3.11460,-54.03630,3.35025" -Z 14 --tilepath tests/fixtures/alert/tiles --output alert

$ node src/cli.js --style tests/fixtures/lofoten/style.json --bounds "12.46810,67.61450,15.43150,68.49630" -Z 12 --tilepath tests/fixtures/lofoten --output lofoten
$ node src/cli.js --style tests/fixtures/lofoten/style-with-tiles.json --bounds "12.46810,67.61450,15.43150,68.49630" -Z 12 --tilepath tests/fixtures/lofoten --output lofoten

$ node src/cli.js --style tests/fixtures/xyz/style.json --bounds "12.46810,67.61450,15.43150,68.49630" -Z 8 --input tests/fixtures/xyz/tiles
```

These commands will use one of the styles and tilesets from the fixtures to generate an mbtiles file in the outputs directory. The alert output will show a vector polygon overlaid in transparent red over satellite imagery, as can be seen in the stylesheet.
Expand Down
94 changes: 66 additions & 28 deletions src/request_resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import MBTiles from "@mapbox/mbtiles";

// Validations for source URLs
const TILE_REGEXP = RegExp("mbtiles://([^/]+)/(\\d+)/(\\d+)/(\\d+)");
const XYZ_REGEXP = /(\d+)\/(\d+)\/(\d+)\.(jpg|png|pbf)$/;
const isMBTilesURL = (url) => url.startsWith("mbtiles://");
const isGeoJSONURL = (url) => url.endsWith(".geojson");
const isXYZDirURL = (url) => /\/\d+\/\d+\/\d+/.test(url);

// Split out mbtiles service name from the URL
const resolveNamefromURL = (url) => url.split("://")[1].split("/")[0];
Expand Down Expand Up @@ -72,32 +74,8 @@ const getLocalGlyph = (styleDir, url, callback) => {
});
};

// Given a URL to a local GeoJSON file, get the GeoJSON for that to load correct tiles.
const getLocalGeoJSON = (sourceDir, url, callback) => {
/*
* @param {String} geojsonPath - path containing GeoJSON files.
* @param {String} url - url of a data source in style.json file.
* @param {function} callback - function to call with (err, {data}).
*/
const geojsonFilename = path.normalize(
path.format({
dir: sourceDir,
name: url
})
);

fs.readFile(geojsonFilename, (err, data) => {
if (err) {
callback(err);
return null;
}
callback(null, { data });
return null;
});
};

// Given a URL to a local mbtiles file, get the TileJSON for that to load correct tiles.
const getLocalTileJSON = (sourceDir, url, callback) => {
const getLocalMBTileJSON = (sourceDir, url, callback) => {
/*
* @param {String} sourceDir - path containing mbtiles files.
* @param {String} url - url of a data source in style.json file.
Expand Down Expand Up @@ -140,7 +118,7 @@ const getLocalTileJSON = (sourceDir, url, callback) => {
};

// Fetch a tile from a local mbtiles file.
const getLocalTile = (sourceDir, url, callback) => {
const getLocalMBTile = (sourceDir, url, callback) => {
/*
* @param {String} sourceDir - path containing mbtiles files.
* @param {String} url - url of a data source in style.json file.
Expand Down Expand Up @@ -179,6 +157,62 @@ const getLocalTile = (sourceDir, url, callback) => {
});
};

// Fetch a tile from a local XYZ directory.
const getLocalXYZTile = (sourceDir, url, callback) => {
/*
* @param {String} sourceDir - path containing XYZ tiles.
* @param {String} url - url of a data source in style.json file.
* @param {function} callback - function to call with (err, {data}).
*/
const matches = url.match(XYZ_REGEXP);
if (!matches) {
callback(new Error('Invalid URL format'));
return;
}
const [ , z, x, y, ext] = matches;
const xyzDir = path.normalize(
path.format({
dir: sourceDir,
name: url.split("://")[1],
})
);

const tilePath = path.join(xyzDir, z, x, `${y}.${ext}`);

fs.readFile(tilePath, (err, data) => {
if (err) {
callback(null, {});
return;
}

callback(null, { data });
});
};

// Given a URL to a local GeoJSON file, get the GeoJSON for that to load correct tiles.
const getLocalGeoJSON = (sourceDir, url, callback) => {
/*
* @param {String} geojsonPath - path containing GeoJSON files.
* @param {String} url - url of a data source in style.json file.
* @param {function} callback - function to call with (err, {data}).
*/
const geojsonFilename = path.normalize(
path.format({
dir: sourceDir,
name: url
})
);

fs.readFile(geojsonFilename, (err, data) => {
if (err) {
callback(err);
return null;
}
callback(null, { data });
return null;
});
};

// requestHandler constructs a request handler for the map to load resources.
// More about request types (kinds): https://github.com/maplibre/maplibre-native/blob/main/platform/node/README.md
export const requestHandler = (sourceDir, styleDir) => ({ url, kind }, callback) => {
Expand All @@ -187,7 +221,9 @@ export const requestHandler = (sourceDir, styleDir) => ({ url, kind }, callback)
case 2: {
// source
if (isMBTilesURL(url)) {
getLocalTileJSON(sourceDir, url, callback);
getLocalMBTileJSON(sourceDir, url, callback);
} else if (isXYZDirURL(url)) {
getLocalXYZTile(sourceDir, url, callback);
} else if (isGeoJSONURL(url)) {
getLocalGeoJSON(sourceDir, url, callback);
} else {
Expand All @@ -199,7 +235,9 @@ export const requestHandler = (sourceDir, styleDir) => ({ url, kind }, callback)
case 3: {
// tile
if (isMBTilesURL(url)) {
getLocalTile(sourceDir, url, callback);
getLocalMBTile(sourceDir, url, callback);
} else if (isXYZDirURL(url)) {
getLocalXYZTile(sourceDir, url, callback);
} else if (isGeoJSONURL(url)) {
getLocalGeoJSON(sourceDir, url, callback);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/lofoten/style.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
{
"id": "osm-layer",
"type": "raster",
"source": "lofoten",
"source": "raster_source",
"paint": {}
}
],
Expand Down
30 changes: 30 additions & 0 deletions tests/fixtures/xyz/style.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"version": 8,
"sources": {
"raster_source": {
"type": "raster",
"scheme": "xyz",
"tilejson": "2.2.0",
"tiles": [
"tiles/{z}/{x}/{y}.jpg"
],
"tileSize": 256
}
},
"layers": [
{
"id": "background",
"type": "background",
"paint": {
"background-color": "#f9f9f9"
}
},
{
"id": "osm-layer",
"type": "raster",
"source": "raster_source",
"paint": {}
}
],
"id": "output"
}
Binary file added tests/fixtures/xyz/tiles/0/0/0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/1/1/0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/2/2/0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/3/4/1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/4/8/3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/5/17/7.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/6/34/15.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/7/68/30.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/7/69/30.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/8/136/60.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/8/136/61.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/8/137/60.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/8/137/61.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/8/138/60.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/8/138/61.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/8/139/60.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/xyz/tiles/8/139/61.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.