UNPKG

@csi-foxbyte/cityjson-to-3d-tiles

Version:

A Node.js library that converts CityJSON files into Cesium 3D Tiles—complete with automatic texture atlas packing, Basis compression, three LOD levels, and customizable threading.

2 lines • 3.03 kB
import {mkdir,writeFile}from'fs/promises';import {Box3,Vector3,Box2,Vector2}from'three';import {Cartographic}from'cesium';import {PromisePool}from'@supercharge/promise-pool/dist/index.js';import {Grid2D}from'../grid2d/index.js';import {calculateBBoxVolume}from'./calculateBoundingVolume.js';import {createDatabase}from'../database/index.js';import g from'path';import {fork}from'child_process';import {ChildProcessPool}from'../lib/ChildProcessPool.js';async function K(h,m,C,p,f={}){console.time("RUN TOOK");try{await mkdir(m,{recursive:!0});}catch{}const{threadCount:y=4}=f,k=[],e=new Box3,w=await createDatabase(h,false);await w.each("SELECT name, bbMinX, bbMinY, bbMinZ, bbMaxX, bbMaxY, isInstanced, bbMaxZ, attributes, type, address FROM data",(t,r)=>{const n=new Cartographic(r.bbMinX,r.bbMinY,r.bbMinZ),i=new Cartographic(r.bbMaxX,r.bbMaxY,r.bbMaxZ),b=new Box3(new Vector3(n.longitude,n.latitude,n.height),new Vector3(i.longitude,i.latitude,i.height));e.union(b);const s=r.name;k.push({minX:n.longitude,maxX:i.longitude,minY:n.latitude,maxY:i.latitude,name:s,isInstanced:r.isInstanced===1,minHeight:n.height,maxHeight:i.height,attributes:{...JSON.parse(r.attributes??"{}"),...f.simplifyAdresses?{address:JSON.parse(r.address??"[]")?.[0]}:{addresses:JSON.parse(r.address??"[]")}},type:r.type,region:[n.longitude,n.latitude,i.longitude,i.latitude,n.height,i.height]});});try{await w.close();}catch(t){console.error(t);}const u={refine:"ADD",geometricError:calculateBBoxVolume(e),boundingVolume:{region:[e.min.x,e.min.y,e.max.x,e.max.y,e.min.z,e.max.z]},children:[]},l=new Grid2D(new Box2(new Vector2(e.min.x,e.min.y),new Vector2(e.max.x,e.max.y)),2e-4);for(const t of k)l.add((t.maxX-t.minX)*.5+t.minX,(t.maxY-t.minY)*.5+t.minY,t);let d=0;const c=new ChildProcessPool(()=>fork(g.join(import.meta.dirname,"worker.js"),{silent:true}),y);await PromisePool.withConcurrency(y).for(l.cells).process(async t=>{try{const r=await c.acquire();let n=null,i=null;const b=new Promise((o,a)=>{n=o,i=a;});r.on("message",o=>{n(o);let a=!1;o||(a=!0),o&&o.heapUsed>500*1024*1024&&(a=!0),c.release(r,a);}),r.on("exit",(o,a)=>{o!==0&&i(new Error(`Worker exited with code ${o}, signal ${a}`)),c.release(r,!0);}),r.on("error",o=>{i(o),c.release(r,!0);}),r.send({data:{cell:t,outputFolder:m,hasAlphaEnabled:C,databasePath:h},type:"work"});const s=await b;if(!s)return;u.children.push(s.tile),await writeFile(g.join(m,"tileset.json"),JSON.stringify({asset:{version:"1.1"},geometricError:calculateBBoxVolume(e),boundingVolume:{region:[e.min.x,e.min.y,e.max.x,e.max.y,e.min.z,e.max.z]},root:u},void 0,4)),d++,p(d/l.cells.length,s.files);return}catch(r){console.error(r);}d++,p(d/l.cells.length,[]);}),await writeFile(g.join(m,"tileset.json"),JSON.stringify({asset:{version:"1.1"},geometricError:calculateBBoxVolume(e),boundingVolume:{region:[e.min.x,e.min.y,e.max.x,e.max.y,e.min.z,e.max.z]},root:u},void 0,4)),console.timeEnd("RUN TOOK");}export{K as generate3DTilesFromTileDatabase};//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map