Last active
June 29, 2022 21:19
-
-
Save wallabyway/4c7de696d96edc6b57725e21d0dea374 to your computer and use it in GitHub Desktop.
handy batch download of 3d-tiles tileset.json from bim360 (using batchPromises for threads)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// PURPOSE: download 3d-tiles files from BIM360, to local drive | |
// INSTALL: npm install node-fetch | |
// RUN: add your BIM360 access-token and the base url, then type | |
// > node pull-tiles-offline.mjs myOutputFolder | |
import fetch from 'node-fetch'; | |
import fs from 'fs'; | |
import util from 'util'; | |
import stream from 'stream'; | |
const token = "eyJh...DV-OCgxNcjnIp-3bNk7Sc8ZE..ISKykb5Q"; | |
const URN = "dXJuOm...yc2lvbj0x"; | |
const url = `https://cdn.derivative.autodesk.com/derivativeservice/v2/derivatives/urn:adsk.viewing:fs.file:${URN}/output/` | |
const NUMTHREADS = 64; | |
const uris = ["tileset.json"]; | |
//-----------UTILS | |
function recurveNode(node) { | |
uris.push(node.content.uri); | |
for (var n in node.children) { | |
recurveNode(node.children[n]); | |
}; | |
return node; | |
} | |
// https://github.com/Nicktho/batch-promises/blob/3b73b218b165b974d116b2cc5a7720895af489db/index.js#L4 | |
async function batchPromises(batchSize, collection, callback) { | |
const arr = await Promise.resolve(collection); | |
return arr | |
.map((_, i) => (i % batchSize ? [] : arr.slice(i, i + batchSize))) | |
.map((group) => (res) => Promise.all(group.map(callback)).then((r) => res.concat(r))) | |
.reduce((chain, work) => chain.then(work), Promise.resolve([])); | |
} | |
// download each tile | |
const streamPipeline = util.promisify(stream.pipeline); | |
//end----------- UTILS | |
async function downloadFile (url, szFile, outfolder) { | |
console.log(`downloading... ${szFile}`) | |
const response = await fetch(url + szFile, { headers:{ 'Authorization':`Bearer ${token}`}}); | |
if (!response.ok) return;//skip it... throw new Error(`unexpected response ${response.statusText}`) | |
await streamPipeline(response.body, fs.createWriteStream(`${outfolder}/${szFile}`)); | |
} | |
async function main (outfolder) { | |
fs.promises.mkdir(outfolder, { recursive: true }); // make destination folder, if not exist | |
// download tileset.json file | |
const jsonTileset = await (await fetch(url + "tileset.json", { headers:{ 'Authorization':`Bearer ${token}`} })).json(); | |
// decode all it's uri's | |
recurveNode(jsonTileset.root); | |
// now wget those uri's, using 64 threads | |
console.log(`downloading ${uris.length} files`) | |
await batchPromises(NUMTHREADS, uris, (szFile) => | |
downloadFile(url, szFile, outfolder | |
)) | |
}; | |
await main(process.argv.slice(2)[0] || 'result'); | |
console.log('done'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment