core_VoxelGrid.js - hiro-nyon/cesium-heatbox GitHub Wiki
Source: core/VoxelGrid.js
日本語 | English
English
See also: Class: VoxelGrid
/**
* ボクセルグリッドを管理するクラス(シンプル実装)
*/
import { Logger } from '../utils/logger.js';
/**
* Class for managing 3D voxel grids.
* 3Dボクセルグリッドを管理するクラス。
*/
export class VoxelGrid {
/**
* Create a grid from bounds and voxel size (simple version).
* 境界情報とボクセルサイズからグリッドを作成(シンプル版)。
* @param {Object} bounds - Bounds info / 境界情報
* @param {number} voxelSizeMeters - Target voxel size in meters (actual cell size is range/divisions per axis) / 目標ボクセルサイズ(メートル)。実セルサイズは各軸で範囲/分割数。
* @returns {Object} Grid info { numVoxelsX, numVoxelsY, numVoxelsZ, totalVoxels, voxelSizeMeters, cellSizeX, cellSizeY, cellSizeZ, lonRangeMeters, latRangeMeters, altRangeMeters }
*/
static createGrid(bounds, voxelSizeMeters) {
// 緯度・経度をメートルに概算変換(シンプルな公式)
const centerLat = (bounds.minLat + bounds.maxLat) / 2;
const lonRangeMeters = (bounds.maxLon - bounds.minLon) * 111000 * Math.cos(centerLat * Math.PI / 180);
const latRangeMeters = (bounds.maxLat - bounds.minLat) * 111000;
const altRangeMeters = bounds.maxAlt - bounds.minAlt;
// 各軸のボクセル数を計算
const numVoxelsX = Math.max(1, Math.ceil(lonRangeMeters / voxelSizeMeters));
const numVoxelsY = Math.max(1, Math.ceil(latRangeMeters / voxelSizeMeters));
const numVoxelsZ = Math.max(1, Math.ceil(altRangeMeters / voxelSizeMeters));
// 実際の各軸セルサイズ(メートル)
// ceil により分割数が増える場合があるため、実セルサイズは指定サイズ以下になる。
const cellSizeX = numVoxelsX > 0 ? (lonRangeMeters / numVoxelsX) : voxelSizeMeters;
const cellSizeY = numVoxelsY > 0 ? (latRangeMeters / numVoxelsY) : voxelSizeMeters;
// 高度差が極小の場合に0にならないよう最低1mを確保
const cellSizeZ = numVoxelsZ > 0 ? Math.max(altRangeMeters / numVoxelsZ, 1) : Math.max(voxelSizeMeters, 1);
const totalVoxels = numVoxelsX * numVoxelsY * numVoxelsZ;
Logger.debug('VoxelGrid created:', {
numVoxelsX,
numVoxelsY,
numVoxelsZ,
totalVoxels,
voxelSizeMeters,
cellSizeX,
cellSizeY,
cellSizeZ,
lonRangeMeters,
latRangeMeters,
altRangeMeters
});
return {
numVoxelsX,
numVoxelsY,
numVoxelsZ,
totalVoxels,
voxelSizeMeters,
cellSizeX,
cellSizeY,
cellSizeZ,
lonRangeMeters,
latRangeMeters,
altRangeMeters
};
}
/**
* Generate a key from voxel indices.
* ボクセルインデックスからキーを生成します。
* @param {number} x - X index / X軸インデックス
* @param {number} y - Y index / Y軸インデックス
* @param {number} z - Z index / Z軸インデックス
* @returns {string} Voxel key / ボクセルキー
*/
static getVoxelKey(x, y, z) {
return `${x},${y},${z}`;
}
/**
* Parse voxel key into indices.
* ボクセルキーからインデックスを解析します。
* @param {string} key - Voxel key / ボクセルキー
* @returns {Object} Indices {x, y, z} / インデックス {x, y, z}
*/
static parseVoxelKey(key) {
const [x, y, z] = key.split(',').map(Number);
return { x, y, z };
}
/**
* Iterate all voxels and invoke callback per cell.
* グリッド内の全ボクセルを反復処理します。
* @param {Object} grid - Grid info / グリッド情報
* @param {Function} callback - Callback per voxel / 各ボクセルに対するコールバック関数
*/
static iterateAllVoxels(grid, callback) {
const { numVoxelsX, numVoxelsY, numVoxelsZ } = grid;
for (let x = 0; x < numVoxelsX; x++) {
for (let y = 0; y < numVoxelsY; y++) {
for (let z = 0; z < numVoxelsZ; z++) {
const key = this.getVoxelKey(x, y, z);
callback(x, y, z, key);
}
}
}
}
}
日本語
関連: VoxelGridクラス
/**
* ボクセルグリッドを管理するクラス(シンプル実装)
*/
import { Logger } from '../utils/logger.js';
/**
* Class for managing 3D voxel grids.
* 3Dボクセルグリッドを管理するクラス。
*/
export class VoxelGrid {
/**
* Create a grid from bounds and voxel size (simple version).
* 境界情報とボクセルサイズからグリッドを作成(シンプル版)。
* @param {Object} bounds - Bounds info / 境界情報
* @param {number} voxelSizeMeters - Target voxel size in meters (actual cell size is range/divisions per axis) / 目標ボクセルサイズ(メートル)。実セルサイズは各軸で範囲/分割数。
* @returns {Object} Grid info { numVoxelsX, numVoxelsY, numVoxelsZ, totalVoxels, voxelSizeMeters, cellSizeX, cellSizeY, cellSizeZ, lonRangeMeters, latRangeMeters, altRangeMeters }
*/
static createGrid(bounds, voxelSizeMeters) {
// 緯度・経度をメートルに概算変換(シンプルな公式)
const centerLat = (bounds.minLat + bounds.maxLat) / 2;
const lonRangeMeters = (bounds.maxLon - bounds.minLon) * 111000 * Math.cos(centerLat * Math.PI / 180);
const latRangeMeters = (bounds.maxLat - bounds.minLat) * 111000;
const altRangeMeters = bounds.maxAlt - bounds.minAlt;
// 各軸のボクセル数を計算
const numVoxelsX = Math.max(1, Math.ceil(lonRangeMeters / voxelSizeMeters));
const numVoxelsY = Math.max(1, Math.ceil(latRangeMeters / voxelSizeMeters));
const numVoxelsZ = Math.max(1, Math.ceil(altRangeMeters / voxelSizeMeters));
// 実際の各軸セルサイズ(メートル)
// ceil により分割数が増える場合があるため、実セルサイズは指定サイズ以下になる。
const cellSizeX = numVoxelsX > 0 ? (lonRangeMeters / numVoxelsX) : voxelSizeMeters;
const cellSizeY = numVoxelsY > 0 ? (latRangeMeters / numVoxelsY) : voxelSizeMeters;
// 高度差が極小の場合に0にならないよう最低1mを確保
const cellSizeZ = numVoxelsZ > 0 ? Math.max(altRangeMeters / numVoxelsZ, 1) : Math.max(voxelSizeMeters, 1);
const totalVoxels = numVoxelsX * numVoxelsY * numVoxelsZ;
Logger.debug('VoxelGrid created:', {
numVoxelsX,
numVoxelsY,
numVoxelsZ,
totalVoxels,
voxelSizeMeters,
cellSizeX,
cellSizeY,
cellSizeZ,
lonRangeMeters,
latRangeMeters,
altRangeMeters
});
return {
numVoxelsX,
numVoxelsY,
numVoxelsZ,
totalVoxels,
voxelSizeMeters,
cellSizeX,
cellSizeY,
cellSizeZ,
lonRangeMeters,
latRangeMeters,
altRangeMeters
};
}
/**
* Generate a key from voxel indices.
* ボクセルインデックスからキーを生成します。
* @param {number} x - X index / X軸インデックス
* @param {number} y - Y index / Y軸インデックス
* @param {number} z - Z index / Z軸インデックス
* @returns {string} Voxel key / ボクセルキー
*/
static getVoxelKey(x, y, z) {
return `${x},${y},${z}`;
}
/**
* Parse voxel key into indices.
* ボクセルキーからインデックスを解析します。
* @param {string} key - Voxel key / ボクセルキー
* @returns {Object} Indices {x, y, z} / インデックス {x, y, z}
*/
static parseVoxelKey(key) {
const [x, y, z] = key.split(',').map(Number);
return { x, y, z };
}
/**
* Iterate all voxels and invoke callback per cell.
* グリッド内の全ボクセルを反復処理します。
* @param {Object} grid - Grid info / グリッド情報
* @param {Function} callback - Callback per voxel / 各ボクセルに対するコールバック関数
*/
static iterateAllVoxels(grid, callback) {
const { numVoxelsX, numVoxelsY, numVoxelsZ } = grid;
for (let x = 0; x < numVoxelsX; x++) {
for (let y = 0; y < numVoxelsY; y++) {
for (let z = 0; z < numVoxelsZ; z++) {
const key = this.getVoxelKey(x, y, z);
callback(x, y, z, key);
}
}
}
}
}