add tile-pre-rendering and fetching
This commit is contained in:
136
ui/src/batch-renderer.js
Normal file
136
ui/src/batch-renderer.js
Normal file
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* Batch Renderer for Hopewell Lidar Tiles
|
||||
*
|
||||
* Usage in dev console with loaded app:
|
||||
* import { batchRenderTiles } from './batch-renderer.js';
|
||||
* const app = document.querySelector('#app').__vue_app__;
|
||||
* const sandboxRef = app._instance.refs.sandboxRef;
|
||||
* const tileCache = app._instance.data.tileCache;
|
||||
*
|
||||
* await batchRenderTiles(sandboxRef, tileCache, tileNames);
|
||||
*/
|
||||
|
||||
/**
|
||||
* Download a data URL as a file
|
||||
*/
|
||||
function downloadDataURL(dataURL, filename) {
|
||||
const link = document.createElement('a');
|
||||
link.href = dataURL;
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download text content as a file
|
||||
*/
|
||||
function downloadText(text, filename) {
|
||||
const blob = new Blob([text], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch render tiles using already-loaded app
|
||||
*
|
||||
* @param {Object} sandboxRef - Vue ref to ShadingSandbox component
|
||||
* @param {Object} tileCache - Cache of loaded tile data
|
||||
* @param {string[]} tileNames - Array of tile names to render
|
||||
* @param {Object} options - Options
|
||||
* @param {Object} options.renderSettings - Override render settings
|
||||
* @param {number} options.renderQuality - Render quality (default: 1024)
|
||||
*
|
||||
* @returns {Promise<Object[]>} Array of results
|
||||
*/
|
||||
export async function batchRenderTiles(sandboxRef, tileCache, tileNames, options = {}) {
|
||||
const {
|
||||
renderSettings = null, // Use sandbox defaults if null
|
||||
renderQuality = 1024
|
||||
} = options;
|
||||
|
||||
console.log(`[BatchRenderer] Starting batch render of ${tileNames.length} tiles`);
|
||||
console.log(`[BatchRenderer] Quality: ${renderQuality}px`);
|
||||
|
||||
const results = [];
|
||||
const startTime = Date.now();
|
||||
|
||||
for (let i = 0; i < tileNames.length; i++) {
|
||||
const tileName = tileNames[i];
|
||||
const current = i + 1;
|
||||
const total = tileNames.length;
|
||||
|
||||
console.log(`[BatchRenderer] [${current}/${total}] Processing ${tileName}...`);
|
||||
|
||||
try {
|
||||
const tileData = tileCache[tileName];
|
||||
if (!tileData) {
|
||||
throw new Error(`Tile ${tileName} not found in cache`);
|
||||
}
|
||||
|
||||
// Render
|
||||
console.log(`[BatchRenderer] Rendering...`);
|
||||
const renderResult = await sandboxRef.renderTileWithSettings(
|
||||
tileData,
|
||||
renderSettings || sandboxRef.getSettings(),
|
||||
renderQuality
|
||||
);
|
||||
|
||||
if (!renderResult.success) {
|
||||
throw new Error(renderResult.error || 'Render failed');
|
||||
}
|
||||
|
||||
console.log(`[BatchRenderer] Rendered in ${renderResult.renderTime}ms`);
|
||||
|
||||
// Generate metadata
|
||||
const metadata = {
|
||||
tileName,
|
||||
bounds: tileData.bounds,
|
||||
renderSettings: renderSettings || sandboxRef.getSettings(),
|
||||
renderQuality,
|
||||
pointCount: tileData.pointCount,
|
||||
triangleCount: tileData.triangleCount,
|
||||
renderedAt: new Date().toISOString()
|
||||
};
|
||||
|
||||
// Download
|
||||
downloadDataURL(renderResult.dataURL, `${tileName}.png`);
|
||||
downloadText(JSON.stringify(metadata, null, 2), `${tileName}.json`);
|
||||
|
||||
results.push({
|
||||
tileName,
|
||||
metadata,
|
||||
renderTime: renderResult.renderTime,
|
||||
success: true
|
||||
});
|
||||
|
||||
console.log(`[BatchRenderer] ✓ Complete`);
|
||||
|
||||
// Small delay
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
} catch (err) {
|
||||
console.error(`[BatchRenderer] ✗ Failed: ${err.message}`);
|
||||
results.push({
|
||||
tileName,
|
||||
success: false,
|
||||
error: err.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const totalTime = Date.now() - startTime;
|
||||
const successCount = results.filter(r => r.success).length;
|
||||
const failCount = results.filter(r => !r.success).length;
|
||||
|
||||
console.log(`[BatchRenderer] Batch complete in ${(totalTime / 1000).toFixed(1)}s`);
|
||||
console.log(`[BatchRenderer] Success: ${successCount}, Failed: ${failCount}`);
|
||||
|
||||
return results;
|
||||
}
|
||||
Reference in New Issue
Block a user