cesium-heatbox 0.1.13 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("cesium")):"function"==typeof define&&define.amd?define(["cesium"],t):"object"==typeof exports?exports.CesiumHeatbox=t(require("cesium")):e.CesiumHeatbox=t(e.Cesium)}(this,e=>(()=>{"use strict";var t={50:t=>{t.exports=e}},i={};function n(e){var o=i[e];if(void 0!==o)return o.exports;var a=i[e]={exports:{}};return t[e](a,a.exports,n),a.exports}n.d=(e,t)=>{for(var i in t)n.o(t,i)&&!n.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var o={};n.d(o,{default:()=>$});var a=n(50);const s={voxelSize:20,opacity:.8,emptyOpacity:.03,showOutline:!0,showEmptyVoxels:!1,minColor:[0,32,255],maxColor:[255,64,0],maxRenderVoxels:5e4,batchMode:"auto",debug:!1,autoVoxelSize:!1,colorMap:"custom",diverging:!1,divergingPivot:0,highlightTopN:null,highlightStyle:{outlineWidth:4,boostOpacity:.2},voxelGap:0,outlineOpacity:1,outlineWidthResolver:null,outlineEmulation:"off",outlineInset:0,outlineInsetMode:"all",enableThickFrames:!1,outlineRenderMode:"standard",emulationScope:"off",adaptiveOutlines:!1,outlineWidthPreset:"medium",boxOpacityResolver:null,outlineOpacityResolver:null,adaptiveParams:{neighborhoodRadius:50,densityThreshold:5,cameraDistanceFactor:1,overlapRiskFactor:.3},renderLimitStrategy:"density",minCoverageRatio:.2,coverageBinsXY:"auto",autoVoxelSizeMode:"basic",autoVoxelTargetFill:.6,renderBudgetMode:"manual",autoView:!1,fitViewOptions:{paddingPercent:.1,pitchDegrees:-30,headingDegrees:0,altitudeStrategy:"auto"}},r=5e4,l=1e3,h=(Math.PI,"対象エンティティがありません");let d="undefined"!=typeof process&&process.env&&"true"===process.env.DEBUG?3:"undefined"!=typeof process&&process.env?1:3;const c={error(...e){d>=0&&console.error("[Heatbox ERROR]",...e)},warn(...e){d>=1&&console.warn("[Heatbox WARN]",...e)},info(...e){d>=2&&console.log("[Heatbox INFO]",...e)},debug(...e){d>=3&&console.log("[Heatbox DEBUG]",...e)},setLogLevel:e=>(e&&void 0!==e.debug&&("boolean"==typeof e.debug?d=e.debug?3:1:"object"==typeof e.debug&&null!==e.debug&&(d=3)),d)},u=(c.debug,c.warn,c.error,c.info,new Set);function m(e,t){u.has(e)||(u.add(e),c.warn(t))}const p={"mobile-fast":{maxRenderVoxels:5e3,outlineRenderMode:"emulation-only",adaptiveOutlines:!1,outlineWidthPreset:"thin",opacity:.7,renderLimitStrategy:"density",minCoverageRatio:.1,topNHighlight:10,description:"Mobile devices - prioritizes performance over visual quality"},"desktop-balanced":{maxRenderVoxels:15e3,outlineRenderMode:"standard",adaptiveOutlines:!0,outlineWidthPreset:"medium",opacity:.8,renderLimitStrategy:"hybrid",minCoverageRatio:.2,topNHighlight:20,adaptiveParams:{outlineWidthRange:[1,4],outlineOpacityRange:[.4,1],boxOpacityRange:[.2,.8]},description:"Desktop environments - balanced performance and quality"},"dense-data":{maxRenderVoxels:25e3,outlineRenderMode:"inset",adaptiveOutlines:!0,outlineWidthPreset:"thin",opacity:.6,renderLimitStrategy:"hybrid",minCoverageRatio:.3,topNHighlight:30,outlineInset:.5,highlightTopN:!0,highlightStyle:{boostOpacity:.3,boostOutlineWidth:1.5},description:"High-density datasets - optimized for cluttered environments"},"sparse-data":{maxRenderVoxels:8e3,outlineRenderMode:"standard",adaptiveOutlines:!1,outlineWidthPreset:"thick",opacity:.9,renderLimitStrategy:"coverage",minCoverageRatio:.8,topNHighlight:50,emptyOpacity:.05,showEmptyVoxels:!0,description:"Sparse datasets - emphasizes visibility and coverage"}};function g(){return Object.keys(p)}function x(e){return p[e]||null}function y(e,t={}){const i=x(e);if(!i)return t;const{description:n,...o}=i;return f(o,t)}function f(e,t){const i={...e};for(const e in t)Object.prototype.hasOwnProperty.call(t,e)&&(t[e]&&"object"==typeof t[e]&&!Array.isArray(t[e])?i[e]=f(i[e]||{},t[e]):i[e]=t[e]);return i}function v(e){return!!Array.isArray(e)&&0!==e.length&&(e.length>5e3&&c.warn(`エンティティ数が推奨値(5000)を超えています: ${e.length}`),!0)}function b(e={}){let t=e;var i;e.profile&&"none"!==e.profile&&("string"==typeof(i=e.profile)&&Object.prototype.hasOwnProperty.call(p,i)?(c.debug(`Applying profile: ${e.profile}`),t=y(e.profile,e),delete t.profile):c.warn(`Invalid profile name: ${e.profile}. Available profiles: mobile-fast, desktop-balanced, dense-data, sparse-data`));const n={...t};if(n.batchMode&&n.debug&&c.warn("batchMode option is deprecated and will be removed in v1.0.0. It is currently ignored."),void 0!==n.voxelSize&&("number"!=typeof(o=n.voxelSize)||isNaN(o)||o<5||o>l))throw new Error(`ボクセルサイズが無効です: ${n.voxelSize}`);var o;if(void 0!==n.opacity&&(n.opacity=Math.max(0,Math.min(1,n.opacity))),void 0!==n.emptyOpacity&&(n.emptyOpacity=Math.max(0,Math.min(1,n.emptyOpacity))),n.minColor&&Array.isArray(n.minColor)&&3===n.minColor.length&&(n.minColor=n.minColor.map(e=>Math.max(0,Math.min(255,Math.floor(e))))),n.maxColor&&Array.isArray(n.maxColor)&&3===n.maxColor.length&&(n.maxColor=n.maxColor.map(e=>Math.max(0,Math.min(255,Math.floor(e))))),void 0!==n.colorMap&&(["custom","viridis","inferno"].includes(n.colorMap)||(c.warn(`Invalid colorMap: ${n.colorMap}. Using 'custom'.`),n.colorMap="custom")),void 0!==n.highlightTopN&&null!==n.highlightTopN&&("number"!=typeof n.highlightTopN||n.highlightTopN<=0)&&(c.warn(`Invalid highlightTopN: ${n.highlightTopN}. Must be a positive number.`),n.highlightTopN=null),void 0!==n.voxelGap&&(n.voxelGap=Math.max(0,Math.min(100,parseFloat(n.voxelGap)||0))),void 0!==n.outlineOpacity&&(n.outlineOpacity=Math.max(0,Math.min(1,parseFloat(n.outlineOpacity)||1))),void 0!==n.outlineWidthResolver&&null!==n.outlineWidthResolver&&(m("outlineWidthResolver","[Heatbox][DEPRECATION][v0.2.0] outlineWidthResolver is deprecated; use adaptiveOutlines with outlineWidthPreset and adaptiveParams instead."),delete n.outlineWidthResolver),void 0!==n.outlineOpacityResolver&&null!==n.outlineOpacityResolver&&(m("outlineOpacityResolver","[Heatbox][DEPRECATION][v0.2.0] outlineOpacityResolver is deprecated; prefer adaptiveOutlines with adaptiveParams.outlineOpacityRange."),"function"!=typeof n.outlineOpacityResolver&&(c.warn("outlineOpacityResolver must be a function. Ignoring."),n.outlineOpacityResolver=null)),void 0!==n.boxOpacityResolver&&null!==n.boxOpacityResolver&&(m("boxOpacityResolver","[Heatbox][DEPRECATION][v0.2.0] boxOpacityResolver is deprecated; prefer adaptiveOutlines with adaptiveParams.boxOpacityRange."),"function"!=typeof n.boxOpacityResolver&&(c.warn("boxOpacityResolver must be a function. Ignoring."),n.boxOpacityResolver=null)),void 0!==n.outlineEmulation&&(void 0===n.outlineRenderMode||"standard"===n.outlineRenderMode)){m("outlineEmulation","[Heatbox][DEPRECATION][v0.2.0] outlineEmulation is deprecated; use outlineRenderMode and emulationScope instead.");const e=n.outlineEmulation;!1===e||"off"===e?(n.outlineRenderMode="standard",n.emulationScope="off"):!0===e||"all"===e?(n.outlineRenderMode="emulation-only",n.emulationScope="all"):"topn"===e?(n.outlineRenderMode="standard",n.emulationScope="topn"):"non-topn"===e?(n.outlineRenderMode="standard",n.emulationScope="non-topn"):(c.warn(`Invalid outlineEmulation: ${e}. Using 'standard' mode.`),n.outlineRenderMode="standard"),delete n.outlineEmulation}if(void 0!==n.outlineWidthPreset){const e=n.outlineWidthPreset,t={uniform:"medium","adaptive-density":"adaptive","topn-focus":"thick"};t[e]&&(m(`outlineWidthPreset.${e}`,`[Heatbox][DEPRECATION][v0.2.0] outlineWidthPreset "${e}" is deprecated; use "${t[e]}".`),n.outlineWidthPreset=t[e])}if(void 0!==n.outlineInset){const e=parseFloat(n.outlineInset);n.outlineInset=isNaN(e)||e<0?0:e}if(void 0!==n.outlineInsetMode){let e=n.outlineInsetMode;"off"===e&&(e="none"),["all","topn","none"].includes(e)?n.outlineInsetMode=e:(c.warn(`Invalid outlineInsetMode: ${n.outlineInsetMode}. Using 'all'.`),n.outlineInsetMode="all")}if(void 0!==n.outlineInset){const e=parseFloat(n.outlineInset);n.outlineInset=Math.max(0,Math.min(100,isNaN(e)?0:e))}if(void 0!==n.outlineInsetMode){let e=n.outlineInsetMode;"off"===e&&(e="none"),["all","topn","none"].includes(e)?n.outlineInsetMode=e:(c.warn(`Invalid outlineInsetMode: ${n.outlineInsetMode}. Using 'all'.`),n.outlineInsetMode="all")}if(void 0!==n.enableThickFrames&&(n.enableThickFrames=Boolean(n.enableThickFrames)),void 0!==n.renderLimitStrategy&&(["density","coverage","hybrid"].includes(n.renderLimitStrategy)||(c.warn(`Invalid renderLimitStrategy: ${n.renderLimitStrategy}. Using 'density'.`),n.renderLimitStrategy="density")),void 0!==n.minCoverageRatio){const e=parseFloat(n.minCoverageRatio);n.minCoverageRatio=isNaN(e)?.2:Math.max(0,Math.min(1,e))}if(void 0!==n.coverageBinsXY){const e=n.coverageBinsXY;if("auto"!==e){const t=parseInt(e,10);!Number.isFinite(t)||t<=0?(c.warn(`Invalid coverageBinsXY: ${e}. Using 'auto'.`),n.coverageBinsXY="auto"):n.coverageBinsXY=t}}if(void 0!==n.autoVoxelSizeMode&&(["basic","occupancy"].includes(n.autoVoxelSizeMode)||(c.warn(`Invalid autoVoxelSizeMode: ${n.autoVoxelSizeMode}. Using 'basic'.`),n.autoVoxelSizeMode="basic")),void 0!==n.autoVoxelTargetFill){const e=parseFloat(n.autoVoxelTargetFill);n.autoVoxelTargetFill=isNaN(e)?.6:Math.max(0,Math.min(1,e))}if(void 0!==n.renderBudgetMode&&(["manual","auto"].includes(n.renderBudgetMode)||(c.warn(`Invalid renderBudgetMode: ${n.renderBudgetMode}. Using 'manual'.`),n.renderBudgetMode="manual")),void 0!==n.fitViewOptions){const e=n.fitViewOptions||{};void 0!==e.pitch&&void 0===e.pitchDegrees&&m("fitViewOptions.pitch","[Heatbox][DEPRECATION][v0.2.0] fitViewOptions.pitch is deprecated; use fitViewOptions.pitchDegrees."),void 0!==e.heading&&void 0===e.headingDegrees&&m("fitViewOptions.heading","[Heatbox][DEPRECATION][v0.2.0] fitViewOptions.heading is deprecated; use fitViewOptions.headingDegrees.");const t=parseFloat(e.paddingPercent),i=void 0!==e.pitchDegrees?parseFloat(e.pitchDegrees):parseFloat(e.pitch),o=void 0!==e.headingDegrees?parseFloat(e.headingDegrees):parseFloat(e.heading),a=e.altitudeStrategy;n.fitViewOptions={paddingPercent:Number.isFinite(t)?Math.max(0,Math.min(1,t)):.1,pitchDegrees:Number.isFinite(i)?Math.max(-90,Math.min(0,i)):-30,headingDegrees:Number.isFinite(o)?o:0,altitudeStrategy:"manual"===a?"manual":"auto"}}return n}function M(e,t){const i=w(e),n=i.x*i.y*Math.max(i.z,10),o=t/n;let a;return a=o>.001?Math.max(10,Math.min(20,20/Math.sqrt(1e3*o))):o>1e-4?Math.max(20,Math.min(50,50/Math.sqrt(1e4*o))):Math.max(50,Math.min(100,100/Math.sqrt(1e5*o))),a=Math.max(5,Math.min(l,a)),c.debug(`Basic voxel size estimated: ${a}m (density: ${o}, volume: ${n})`),Math.round(a)}function w(e){try{const t={minLat:Number.isFinite(e.minLat)?Math.max(-90,Math.min(90,e.minLat)):0,maxLat:Number.isFinite(e.maxLat)?Math.max(-90,Math.min(90,e.maxLat)):.1,minLon:Number.isFinite(e.minLon)?Math.max(-180,Math.min(180,e.minLon)):0,maxLon:Number.isFinite(e.maxLon)?Math.max(-180,Math.min(180,e.maxLon)):.1,minAlt:Number.isFinite(e.minAlt)?e.minAlt:0,maxAlt:Number.isFinite(e.maxAlt)?e.maxAlt:100};t.maxLat<=t.minLat&&(t.maxLat=t.minLat+.001),t.maxLon<=t.minLon&&(t.maxLon=t.minLon+.001),t.maxAlt<=t.minAlt&&(t.maxAlt=t.minAlt+1);const i=(t.minLat+t.maxLat)/2,n=Math.cos(Math.max(-Math.PI/2,Math.min(Math.PI/2,i*Math.PI/180))),o=111e3*Math.abs(t.maxLon-t.minLon)*Math.abs(n),a=111e3*Math.abs(t.maxLat-t.minLat),s=Math.abs(t.maxAlt-t.minAlt);return{x:Math.max(1,Math.min(1e6,o)),y:Math.max(1,Math.min(1e6,a)),z:Math.max(1,Math.min(1e4,s))}}catch(e){return c.warn("Data range calculation failed:",e),{x:1e3,y:1e3,z:100}}}const S={low:{min:4e3,max:8e3},mid:{min:8e3,max:15e3},high:{min:15e3,max:25e3}};class R{static calculateBounds(e){if(!Array.isArray(e)||0===e.length)throw new Error("エンティティが提供されていません");let t=1/0,i=-1/0,n=1/0,o=-1/0,s=1/0,r=-1/0,l=0;const h=a.JulianDate.now();if(e.forEach((e,d)=>{try{let d,c,u,m;if(e.position&&(d="function"==typeof e.position.getValue?e.position.getValue(h):e.position),!d)return;if("number"==typeof d?.x&&"number"==typeof d?.y&&Math.abs(d.x)<=360&&Math.abs(d.y)<=90)c=d.x,u=d.y,m="number"==typeof d.z?d.z:0;else{const e=a.Cartographic.fromCartesian(d);if(!e)return;c=a.Math.toDegrees(e.longitude),u=a.Math.toDegrees(e.latitude),m=e.height}t=Math.min(t,c),i=Math.max(i,c),n=Math.min(n,u),o=Math.max(o,u),s=Math.min(s,m),r=Math.max(r,m),l++}catch(e){c.warn(`エンティティ ${d} の処理に失敗:`,e)}}),0===l)throw new Error("有効な位置情報を持つエンティティが見つかりません");return c.debug("座標範囲計算完了:",{validCount:l,bounds:{minLon:t,maxLon:i,minLat:n,maxLat:o,minAlt:s,maxAlt:r}}),{minLon:t,maxLon:i,minLat:n,maxLat:o,minAlt:s,maxAlt:r,centerLon:(t+i)/2,centerLat:(n+o)/2,centerAlt:(s+r)/2}}static voxelIndexToCoordinate(e,t,i,n,o){const{minLon:a,maxLon:s,minLat:r,maxLat:l,minAlt:h,maxAlt:d}=n,{numVoxelsX:c,numVoxelsY:u,numVoxelsZ:m}=o;return{lon:a+(e+.5)/c*(s-a),lat:r+(t+.5)/u*(l-r),alt:h+(i+.5)/m*(d-h)}}static coordinateToCartesian3(e,t,i){return a.Cartesian3.fromDegrees(e,t,i)}}class z{static createGrid(e,t){const i=(e.minLat+e.maxLat)/2,n=111e3*(e.maxLon-e.minLon)*Math.cos(i*Math.PI/180),o=111e3*(e.maxLat-e.minLat),a=e.maxAlt-e.minAlt,s=Math.max(1,Math.ceil(n/t)),r=Math.max(1,Math.ceil(o/t)),l=Math.max(1,Math.ceil(a/t)),h=s>0?n/s:t,d=r>0?o/r:t,u=l>0?Math.max(a/l,1):Math.max(t,1),m=s*r*l;return c.debug("VoxelGrid created:",{numVoxelsX:s,numVoxelsY:r,numVoxelsZ:l,totalVoxels:m,voxelSizeMeters:t,cellSizeX:h,cellSizeY:d,cellSizeZ:u,lonRangeMeters:n,latRangeMeters:o,altRangeMeters:a}),{numVoxelsX:s,numVoxelsY:r,numVoxelsZ:l,totalVoxels:m,voxelSizeMeters:t,cellSizeX:h,cellSizeY:d,cellSizeZ:u,lonRangeMeters:n,latRangeMeters:o,altRangeMeters:a}}static getVoxelKey(e,t,i){return`${e},${t},${i}`}static parseVoxelKey(e){const[t,i,n]=e.split(",").map(Number);return{x:t,y:i,z:n}}static iterateAllVoxels(e,t){const{numVoxelsX:i,numVoxelsY:n,numVoxelsZ:o}=e;for(let e=0;e<i;e++)for(let i=0;i<n;i++)for(let n=0;n<o;n++)t(e,i,n,this.getVoxelKey(e,i,n))}}class V{static classifyEntitiesIntoVoxels(e,t,i){const n=new Map;let o=0,s=0;c.debug(`Processing ${e.length} entities for classification`);const r=a.JulianDate.now();return e.forEach((e,l)=>{try{let l,h,d,c;if(e.position&&(l="function"==typeof e.position.getValue?e.position.getValue(r):e.position),!l)return void s++;if("number"==typeof l?.x&&"number"==typeof l?.y&&Math.abs(l.x)<=360&&Math.abs(l.y)<=90)h=l.x,d=l.y,c="number"==typeof l.z?l.z:0;else if(a.Cartographic&&"function"==typeof a.Cartographic.fromCartesian){const e=a.Cartographic.fromCartesian(l);if(!e)return void s++;h=a.Math.toDegrees(e.longitude),d=a.Math.toDegrees(e.latitude),c=e.height}else{if("number"!=typeof l.x||"number"!=typeof l.y)return void s++;h=l.x,d=l.y,c="number"==typeof l.z?l.z:0}if(h<t.minLon-.001||h>t.maxLon+.001||d<t.minLat-.001||d>t.maxLat+.001||c<t.minAlt-1||c>t.maxAlt+1)return void s++;const u=t.maxLon-t.minLon,m=t.maxLat-t.minLat,p=t.maxAlt-t.minAlt,g=0===u?0:Math.min(i.numVoxelsX-1,Math.floor((h-t.minLon)/u*i.numVoxelsX)),x=0===m?0:Math.min(i.numVoxelsY-1,Math.floor((d-t.minLat)/m*i.numVoxelsY)),y=0===p?0:Math.min(i.numVoxelsZ-1,Math.floor((c-t.minAlt)/p*i.numVoxelsZ));if(g>=0&&g<i.numVoxelsX&&x>=0&&x<i.numVoxelsY&&y>=0&&y<i.numVoxelsZ){const t=z.getVoxelKey(g,x,y);n.has(t)||n.set(t,{x:g,y:x,z:y,entities:[],count:0});const i=n.get(t);i.entities.push(e),i.count++,o++}else s++}catch(e){c.warn(`エンティティ ${l} の処理に失敗:`,e),s++}}),c.info(`${o}個のエンティティを${n.size}個のボクセルに分類(${s}個はスキップ)`),n}static calculateStatistics(e,t){if(0===e.size)return{totalVoxels:t.totalVoxels,renderedVoxels:0,nonEmptyVoxels:0,emptyVoxels:t.totalVoxels,totalEntities:0,minCount:0,maxCount:0,averageCount:0,autoAdjusted:!1,originalVoxelSize:null,finalVoxelSize:null,adjustmentReason:null};const i=Array.from(e.values()).map(e=>e.count),n=i.reduce((e,t)=>e+t,0),o={totalVoxels:t.totalVoxels,renderedVoxels:0,nonEmptyVoxels:e.size,emptyVoxels:t.totalVoxels-e.size,totalEntities:n,minCount:Math.min(...i),maxCount:Math.max(...i),averageCount:n/e.size,autoAdjusted:!1,originalVoxelSize:null,finalVoxelSize:null,adjustmentReason:null};return c.debug("統計情報計算完了:",o),o}static getTopNVoxels(e,t){if(0===e.size||t<=0)return[];const i=Array.from(e.values()).sort((e,t)=>t.count-e.count);return i.slice(0,Math.min(t,i.length))}}const _=Object.freeze({viridis:Object.freeze([[68,1,84],[72,40,120],[62,74,137],[49,104,142],[38,130,142],[31,158,137],[53,183,121],[109,205,89],[180,222,44],[253,231,37]]),inferno:Object.freeze([[0,0,4],[31,12,72],[85,15,109],[136,34,106],[186,54,85],[227,89,51],[249,142,8],[252,187,17],[245,219,76],[252,255,164]]),diverging:Object.freeze([[0,0,255],[32,64,255],[64,128,255],[96,160,255],[128,192,255],[160,224,255],[192,240,255],[224,248,255],[255,255,255],[255,248,224],[255,240,192],[255,224,160],[255,192,128],[255,160,96],[255,128,64],[255,64,32],[255,0,0]])});class O{static calculateColor(e,t=null,i={}){try{Number.isFinite(e)||(c.warn(`Invalid normalizedDensity: ${e}. Using 0.5 as fallback.`),e=.5);const{minColor:n=[0,0,255],maxColor:o=[255,0,0],colorMap:a,diverging:s=!1,divergingPivot:r=0}=i;if(s&&null!==t){const e="number"==typeof r?r:0;return O.calculateDivergingColor(t,{divergingPivot:e})}return a&&"custom"!==a?O.interpolateFromColorMap(e,a):O.interpolateLinear(e,n,o)}catch(e){return c.warn(`Color calculation failed: ${e.message}. Falling back to gray.`),a.Color.GRAY}}static interpolateLinear(e,t,i){const n=Math.max(0,Math.min(1,e)),[o,s,r]=t,[l,h,d]=i,c=Math.round(o+(l-o)*n),u=Math.round(s+(h-s)*n),m=Math.round(r+(d-r)*n);return a.Color.fromBytes(c,u,m)}static interpolateFromColorMap(e,t){const i=_[t];if(!i)return c.warn(`Unknown color map: ${t}. Falling back to linear interpolation.`),O.interpolateLinear(e,[0,0,255],[255,0,0]);const n=Math.max(0,Math.min(1,e))*(i.length-1),o=Math.floor(n),s=Math.min(o+1,i.length-1),r=n-o,[l,h,d]=i[o],[u,m,p]=i[s],g=Math.round(l+(u-l)*r),x=Math.round(h+(m-h)*r),y=Math.round(d+(p-d)*r);return a.Color.fromBytes(g,x,y)}static calculateDivergingColor(e,t={}){const{divergingPivot:i=0}=t,n=i;let o;return 0===n?e<0?(o=1/(1-e)*.5,o=Math.max(0,Math.min(.5,o))):e>0?(o=.5+e/(1+e)*.5,o=Math.max(.5,Math.min(1,o))):o=.5:e<=n?(o=e/n*.5,o=Math.max(0,Math.min(.5,o))):(o=.5+(e-n)/n*.5,o=Math.max(.5,Math.min(1,o))),O.interpolateFromColorMap(o,"diverging")}static getAvailableColorMaps(){return Object.keys(_)}static isValidColorMap(e){return Object.hasOwn(_,e)}}class C{constructor(e={}){this.options={renderLimitStrategy:"density",highlightTopN:0,coverageBinsXY:"auto",minCoverageRatio:.2,...e},this._lastSelectionStats=null,c.debug(`VoxelSelector initialized with strategy: ${this.options.renderLimitStrategy}`)}selectVoxels(e,t,i={}){try{if(!Array.isArray(e)||0===e.length)return c.warn("VoxelSelector: Empty or invalid voxel array provided"),this._createEmptyResult();if(t<=0)return c.warn(`VoxelSelector: Invalid maxCount: ${t}`),this._createEmptyResult();if(e.length<=t)return this._createResult(e,this.options.renderLimitStrategy,e.length,0);const{grid:n}=i,o=this.options.renderLimitStrategy||"density",a=this._identifyTopNVoxels(e);let s;switch(o){case"coverage":s=this._selectByCoverageStrategy(e,t,n,a);break;case"hybrid":s=this._selectByHybridStrategy(e,t,n,a);break;default:s=this._selectByDensityStrategy(e,t,a)}return this._lastSelectionStats={strategy:s.strategy,clippedNonEmpty:s.clippedNonEmpty,coverageRatio:s.coverageRatio||null,selectedCount:s.selectedVoxels.length,totalCount:e.length},c.debug(`VoxelSelector: Applied ${s.strategy} strategy - selected ${s.selectedVoxels.length}/${e.length} voxels`),s}catch(i){return c.error(`VoxelSelector: Selection failed: ${i.message}. Falling back to density strategy.`),this._fallbackToDensitySelection(e,t)}}getLastSelectionStats(){return this._lastSelectionStats}_identifyTopNVoxels(e){const t=new Set;if(this.options.highlightTopN&&this.options.highlightTopN>0){const i=[...e].sort((e,t)=>t.info.count-e.info.count).slice(0,this.options.highlightTopN);i.forEach(e=>t.add(e.key)),c.debug(`VoxelSelector: Identified ${i.length} TopN voxels for forced inclusion`)}return t}_selectByDensityStrategy(e,t,i=new Set){const n=[...e].sort((e,t)=>t.info.count-e.info.count),o=[],a=new Set;n.forEach(e=>{i.has(e.key)&&o.length<t&&(o.push(e),a.add(e.key))}),n.forEach(e=>{!a.has(e.key)&&o.length<t&&(o.push(e),a.add(e.key))});const s=e.length-o.length;return this._createResult(o,"density",o.length,s)}_selectByCoverageStrategy(e,t,i,n=new Set){const o=[],a=new Set;e.forEach(e=>{n.has(e.key)&&o.length<t&&(o.push(e),a.add(e.key))});const s="auto"===this.options.coverageBinsXY?Math.ceil(Math.sqrt(t/4)):this.options.coverageBinsXY,r=new Map;e.filter(e=>!a.has(e.key)).forEach(e=>{const t=`${Math.max(0,Math.min(s-1,Math.floor(e.info.x/Math.max(1,i.numVoxelsX)*s)))},${Math.max(0,Math.min(s-1,Math.floor(e.info.y/Math.max(1,i.numVoxelsY)*s)))}`;r.has(t)||r.set(t,[]),r.get(t).push(e)});const l=Array.from(r.keys());let h=0;for(;o.length<t&&h<10*l.length;){const e=l[h%l.length],t=r.get(e);if(t&&t.length>0){t.sort((e,t)=>t.info.count-e.info.count);const i=t.shift();a.has(i.key)||(o.push(i),a.add(i.key)),0===t.length&&(r.delete(e),l.splice(l.indexOf(e),1))}h++}const d=e.length-o.length;return this._createResult(o,"coverage",o.length,d)}_selectByHybridStrategy(e,t,i,n=new Set){const o=this.options.minCoverageRatio||.2,a=[],s=new Set;e.forEach(e=>{n.has(e.key)&&a.length<t&&(a.push(e),s.add(e.key))});const r=t-a.length,l=Math.floor(r*o),h=r-l;l>0&&this._selectByCoverageStrategy(e.filter(e=>!s.has(e.key)),l,i,new Set).selectedVoxels.forEach(e=>{a.length<t&&!s.has(e.key)&&(a.push(e),s.add(e.key))}),h>0&&this._selectByDensityStrategy(e.filter(e=>!s.has(e.key)),h,new Set).selectedVoxels.forEach(e=>{a.length<t&&!s.has(e.key)&&(a.push(e),s.add(e.key))});const d=l>0?(a.length-n.size-h)/(a.length-n.size):0,c=e.length-a.length;return this._createResult(a,"hybrid",a.length,c,d)}_fallbackToDensitySelection(e,t){try{const i=new Set,n=this._selectByDensityStrategy(e,t,i);return n.strategy="density-fallback",this._lastSelectionStats={strategy:n.strategy,clippedNonEmpty:n.clippedNonEmpty,coverageRatio:null,selectedCount:n.selectedVoxels.length,totalCount:e.length,error:!0},n}catch(e){return c.error(`VoxelSelector: Even fallback failed: ${e.message}`),this._createEmptyResult()}}_createResult(e,t,i,n,o=null){return{selectedVoxels:e,strategy:t,clippedNonEmpty:n,coverageRatio:o}}_createEmptyResult(){return{selectedVoxels:[],strategy:"none",clippedNonEmpty:0,coverageRatio:null}}}class L{constructor(e={}){this.options={...e,adaptiveParams:{neighborhoodRadius:50,densityThreshold:5,cameraDistanceFactor:1,overlapRiskFactor:.3,...e.adaptiveParams}},c.debug("AdaptiveController initialized with options:",this.options)}calculateNeighborhoodDensity(e,t,i=null){if(!t||"function"!=typeof t.get)return{isDenseArea:!1,neighborhoodDensity:0,neighborCount:0};const{x:n,y:o,z:a}=e,s=null!==i?i:Math.max(1,Math.floor(this.options.adaptiveParams.neighborhoodRadius/20));let r=0,l=0;for(let e=-s;e<=s;e++)for(let i=-s;i<=s;i++)for(let h=-s;h<=s;h++){if(0===e&&0===i&&0===h)continue;const s=`${n+e},${o+i},${a+h}`,d=t.get(s);d&&(r+=d.count,l++)}const h=l>0?r/l:0;return{totalDensity:r,neighborCount:l,avgDensity:h,isDenseArea:h>this.options.adaptiveParams.densityThreshold,searchRadius:s}}applyPresetLogic(e,t,i,n,o){let a,s,r;switch(e){case"thin":a=Math.max(1,.8*o.outlineWidth),s=o.opacity,r=o.outlineOpacity||.8;break;case"medium":case"uniform":default:a=o.outlineWidth,s=o.opacity,r=o.outlineOpacity||1;break;case"thick":a=Math.max(1,1.5*o.outlineWidth),s=o.opacity,r=o.outlineOpacity||1;break;case"adaptive":case"adaptive-density":{const e=n?.8+.4*i:1;a=Math.max(1,Math.min(3*o.outlineWidth,o.outlineWidth*e)),s=n?.8*o.opacity:o.opacity,r=n?.6:1;break}case"topn-focus":a=t?Math.max(1,Math.min(3*o.outlineWidth,o.outlineWidth*(1.5+.5*i))):Math.max(1,.8*o.outlineWidth),s=t?o.opacity:.6*o.opacity,r=t?1:.4}return{adaptiveWidth:a,adaptiveBoxOpacity:s,adaptiveOutlineOpacity:r}}calculateAdaptiveParams(e,t,i,n,o){if(!e||!n||!o)return{outlineWidth:null,boxOpacity:null,outlineOpacity:null,shouldUseEmulation:!1};if(!o.adaptiveOutlines)return{outlineWidth:null,boxOpacity:null,outlineOpacity:null,shouldUseEmulation:!1};const{count:a}=e,s=n.maxCount>n.minCount?(a-n.minCount)/(n.maxCount-n.minCount):0,r=this.calculateNeighborhoodDensity(e,i),{isDenseArea:l}=r,h=Math.min(1,1)*this.options.adaptiveParams.cameraDistanceFactor,d=l?this.options.adaptiveParams.overlapRiskFactor:0,c=this.applyPresetLogic(o.outlineWidthPreset,t,s,l,o),u=c.adaptiveWidth*h,m=Math.max(.2,c.adaptiveOutlineOpacity*(1-d));return{outlineWidth:Math.max(1,u),boxOpacity:Math.max(.1,Math.min(1,c.adaptiveBoxOpacity)),outlineOpacity:Math.max(.2,Math.min(1,m)),shouldUseEmulation:l||u>2&&"standard"!==o.outlineRenderMode,_debug:{normalizedDensity:s,neighborhoodResult:r,cameraFactor:h,overlapRisk:d,preset:o.outlineWidthPreset}}}updateOptions(e){this.options={...this.options,...e,adaptiveParams:{...this.options.adaptiveParams,...e.adaptiveParams||{}}},c.debug("AdaptiveController options updated:",this.options)}getConfiguration(){return{...this.options,version:"0.1.11",phase:"ADR-0009 Phase 3"}}}class A{constructor(e,t={}){this.viewer=e,this.options={wireframeOnly:!1,showOutline:!0,outlineWidth:2,outlineInset:0,outlineInsetMode:"all",outlineRenderMode:"standard",enableThickFrames:!1,...t},this.entities=[],c.debug("GeometryRenderer initialized with viewer and options:",this.options)}createVoxelBox(e){const{centerLon:t,centerLat:i,centerAlt:n,cellSizeX:o,cellSizeY:s,boxHeight:r,color:l,opacity:h,shouldShowOutline:d,outlineColor:u,outlineWidth:m,voxelInfo:p,voxelKey:g,emulateThick:x=!1}=e,y=Number.isFinite(t)?Math.max(-180,Math.min(180,t)):0,f=Number.isFinite(i)?Math.max(-90,Math.min(90,i)):0,v=Number.isFinite(n)?Math.max(-1e4,Math.min(1e5,n)):0,b=Number.isFinite(o)&&o>0?Math.min(o,1e6):1,M=Number.isFinite(s)&&s>0?Math.min(s,1e6):1,w=Number.isFinite(r)&&r>0?Math.min(r,1e6):1;y===t&&f===i&&v===n&&b===o&&M===s&&w===r||c.warn(`Clamped invalid geometry values for voxel ${g}:`,{original:{centerLon:t,centerLat:i,centerAlt:n,cellSizeX:o,cellSizeY:s,boxHeight:r},clamped:{safeCenterLon:y,safeCenterLat:f,safeCenterAlt:v,safeCellSizeX:b,safeCellSizeY:M,safeBoxHeight:w}});const S=Boolean(d&&!x),R={dimensions:new a.Cartesian3(b,M,w),outline:S};S&&(R.outlineColor=u,R.outlineWidth=Math.max(m||1,1));const z={position:a.Cartesian3.fromDegrees(y,f,v),box:R,properties:{type:"voxel",key:g,count:p.count,x:p.x,y:p.y,z:p.z},description:this.createVoxelDescription(p,g)};this.options.wireframeOnly?(z.box.material=a.Color.TRANSPARENT,z.box.fill=!1):(z.box.material=l.withAlpha(h),z.box.fill=!0);const V=this.viewer.entities.add(z);return this.entities.push(V),V}createInsetOutline(e){const{centerLon:t,centerLat:i,centerAlt:n,baseSizeX:o,baseSizeY:s,baseSizeZ:r,outlineColor:l,outlineWidth:h,voxelKey:d,insetAmount:u=null}=e,m=Number.isFinite(t)?Math.max(-180,Math.min(180,t)):0,p=Number.isFinite(i)?Math.max(-90,Math.min(90,i)):0,g=Number.isFinite(n)?Math.max(-1e4,Math.min(1e5,n)):0,x=Number.isFinite(o)&&o>0?Math.min(o,1e6):1,y=Number.isFinite(s)&&s>0?Math.min(s,1e6):1,f=Number.isFinite(r)&&r>0?Math.min(r,1e6):1,v=.2*x,b=.2*y,M=.2*f,w=null!==u?u:this.options.outlineInset,S=Math.min(w,v),R=Math.min(w,b),z=Math.min(w,M),V=Math.max(x-2*S,.1*x),_=Math.max(y-2*R,.1*y),O=Math.max(f-2*z,.1*f),C=this.viewer.entities.add({position:a.Cartesian3.fromDegrees(m,p,g),box:{dimensions:new a.Cartesian3(V,_,O),fill:!1,outline:!0,outlineColor:l,outlineWidth:Math.max(h||1,1)},properties:{type:"voxel-inset-outline",parentKey:d,insetSize:{x:V,y:_,z:O}}});return this.entities.push(C),this.options.enableThickFrames&&(S>.1||R>.1||z>.1)&&this.createThickOutlineFrames({centerLon:m,centerLat:p,centerAlt:g,outerX:x,outerY:y,outerZ:f,innerX:V,innerY:_,innerZ:O,frameColor:l,voxelKey:d}),c.debug(`Inset outline created for voxel ${d}:`,{originalSize:{x:o,y:s,z:r},insetSize:{x:V,y:_,z:O},effectiveInset:{x:S,y:R,z}}),C}createThickOutlineFrames(e){const{centerLon:t,centerLat:i,centerAlt:n,outerX:o,outerY:s,outerZ:r,innerX:l,innerY:h,innerZ:d,frameColor:u,voxelKey:m}=e;let p=(o-l)/2,g=(s-h)/2,x=(r-d)/2;const y=.05;if(p<=0||g<=0||x<=0)return c.warn(`Invalid frame thickness for voxel ${m}, skipping thick frames`),[];p=Math.max(p,y),g=Math.max(g,y),x=Math.max(x,y);const f=o/2,v=s/2,b=r/2,M=[],w=[{x:f,z:b,sizeX:p,sizeZ:x},{x:-f,z:b,sizeX:p,sizeZ:x},{x:f,z:-b,sizeX:p,sizeZ:x},{x:-f,z:-b,sizeX:p,sizeZ:x}],S=[{x:f,y:v,sizeX:p,sizeY:g},{x:-f,y:v,sizeX:p,sizeY:g},{x:f,y:-v,sizeX:p,sizeY:g},{x:-f,y:-v,sizeX:p,sizeY:g}];return[{y:v,z:b,sizeY:g,sizeZ:x},{y:-v,z:b,sizeY:g,sizeZ:x},{y:v,z:-b,sizeY:g,sizeZ:x},{y:-v,z:-b,sizeY:g,sizeZ:x}].forEach((e,s)=>{const r=a.Cartesian3.fromDegrees(t,i+e.y/111320,n+e.z),l=this.viewer.entities.add({position:r,box:{dimensions:new a.Cartesian3(o,e.sizeY,e.sizeZ),fill:!0,material:u.withAlpha(.3),outline:!1},properties:{type:"voxel-thick-frame-x",parentKey:m,frameIndex:s}});this.entities.push(l),M.push(l)}),w.forEach((e,o)=>{const r=a.Cartesian3.fromDegrees(t+e.x/(111320*Math.cos(i*Math.PI/180)),i,n+e.z),l=this.viewer.entities.add({position:r,box:{dimensions:new a.Cartesian3(e.sizeX,s,e.sizeZ),fill:!0,material:u.withAlpha(.3),outline:!1},properties:{type:"voxel-thick-frame-y",parentKey:m,frameIndex:o}});this.entities.push(l),M.push(l)}),S.forEach((e,o)=>{const s=a.Cartesian3.fromDegrees(t+e.x/(111320*Math.cos(i*Math.PI/180)),i+e.y/111320,n),l=this.viewer.entities.add({position:s,box:{dimensions:new a.Cartesian3(e.sizeX,e.sizeY,r),fill:!0,material:u.withAlpha(.3),outline:!1},properties:{type:"voxel-thick-frame-z",parentKey:m,frameIndex:o}});this.entities.push(l),M.push(l)}),c.debug(`Created ${M.length} thick frame entities for voxel ${m}`),M}createEdgePolylines(e){const{centerLon:t,centerLat:i,centerAlt:n,cellSizeX:o,cellSizeY:s,boxHeight:r,outlineColor:l,outlineWidth:h,voxelKey:d}=e,u=[],m=Number.isFinite(t)?Math.max(-180,Math.min(180,t)):0,p=Number.isFinite(i)?Math.max(-85,Math.min(85,i)):0,g=Number.isFinite(n)?Math.max(-1e4,Math.min(1e5,n)):0,x=Number.isFinite(o)&&o>0?Math.min(o,1e5):1,y=Number.isFinite(s)&&s>0?Math.min(s,1e5):1,f=Number.isFinite(r)&&r>0?Math.min(r,1e5):1;if(x<.001||y<.001||f<.001)return c.warn(`Dimensions too small for voxel ${d}, skipping edge polylines`),u;const v=x/2,b=y/2,M=f/2,w=Math.cos(p*Math.PI/180),S=v/(111320*Math.max(.1,Math.abs(w))),R=b/111320;if(!Number.isFinite(S)||!Number.isFinite(R)||Math.abs(S)>.1||Math.abs(R)>.1)return c.warn(`Coordinate offsets out of range for voxel ${d}, skipping edge polylines`),u;const z=[[m-S,p-R,g-M],[m+S,p-R,g-M],[m+S,p+R,g-M],[m-S,p+R,g-M],[m-S,p-R,g+M],[m+S,p-R,g+M],[m+S,p+R,g+M],[m-S,p+R,g+M]];if(!z.every(([e,t,i])=>Number.isFinite(e)&&Number.isFinite(t)&&Number.isFinite(i)&&e>=-180&&e<=180&&t>=-85&&t<=85&&i>=-5e4&&i<=5e5))return c.warn(`Invalid vertex coordinates for voxel ${d}, skipping edge polylines`),u;let V;try{V=z.map(([e,t,i])=>a.Cartesian3.fromDegrees(e,t,i))}catch(e){return c.warn(`Failed to create Cartesian3 vertices for voxel ${d}:`,e),u}return V.every(e=>e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.z))?([[0,1],[1,2],[2,3],[3,0],[4,5],[5,6],[6,7],[7,4],[0,4],[1,5],[2,6],[3,7]].forEach((e,t)=>{try{const i=V[e[0]],n=V[e[1]];if(!i||!n)return void c.warn(`Missing vertices for edge ${t} in voxel ${d}`);const o=[i,n];if(2!==o.length)return void c.warn(`Invalid positions array length for edge ${t} in voxel ${d}`);const a=this.viewer.entities.add({polyline:{positions:o,width:Math.max(Math.min(h,20),1),material:l,clampToGround:!1},properties:{type:"voxel-edge-polyline",parentKey:d,edgeIndex:t}});this.entities.push(a),u.push(a)}catch(e){c.warn(`Failed to create polyline for edge ${t} in voxel ${d}:`,e)}}),c.debug(`Created ${u.length} edge polylines for voxel ${d}`),u):(c.warn(`Generated vertices contain invalid values for voxel ${d}, skipping edge polylines`),u)}createVoxelDescription(e,t){return`\n <div style="padding: 10px; font-family: Arial, sans-serif;">\n <h3 style="margin-top: 0;">ボクセル [${e.x}, ${e.y}, ${e.z}]</h3>\n <table style="width: 100%;">\n <tr><td><b>エンティティ数:</b></td><td>${e.count}</td></tr>\n <tr><td><b>ボクセルキー:</b></td><td>${t}</td></tr>\n <tr><td><b>座標:</b></td><td>X=${e.x}, Y=${e.y}, Z=${e.z}</td></tr>\n </table>\n <p style="margin-bottom: 0;">\n <small>v0.1.11 GeometryRenderer</small>\n </p>\n </div>\n `}shouldApplyInsetOutline(e){switch(this.options.outlineInsetMode||"all"){case"topn":return e;case"all":default:return!0;case"none":return!1}}clear(){c.debug("GeometryRenderer.clear - Removing",this.entities.length,"entities"),this.entities.forEach(e=>{try{const t=!(!e||"function"!=typeof e.isDestroyed)&&e.isDestroyed();e&&!t&&this.viewer.entities.remove(e)}catch(e){c.warn("Entity removal error:",e)}}),this.entities=[]}renderBoundingBox(e){if(e)try{const t=(e.minLon+e.maxLon)/2,i=(e.minLat+e.maxLat)/2,n=(e.minAlt+e.maxAlt)/2,o=111e3*(e.maxLon-e.minLon)*Math.cos(i*Math.PI/180),s=111e3*(e.maxLat-e.minLat),r=e.maxAlt-e.minAlt,l=this.viewer.entities.add({position:a.Cartesian3.fromDegrees(t,i,n),box:{dimensions:new a.Cartesian3(o,s,r),material:a.Color.YELLOW.withAlpha(.1),outline:!0,outlineColor:a.Color.YELLOW.withAlpha(.3),outlineWidth:2},description:`Bounding Box<br>Size: ${o.toFixed(1)} x ${s.toFixed(1)} x ${r.toFixed(1)} m`});this.entities.push(l),c.debug("Debug bounding box added:",{center:{lon:t,lat:i,alt:n},size:{width:o,depth:s,height:r}})}catch(e){c.warn("Failed to render bounding box:",e)}}getEntityCount(){return this.entities.length}updateOptions(e){this.options={...this.options,...e},c.debug("GeometryRenderer options updated:",this.options)}getConfiguration(){return{...this.options,entityCount:this.entities.length,version:"0.1.11",phase:"ADR-0009 Phase 4"}}}class F{constructor(e,t={}){this.viewer=e,this.options={minColor:[0,0,255],maxColor:[255,0,0],opacity:.8,emptyOpacity:.03,showOutline:!0,showEmptyVoxels:!1,wireframeOnly:!1,heightBased:!1,outlineWidth:2,outlineInset:0,outlineInsetMode:"all",outlineRenderMode:"standard",emulationScope:"off",adaptiveOutlines:!1,outlineWidthPreset:"medium",...t},this.voxelSelector=new C(this.options),this._selectionStats=null,this.adaptiveController=new L(this.options),this.geometryRenderer=new A(this.viewer,this.options),Object.defineProperty(this,"voxelEntities",{get:()=>this.geometryRenderer.entities,enumerable:!0,configurable:!0}),c.debug("VoxelRenderer initialized with options:",this.options)}_calculateAdaptiveParams(e,t,i,n){return this.adaptiveController.calculateAdaptiveParams(e,t,i,n,this.options)}_shouldApplyInsetOutline(e){return this.geometryRenderer.shouldApplyInsetOutline(e)}render(e,t,i,n){this.geometryRenderer.clear(),c.debug("VoxelRenderer.render - Starting render with simplified approach",{voxelDataSize:e.size,bounds:t,grid:i,statistics:n}),this._shouldShowBounds()&&this.geometryRenderer.renderBoundingBox(t);let o=[];const a=new Set;if(this.options.showEmptyVoxels){const t=Math.min(i.totalVoxels,this.options.maxRenderVoxels||1e4);c.debug(`Generating grid for up to ${t} voxels`);for(let n=0;n<i.numVoxelsX;n++){for(let a=0;a<i.numVoxelsY;a++){for(let s=0;s<i.numVoxelsZ;s++){const i=`${n},${a},${s}`,r=e.get(i)||{x:n,y:a,z:s,count:0};if(o.push({key:i,info:r}),o.length>=t){c.debug(`Reached maximum voxel limit of ${t}`);break}}if(o.length>=t)break}if(o.length>=t)break}}else if(o=Array.from(e.entries()).map(([e,t])=>({key:e,info:t})),this.options.maxRenderVoxels&&o.length>this.options.maxRenderVoxels){const e=this._selectVoxelsForRendering(o,this.options.maxRenderVoxels,t,i);o=e.selectedVoxels,this._selectionStats={strategy:e.strategy,clippedNonEmpty:e.clippedNonEmpty,coverageRatio:e.coverageRatio||0},c.debug(`Applied ${e.strategy} strategy: ${o.length} voxels selected, ${e.clippedNonEmpty} clipped`)}this.options.highlightTopN&&this.options.highlightTopN>0&&([...o].sort((e,t)=>t.info.count-e.info.count).slice(0,this.options.highlightTopN).forEach(e=>a.add(e.key)),c.debug(`TopN highlight enabled: ${a.size} voxels will be highlighted`)),c.debug(`Rendering ${o.length} voxels`);let s=0;const r={x:0,y:0,z:0,count:0},l={voxel:r,isTopN:!1,normalizedDensity:0,statistics:n,adaptiveParams:null},h={voxel:r,isTopN:!1,normalizedDensity:0,statistics:n,adaptiveParams:null};return o.forEach(({key:e,info:o})=>{try{s+=this._renderSingleVoxel(e,o,t,i,n,a,r,l,h)}catch(e){c.warn("Error rendering voxel:",e)}}),c.info(`Successfully rendered ${s} voxels`),s}_renderSingleVoxel(e,t,i,n,o,a,s,r,l){const h=a.has(e),d=this._calculateVoxelRenderingParams(t,i,n,o,h,s,r,l);return d?(this._delegateVoxelRendering(e,d),1):0}_calculateVoxelRenderingParams(e,t,i,n,o,a,s,r){if(!(e&&t&&i&&n))return null;const{x:l,y:h,z:d}=e,c=t.minLon+(l+.5)*(t.maxLon-t.minLon)/i.numVoxelsX,u=t.minLat+(h+.5)*(t.maxLat-t.minLat)/i.numVoxelsY,m=t.minAlt+(d+.5)*(t.maxAlt-t.minAlt)/i.numVoxelsZ,p=n.maxCount>n.minCount?(e.count-n.minCount)/(n.maxCount-n.minCount):0,g=this._calculateAdaptiveParams(e,o,null,n),{color:x,opacity:y}=this._calculateColorAndOpacity(e,p,o,g,n,a,r),{cellSizeX:f,cellSizeY:v,boxHeight:b}=this._calculateDimensions(i,p);return{centerLon:c,centerLat:u,centerAlt:m,cellSizeX:f,cellSizeY:v,boxHeight:b,color:x,opacity:y,...this._calculateOutlineProperties(e,o,p,g,n,x,a,s),voxelInfo:e,isTopN:o,adaptiveParams:g}}_calculateColorAndOpacity(e,t,i,n,o,s,r){let l,h;if(0===e.count)l=a.Color.LIGHTGRAY,h=this.options.emptyOpacity;else{if(l=O.calculateColor(t,e.count,this.options),this.options.boxOpacityResolver&&"function"==typeof this.options.boxOpacityResolver){s.x=e.x,s.y=e.y,s.z=e.z,s.count=e.count,r.isTopN=i,r.normalizedDensity=t,r.adaptiveParams=n;try{const e=this.options.boxOpacityResolver(r);h=isNaN(e)?this.options.opacity:Math.max(0,Math.min(1,e))}catch(e){c.warn("boxOpacityResolver error, using fallback:",e),h=n.boxOpacity||this.options.opacity}}else h=n.boxOpacity||this.options.opacity;this.options.highlightTopN&&!i&&(h*=1-(this.options.highlightStyle?.boostOpacity||.2))}return{color:l,opacity:h}}_calculateDimensions(e,t){let i=e.cellSizeX||(e.lonRangeMeters?e.lonRangeMeters/e.numVoxelsX:e.voxelSizeMeters),n=e.cellSizeY||(e.latRangeMeters?e.latRangeMeters/e.numVoxelsY:e.voxelSizeMeters),o=e.cellSizeZ||(e.altRangeMeters?Math.max(e.altRangeMeters/Math.max(e.numVoxelsZ,1),1):Math.max(e.voxelSizeMeters,1));this.options.voxelGap>0&&(i=Math.max(i-this.options.voxelGap,.1*i),n=Math.max(n-this.options.voxelGap,.1*n),o=Math.max(o-this.options.voxelGap,.1*o));let a=o;return this.options.heightBased&&(a=o*(.1+.9*t)),{cellSizeX:i,cellSizeY:n,boxHeight:a}}_calculateOutlineProperties(e,t,i,n,o,a,s,r){let l;if(this.options.outlineWidthResolver&&"function"==typeof this.options.outlineWidthResolver){s.x=e.x,s.y=e.y,s.z=e.z,s.count=e.count,r.isTopN=t,r.normalizedDensity=i,r.adaptiveParams=n;try{l=this.options.outlineWidthResolver(r),isNaN(l)&&(l=n.outlineWidth||this.options.outlineWidth)}catch(e){c.warn("outlineWidthResolver error, using fallback:",e),l=n.outlineWidth||this.options.outlineWidth}}else l=this.options.adaptiveOutlines&&null!==n.outlineWidth?n.outlineWidth:t&&this.options.highlightTopN&&this.options.highlightStyle?.outlineWidth||this.options.outlineWidth;const h=n.outlineOpacity||(this.options.outlineOpacity??1),d=a.withAlpha(h),u=this._determineRenderModeConfig();let m=u.shouldUseEmulationOnly;if(!u.shouldUseEmulationOnly){const e=this.options.emulationScope||"off";"topn"===e?m=t&&(l||1)>1:"non-topn"===e?m=!t&&(l||1)>1:"all"===e?m=(l||1)>1:this.options.adaptiveOutlines&&n.shouldUseEmulation&&(m="off"!==e)}return{shouldShowOutline:u.shouldShowStandardOutline,outlineColor:d,outlineWidth:l||1,shouldShowInsetOutline:u.shouldShowInsetOutline,emulateThick:m}}_determineRenderModeConfig(){let e=!0,t=!1,i=!1;switch(this.options.outlineRenderMode){case"standard":e=this.options.showOutline,t=this.options.outlineInset>0;break;case"inset":e=!1,t=!0;break;case"emulation-only":e=!1,t=!1,i=!0}return{shouldShowStandardOutline:e,shouldShowInsetOutline:t,shouldUseEmulationOnly:i}}_delegateVoxelRendering(e,t){if(this.geometryRenderer.createVoxelBox({centerLon:t.centerLon,centerLat:t.centerLat,centerAlt:t.centerAlt,cellSizeX:t.cellSizeX,cellSizeY:t.cellSizeY,boxHeight:t.boxHeight,color:t.color,opacity:t.opacity,shouldShowOutline:t.shouldShowOutline,outlineColor:t.outlineColor,outlineWidth:t.outlineWidth,voxelInfo:t.voxelInfo,voxelKey:e,emulateThick:t.emulateThick}),t.shouldShowInsetOutline&&this.geometryRenderer.shouldApplyInsetOutline(t.isTopN))try{const i=this.options.outlineInset>0?this.options.outlineInset:1;this.geometryRenderer.createInsetOutline({centerLon:t.centerLon,centerLat:t.centerLat,centerAlt:t.centerAlt,baseSizeX:t.cellSizeX,baseSizeY:t.cellSizeY,baseSizeZ:t.boxHeight,outlineColor:t.outlineColor,outlineWidth:Math.max(t.outlineWidth,1),voxelKey:e,insetAmount:i})}catch(e){c.warn("Failed to create inset outline:",e)}if(("emulation-only"===this.options.outlineRenderMode||this.options.emulationScope&&"off"!==this.options.emulationScope)&&t.emulateThick)try{this.geometryRenderer.createEdgePolylines({centerLon:t.centerLon,centerLat:t.centerLat,centerAlt:t.centerAlt,cellSizeX:t.cellSizeX,cellSizeY:t.cellSizeY,boxHeight:t.boxHeight,outlineColor:t.outlineColor,outlineWidth:Math.max(t.outlineWidth,1),voxelKey:e})}catch(e){c.warn("Failed to add emulated thick outline polylines:",e)}}interpolateColor(e,t=null){return O.calculateColor(e,t,this.options)}clear(){this.geometryRenderer.clear()}_shouldShowBounds(){return!!this.options.debug&&("boolean"==typeof this.options.debug?this.options.debug:"object"==typeof this.options.debug&&null!==this.options.debug&&!0===this.options.debug.showBounds)}setVisible(e){c.debug("VoxelRenderer.setVisible:",e),this.voxelEntities.forEach(t=>{!t||t.isDestroyed&&t.isDestroyed()||(t.show=e)})}_selectVoxelsForRendering(e,t,i,n){const o=this.voxelSelector.selectVoxels(e,t,{grid:n,bounds:i});return this._selectionStats=this.voxelSelector.getLastSelectionStats(),o}getSelectionStats(){return this._selectionStats||null}}class N{constructor(e={}){this.options={position:"top-right",fpsAveragingWindowMs:1e3,autoUpdate:!0,...e},this.element=null,this.isVisible=!1,this.updateInterval=null,this.frameTimeHistory=[],this.lastUpdateTime=Date.now(),this._createOverlay()}_createOverlay(){this.element=document.createElement("div"),this.element.id="cesium-heatbox-perf-overlay",this.element.style.cssText=`\n position: absolute;\n ${this._getPositionStyles()}\n background: rgba(0, 0, 0, 0.8);\n color: #fff;\n padding: 10px;\n border-radius: 5px;\n font-family: 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.4;\n z-index: 1000;\n min-width: 200px;\n user-select: none;\n pointer-events: auto;\n display: none;\n `;const e=document.createElement("button");e.textContent="×",e.style.cssText="\n position: absolute;\n top: 2px;\n right: 5px;\n background: none;\n border: none;\n color: #fff;\n font-size: 16px;\n cursor: pointer;\n padding: 0;\n width: 20px;\n height: 20px;\n ",e.onclick=()=>this.hide(),this.element.appendChild(e),this.contentElement=document.createElement("div"),this.contentElement.style.marginTop="15px",this.element.appendChild(this.contentElement),document.body.appendChild(this.element)}_getPositionStyles(){const e={"top-left":"top: 10px; left: 10px;","top-right":"top: 10px; right: 10px;","bottom-left":"bottom: 10px; left: 10px;","bottom-right":"bottom: 10px; right: 10px;"};return e[this.options.position]||e["top-right"]}show(){this.element&&(this.element.style.display="block",this.isVisible=!0,this.options.autoUpdate&&this.startAutoUpdate())}hide(){this.element&&(this.element.style.display="none",this.isVisible=!1,this.stopAutoUpdate())}toggle(){this.isVisible?this.hide():this.show()}update(e,t){if(!this.contentElement||!this.isVisible)return;void 0!==t&&this._trackFrameTime(t);const i=this._calculateFPS(),n=this._formatStats(e,i,t);this.contentElement.innerHTML=n}_trackFrameTime(e){const t=Date.now();this.frameTimeHistory.push({time:t,frameTime:e});const i=t-this.options.fpsAveragingWindowMs;this.frameTimeHistory=this.frameTimeHistory.filter(e=>e.time>i)}_calculateFPS(){if(this.frameTimeHistory.length<2)return 0;const e=this.frameTimeHistory.reduce((e,t)=>e+t.frameTime,0)/this.frameTimeHistory.length;return e>0?Math.round(1e3/e):0}_formatStats(e,t,i){const n=[];if(n.push('<div style="font-weight: bold; color: #4CAF50;">🚀 Performance Stats</div>'),n.push(""),t>0){const e=t>=30?"#4CAF50":t>=15?"#FF9800":"#F44336";n.push(`<div style="color: ${e};">FPS: ${t}</div>`)}if(void 0!==i){const e=i<=33?"#4CAF50":i<=66?"#FF9800":"#F44336";n.push(`<div style="color: ${e};">Frame: ${i.toFixed(1)}ms</div>`)}if(n.push(""),e){if(n.push('<div style="font-weight: bold;">Voxels:</div>'),n.push(` Total: ${e.totalVoxels||0}`),n.push(` Rendered: ${e.renderedVoxels||0}`),e.totalVoxels>0){const t=((e.renderedVoxels||0)/e.totalVoxels*100).toFixed(1);n.push(` Ratio: ${t}%`)}if(e.topNCount&&n.push(` TopN: ${e.topNCount}`),n.push(""),e.selectionStrategy&&(n.push('<div style="font-weight: bold;">Strategy:</div>'),n.push(` Selection: ${e.selectionStrategy}`),void 0!==e.coverageRatio&&n.push(` Coverage: ${(100*e.coverageRatio).toFixed(1)}%`),e.renderBudgetTier&&n.push(` Budget Tier: ${e.renderBudgetTier}`),n.push("")),void 0!==e.renderTimeMs){const t=e.renderTimeMs<=50?"#4CAF50":e.renderTimeMs<=100?"#FF9800":"#F44336";n.push(`<div style="color: ${t};">Render Time: ${e.renderTimeMs.toFixed(1)}ms</div>`)}if(void 0!==e.memoryUsageMB){const t=e.memoryUsageMB<=50?"#4CAF50":e.memoryUsageMB<=100?"#FF9800":"#F44336";n.push(`<div style="color: ${t};">Memory: ${e.memoryUsageMB.toFixed(1)}MB</div>`)}}return n.join("<br>")}startAutoUpdate(){this.stopAutoUpdate(),this.updateInterval=setInterval(()=>{},100)}stopAutoUpdate(){this.updateInterval&&(clearInterval(this.updateInterval),this.updateInterval=null)}destroy(){this.stopAutoUpdate(),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.contentElement=null}}const $=class{constructor(e,t={}){if(!function(e){if(!e)return!1;if(!e.scene||!e.entities||!e.scene.canvas)return!1;const t=e.scene.canvas;return!!(t.getContext("webgl2")||t.getContext("webgl")||t.getContext("experimental-webgl"))}(e))throw new Error("CesiumJS Viewerが無効です");this.viewer=e;let i={...t||{}};i.profile&&g().includes(i.profile)&&(i=y(i.profile,i),delete i.profile);const n={...s,...i};this.options=b(function(e){if("auto"!==e.renderBudgetMode&&"auto"!==e.maxRenderVoxels)return e;const t=function(){try{const e=function(){try{const e=document.createElement("canvas"),t=e.getContext("webgl2")||e.getContext("webgl");if(!t)return{webgl2:!1,maxTextureSize:0,maxRenderbufferSize:0};const i={webgl2:!!e.getContext("webgl2"),maxTextureSize:t.getParameter(t.MAX_TEXTURE_SIZE),maxRenderbufferSize:t.getParameter(t.MAX_RENDERBUFFER_SIZE)};return e.remove(),i}catch(e){return c.warn("WebGL info detection failed:",e),{webgl2:!1,maxTextureSize:0,maxRenderbufferSize:0}}}(),t=function(){try{return{deviceMemory:navigator.deviceMemory||null,hardwareConcurrency:navigator.hardwareConcurrency||null,devicePixelRatio:window.devicePixelRatio||1,screenPixels:screen.width*screen.height*Math.pow(window.devicePixelRatio||1,2),userAgent:navigator.userAgent}}catch(e){return c.warn("Device info detection failed:",e),{deviceMemory:null,hardwareConcurrency:null,devicePixelRatio:1,screenPixels:2073600,userAgent:""}}}();let i="mid",n="fallback";if(null!==t.deviceMemory)i=t.deviceMemory<=4?"low":t.deviceMemory<=8?"mid":"high",n="deviceMemory";else if(null!==t.hardwareConcurrency){const e=t.hardwareConcurrency*Math.min(t.screenPixels/2073600,2);i=e<=4?"low":e<=8?"mid":"high",n="hardwareConcurrency+resolution"}(e.maxTextureSize<4096||!e.webgl2)&&(i="high"===i?"mid":"low",n+="+webglLimits");const o=S[i];let a=Math.min(Math.floor((o.min+o.max)/2),r);try{const e=navigator&&navigator.userAgent?navigator.userAgent:"",t=/iPhone|iPad|iPod|Android/i.test(e),i=/Safari\//.test(e)&&!/Chrome\//.test(e);(t||i)&&(a=Math.min(a,12e3))}catch(e){}return c.debug(`Device tier detected: ${i} (${n}), maxRenderVoxels: ${a}`),{tier:i,maxRenderVoxels:a,detectionMethod:n,deviceInfo:t,webglInfo:e}}catch(e){return c.warn("Device tier detection failed, using default mid tier:",e),{tier:"mid",maxRenderVoxels:Math.min(25e3,r),detectionMethod:"error-fallback",deviceInfo:null,webglInfo:null}}}(),i={...e,maxRenderVoxels:t.maxRenderVoxels,_autoRenderBudget:{tier:t.tier,detectionMethod:t.detectionMethod,autoMaxRenderVoxels:t.maxRenderVoxels}};return c.info(`Auto Render Budget applied: ${t.tier} tier, maxRenderVoxels: ${t.maxRenderVoxels}`),i}(n)),c.setLogLevel(this.options),this.renderer=new F(this.viewer,this.options),this._bounds=null,this._grid=null,this._voxelData=null,this._statistics=null,this._eventHandler=null,this._performanceOverlay=null,this._lastRenderTime=null,this._overlayLastUpdate=0,this._postRenderListener=null,this._prevFrameTimestamp=null,this._initializeEventListeners(),this.options.performanceOverlay&&this.options.performanceOverlay.enabled&&this._initializePerformanceOverlay()}getEffectiveOptions(){try{return JSON.parse(JSON.stringify(this.options))}catch(e){return{...this.options}}}static listProfiles(){return g()}static getProfileDetails(e){return x(e)}_initializePerformanceOverlay(){if("undefined"==typeof window)return void c.warn("Performance overlay requires browser environment");const e={position:"top-right",fpsAveragingWindowMs:1e3,autoUpdate:!0,updateIntervalMs:500,...this.options.performanceOverlay};this._performanceOverlay=new N(e),e.autoShow&&this._performanceOverlay.show(),c.debug("Performance overlay initialized"),this._hookPerformanceOverlayUpdates()}togglePerformanceOverlay(){return this._performanceOverlay?(this._performanceOverlay.toggle(),this._performanceOverlay.isVisible):(c.warn("Performance overlay not initialized. Set performanceOverlay.enabled: true in options."),!1)}showPerformanceOverlay(){this._performanceOverlay&&this._performanceOverlay.show()}hidePerformanceOverlay(){this._performanceOverlay&&this._performanceOverlay.hide()}setPerformanceOverlayEnabled(e,t={}){if(e)return this._performanceOverlay?(t&&Object.keys(t).length>0&&(this._performanceOverlay.options={...this._performanceOverlay.options,...t}),this._performanceOverlay.show()):(this.options.performanceOverlay={enabled:!0,...this.options.performanceOverlay||{},...t},this._initializePerformanceOverlay()),!0;if(this._performanceOverlay&&this._performanceOverlay.hide(),this._postRenderListener){try{this.viewer.scene.postRender.removeEventListener(this._postRenderListener)}catch(e){c.debug("postRender listener removal failed (non-fatal)")}this._postRenderListener=null}return!1}_estimateMemoryUsage(){try{const e=(1024*(this.renderer?.geometryRenderer?.entities?.length||this.renderer?.voxelEntities?.length||0)+100*(this._voxelData?Object.keys(this._voxelData).length:0))/1048576;return Math.max(.1,e)}catch(e){return 0}}async setData(e){if(v(e))try{if(c.debug("Heatbox.setData - 処理開始:",e.length,"個のエンティティ"),c.debug("Step 1: 境界計算"),this._bounds=R.calculateBounds(e),!this._bounds)return c.error("境界計算に失敗"),void this.clear();c.debug("境界計算完了:",this._bounds);let t=this.options.voxelSize||s.voxelSize,i=null;if(this.options.autoVoxelSize&&!this.options.voxelSize)try{c.debug("自動ボクセルサイズ調整開始");const n={autoVoxelSizeMode:this.options.autoVoxelSizeMode,autoVoxelTargetFill:this.options.autoVoxelTargetFill,maxRenderVoxels:this.options.maxRenderVoxels},o=function(e,t,i={}){try{return"occupancy"===(i.autoVoxelSizeMode||"basic")?function(e,t,i){const n=w(e),o=i.maxRenderVoxels||5e4,a=i.autoVoxelTargetFill||.6;let s=M(e,t);c.debug(`Starting occupancy-based estimation: N=${t}, target=${a}, maxVoxels=${o}`);for(let i=0;i<10;i++){(!Number.isFinite(s)||s<=0)&&(c.warn(`Invalid currentSize detected: ${s}, using fallback`),s=M(e,t),(!Number.isFinite(s)||s<=0)&&(s=5));const r=Math.max(1,Math.ceil(Math.max(0,n.x)/s))*Math.max(1,Math.ceil(Math.max(0,n.y)/s))*Math.max(1,Math.ceil(Math.max(0,n.z)/s));if(!Number.isFinite(r)||r<=0||r>1e9){c.warn(`Invalid totalVoxels calculated: ${r}, breaking iteration`);break}const h=r*(1-Math.exp(-t/r)),d=Math.min(h/o,1);if(c.debug(`Iteration ${i}: size=${s.toFixed(1)}m, totalVoxels=${r}, expectedOccupied=${h.toFixed(0)}, fill=${d.toFixed(3)}`),Math.abs(d-a)<.05){c.debug(`Converged at iteration ${i}: size=${s.toFixed(1)}m, fill=${d.toFixed(3)}`);break}const u=Math.max(.1,Math.min(10,d/a));s*=Math.pow(u,.3),s=Math.max(5,Math.min(l,s))}const r=Math.round(s);return c.info(`Occupancy-based voxel size: ${r}m (target fill: ${a})`),r}(e,t,i):M(e,t)}catch(e){return c.warn("Initial voxel size estimation failed:",e),20}}(this._bounds,e.length,n),a=z.createGrid(this._bounds,o),s=function(e,t){const i={valid:!0,warning:!1,error:null,recommendedSize:null};if(e>r){i.valid=!1,i.error="ボクセル数が上限を超えています";const n=e/r,o=t*Math.pow(Math.max(1,Math.min(1e3,n)),1/3);i.recommendedSize=Math.ceil(Math.max(5,Math.min(l,o)))}else e>3e4&&(i.warning=!0,i.error="推定メモリ使用量が警告値を超えています");return i}(a.totalVoxels,o);!s.valid&&s.recommendedSize?(t=s.recommendedSize,i={enabled:!0,mode:this.options.autoVoxelSizeMode,originalSize:o,finalSize:t,adjusted:!0,reason:`Performance limit exceeded: ${a.totalVoxels} > 50000`},c.info(`Auto-adjusted voxelSize: ${o}m → ${t}m (${a.totalVoxels} voxels)`)):(t=o,i={enabled:!0,mode:this.options.autoVoxelSizeMode,originalSize:o,finalSize:t,adjusted:!1,reason:null},c.info(`Auto-determined voxelSize: ${t}m`))}catch(e){c.warn("Auto voxel size adjustment failed, using default:",e),t=s.voxelSize,i={enabled:!0,adjusted:!1,reason:"Estimation failed, using default size",originalSize:null,finalSize:t}}c.debug("Step 2: グリッド生成 (サイズ:",t,"m)"),this._grid=z.createGrid(this._bounds,t),c.debug("グリッド生成完了:",this._grid),c.debug("Step 3: エンティティ分類"),this._voxelData=V.classifyEntitiesIntoVoxels(e,this._bounds,this._grid),c.debug("エンティティ分類完了:",this._voxelData.size,"個のボクセル"),c.debug("Step 4: 統計計算"),this._statistics=V.calculateStatistics(this._voxelData,this._grid),c.debug("統計情報:",this._statistics),i&&(this._statistics.autoAdjusted=i.adjusted,this._statistics.originalVoxelSize=i.originalSize,this._statistics.finalVoxelSize=i.finalSize,this._statistics.adjustmentReason=i.reason),c.debug("Step 5: 描画");const n="undefined"!=typeof performance&&performance.now?performance.now():Date.now(),o=this.renderer.render(this._voxelData,this._bounds,this._grid,this._statistics),a="undefined"!=typeof performance&&performance.now?performance.now():Date.now();if(this._lastRenderTime=Math.max(0,a-n),this._statistics.renderedVoxels=o,this._statistics.renderTimeMs=this._lastRenderTime,c.info("描画完了 - 実際の描画数:",o),this.options.autoView)try{c.debug("Auto view adjustment triggered"),await this.fitView(),c.debug("Auto view adjustment completed")}catch(e){c.warn("Auto view adjustment failed:",e)}if(c.debug("Heatbox.setData - 処理完了"),this._performanceOverlay&&this._performanceOverlay.isVisible){const e=this.getStatistics()||{};e.renderTimeMs=this._lastRenderTime,e.memoryUsageMB=this._estimateMemoryUsage(),this._performanceOverlay.update(e,void 0)}}catch(e){throw c.error("ヒートマップ作成エラー:",e),this.clear(),e}else this.clear()}async createFromEntities(e){if(!v(e))throw new Error(h);return await this.setData(e),this.getStatistics()}setVisible(e){this.renderer.setVisible(e)}clear(){this.renderer.clear(),this._bounds=null,this._grid=null,this._voxelData=null,this._statistics=null}destroy(){if(this.clear(),this._eventHandler&&!this._eventHandler.isDestroyed()&&this._eventHandler.destroy(),this._postRenderListener){try{this.viewer.scene.postRender.removeEventListener(this._postRenderListener)}catch(e){c.debug("postRender listener removal failed (non-fatal)")}this._postRenderListener=null}if(this._performanceOverlay){try{this._performanceOverlay.destroy()}catch(e){c.debug("overlay destroy failed (non-fatal)")}this._performanceOverlay=null}this._eventHandler=null}dispose(){this.destroy()}getOptions(){return{...this.options}}updateOptions(e){if(this.options=b({...this.options,...e}),this.renderer.options=this.options,this._voxelData){const e=this.renderer.render(this._voxelData,this._bounds,this._grid,this._statistics);this._statistics.renderedVoxels=e}}_initializeEventListeners(){this._eventHandler=new a.ScreenSpaceEventHandler(this.viewer.scene.canvas),this._eventHandler.setInputAction(e=>{const t=this.viewer.scene.pick(e.position);if(a.defined(t)&&t.id&&t.id.properties&&"voxel"===t.id.properties.type){const e=t.id.properties.key,i={x:t.id.properties.x,y:t.id.properties.y,z:t.id.properties.z,count:t.id.properties.count},n=new a.Entity({id:`voxel-${e}`,description:this.renderer.createVoxelDescription(i,e)});this.viewer.selectedEntity=n}},a.ScreenSpaceEventType.LEFT_CLICK)}getStatistics(){if(!this._statistics)return null;const e={...this._statistics},t=this.renderer.getSelectionStats();return t&&(e.selectionStrategy=t.strategy,e.clippedNonEmpty=t.clippedNonEmpty,e.coverageRatio=t.coverageRatio??0),this.options._autoRenderBudget&&(e.renderBudgetTier=this.options._autoRenderBudget.tier,e.autoMaxRenderVoxels=this.options._autoRenderBudget.autoMaxRenderVoxels),"number"==typeof this.options.maxRenderVoxels&&this.options.maxRenderVoxels>0?e.occupancyRatio=Math.min(1,Math.max(0,(e.renderedVoxels||0)/this.options.maxRenderVoxels)):e.occupancyRatio=null,e}getBounds(){return this._bounds}getDebugInfo(){const e={options:{...this.options},bounds:this._bounds,grid:this._grid,statistics:this._statistics};return this.options.autoVoxelSize&&(e.autoVoxelSizeInfo={enabled:this.options.autoVoxelSize,originalSize:this._statistics?.originalVoxelSize,finalSize:this._statistics?.finalVoxelSize,adjusted:this._statistics?.autoAdjusted||!1,reason:this._statistics?.adjustmentReason,dataRange:this._bounds?w(this._bounds):null,estimatedDensity:this._bounds&&this._statistics?this._statistics.totalEntities/(w(this._bounds).x*w(this._bounds).y*w(this._bounds).z):null}),e}_hookPerformanceOverlayUpdates(){if(!this._performanceOverlay||this._postRenderListener)return;const e=this._performanceOverlay.options?.updateIntervalMs??500;this._postRenderListener=()=>{if(!this._performanceOverlay||!this._performanceOverlay.isVisible)return;const t="undefined"!=typeof performance&&performance.now?performance.now():Date.now();let i;if(null!=this._prevFrameTimestamp&&(i=Math.max(0,t-this._prevFrameTimestamp)),this._prevFrameTimestamp=t,t-this._overlayLastUpdate<e)return;this._overlayLastUpdate=t;const n=this.getStatistics()||{};null!=this._lastRenderTime&&(n.renderTimeMs=this._lastRenderTime),n.memoryUsageMB=this._estimateMemoryUsage();try{this._performanceOverlay.update(n,i)}catch(e){}};try{this.viewer.scene.postRender.addEventListener(this._postRenderListener)}catch(e){}}async fitView(e=null,t={}){try{const i=e||this._bounds;if(!i)return void c.warn("No bounds available for fitView");if(!this._isValidBounds(i))return void c.warn("Invalid bounds provided to fitView:",i);const n={...this.options.fitViewOptions,...t};c.debug("fitView called with bounds:",i,"options:",n);const o={...n};return Number.isFinite(o.pitchDegrees)||(o.pitchDegrees=-35),Number.isFinite(o.headingDegrees)||(o.headingDegrees=0),await new Promise(e=>{let t=!1;const n=async()=>{if(!t){t=!0;try{await this._fitByBoundingSphere(i,o)}catch(e){c.warn("fitView (postRender) failed, trying fallback:",e);try{await this.viewer.zoomTo(this.viewer.entities)}catch(e){c.warn("zoomTo fallback failed:",e)}}finally{try{this.viewer.scene.postRender.removeEventListener(n)}catch(e){c.debug("postRender removeEventListener failed (non-fatal):",e)}e()}}};try{this.viewer.scene.postRender.addEventListener(n)}catch(t){c.warn("postRender addEventListener failed:",t),e()}})}catch(e){throw c.error("fitView failed:",e),e}}async _fitByBoundingSphere(e,t){const i=a.Rectangle.fromDegrees(e.minLon,e.minLat,e.maxLon,e.maxLat),n=a.BoundingSphere.fromRectangle3D(i,a.Ellipsoid.WGS84,Math.max(0,e.minAlt||0)),o=a.Math.toRadians(t.headingDegrees??0),s=Math.max(-85,Math.min(-10,t.pitchDegrees??-35)),r=a.Math.toRadians(s),l=Math.max(2.2*n.radius,1e3);await this.viewer.camera.flyToBoundingSphere(n,{duration:1.2,offset:new a.HeadingPitchRange(o,r,l)})}_isValidBounds(e){return e&&"number"==typeof e.minLon&&!isNaN(e.minLon)&&"number"==typeof e.maxLon&&!isNaN(e.maxLon)&&"number"==typeof e.minLat&&!isNaN(e.minLat)&&"number"==typeof e.maxLat&&!isNaN(e.maxLat)&&"number"==typeof e.minAlt&&!isNaN(e.minAlt)&&"number"==typeof e.maxAlt&&!isNaN(e.maxAlt)&&e.minLon<=e.maxLon&&e.minLat<=e.maxLat&&e.minAlt<=e.maxAlt}async _handleMinimalDataRange(e,t,i,n){c.debug("Handling minimal data range");const o=a.Cartesian3.fromDegrees(e,t,i+2e3),s=a.Math.toRadians(n.headingDegrees||n.heading),r=a.Math.toRadians(n.pitchDegrees||n.pitch);return this.viewer.camera.flyTo({destination:o,orientation:{heading:s,pitch:r,roll:0},duration:1.5})}async _handleLargeDataRange(e,t){c.debug("Handling large data range with bounding sphere");const i=(e.minLon+e.maxLon)/2,n=(e.minLat+e.maxLat)/2,o=(e.minAlt+e.maxAlt)/2,s=w(e),r=Math.max(s.x,s.y,s.z),l=new a.BoundingSphere(a.Cartesian3.fromDegrees(i,n,o),r/2),h=a.Math.toRadians(t.headingDegrees||t.heading),d=a.Math.toRadians(t.pitchDegrees||t.pitch);return this.viewer.camera.flyToBoundingSphere(l,{duration:2.5,offset:new a.HeadingPitchRange(h,d,0)})}_calculateOptimalCameraHeight(e,t,i){if("auto"!==i.altitudeStrategy)return i.altitude||5e3;try{const n=a.Math.toRadians(i.pitchDegrees||i.pitch),o=this.viewer.camera.frustum.fovy||a.Math.toRadians(60),s=(e+t)/(2*Math.tan(o/2)),r=Math.abs(n);let l=s*Math.max(.5,Math.sin(Math.PI/2-r)+.3);const h=e/Math.min(e,100);h>5&&(l*=Math.log10(h)+1);const d=Math.max(500,.1*e),u=Math.min(1e5,10*e);return l=Math.max(d,Math.min(u,l)),c.debug(`Camera height calculated: ${l.toFixed(0)}m (range: ${e.toFixed(0)}m, pitch: ${i.pitchDegrees||i.pitch}°)`),l}catch(t){return c.warn("Camera height calculation failed, using fallback:",t),Math.max(2e3,2*e)}}async _executeCameraMovement(e,t,i,n,o,s,r){try{const l=a.Cartesian3.fromDegrees(e,t,i+n),h=a.Math.toRadians(o.headingDegrees||o.heading),d=a.Math.toRadians(o.pitchDegrees||o.pitch),u={heading:h,pitch:d,roll:0};c.debug(`Camera target: position=${e.toFixed(6)},${t.toFixed(6)},${(i+n).toFixed(0)}, heading=${o.headingDegrees||o.heading}°, pitch=${o.pitchDegrees||o.pitch}°`);const m=Math.max(1,Math.min(3,.8*Math.log10(s))),p=this.viewer.camera.flyTo({destination:l,orientation:u,duration:m,complete:()=>{c.debug("fitView camera movement completed")},cancel:()=>{c.debug("fitView camera movement cancelled")}});if(p)await p;else{c.debug("Using fallback: flyToBoundingSphere");const n=new a.BoundingSphere(a.Cartesian3.fromDegrees(e,t,i),s/2+r);await this.viewer.camera.flyToBoundingSphere(n,{duration:m,offset:new a.HeadingPitchRange(h,d,0)})}c.info("fitView completed successfully")}catch(e){throw c.error("Camera movement execution failed:",e),e}}static filterEntities(e,t){return Array.isArray(e)&&"function"==typeof t?e.filter(t):[]}};return c.info("CesiumJS Heatbox v0.1.13 loaded"),o.default})());
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("cesium")):"function"==typeof define&&define.amd?define(["cesium"],t):"object"==typeof exports?exports.CesiumHeatbox=t(require("cesium")):e.CesiumHeatbox=t(e.Cesium)}(this,e=>(()=>{"use strict";var t={50:t=>{t.exports=e}},i={};function n(e){var o=i[e];if(void 0!==o)return o.exports;var a=i[e]={exports:{}};return t[e](a,a.exports,n),a.exports}n.d=(e,t)=>{for(var i in t)n.o(t,i)&&!n.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var o={};n.d(o,{default:()=>$});var a=n(50);const s={voxelSize:20,opacity:.8,emptyOpacity:.03,showOutline:!0,showEmptyVoxels:!1,minColor:[0,32,255],maxColor:[255,64,0],maxRenderVoxels:5e4,batchMode:"auto",debug:!1,autoVoxelSize:!1,colorMap:"custom",diverging:!1,divergingPivot:0,highlightTopN:null,highlightStyle:{outlineWidth:4,boostOpacity:.2},voxelGap:0,outlineOpacity:1,outlineWidthResolver:null,outlineEmulation:"off",outlineInset:0,outlineInsetMode:"all",enableThickFrames:!1,outlineRenderMode:"standard",emulationScope:"off",adaptiveOutlines:!1,outlineWidthPreset:"medium",boxOpacityResolver:null,outlineOpacityResolver:null,adaptiveParams:{neighborhoodRadius:50,densityThreshold:5,cameraDistanceFactor:1,overlapRiskFactor:.3},renderLimitStrategy:"density",minCoverageRatio:.2,coverageBinsXY:"auto",autoVoxelSizeMode:"basic",autoVoxelTargetFill:.6,renderBudgetMode:"manual",autoView:!1,fitViewOptions:{paddingPercent:.1,pitchDegrees:-30,headingDegrees:0,altitudeStrategy:"auto"}},r=5e4,l=1e3,h=(Math.PI,"対象エンティティがありません");let d="undefined"!=typeof process&&process.env&&"true"===process.env.DEBUG?3:"undefined"!=typeof process&&process.env?1:3;const c={error(...e){d>=0&&console.error("[Heatbox ERROR]",...e)},warn(...e){d>=1&&console.warn("[Heatbox WARN]",...e)},info(...e){d>=2&&console.log("[Heatbox INFO]",...e)},debug(...e){d>=3&&console.log("[Heatbox DEBUG]",...e)},setLogLevel:e=>(e&&void 0!==e.debug&&("boolean"==typeof e.debug?d=e.debug?3:1:"object"==typeof e.debug&&null!==e.debug&&(d=3)),d)},u=(c.debug,c.warn,c.error,c.info,new Set);function m(e,t){u.has(e)||(u.add(e),c.warn(t))}const p={"mobile-fast":{maxRenderVoxels:5e3,outlineRenderMode:"emulation-only",adaptiveOutlines:!1,outlineWidthPreset:"thin",opacity:.7,renderLimitStrategy:"density",minCoverageRatio:.1,topNHighlight:10,description:"Mobile devices - prioritizes performance over visual quality"},"desktop-balanced":{maxRenderVoxels:15e3,outlineRenderMode:"standard",adaptiveOutlines:!0,outlineWidthPreset:"medium",opacity:.8,renderLimitStrategy:"hybrid",minCoverageRatio:.2,topNHighlight:20,adaptiveParams:{outlineWidthRange:[1,4],outlineOpacityRange:[.4,1],boxOpacityRange:[.2,.8]},description:"Desktop environments - balanced performance and quality"},"dense-data":{maxRenderVoxels:25e3,outlineRenderMode:"inset",adaptiveOutlines:!0,outlineWidthPreset:"thin",opacity:.6,renderLimitStrategy:"hybrid",minCoverageRatio:.3,topNHighlight:30,outlineInset:.5,highlightTopN:!0,highlightStyle:{boostOpacity:.3,boostOutlineWidth:1.5},description:"High-density datasets - optimized for cluttered environments"},"sparse-data":{maxRenderVoxels:8e3,outlineRenderMode:"standard",adaptiveOutlines:!1,outlineWidthPreset:"thick",opacity:.9,renderLimitStrategy:"coverage",minCoverageRatio:.8,topNHighlight:50,emptyOpacity:.05,showEmptyVoxels:!0,description:"Sparse datasets - emphasizes visibility and coverage"}};function g(){return Object.keys(p)}function x(e){return p[e]||null}function y(e,t={}){const i=x(e);if(!i)return t;const{description:n,...o}=i;return f(o,t)}function f(e,t){const i={...e};for(const e in t)Object.prototype.hasOwnProperty.call(t,e)&&(t[e]&&"object"==typeof t[e]&&!Array.isArray(t[e])?i[e]=f(i[e]||{},t[e]):i[e]=t[e]);return i}function v(e){return!!Array.isArray(e)&&0!==e.length&&(e.length>5e3&&c.warn(`エンティティ数が推奨値(5000)を超えています: ${e.length}`),!0)}function b(e={}){let t=e;var i;e.profile&&"none"!==e.profile&&("string"==typeof(i=e.profile)&&Object.prototype.hasOwnProperty.call(p,i)?(c.debug(`Applying profile: ${e.profile}`),t=y(e.profile,e),delete t.profile):c.warn(`Invalid profile name: ${e.profile}. Available profiles: mobile-fast, desktop-balanced, dense-data, sparse-data`));const n={...t};if(n.batchMode&&n.debug&&c.warn("batchMode option is deprecated and will be removed in v1.0.0. It is currently ignored."),void 0!==n.voxelSize&&("number"!=typeof(o=n.voxelSize)||isNaN(o)||o<5||o>l))throw new Error(`ボクセルサイズが無効です: ${n.voxelSize}`);var o;if(void 0!==n.opacity&&(n.opacity=Math.max(0,Math.min(1,n.opacity))),void 0!==n.emptyOpacity&&(n.emptyOpacity=Math.max(0,Math.min(1,n.emptyOpacity))),n.minColor&&Array.isArray(n.minColor)&&3===n.minColor.length&&(n.minColor=n.minColor.map(e=>Math.max(0,Math.min(255,Math.floor(e))))),n.maxColor&&Array.isArray(n.maxColor)&&3===n.maxColor.length&&(n.maxColor=n.maxColor.map(e=>Math.max(0,Math.min(255,Math.floor(e))))),void 0!==n.colorMap&&(["custom","viridis","inferno"].includes(n.colorMap)||(c.warn(`Invalid colorMap: ${n.colorMap}. Using 'custom'.`),n.colorMap="custom")),void 0!==n.highlightTopN&&null!==n.highlightTopN&&("number"!=typeof n.highlightTopN||n.highlightTopN<=0)&&(c.warn(`Invalid highlightTopN: ${n.highlightTopN}. Must be a positive number.`),n.highlightTopN=null),void 0!==n.voxelGap&&(n.voxelGap=Math.max(0,Math.min(100,parseFloat(n.voxelGap)||0))),void 0!==n.outlineOpacity&&(n.outlineOpacity=Math.max(0,Math.min(1,parseFloat(n.outlineOpacity)||1))),void 0!==n.outlineWidthResolver&&null!==n.outlineWidthResolver&&(m("outlineWidthResolver","[Heatbox][DEPRECATION][v0.2.0] outlineWidthResolver is deprecated; prefer adaptiveOutlines with outlineWidthPreset and adaptiveParams."),"function"!=typeof n.outlineWidthResolver&&(c.warn("outlineWidthResolver must be a function. Ignoring."),n.outlineWidthResolver=null)),void 0!==n.outlineOpacityResolver&&null!==n.outlineOpacityResolver&&(m("outlineOpacityResolver","[Heatbox][DEPRECATION][v0.2.0] outlineOpacityResolver is deprecated; prefer adaptiveOutlines with adaptiveParams.outlineOpacityRange."),"function"!=typeof n.outlineOpacityResolver&&(c.warn("outlineOpacityResolver must be a function. Ignoring."),n.outlineOpacityResolver=null)),void 0!==n.boxOpacityResolver&&null!==n.boxOpacityResolver&&(m("boxOpacityResolver","[Heatbox][DEPRECATION][v0.2.0] boxOpacityResolver is deprecated; prefer adaptiveOutlines with adaptiveParams.boxOpacityRange."),"function"!=typeof n.boxOpacityResolver&&(c.warn("boxOpacityResolver must be a function. Ignoring."),n.boxOpacityResolver=null)),void 0!==n.outlineEmulation&&(void 0===n.outlineRenderMode||"standard"===n.outlineRenderMode)){m("outlineEmulation","[Heatbox][DEPRECATION][v0.2.0] outlineEmulation is deprecated; use outlineRenderMode and emulationScope instead.");const e=n.outlineEmulation;!1===e||"off"===e?(n.outlineRenderMode="standard",n.emulationScope="off"):!0===e||"all"===e?(n.outlineRenderMode="emulation-only",n.emulationScope="all"):"topn"===e?(n.outlineRenderMode="standard",n.emulationScope="topn"):"non-topn"===e?(n.outlineRenderMode="standard",n.emulationScope="non-topn"):(c.warn(`Invalid outlineEmulation: ${e}. Using 'standard' mode.`),n.outlineRenderMode="standard"),delete n.outlineEmulation}if(void 0!==n.outlineWidthPreset){const e=n.outlineWidthPreset,t={uniform:"medium","adaptive-density":"adaptive","topn-focus":"thick"};t[e]&&(m(`outlineWidthPreset.${e}`,`[Heatbox][DEPRECATION][v0.2.0] outlineWidthPreset "${e}" is deprecated; use "${t[e]}".`),n.outlineWidthPreset=t[e])}if(void 0!==n.outlineInset){const e=parseFloat(n.outlineInset);n.outlineInset=isNaN(e)||e<0?0:e}if(void 0!==n.outlineInsetMode){let e=n.outlineInsetMode;"off"===e&&(e="none"),["all","topn","none"].includes(e)?n.outlineInsetMode=e:(c.warn(`Invalid outlineInsetMode: ${n.outlineInsetMode}. Using 'all'.`),n.outlineInsetMode="all")}if(void 0!==n.outlineInset){const e=parseFloat(n.outlineInset);n.outlineInset=Math.max(0,Math.min(100,isNaN(e)?0:e))}if(void 0!==n.outlineInsetMode){let e=n.outlineInsetMode;"off"===e&&(e="none"),["all","topn","none"].includes(e)?n.outlineInsetMode=e:(c.warn(`Invalid outlineInsetMode: ${n.outlineInsetMode}. Using 'all'.`),n.outlineInsetMode="all")}if(void 0!==n.enableThickFrames&&(n.enableThickFrames=Boolean(n.enableThickFrames)),void 0!==n.renderLimitStrategy&&(["density","coverage","hybrid"].includes(n.renderLimitStrategy)||(c.warn(`Invalid renderLimitStrategy: ${n.renderLimitStrategy}. Using 'density'.`),n.renderLimitStrategy="density")),void 0!==n.minCoverageRatio){const e=parseFloat(n.minCoverageRatio);n.minCoverageRatio=isNaN(e)?.2:Math.max(0,Math.min(1,e))}if(void 0!==n.coverageBinsXY){const e=n.coverageBinsXY;if("auto"!==e){const t=parseInt(e,10);!Number.isFinite(t)||t<=0?(c.warn(`Invalid coverageBinsXY: ${e}. Using 'auto'.`),n.coverageBinsXY="auto"):n.coverageBinsXY=t}}if(void 0!==n.autoVoxelSizeMode&&(["basic","occupancy"].includes(n.autoVoxelSizeMode)||(c.warn(`Invalid autoVoxelSizeMode: ${n.autoVoxelSizeMode}. Using 'basic'.`),n.autoVoxelSizeMode="basic")),void 0!==n.autoVoxelTargetFill){const e=parseFloat(n.autoVoxelTargetFill);n.autoVoxelTargetFill=isNaN(e)?.6:Math.max(0,Math.min(1,e))}if(void 0!==n.renderBudgetMode&&(["manual","auto"].includes(n.renderBudgetMode)||(c.warn(`Invalid renderBudgetMode: ${n.renderBudgetMode}. Using 'manual'.`),n.renderBudgetMode="manual")),void 0!==n.fitViewOptions){const e=n.fitViewOptions||{};void 0!==e.pitch&&void 0===e.pitchDegrees&&m("fitViewOptions.pitch","[Heatbox][DEPRECATION][v0.2.0] fitViewOptions.pitch is deprecated; use fitViewOptions.pitchDegrees."),void 0!==e.heading&&void 0===e.headingDegrees&&m("fitViewOptions.heading","[Heatbox][DEPRECATION][v0.2.0] fitViewOptions.heading is deprecated; use fitViewOptions.headingDegrees.");const t=parseFloat(e.paddingPercent),i=void 0!==e.pitchDegrees?parseFloat(e.pitchDegrees):parseFloat(e.pitch),o=void 0!==e.headingDegrees?parseFloat(e.headingDegrees):parseFloat(e.heading),a=e.altitudeStrategy;n.fitViewOptions={paddingPercent:Number.isFinite(t)?Math.max(0,Math.min(1,t)):.1,pitchDegrees:Number.isFinite(i)?Math.max(-90,Math.min(0,i)):-30,headingDegrees:Number.isFinite(o)?o:0,altitudeStrategy:"manual"===a?"manual":"auto"}}return n}function M(e,t){const i=w(e),n=i.x*i.y*Math.max(i.z,10),o=t/n;let a;return a=o>.001?Math.max(10,Math.min(20,20/Math.sqrt(1e3*o))):o>1e-4?Math.max(20,Math.min(50,50/Math.sqrt(1e4*o))):Math.max(50,Math.min(100,100/Math.sqrt(1e5*o))),a=Math.max(5,Math.min(l,a)),c.debug(`Basic voxel size estimated: ${a}m (density: ${o}, volume: ${n})`),Math.round(a)}function w(e){try{const t={minLat:Number.isFinite(e.minLat)?Math.max(-90,Math.min(90,e.minLat)):0,maxLat:Number.isFinite(e.maxLat)?Math.max(-90,Math.min(90,e.maxLat)):.1,minLon:Number.isFinite(e.minLon)?Math.max(-180,Math.min(180,e.minLon)):0,maxLon:Number.isFinite(e.maxLon)?Math.max(-180,Math.min(180,e.maxLon)):.1,minAlt:Number.isFinite(e.minAlt)?e.minAlt:0,maxAlt:Number.isFinite(e.maxAlt)?e.maxAlt:100};t.maxLat<=t.minLat&&(t.maxLat=t.minLat+.001),t.maxLon<=t.minLon&&(t.maxLon=t.minLon+.001),t.maxAlt<=t.minAlt&&(t.maxAlt=t.minAlt+1);const i=(t.minLat+t.maxLat)/2,n=Math.cos(Math.max(-Math.PI/2,Math.min(Math.PI/2,i*Math.PI/180))),o=111e3*Math.abs(t.maxLon-t.minLon)*Math.abs(n),a=111e3*Math.abs(t.maxLat-t.minLat),s=Math.abs(t.maxAlt-t.minAlt);return{x:Math.max(1,Math.min(1e6,o)),y:Math.max(1,Math.min(1e6,a)),z:Math.max(1,Math.min(1e4,s))}}catch(e){return c.warn("Data range calculation failed:",e),{x:1e3,y:1e3,z:100}}}const S={low:{min:4e3,max:8e3},mid:{min:8e3,max:15e3},high:{min:15e3,max:25e3}};class R{static calculateBounds(e){if(!Array.isArray(e)||0===e.length)throw new Error("エンティティが提供されていません");let t=1/0,i=-1/0,n=1/0,o=-1/0,s=1/0,r=-1/0,l=0;const h=a.JulianDate.now();if(e.forEach((e,d)=>{try{let d,c,u,m;if(e.position&&(d="function"==typeof e.position.getValue?e.position.getValue(h):e.position),!d)return;if("number"==typeof d?.x&&"number"==typeof d?.y&&Math.abs(d.x)<=360&&Math.abs(d.y)<=90)c=d.x,u=d.y,m="number"==typeof d.z?d.z:0;else{const e=a.Cartographic.fromCartesian(d);if(!e)return;c=a.Math.toDegrees(e.longitude),u=a.Math.toDegrees(e.latitude),m=e.height}t=Math.min(t,c),i=Math.max(i,c),n=Math.min(n,u),o=Math.max(o,u),s=Math.min(s,m),r=Math.max(r,m),l++}catch(e){c.warn(`エンティティ ${d} の処理に失敗:`,e)}}),0===l)throw new Error("有効な位置情報を持つエンティティが見つかりません");return c.debug("座標範囲計算完了:",{validCount:l,bounds:{minLon:t,maxLon:i,minLat:n,maxLat:o,minAlt:s,maxAlt:r}}),{minLon:t,maxLon:i,minLat:n,maxLat:o,minAlt:s,maxAlt:r,centerLon:(t+i)/2,centerLat:(n+o)/2,centerAlt:(s+r)/2}}static voxelIndexToCoordinate(e,t,i,n,o){const{minLon:a,maxLon:s,minLat:r,maxLat:l,minAlt:h,maxAlt:d}=n,{numVoxelsX:c,numVoxelsY:u,numVoxelsZ:m}=o;return{lon:a+(e+.5)/c*(s-a),lat:r+(t+.5)/u*(l-r),alt:h+(i+.5)/m*(d-h)}}static coordinateToCartesian3(e,t,i){return a.Cartesian3.fromDegrees(e,t,i)}}class z{static createGrid(e,t){const i=(e.minLat+e.maxLat)/2,n=111e3*(e.maxLon-e.minLon)*Math.cos(i*Math.PI/180),o=111e3*(e.maxLat-e.minLat),a=e.maxAlt-e.minAlt,s=Math.max(1,Math.ceil(n/t)),r=Math.max(1,Math.ceil(o/t)),l=Math.max(1,Math.ceil(a/t)),h=s>0?n/s:t,d=r>0?o/r:t,u=l>0?Math.max(a/l,1):Math.max(t,1),m=s*r*l;return c.debug("VoxelGrid created:",{numVoxelsX:s,numVoxelsY:r,numVoxelsZ:l,totalVoxels:m,voxelSizeMeters:t,cellSizeX:h,cellSizeY:d,cellSizeZ:u,lonRangeMeters:n,latRangeMeters:o,altRangeMeters:a}),{numVoxelsX:s,numVoxelsY:r,numVoxelsZ:l,totalVoxels:m,voxelSizeMeters:t,cellSizeX:h,cellSizeY:d,cellSizeZ:u,lonRangeMeters:n,latRangeMeters:o,altRangeMeters:a}}static getVoxelKey(e,t,i){return`${e},${t},${i}`}static parseVoxelKey(e){const[t,i,n]=e.split(",").map(Number);return{x:t,y:i,z:n}}static iterateAllVoxels(e,t){const{numVoxelsX:i,numVoxelsY:n,numVoxelsZ:o}=e;for(let e=0;e<i;e++)for(let i=0;i<n;i++)for(let n=0;n<o;n++)t(e,i,n,this.getVoxelKey(e,i,n))}}class V{static classifyEntitiesIntoVoxels(e,t,i){const n=new Map;let o=0,s=0;c.debug(`Processing ${e.length} entities for classification`);const r=a.JulianDate.now();return e.forEach((e,l)=>{try{let l,h,d,c;if(e.position&&(l="function"==typeof e.position.getValue?e.position.getValue(r):e.position),!l)return void s++;if("number"==typeof l?.x&&"number"==typeof l?.y&&Math.abs(l.x)<=360&&Math.abs(l.y)<=90)h=l.x,d=l.y,c="number"==typeof l.z?l.z:0;else if(a.Cartographic&&"function"==typeof a.Cartographic.fromCartesian){const e=a.Cartographic.fromCartesian(l);if(!e)return void s++;h=a.Math.toDegrees(e.longitude),d=a.Math.toDegrees(e.latitude),c=e.height}else{if("number"!=typeof l.x||"number"!=typeof l.y)return void s++;h=l.x,d=l.y,c="number"==typeof l.z?l.z:0}if(h<t.minLon-.001||h>t.maxLon+.001||d<t.minLat-.001||d>t.maxLat+.001||c<t.minAlt-1||c>t.maxAlt+1)return void s++;const u=t.maxLon-t.minLon,m=t.maxLat-t.minLat,p=t.maxAlt-t.minAlt,g=0===u?0:Math.min(i.numVoxelsX-1,Math.floor((h-t.minLon)/u*i.numVoxelsX)),x=0===m?0:Math.min(i.numVoxelsY-1,Math.floor((d-t.minLat)/m*i.numVoxelsY)),y=0===p?0:Math.min(i.numVoxelsZ-1,Math.floor((c-t.minAlt)/p*i.numVoxelsZ));if(g>=0&&g<i.numVoxelsX&&x>=0&&x<i.numVoxelsY&&y>=0&&y<i.numVoxelsZ){const t=z.getVoxelKey(g,x,y);n.has(t)||n.set(t,{x:g,y:x,z:y,entities:[],count:0});const i=n.get(t);i.entities.push(e),i.count++,o++}else s++}catch(e){c.warn(`エンティティ ${l} の処理に失敗:`,e),s++}}),c.info(`${o}個のエンティティを${n.size}個のボクセルに分類(${s}個はスキップ)`),n}static calculateStatistics(e,t){if(0===e.size)return{totalVoxels:t.totalVoxels,renderedVoxels:0,nonEmptyVoxels:0,emptyVoxels:t.totalVoxels,totalEntities:0,minCount:0,maxCount:0,averageCount:0,autoAdjusted:!1,originalVoxelSize:null,finalVoxelSize:null,adjustmentReason:null};const i=Array.from(e.values()).map(e=>e.count),n=i.reduce((e,t)=>e+t,0),o={totalVoxels:t.totalVoxels,renderedVoxels:0,nonEmptyVoxels:e.size,emptyVoxels:t.totalVoxels-e.size,totalEntities:n,minCount:Math.min(...i),maxCount:Math.max(...i),averageCount:n/e.size,autoAdjusted:!1,originalVoxelSize:null,finalVoxelSize:null,adjustmentReason:null};return c.debug("統計情報計算完了:",o),o}static getTopNVoxels(e,t){if(0===e.size||t<=0)return[];const i=Array.from(e.values()).sort((e,t)=>t.count-e.count);return i.slice(0,Math.min(t,i.length))}}const _=Object.freeze({viridis:Object.freeze([[68,1,84],[72,40,120],[62,74,137],[49,104,142],[38,130,142],[31,158,137],[53,183,121],[109,205,89],[180,222,44],[253,231,37]]),inferno:Object.freeze([[0,0,4],[31,12,72],[85,15,109],[136,34,106],[186,54,85],[227,89,51],[249,142,8],[252,187,17],[245,219,76],[252,255,164]]),diverging:Object.freeze([[0,0,255],[32,64,255],[64,128,255],[96,160,255],[128,192,255],[160,224,255],[192,240,255],[224,248,255],[255,255,255],[255,248,224],[255,240,192],[255,224,160],[255,192,128],[255,160,96],[255,128,64],[255,64,32],[255,0,0]])});class O{static calculateColor(e,t=null,i={}){try{Number.isFinite(e)||(c.warn(`Invalid normalizedDensity: ${e}. Using 0.5 as fallback.`),e=.5);const{minColor:n=[0,0,255],maxColor:o=[255,0,0],colorMap:a,diverging:s=!1,divergingPivot:r=0}=i;if(s&&null!==t){const e="number"==typeof r?r:0;return O.calculateDivergingColor(t,{divergingPivot:e})}return a&&"custom"!==a?O.interpolateFromColorMap(e,a):O.interpolateLinear(e,n,o)}catch(e){return c.warn(`Color calculation failed: ${e.message}. Falling back to gray.`),a.Color.GRAY}}static interpolateLinear(e,t,i){const n=Math.max(0,Math.min(1,e)),[o,s,r]=t,[l,h,d]=i,c=Math.round(o+(l-o)*n),u=Math.round(s+(h-s)*n),m=Math.round(r+(d-r)*n);return a.Color.fromBytes(c,u,m)}static interpolateFromColorMap(e,t){const i=_[t];if(!i)return c.warn(`Unknown color map: ${t}. Falling back to linear interpolation.`),O.interpolateLinear(e,[0,0,255],[255,0,0]);const n=Math.max(0,Math.min(1,e))*(i.length-1),o=Math.floor(n),s=Math.min(o+1,i.length-1),r=n-o,[l,h,d]=i[o],[u,m,p]=i[s],g=Math.round(l+(u-l)*r),x=Math.round(h+(m-h)*r),y=Math.round(d+(p-d)*r);return a.Color.fromBytes(g,x,y)}static calculateDivergingColor(e,t={}){const{divergingPivot:i=0}=t,n=i;let o;return 0===n?e<0?(o=1/(1-e)*.5,o=Math.max(0,Math.min(.5,o))):e>0?(o=.5+e/(1+e)*.5,o=Math.max(.5,Math.min(1,o))):o=.5:e<=n?(o=e/n*.5,o=Math.max(0,Math.min(.5,o))):(o=.5+(e-n)/n*.5,o=Math.max(.5,Math.min(1,o))),O.interpolateFromColorMap(o,"diverging")}static getAvailableColorMaps(){return Object.keys(_)}static isValidColorMap(e){return Object.hasOwn(_,e)}}class C{constructor(e={}){this.options={renderLimitStrategy:"density",highlightTopN:0,coverageBinsXY:"auto",minCoverageRatio:.2,...e},this._lastSelectionStats=null,c.debug(`VoxelSelector initialized with strategy: ${this.options.renderLimitStrategy}`)}selectVoxels(e,t,i={}){try{if(!Array.isArray(e)||0===e.length)return c.warn("VoxelSelector: Empty or invalid voxel array provided"),this._createEmptyResult();if(t<=0)return c.warn(`VoxelSelector: Invalid maxCount: ${t}`),this._createEmptyResult();if(e.length<=t)return this._createResult(e,this.options.renderLimitStrategy,e.length,0);const{grid:n}=i,o=this.options.renderLimitStrategy||"density",a=this._identifyTopNVoxels(e);let s;switch(o){case"coverage":s=this._selectByCoverageStrategy(e,t,n,a);break;case"hybrid":s=this._selectByHybridStrategy(e,t,n,a);break;default:s=this._selectByDensityStrategy(e,t,a)}return this._lastSelectionStats={strategy:s.strategy,clippedNonEmpty:s.clippedNonEmpty,coverageRatio:s.coverageRatio||null,selectedCount:s.selectedVoxels.length,totalCount:e.length},c.debug(`VoxelSelector: Applied ${s.strategy} strategy - selected ${s.selectedVoxels.length}/${e.length} voxels`),s}catch(i){return c.error(`VoxelSelector: Selection failed: ${i.message}. Falling back to density strategy.`),this._fallbackToDensitySelection(e,t)}}getLastSelectionStats(){return this._lastSelectionStats}_identifyTopNVoxels(e){const t=new Set;if(this.options.highlightTopN&&this.options.highlightTopN>0){const i=[...e].sort((e,t)=>t.info.count-e.info.count).slice(0,this.options.highlightTopN);i.forEach(e=>t.add(e.key)),c.debug(`VoxelSelector: Identified ${i.length} TopN voxels for forced inclusion`)}return t}_selectByDensityStrategy(e,t,i=new Set){const n=[...e].sort((e,t)=>t.info.count-e.info.count),o=[],a=new Set;n.forEach(e=>{i.has(e.key)&&o.length<t&&(o.push(e),a.add(e.key))}),n.forEach(e=>{!a.has(e.key)&&o.length<t&&(o.push(e),a.add(e.key))});const s=e.length-o.length;return this._createResult(o,"density",o.length,s)}_selectByCoverageStrategy(e,t,i,n=new Set){const o=[],a=new Set;e.forEach(e=>{n.has(e.key)&&o.length<t&&(o.push(e),a.add(e.key))});const s="auto"===this.options.coverageBinsXY?Math.ceil(Math.sqrt(t/4)):this.options.coverageBinsXY,r=new Map;e.filter(e=>!a.has(e.key)).forEach(e=>{const t=`${Math.max(0,Math.min(s-1,Math.floor(e.info.x/Math.max(1,i.numVoxelsX)*s)))},${Math.max(0,Math.min(s-1,Math.floor(e.info.y/Math.max(1,i.numVoxelsY)*s)))}`;r.has(t)||r.set(t,[]),r.get(t).push(e)});const l=Array.from(r.keys());let h=0;for(;o.length<t&&h<10*l.length;){const e=l[h%l.length],t=r.get(e);if(t&&t.length>0){t.sort((e,t)=>t.info.count-e.info.count);const i=t.shift();a.has(i.key)||(o.push(i),a.add(i.key)),0===t.length&&(r.delete(e),l.splice(l.indexOf(e),1))}h++}const d=e.length-o.length;return this._createResult(o,"coverage",o.length,d)}_selectByHybridStrategy(e,t,i,n=new Set){const o=this.options.minCoverageRatio||.2,a=[],s=new Set;e.forEach(e=>{n.has(e.key)&&a.length<t&&(a.push(e),s.add(e.key))});const r=t-a.length,l=Math.floor(r*o),h=r-l;l>0&&this._selectByCoverageStrategy(e.filter(e=>!s.has(e.key)),l,i,new Set).selectedVoxels.forEach(e=>{a.length<t&&!s.has(e.key)&&(a.push(e),s.add(e.key))}),h>0&&this._selectByDensityStrategy(e.filter(e=>!s.has(e.key)),h,new Set).selectedVoxels.forEach(e=>{a.length<t&&!s.has(e.key)&&(a.push(e),s.add(e.key))});const d=l>0?(a.length-n.size-h)/(a.length-n.size):0,c=e.length-a.length;return this._createResult(a,"hybrid",a.length,c,d)}_fallbackToDensitySelection(e,t){try{const i=new Set,n=this._selectByDensityStrategy(e,t,i);return n.strategy="density-fallback",this._lastSelectionStats={strategy:n.strategy,clippedNonEmpty:n.clippedNonEmpty,coverageRatio:null,selectedCount:n.selectedVoxels.length,totalCount:e.length,error:!0},n}catch(e){return c.error(`VoxelSelector: Even fallback failed: ${e.message}`),this._createEmptyResult()}}_createResult(e,t,i,n,o=null){return{selectedVoxels:e,strategy:t,clippedNonEmpty:n,coverageRatio:o}}_createEmptyResult(){return{selectedVoxels:[],strategy:"none",clippedNonEmpty:0,coverageRatio:null}}}class L{constructor(e={}){this.options={...e,adaptiveParams:{neighborhoodRadius:50,densityThreshold:5,cameraDistanceFactor:1,overlapRiskFactor:.3,...e.adaptiveParams}},c.debug("AdaptiveController initialized with options:",this.options)}calculateNeighborhoodDensity(e,t,i=null){if(!t||"function"!=typeof t.get)return{isDenseArea:!1,neighborhoodDensity:0,neighborCount:0};const{x:n,y:o,z:a}=e,s=null!==i?i:Math.max(1,Math.floor(this.options.adaptiveParams.neighborhoodRadius/20));let r=0,l=0;for(let e=-s;e<=s;e++)for(let i=-s;i<=s;i++)for(let h=-s;h<=s;h++){if(0===e&&0===i&&0===h)continue;const s=`${n+e},${o+i},${a+h}`,d=t.get(s);d&&(r+=d.count,l++)}const h=l>0?r/l:0;return{totalDensity:r,neighborCount:l,avgDensity:h,isDenseArea:h>this.options.adaptiveParams.densityThreshold,searchRadius:s}}applyPresetLogic(e,t,i,n,o){let a,s,r;switch(e){case"thin":a=Math.max(1,.8*o.outlineWidth),s=o.opacity,r=o.outlineOpacity||.8;break;case"medium":case"uniform":default:a=o.outlineWidth,s=o.opacity,r=o.outlineOpacity||1;break;case"thick":a=Math.max(1,1.5*o.outlineWidth),s=o.opacity,r=o.outlineOpacity||1;break;case"adaptive":case"adaptive-density":{const e=n?.8+.4*i:1;a=Math.max(1,Math.min(3*o.outlineWidth,o.outlineWidth*e)),s=n?.8*o.opacity:o.opacity,r=n?.6:1;break}case"topn-focus":a=t?Math.max(1,Math.min(3*o.outlineWidth,o.outlineWidth*(1.5+.5*i))):Math.max(1,.8*o.outlineWidth),s=t?o.opacity:.6*o.opacity,r=t?1:.4}return{adaptiveWidth:a,adaptiveBoxOpacity:s,adaptiveOutlineOpacity:r}}calculateAdaptiveParams(e,t,i,n,o){if(!e||!n||!o)return{outlineWidth:null,boxOpacity:null,outlineOpacity:null,shouldUseEmulation:!1};if(!o.adaptiveOutlines)return{outlineWidth:null,boxOpacity:null,outlineOpacity:null,shouldUseEmulation:!1};const{count:a}=e,s=n.maxCount>n.minCount?(a-n.minCount)/(n.maxCount-n.minCount):0,r=this.calculateNeighborhoodDensity(e,i),{isDenseArea:l}=r,h=Math.min(1,1)*this.options.adaptiveParams.cameraDistanceFactor,d=l?this.options.adaptiveParams.overlapRiskFactor:0,c=this.applyPresetLogic(o.outlineWidthPreset,t,s,l,o),u=c.adaptiveWidth*h,m=Math.max(.2,c.adaptiveOutlineOpacity*(1-d));return{outlineWidth:Math.max(1,u),boxOpacity:Math.max(.1,Math.min(1,c.adaptiveBoxOpacity)),outlineOpacity:Math.max(.2,Math.min(1,m)),shouldUseEmulation:l||u>2&&"standard"!==o.outlineRenderMode,_debug:{normalizedDensity:s,neighborhoodResult:r,cameraFactor:h,overlapRisk:d,preset:o.outlineWidthPreset}}}updateOptions(e){this.options={...this.options,...e,adaptiveParams:{...this.options.adaptiveParams,...e.adaptiveParams||{}}},c.debug("AdaptiveController options updated:",this.options)}getConfiguration(){return{...this.options,version:"0.1.11",phase:"ADR-0009 Phase 3"}}}class A{constructor(e,t={}){this.viewer=e,this.options={wireframeOnly:!1,showOutline:!0,outlineWidth:2,outlineInset:0,outlineInsetMode:"all",outlineRenderMode:"standard",enableThickFrames:!1,...t},this.entities=[],c.debug("GeometryRenderer initialized with viewer and options:",this.options)}createVoxelBox(e){const{centerLon:t,centerLat:i,centerAlt:n,cellSizeX:o,cellSizeY:s,boxHeight:r,color:l,opacity:h,shouldShowOutline:d,outlineColor:u,outlineWidth:m,voxelInfo:p,voxelKey:g,emulateThick:x=!1}=e,y=Number.isFinite(t)?Math.max(-180,Math.min(180,t)):0,f=Number.isFinite(i)?Math.max(-90,Math.min(90,i)):0,v=Number.isFinite(n)?Math.max(-1e4,Math.min(1e5,n)):0,b=Number.isFinite(o)&&o>0?Math.min(o,1e6):1,M=Number.isFinite(s)&&s>0?Math.min(s,1e6):1,w=Number.isFinite(r)&&r>0?Math.min(r,1e6):1;y===t&&f===i&&v===n&&b===o&&M===s&&w===r||c.warn(`Clamped invalid geometry values for voxel ${g}:`,{original:{centerLon:t,centerLat:i,centerAlt:n,cellSizeX:o,cellSizeY:s,boxHeight:r},clamped:{safeCenterLon:y,safeCenterLat:f,safeCenterAlt:v,safeCellSizeX:b,safeCellSizeY:M,safeBoxHeight:w}});const S=Boolean(d&&!x),R={dimensions:new a.Cartesian3(b,M,w),outline:S};S&&(R.outlineColor=u,R.outlineWidth=Math.max(m||1,1));const z={position:a.Cartesian3.fromDegrees(y,f,v),box:R,properties:{type:"voxel",key:g,count:p.count,x:p.x,y:p.y,z:p.z},description:this.createVoxelDescription(p,g)};this.options.wireframeOnly?(z.box.material=a.Color.TRANSPARENT,z.box.fill=!1):(z.box.material=l.withAlpha(h),z.box.fill=!0);const V=this.viewer.entities.add(z);return this.entities.push(V),V}createInsetOutline(e){const{centerLon:t,centerLat:i,centerAlt:n,baseSizeX:o,baseSizeY:s,baseSizeZ:r,outlineColor:l,outlineWidth:h,voxelKey:d,insetAmount:u=null}=e,m=Number.isFinite(t)?Math.max(-180,Math.min(180,t)):0,p=Number.isFinite(i)?Math.max(-90,Math.min(90,i)):0,g=Number.isFinite(n)?Math.max(-1e4,Math.min(1e5,n)):0,x=Number.isFinite(o)&&o>0?Math.min(o,1e6):1,y=Number.isFinite(s)&&s>0?Math.min(s,1e6):1,f=Number.isFinite(r)&&r>0?Math.min(r,1e6):1,v=.2*x,b=.2*y,M=.2*f,w=null!==u?u:this.options.outlineInset,S=Math.min(w,v),R=Math.min(w,b),z=Math.min(w,M),V=Math.max(x-2*S,.1*x),_=Math.max(y-2*R,.1*y),O=Math.max(f-2*z,.1*f),C=this.viewer.entities.add({position:a.Cartesian3.fromDegrees(m,p,g),box:{dimensions:new a.Cartesian3(V,_,O),fill:!1,outline:!0,outlineColor:l,outlineWidth:Math.max(h||1,1)},properties:{type:"voxel-inset-outline",parentKey:d,insetSize:{x:V,y:_,z:O}}});return this.entities.push(C),this.options.enableThickFrames&&(S>.1||R>.1||z>.1)&&this.createThickOutlineFrames({centerLon:m,centerLat:p,centerAlt:g,outerX:x,outerY:y,outerZ:f,innerX:V,innerY:_,innerZ:O,frameColor:l,voxelKey:d}),c.debug(`Inset outline created for voxel ${d}:`,{originalSize:{x:o,y:s,z:r},insetSize:{x:V,y:_,z:O},effectiveInset:{x:S,y:R,z}}),C}createThickOutlineFrames(e){const{centerLon:t,centerLat:i,centerAlt:n,outerX:o,outerY:s,outerZ:r,innerX:l,innerY:h,innerZ:d,frameColor:u,voxelKey:m}=e;let p=(o-l)/2,g=(s-h)/2,x=(r-d)/2;const y=.05;if(p<=0||g<=0||x<=0)return c.warn(`Invalid frame thickness for voxel ${m}, skipping thick frames`),[];p=Math.max(p,y),g=Math.max(g,y),x=Math.max(x,y);const f=o/2,v=s/2,b=r/2,M=[],w=[{x:f,z:b,sizeX:p,sizeZ:x},{x:-f,z:b,sizeX:p,sizeZ:x},{x:f,z:-b,sizeX:p,sizeZ:x},{x:-f,z:-b,sizeX:p,sizeZ:x}],S=[{x:f,y:v,sizeX:p,sizeY:g},{x:-f,y:v,sizeX:p,sizeY:g},{x:f,y:-v,sizeX:p,sizeY:g},{x:-f,y:-v,sizeX:p,sizeY:g}];return[{y:v,z:b,sizeY:g,sizeZ:x},{y:-v,z:b,sizeY:g,sizeZ:x},{y:v,z:-b,sizeY:g,sizeZ:x},{y:-v,z:-b,sizeY:g,sizeZ:x}].forEach((e,s)=>{const r=a.Cartesian3.fromDegrees(t,i+e.y/111320,n+e.z),l=this.viewer.entities.add({position:r,box:{dimensions:new a.Cartesian3(o,e.sizeY,e.sizeZ),fill:!0,material:u.withAlpha(.3),outline:!1},properties:{type:"voxel-thick-frame-x",parentKey:m,frameIndex:s}});this.entities.push(l),M.push(l)}),w.forEach((e,o)=>{const r=a.Cartesian3.fromDegrees(t+e.x/(111320*Math.cos(i*Math.PI/180)),i,n+e.z),l=this.viewer.entities.add({position:r,box:{dimensions:new a.Cartesian3(e.sizeX,s,e.sizeZ),fill:!0,material:u.withAlpha(.3),outline:!1},properties:{type:"voxel-thick-frame-y",parentKey:m,frameIndex:o}});this.entities.push(l),M.push(l)}),S.forEach((e,o)=>{const s=a.Cartesian3.fromDegrees(t+e.x/(111320*Math.cos(i*Math.PI/180)),i+e.y/111320,n),l=this.viewer.entities.add({position:s,box:{dimensions:new a.Cartesian3(e.sizeX,e.sizeY,r),fill:!0,material:u.withAlpha(.3),outline:!1},properties:{type:"voxel-thick-frame-z",parentKey:m,frameIndex:o}});this.entities.push(l),M.push(l)}),c.debug(`Created ${M.length} thick frame entities for voxel ${m}`),M}createEdgePolylines(e){const{centerLon:t,centerLat:i,centerAlt:n,cellSizeX:o,cellSizeY:s,boxHeight:r,outlineColor:l,outlineWidth:h,voxelKey:d}=e,u=[],m=Number.isFinite(t)?Math.max(-180,Math.min(180,t)):0,p=Number.isFinite(i)?Math.max(-85,Math.min(85,i)):0,g=Number.isFinite(n)?Math.max(-1e4,Math.min(1e5,n)):0,x=Number.isFinite(o)&&o>0?Math.min(o,1e5):1,y=Number.isFinite(s)&&s>0?Math.min(s,1e5):1,f=Number.isFinite(r)&&r>0?Math.min(r,1e5):1;if(x<.001||y<.001||f<.001)return c.warn(`Dimensions too small for voxel ${d}, skipping edge polylines`),u;const v=x/2,b=y/2,M=f/2,w=Math.cos(p*Math.PI/180),S=v/(111320*Math.max(.1,Math.abs(w))),R=b/111320;if(!Number.isFinite(S)||!Number.isFinite(R)||Math.abs(S)>.1||Math.abs(R)>.1)return c.warn(`Coordinate offsets out of range for voxel ${d}, skipping edge polylines`),u;const z=[[m-S,p-R,g-M],[m+S,p-R,g-M],[m+S,p+R,g-M],[m-S,p+R,g-M],[m-S,p-R,g+M],[m+S,p-R,g+M],[m+S,p+R,g+M],[m-S,p+R,g+M]];if(!z.every(([e,t,i])=>Number.isFinite(e)&&Number.isFinite(t)&&Number.isFinite(i)&&e>=-180&&e<=180&&t>=-85&&t<=85&&i>=-5e4&&i<=5e5))return c.warn(`Invalid vertex coordinates for voxel ${d}, skipping edge polylines`),u;let V;try{V=z.map(([e,t,i])=>a.Cartesian3.fromDegrees(e,t,i))}catch(e){return c.warn(`Failed to create Cartesian3 vertices for voxel ${d}:`,e),u}return V.every(e=>e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.z))?([[0,1],[1,2],[2,3],[3,0],[4,5],[5,6],[6,7],[7,4],[0,4],[1,5],[2,6],[3,7]].forEach((e,t)=>{try{const i=V[e[0]],n=V[e[1]];if(!i||!n)return void c.warn(`Missing vertices for edge ${t} in voxel ${d}`);const o=[i,n];if(2!==o.length)return void c.warn(`Invalid positions array length for edge ${t} in voxel ${d}`);const a=this.viewer.entities.add({polyline:{positions:o,width:Math.max(Math.min(h,20),1),material:l,clampToGround:!1},properties:{type:"voxel-edge-polyline",parentKey:d,edgeIndex:t}});this.entities.push(a),u.push(a)}catch(e){c.warn(`Failed to create polyline for edge ${t} in voxel ${d}:`,e)}}),c.debug(`Created ${u.length} edge polylines for voxel ${d}`),u):(c.warn(`Generated vertices contain invalid values for voxel ${d}, skipping edge polylines`),u)}createVoxelDescription(e,t){return`\n <div style="padding: 10px; font-family: Arial, sans-serif;">\n <h3 style="margin-top: 0;">ボクセル [${e.x}, ${e.y}, ${e.z}]</h3>\n <table style="width: 100%;">\n <tr><td><b>エンティティ数:</b></td><td>${e.count}</td></tr>\n <tr><td><b>ボクセルキー:</b></td><td>${t}</td></tr>\n <tr><td><b>座標:</b></td><td>X=${e.x}, Y=${e.y}, Z=${e.z}</td></tr>\n </table>\n <p style="margin-bottom: 0;">\n <small>v0.1.11 GeometryRenderer</small>\n </p>\n </div>\n `}shouldApplyInsetOutline(e){switch(this.options.outlineInsetMode||"all"){case"topn":return e;case"all":default:return!0;case"none":return!1}}clear(){c.debug("GeometryRenderer.clear - Removing",this.entities.length,"entities"),this.entities.forEach(e=>{try{const t=!(!e||"function"!=typeof e.isDestroyed)&&e.isDestroyed();e&&!t&&this.viewer.entities.remove(e)}catch(e){c.warn("Entity removal error:",e)}}),this.entities=[]}renderBoundingBox(e){if(e)try{const t=(e.minLon+e.maxLon)/2,i=(e.minLat+e.maxLat)/2,n=(e.minAlt+e.maxAlt)/2,o=111e3*(e.maxLon-e.minLon)*Math.cos(i*Math.PI/180),s=111e3*(e.maxLat-e.minLat),r=e.maxAlt-e.minAlt,l=this.viewer.entities.add({position:a.Cartesian3.fromDegrees(t,i,n),box:{dimensions:new a.Cartesian3(o,s,r),material:a.Color.YELLOW.withAlpha(.1),outline:!0,outlineColor:a.Color.YELLOW.withAlpha(.3),outlineWidth:2},description:`Bounding Box<br>Size: ${o.toFixed(1)} x ${s.toFixed(1)} x ${r.toFixed(1)} m`});this.entities.push(l),c.debug("Debug bounding box added:",{center:{lon:t,lat:i,alt:n},size:{width:o,depth:s,height:r}})}catch(e){c.warn("Failed to render bounding box:",e)}}getEntityCount(){return this.entities.length}updateOptions(e){this.options={...this.options,...e},c.debug("GeometryRenderer options updated:",this.options)}getConfiguration(){return{...this.options,entityCount:this.entities.length,version:"0.1.11",phase:"ADR-0009 Phase 4"}}}class F{constructor(e,t={}){this.viewer=e,this.options={minColor:[0,0,255],maxColor:[255,0,0],opacity:.8,emptyOpacity:.03,showOutline:!0,showEmptyVoxels:!1,wireframeOnly:!1,heightBased:!1,outlineWidth:2,outlineInset:0,outlineInsetMode:"all",outlineRenderMode:"standard",emulationScope:"off",adaptiveOutlines:!1,outlineWidthPreset:"medium",...t},this.voxelSelector=new C(this.options),this._selectionStats=null,this.adaptiveController=new L(this.options),this.geometryRenderer=new A(this.viewer,this.options),Object.defineProperty(this,"voxelEntities",{get:()=>this.geometryRenderer.entities,enumerable:!0,configurable:!0}),c.debug("VoxelRenderer initialized with options:",this.options)}_calculateAdaptiveParams(e,t,i,n){return this.adaptiveController.calculateAdaptiveParams(e,t,i,n,this.options)}_shouldApplyInsetOutline(e){return this.geometryRenderer.shouldApplyInsetOutline(e)}render(e,t,i,n){this.geometryRenderer.clear(),c.debug("VoxelRenderer.render - Starting render with simplified approach",{voxelDataSize:e.size,bounds:t,grid:i,statistics:n}),this._shouldShowBounds()&&this.geometryRenderer.renderBoundingBox(t);let o=[];const a=new Set;if(this.options.showEmptyVoxels){const t=Math.min(i.totalVoxels,this.options.maxRenderVoxels||1e4);c.debug(`Generating grid for up to ${t} voxels`);for(let n=0;n<i.numVoxelsX;n++){for(let a=0;a<i.numVoxelsY;a++){for(let s=0;s<i.numVoxelsZ;s++){const i=`${n},${a},${s}`,r=e.get(i)||{x:n,y:a,z:s,count:0};if(o.push({key:i,info:r}),o.length>=t){c.debug(`Reached maximum voxel limit of ${t}`);break}}if(o.length>=t)break}if(o.length>=t)break}}else if(o=Array.from(e.entries()).map(([e,t])=>({key:e,info:t})),this.options.maxRenderVoxels&&o.length>this.options.maxRenderVoxels){const e=this._selectVoxelsForRendering(o,this.options.maxRenderVoxels,t,i);o=e.selectedVoxels,this._selectionStats={strategy:e.strategy,clippedNonEmpty:e.clippedNonEmpty,coverageRatio:e.coverageRatio||0},c.debug(`Applied ${e.strategy} strategy: ${o.length} voxels selected, ${e.clippedNonEmpty} clipped`)}this.options.highlightTopN&&this.options.highlightTopN>0&&([...o].sort((e,t)=>t.info.count-e.info.count).slice(0,this.options.highlightTopN).forEach(e=>a.add(e.key)),c.debug(`TopN highlight enabled: ${a.size} voxels will be highlighted`)),c.debug(`Rendering ${o.length} voxels`);let s=0;const r={x:0,y:0,z:0,count:0},l={voxel:r,isTopN:!1,normalizedDensity:0,statistics:n,adaptiveParams:null},h={voxel:r,isTopN:!1,normalizedDensity:0,statistics:n,adaptiveParams:null};return o.forEach(({key:e,info:o})=>{try{s+=this._renderSingleVoxel(e,o,t,i,n,a,r,l,h)}catch(e){c.warn("Error rendering voxel:",e)}}),c.info(`Successfully rendered ${s} voxels`),s}_renderSingleVoxel(e,t,i,n,o,a,s,r,l){const h=a.has(e),d=this._calculateVoxelRenderingParams(t,i,n,o,h,s,r,l);return d?(this._delegateVoxelRendering(e,d),1):0}_calculateVoxelRenderingParams(e,t,i,n,o,a,s,r){if(!(e&&t&&i&&n))return null;const{x:l,y:h,z:d}=e,c=t.minLon+(l+.5)*(t.maxLon-t.minLon)/i.numVoxelsX,u=t.minLat+(h+.5)*(t.maxLat-t.minLat)/i.numVoxelsY,m=t.minAlt+(d+.5)*(t.maxAlt-t.minAlt)/i.numVoxelsZ,p=n.maxCount>n.minCount?(e.count-n.minCount)/(n.maxCount-n.minCount):0,g=this._calculateAdaptiveParams(e,o,null,n),{color:x,opacity:y}=this._calculateColorAndOpacity(e,p,o,g,n,a,r),{cellSizeX:f,cellSizeY:v,boxHeight:b}=this._calculateDimensions(i,p);return{centerLon:c,centerLat:u,centerAlt:m,cellSizeX:f,cellSizeY:v,boxHeight:b,color:x,opacity:y,...this._calculateOutlineProperties(e,o,p,g,n,x,a,s),voxelInfo:e,isTopN:o,adaptiveParams:g}}_calculateColorAndOpacity(e,t,i,n,o,s,r){let l,h;if(0===e.count)l=a.Color.LIGHTGRAY,h=this.options.emptyOpacity;else{if(l=O.calculateColor(t,e.count,this.options),this.options.boxOpacityResolver&&"function"==typeof this.options.boxOpacityResolver){s.x=e.x,s.y=e.y,s.z=e.z,s.count=e.count,r.isTopN=i,r.normalizedDensity=t,r.adaptiveParams=n;try{const e=this.options.boxOpacityResolver(r);h=isNaN(e)?this.options.opacity:Math.max(0,Math.min(1,e))}catch(e){c.warn("boxOpacityResolver error, using fallback:",e),h=n.boxOpacity||this.options.opacity}}else h=n.boxOpacity||this.options.opacity;this.options.highlightTopN&&!i&&(h*=1-(this.options.highlightStyle?.boostOpacity||.2))}return{color:l,opacity:h}}_calculateDimensions(e,t){let i=e.cellSizeX||(e.lonRangeMeters?e.lonRangeMeters/e.numVoxelsX:e.voxelSizeMeters),n=e.cellSizeY||(e.latRangeMeters?e.latRangeMeters/e.numVoxelsY:e.voxelSizeMeters),o=e.cellSizeZ||(e.altRangeMeters?Math.max(e.altRangeMeters/Math.max(e.numVoxelsZ,1),1):Math.max(e.voxelSizeMeters,1));this.options.voxelGap>0&&(i=Math.max(i-this.options.voxelGap,.1*i),n=Math.max(n-this.options.voxelGap,.1*n),o=Math.max(o-this.options.voxelGap,.1*o));let a=o;return this.options.heightBased&&(a=o*(.1+.9*t)),{cellSizeX:i,cellSizeY:n,boxHeight:a}}_calculateOutlineProperties(e,t,i,n,o,a,s,r){let l;if(this.options.outlineWidthResolver&&"function"==typeof this.options.outlineWidthResolver){s.x=e.x,s.y=e.y,s.z=e.z,s.count=e.count,r.isTopN=t,r.normalizedDensity=i,r.adaptiveParams=n;try{l=this.options.outlineWidthResolver(r),isNaN(l)&&(l=n.outlineWidth||this.options.outlineWidth)}catch(e){c.warn("outlineWidthResolver error, using fallback:",e),l=n.outlineWidth||this.options.outlineWidth}}else l=this.options.adaptiveOutlines&&null!==n.outlineWidth?n.outlineWidth:t&&this.options.highlightTopN&&this.options.highlightStyle?.outlineWidth||this.options.outlineWidth;const h=n.outlineOpacity||(this.options.outlineOpacity??1),d=a.withAlpha(h),u=this._determineRenderModeConfig();let m=u.shouldUseEmulationOnly;if(!u.shouldUseEmulationOnly){const e=this.options.emulationScope||"off";"topn"===e?m=t&&(l||1)>1:"non-topn"===e?m=!t&&(l||1)>1:"all"===e?m=(l||1)>1:this.options.adaptiveOutlines&&n.shouldUseEmulation&&(m="off"!==e)}return{shouldShowOutline:u.shouldShowStandardOutline,outlineColor:d,outlineWidth:l||1,shouldShowInsetOutline:u.shouldShowInsetOutline,emulateThick:m}}_determineRenderModeConfig(){let e=!0,t=!1,i=!1;switch(this.options.outlineRenderMode){case"standard":e=this.options.showOutline,t=this.options.outlineInset>0;break;case"inset":e=!1,t=!0;break;case"emulation-only":e=!1,t=!1,i=!0}return{shouldShowStandardOutline:e,shouldShowInsetOutline:t,shouldUseEmulationOnly:i}}_delegateVoxelRendering(e,t){if(this.geometryRenderer.createVoxelBox({centerLon:t.centerLon,centerLat:t.centerLat,centerAlt:t.centerAlt,cellSizeX:t.cellSizeX,cellSizeY:t.cellSizeY,boxHeight:t.boxHeight,color:t.color,opacity:t.opacity,shouldShowOutline:t.shouldShowOutline,outlineColor:t.outlineColor,outlineWidth:t.outlineWidth,voxelInfo:t.voxelInfo,voxelKey:e,emulateThick:t.emulateThick}),t.shouldShowInsetOutline&&this.geometryRenderer.shouldApplyInsetOutline(t.isTopN))try{const i=this.options.outlineInset>0?this.options.outlineInset:1;this.geometryRenderer.createInsetOutline({centerLon:t.centerLon,centerLat:t.centerLat,centerAlt:t.centerAlt,baseSizeX:t.cellSizeX,baseSizeY:t.cellSizeY,baseSizeZ:t.boxHeight,outlineColor:t.outlineColor,outlineWidth:Math.max(t.outlineWidth,1),voxelKey:e,insetAmount:i})}catch(e){c.warn("Failed to create inset outline:",e)}if(("emulation-only"===this.options.outlineRenderMode||this.options.emulationScope&&"off"!==this.options.emulationScope)&&t.emulateThick)try{this.geometryRenderer.createEdgePolylines({centerLon:t.centerLon,centerLat:t.centerLat,centerAlt:t.centerAlt,cellSizeX:t.cellSizeX,cellSizeY:t.cellSizeY,boxHeight:t.boxHeight,outlineColor:t.outlineColor,outlineWidth:Math.max(t.outlineWidth,1),voxelKey:e})}catch(e){c.warn("Failed to add emulated thick outline polylines:",e)}}interpolateColor(e,t=null){return O.calculateColor(e,t,this.options)}clear(){this.geometryRenderer.clear()}_shouldShowBounds(){return!!this.options.debug&&("boolean"==typeof this.options.debug?this.options.debug:"object"==typeof this.options.debug&&null!==this.options.debug&&!0===this.options.debug.showBounds)}setVisible(e){c.debug("VoxelRenderer.setVisible:",e),this.voxelEntities.forEach(t=>{!t||t.isDestroyed&&t.isDestroyed()||(t.show=e)})}_selectVoxelsForRendering(e,t,i,n){const o=this.voxelSelector.selectVoxels(e,t,{grid:n,bounds:i});return this._selectionStats=this.voxelSelector.getLastSelectionStats(),o}getSelectionStats(){return this._selectionStats||null}}class N{constructor(e={}){this.options={position:"top-right",fpsAveragingWindowMs:1e3,autoUpdate:!0,...e},this.element=null,this.isVisible=!1,this.updateInterval=null,this.frameTimeHistory=[],this.lastUpdateTime=Date.now(),this._createOverlay()}_createOverlay(){this.element=document.createElement("div"),this.element.id="cesium-heatbox-perf-overlay",this.element.style.cssText=`\n position: absolute;\n ${this._getPositionStyles()}\n background: rgba(0, 0, 0, 0.8);\n color: #fff;\n padding: 10px;\n border-radius: 5px;\n font-family: 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.4;\n z-index: 1000;\n min-width: 200px;\n user-select: none;\n pointer-events: auto;\n display: none;\n `;const e=document.createElement("button");e.textContent="×",e.style.cssText="\n position: absolute;\n top: 2px;\n right: 5px;\n background: none;\n border: none;\n color: #fff;\n font-size: 16px;\n cursor: pointer;\n padding: 0;\n width: 20px;\n height: 20px;\n ",e.onclick=()=>this.hide(),this.element.appendChild(e),this.contentElement=document.createElement("div"),this.contentElement.style.marginTop="15px",this.element.appendChild(this.contentElement),document.body.appendChild(this.element)}_getPositionStyles(){const e={"top-left":"top: 10px; left: 10px;","top-right":"top: 10px; right: 10px;","bottom-left":"bottom: 10px; left: 10px;","bottom-right":"bottom: 10px; right: 10px;"};return e[this.options.position]||e["top-right"]}show(){this.element&&(this.element.style.display="block",this.isVisible=!0,this.options.autoUpdate&&this.startAutoUpdate())}hide(){this.element&&(this.element.style.display="none",this.isVisible=!1,this.stopAutoUpdate())}toggle(){this.isVisible?this.hide():this.show()}update(e,t){if(!this.contentElement||!this.isVisible)return;void 0!==t&&this._trackFrameTime(t);const i=this._calculateFPS(),n=this._formatStats(e,i,t);this.contentElement.innerHTML=n}_trackFrameTime(e){const t=Date.now();this.frameTimeHistory.push({time:t,frameTime:e});const i=t-this.options.fpsAveragingWindowMs;this.frameTimeHistory=this.frameTimeHistory.filter(e=>e.time>i)}_calculateFPS(){if(this.frameTimeHistory.length<2)return 0;const e=this.frameTimeHistory.reduce((e,t)=>e+t.frameTime,0)/this.frameTimeHistory.length;return e>0?Math.round(1e3/e):0}_formatStats(e,t,i){const n=[];if(n.push('<div style="font-weight: bold; color: #4CAF50;">🚀 Performance Stats</div>'),n.push(""),t>0){const e=t>=30?"#4CAF50":t>=15?"#FF9800":"#F44336";n.push(`<div style="color: ${e};">FPS: ${t}</div>`)}if(void 0!==i){const e=i<=33?"#4CAF50":i<=66?"#FF9800":"#F44336";n.push(`<div style="color: ${e};">Frame: ${i.toFixed(1)}ms</div>`)}if(n.push(""),e){if(n.push('<div style="font-weight: bold;">Voxels:</div>'),n.push(` Total: ${e.totalVoxels||0}`),n.push(` Rendered: ${e.renderedVoxels||0}`),e.totalVoxels>0){const t=((e.renderedVoxels||0)/e.totalVoxels*100).toFixed(1);n.push(` Ratio: ${t}%`)}if(e.topNCount&&n.push(` TopN: ${e.topNCount}`),n.push(""),e.selectionStrategy&&(n.push('<div style="font-weight: bold;">Strategy:</div>'),n.push(` Selection: ${e.selectionStrategy}`),void 0!==e.coverageRatio&&n.push(` Coverage: ${(100*e.coverageRatio).toFixed(1)}%`),e.renderBudgetTier&&n.push(` Budget Tier: ${e.renderBudgetTier}`),n.push("")),void 0!==e.renderTimeMs){const t=e.renderTimeMs<=50?"#4CAF50":e.renderTimeMs<=100?"#FF9800":"#F44336";n.push(`<div style="color: ${t};">Render Time: ${e.renderTimeMs.toFixed(1)}ms</div>`)}if(void 0!==e.memoryUsageMB){const t=e.memoryUsageMB<=50?"#4CAF50":e.memoryUsageMB<=100?"#FF9800":"#F44336";n.push(`<div style="color: ${t};">Memory: ${e.memoryUsageMB.toFixed(1)}MB</div>`)}}return n.join("<br>")}startAutoUpdate(){this.stopAutoUpdate(),this.updateInterval=setInterval(()=>{},100)}stopAutoUpdate(){this.updateInterval&&(clearInterval(this.updateInterval),this.updateInterval=null)}destroy(){this.stopAutoUpdate(),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.contentElement=null}}const $=class{constructor(e,t={}){if(!function(e){if(!e)return!1;if(!e.scene||!e.entities||!e.scene.canvas)return!1;const t=e.scene.canvas;return!!(t.getContext("webgl2")||t.getContext("webgl")||t.getContext("experimental-webgl"))}(e))throw new Error("CesiumJS Viewerが無効です");this.viewer=e;let i={...t||{}};i.profile&&g().includes(i.profile)&&(i=y(i.profile,i),delete i.profile);const n={...s,...i};this.options=b(function(e){if("auto"!==e.renderBudgetMode&&"auto"!==e.maxRenderVoxels)return e;const t=function(){try{const e=function(){try{const e=document.createElement("canvas"),t=e.getContext("webgl2")||e.getContext("webgl");if(!t)return{webgl2:!1,maxTextureSize:0,maxRenderbufferSize:0};const i={webgl2:!!e.getContext("webgl2"),maxTextureSize:t.getParameter(t.MAX_TEXTURE_SIZE),maxRenderbufferSize:t.getParameter(t.MAX_RENDERBUFFER_SIZE)};return e.remove(),i}catch(e){return c.warn("WebGL info detection failed:",e),{webgl2:!1,maxTextureSize:0,maxRenderbufferSize:0}}}(),t=function(){try{return{deviceMemory:navigator.deviceMemory||null,hardwareConcurrency:navigator.hardwareConcurrency||null,devicePixelRatio:window.devicePixelRatio||1,screenPixels:screen.width*screen.height*Math.pow(window.devicePixelRatio||1,2),userAgent:navigator.userAgent}}catch(e){return c.warn("Device info detection failed:",e),{deviceMemory:null,hardwareConcurrency:null,devicePixelRatio:1,screenPixels:2073600,userAgent:""}}}();let i="mid",n="fallback";if(null!==t.deviceMemory)i=t.deviceMemory<=4?"low":t.deviceMemory<=8?"mid":"high",n="deviceMemory";else if(null!==t.hardwareConcurrency){const e=t.hardwareConcurrency*Math.min(t.screenPixels/2073600,2);i=e<=4?"low":e<=8?"mid":"high",n="hardwareConcurrency+resolution"}(e.maxTextureSize<4096||!e.webgl2)&&(i="high"===i?"mid":"low",n+="+webglLimits");const o=S[i];let a=Math.min(Math.floor((o.min+o.max)/2),r);try{const e=navigator&&navigator.userAgent?navigator.userAgent:"",t=/iPhone|iPad|iPod|Android/i.test(e),i=/Safari\//.test(e)&&!/Chrome\//.test(e);(t||i)&&(a=Math.min(a,12e3))}catch(e){}return c.debug(`Device tier detected: ${i} (${n}), maxRenderVoxels: ${a}`),{tier:i,maxRenderVoxels:a,detectionMethod:n,deviceInfo:t,webglInfo:e}}catch(e){return c.warn("Device tier detection failed, using default mid tier:",e),{tier:"mid",maxRenderVoxels:Math.min(25e3,r),detectionMethod:"error-fallback",deviceInfo:null,webglInfo:null}}}(),i={...e,maxRenderVoxels:t.maxRenderVoxels,_autoRenderBudget:{tier:t.tier,detectionMethod:t.detectionMethod,autoMaxRenderVoxels:t.maxRenderVoxels}};return c.info(`Auto Render Budget applied: ${t.tier} tier, maxRenderVoxels: ${t.maxRenderVoxels}`),i}(n)),c.setLogLevel(this.options),this.renderer=new F(this.viewer,this.options),this._bounds=null,this._grid=null,this._voxelData=null,this._statistics=null,this._eventHandler=null,this._performanceOverlay=null,this._lastRenderTime=null,this._overlayLastUpdate=0,this._postRenderListener=null,this._prevFrameTimestamp=null,this._initializeEventListeners(),this.options.performanceOverlay&&this.options.performanceOverlay.enabled&&this._initializePerformanceOverlay()}getEffectiveOptions(){try{return JSON.parse(JSON.stringify(this.options))}catch(e){return{...this.options}}}static listProfiles(){return g()}static getProfileDetails(e){return x(e)}_initializePerformanceOverlay(){if("undefined"==typeof window)return void c.warn("Performance overlay requires browser environment");const e={position:"top-right",fpsAveragingWindowMs:1e3,autoUpdate:!0,updateIntervalMs:500,...this.options.performanceOverlay};this._performanceOverlay=new N(e),e.autoShow&&this._performanceOverlay.show(),c.debug("Performance overlay initialized"),this._hookPerformanceOverlayUpdates()}togglePerformanceOverlay(){return this._performanceOverlay?(this._performanceOverlay.toggle(),this._performanceOverlay.isVisible):(c.warn("Performance overlay not initialized. Set performanceOverlay.enabled: true in options."),!1)}showPerformanceOverlay(){this._performanceOverlay&&this._performanceOverlay.show()}hidePerformanceOverlay(){this._performanceOverlay&&this._performanceOverlay.hide()}setPerformanceOverlayEnabled(e,t={}){if(e)return this._performanceOverlay?(t&&Object.keys(t).length>0&&(this._performanceOverlay.options={...this._performanceOverlay.options,...t}),this._performanceOverlay.show()):(this.options.performanceOverlay={enabled:!0,...this.options.performanceOverlay||{},...t},this._initializePerformanceOverlay()),!0;if(this._performanceOverlay&&this._performanceOverlay.hide(),this._postRenderListener){try{this.viewer.scene.postRender.removeEventListener(this._postRenderListener)}catch(e){c.debug("postRender listener removal failed (non-fatal)")}this._postRenderListener=null}return!1}_estimateMemoryUsage(){try{const e=(1024*(this.renderer?.geometryRenderer?.entities?.length||this.renderer?.voxelEntities?.length||0)+100*(this._voxelData?Object.keys(this._voxelData).length:0))/1048576;return Math.max(.1,e)}catch(e){return 0}}async setData(e){if(v(e))try{if(c.debug("Heatbox.setData - 処理開始:",e.length,"個のエンティティ"),c.debug("Step 1: 境界計算"),this._bounds=R.calculateBounds(e),!this._bounds)return c.error("境界計算に失敗"),void this.clear();c.debug("境界計算完了:",this._bounds);let t=this.options.voxelSize||s.voxelSize,i=null;if(this.options.autoVoxelSize&&!this.options.voxelSize)try{c.debug("自動ボクセルサイズ調整開始");const n={autoVoxelSizeMode:this.options.autoVoxelSizeMode,autoVoxelTargetFill:this.options.autoVoxelTargetFill,maxRenderVoxels:this.options.maxRenderVoxels},o=function(e,t,i={}){try{return"occupancy"===(i.autoVoxelSizeMode||"basic")?function(e,t,i){const n=w(e),o=i.maxRenderVoxels||5e4,a=i.autoVoxelTargetFill||.6;let s=M(e,t);c.debug(`Starting occupancy-based estimation: N=${t}, target=${a}, maxVoxels=${o}`);for(let i=0;i<10;i++){(!Number.isFinite(s)||s<=0)&&(c.warn(`Invalid currentSize detected: ${s}, using fallback`),s=M(e,t),(!Number.isFinite(s)||s<=0)&&(s=5));const r=Math.max(1,Math.ceil(Math.max(0,n.x)/s))*Math.max(1,Math.ceil(Math.max(0,n.y)/s))*Math.max(1,Math.ceil(Math.max(0,n.z)/s));if(!Number.isFinite(r)||r<=0||r>1e9){c.warn(`Invalid totalVoxels calculated: ${r}, breaking iteration`);break}const h=r*(1-Math.exp(-t/r)),d=Math.min(h/o,1);if(c.debug(`Iteration ${i}: size=${s.toFixed(1)}m, totalVoxels=${r}, expectedOccupied=${h.toFixed(0)}, fill=${d.toFixed(3)}`),Math.abs(d-a)<.05){c.debug(`Converged at iteration ${i}: size=${s.toFixed(1)}m, fill=${d.toFixed(3)}`);break}const u=Math.max(.1,Math.min(10,d/a));s*=Math.pow(u,.3),s=Math.max(5,Math.min(l,s))}const r=Math.round(s);return c.info(`Occupancy-based voxel size: ${r}m (target fill: ${a})`),r}(e,t,i):M(e,t)}catch(e){return c.warn("Initial voxel size estimation failed:",e),20}}(this._bounds,e.length,n),a=z.createGrid(this._bounds,o),s=function(e,t){const i={valid:!0,warning:!1,error:null,recommendedSize:null};if(e>r){i.valid=!1,i.error="ボクセル数が上限を超えています";const n=e/r,o=t*Math.pow(Math.max(1,Math.min(1e3,n)),1/3);i.recommendedSize=Math.ceil(Math.max(5,Math.min(l,o)))}else e>3e4&&(i.warning=!0,i.error="推定メモリ使用量が警告値を超えています");return i}(a.totalVoxels,o);!s.valid&&s.recommendedSize?(t=s.recommendedSize,i={enabled:!0,mode:this.options.autoVoxelSizeMode,originalSize:o,finalSize:t,adjusted:!0,reason:`Performance limit exceeded: ${a.totalVoxels} > 50000`},c.info(`Auto-adjusted voxelSize: ${o}m → ${t}m (${a.totalVoxels} voxels)`)):(t=o,i={enabled:!0,mode:this.options.autoVoxelSizeMode,originalSize:o,finalSize:t,adjusted:!1,reason:null},c.info(`Auto-determined voxelSize: ${t}m`))}catch(e){c.warn("Auto voxel size adjustment failed, using default:",e),t=s.voxelSize,i={enabled:!0,adjusted:!1,reason:"Estimation failed, using default size",originalSize:null,finalSize:t}}c.debug("Step 2: グリッド生成 (サイズ:",t,"m)"),this._grid=z.createGrid(this._bounds,t),c.debug("グリッド生成完了:",this._grid),c.debug("Step 3: エンティティ分類"),this._voxelData=V.classifyEntitiesIntoVoxels(e,this._bounds,this._grid),c.debug("エンティティ分類完了:",this._voxelData.size,"個のボクセル"),c.debug("Step 4: 統計計算"),this._statistics=V.calculateStatistics(this._voxelData,this._grid),c.debug("統計情報:",this._statistics),i&&(this._statistics.autoAdjusted=i.adjusted,this._statistics.originalVoxelSize=i.originalSize,this._statistics.finalVoxelSize=i.finalSize,this._statistics.adjustmentReason=i.reason),c.debug("Step 5: 描画");const n="undefined"!=typeof performance&&performance.now?performance.now():Date.now(),o=this.renderer.render(this._voxelData,this._bounds,this._grid,this._statistics),a="undefined"!=typeof performance&&performance.now?performance.now():Date.now();if(this._lastRenderTime=Math.max(0,a-n),this._statistics.renderedVoxels=o,this._statistics.renderTimeMs=this._lastRenderTime,c.info("描画完了 - 実際の描画数:",o),this.options.autoView)try{c.debug("Auto view adjustment triggered"),await this.fitView(),c.debug("Auto view adjustment completed")}catch(e){c.warn("Auto view adjustment failed:",e)}if(c.debug("Heatbox.setData - 処理完了"),this._performanceOverlay&&this._performanceOverlay.isVisible){const e=this.getStatistics()||{};e.renderTimeMs=this._lastRenderTime,e.memoryUsageMB=this._estimateMemoryUsage(),this._performanceOverlay.update(e,void 0)}}catch(e){throw c.error("ヒートマップ作成エラー:",e),this.clear(),e}else this.clear()}async createFromEntities(e){if(!v(e))throw new Error(h);return await this.setData(e),this.getStatistics()}setVisible(e){this.renderer.setVisible(e)}clear(){this.renderer.clear(),this._bounds=null,this._grid=null,this._voxelData=null,this._statistics=null}destroy(){if(this.clear(),this._eventHandler&&!this._eventHandler.isDestroyed()&&this._eventHandler.destroy(),this._postRenderListener){try{this.viewer.scene.postRender.removeEventListener(this._postRenderListener)}catch(e){c.debug("postRender listener removal failed (non-fatal)")}this._postRenderListener=null}if(this._performanceOverlay){try{this._performanceOverlay.destroy()}catch(e){c.debug("overlay destroy failed (non-fatal)")}this._performanceOverlay=null}this._eventHandler=null}dispose(){this.destroy()}getOptions(){return{...this.options}}updateOptions(e){if(this.options=b({...this.options,...e}),this.renderer.options=this.options,this._voxelData){const e=this.renderer.render(this._voxelData,this._bounds,this._grid,this._statistics);this._statistics.renderedVoxels=e}}_initializeEventListeners(){this._eventHandler=new a.ScreenSpaceEventHandler(this.viewer.scene.canvas),this._eventHandler.setInputAction(e=>{const t=this.viewer.scene.pick(e.position);if(a.defined(t)&&t.id&&t.id.properties&&"voxel"===t.id.properties.type){const e=t.id.properties.key,i={x:t.id.properties.x,y:t.id.properties.y,z:t.id.properties.z,count:t.id.properties.count},n=new a.Entity({id:`voxel-${e}`,description:this.renderer.createVoxelDescription(i,e)});this.viewer.selectedEntity=n}},a.ScreenSpaceEventType.LEFT_CLICK)}getStatistics(){if(!this._statistics)return null;const e={...this._statistics},t=this.renderer.getSelectionStats();return t&&(e.selectionStrategy=t.strategy,e.clippedNonEmpty=t.clippedNonEmpty,e.coverageRatio=t.coverageRatio??0),this.options._autoRenderBudget&&(e.renderBudgetTier=this.options._autoRenderBudget.tier,e.autoMaxRenderVoxels=this.options._autoRenderBudget.autoMaxRenderVoxels),"number"==typeof this.options.maxRenderVoxels&&this.options.maxRenderVoxels>0?e.occupancyRatio=Math.min(1,Math.max(0,(e.renderedVoxels||0)/this.options.maxRenderVoxels)):e.occupancyRatio=null,e}getBounds(){return this._bounds}getDebugInfo(){const e={options:{...this.options},bounds:this._bounds,grid:this._grid,statistics:this._statistics};return this.options.autoVoxelSize&&(e.autoVoxelSizeInfo={enabled:this.options.autoVoxelSize,originalSize:this._statistics?.originalVoxelSize,finalSize:this._statistics?.finalVoxelSize,adjusted:this._statistics?.autoAdjusted||!1,reason:this._statistics?.adjustmentReason,dataRange:this._bounds?w(this._bounds):null,estimatedDensity:this._bounds&&this._statistics?this._statistics.totalEntities/(w(this._bounds).x*w(this._bounds).y*w(this._bounds).z):null}),e}_hookPerformanceOverlayUpdates(){if(!this._performanceOverlay||this._postRenderListener)return;const e=this._performanceOverlay.options?.updateIntervalMs??500;this._postRenderListener=()=>{if(!this._performanceOverlay||!this._performanceOverlay.isVisible)return;const t="undefined"!=typeof performance&&performance.now?performance.now():Date.now();let i;if(null!=this._prevFrameTimestamp&&(i=Math.max(0,t-this._prevFrameTimestamp)),this._prevFrameTimestamp=t,t-this._overlayLastUpdate<e)return;this._overlayLastUpdate=t;const n=this.getStatistics()||{};null!=this._lastRenderTime&&(n.renderTimeMs=this._lastRenderTime),n.memoryUsageMB=this._estimateMemoryUsage();try{this._performanceOverlay.update(n,i)}catch(e){}};try{this.viewer.scene.postRender.addEventListener(this._postRenderListener)}catch(e){}}async fitView(e=null,t={}){try{const i=e||this._bounds;if(!i)return void c.warn("No bounds available for fitView");if(!this._isValidBounds(i))return void c.warn("Invalid bounds provided to fitView:",i);const n={...this.options.fitViewOptions,...t};c.debug("fitView called with bounds:",i,"options:",n);const o={...n};return Number.isFinite(o.pitchDegrees)||(o.pitchDegrees=-35),Number.isFinite(o.headingDegrees)||(o.headingDegrees=0),await new Promise(e=>{let t=!1;const n=async()=>{if(!t){t=!0;try{await this._fitByBoundingSphere(i,o)}catch(e){c.warn("fitView (postRender) failed, trying fallback:",e);try{await this.viewer.zoomTo(this.viewer.entities)}catch(e){c.warn("zoomTo fallback failed:",e)}}finally{try{this.viewer.scene.postRender.removeEventListener(n)}catch(e){c.debug("postRender removeEventListener failed (non-fatal):",e)}e()}}};try{this.viewer.scene.postRender.addEventListener(n)}catch(t){c.warn("postRender addEventListener failed:",t),e()}})}catch(e){throw c.error("fitView failed:",e),e}}async _fitByBoundingSphere(e,t){const i=a.Rectangle.fromDegrees(e.minLon,e.minLat,e.maxLon,e.maxLat),n=a.BoundingSphere.fromRectangle3D(i,a.Ellipsoid.WGS84,Math.max(0,e.minAlt||0)),o=a.Math.toRadians(t.headingDegrees??0),s=Math.max(-85,Math.min(-10,t.pitchDegrees??-35)),r=a.Math.toRadians(s),l=Math.max(2.2*n.radius,1e3);await this.viewer.camera.flyToBoundingSphere(n,{duration:1.2,offset:new a.HeadingPitchRange(o,r,l)})}_isValidBounds(e){return e&&"number"==typeof e.minLon&&!isNaN(e.minLon)&&"number"==typeof e.maxLon&&!isNaN(e.maxLon)&&"number"==typeof e.minLat&&!isNaN(e.minLat)&&"number"==typeof e.maxLat&&!isNaN(e.maxLat)&&"number"==typeof e.minAlt&&!isNaN(e.minAlt)&&"number"==typeof e.maxAlt&&!isNaN(e.maxAlt)&&e.minLon<=e.maxLon&&e.minLat<=e.maxLat&&e.minAlt<=e.maxAlt}async _handleMinimalDataRange(e,t,i,n){c.debug("Handling minimal data range");const o=a.Cartesian3.fromDegrees(e,t,i+2e3),s=a.Math.toRadians(n.headingDegrees||n.heading),r=a.Math.toRadians(n.pitchDegrees||n.pitch);return this.viewer.camera.flyTo({destination:o,orientation:{heading:s,pitch:r,roll:0},duration:1.5})}async _handleLargeDataRange(e,t){c.debug("Handling large data range with bounding sphere");const i=(e.minLon+e.maxLon)/2,n=(e.minLat+e.maxLat)/2,o=(e.minAlt+e.maxAlt)/2,s=w(e),r=Math.max(s.x,s.y,s.z),l=new a.BoundingSphere(a.Cartesian3.fromDegrees(i,n,o),r/2),h=a.Math.toRadians(t.headingDegrees||t.heading),d=a.Math.toRadians(t.pitchDegrees||t.pitch);return this.viewer.camera.flyToBoundingSphere(l,{duration:2.5,offset:new a.HeadingPitchRange(h,d,0)})}_calculateOptimalCameraHeight(e,t,i){if("auto"!==i.altitudeStrategy)return i.altitude||5e3;try{const n=a.Math.toRadians(i.pitchDegrees||i.pitch),o=this.viewer.camera.frustum.fovy||a.Math.toRadians(60),s=(e+t)/(2*Math.tan(o/2)),r=Math.abs(n);let l=s*Math.max(.5,Math.sin(Math.PI/2-r)+.3);const h=e/Math.min(e,100);h>5&&(l*=Math.log10(h)+1);const d=Math.max(500,.1*e),u=Math.min(1e5,10*e);return l=Math.max(d,Math.min(u,l)),c.debug(`Camera height calculated: ${l.toFixed(0)}m (range: ${e.toFixed(0)}m, pitch: ${i.pitchDegrees||i.pitch}°)`),l}catch(t){return c.warn("Camera height calculation failed, using fallback:",t),Math.max(2e3,2*e)}}async _executeCameraMovement(e,t,i,n,o,s,r){try{const l=a.Cartesian3.fromDegrees(e,t,i+n),h=a.Math.toRadians(o.headingDegrees||o.heading),d=a.Math.toRadians(o.pitchDegrees||o.pitch),u={heading:h,pitch:d,roll:0};c.debug(`Camera target: position=${e.toFixed(6)},${t.toFixed(6)},${(i+n).toFixed(0)}, heading=${o.headingDegrees||o.heading}°, pitch=${o.pitchDegrees||o.pitch}°`);const m=Math.max(1,Math.min(3,.8*Math.log10(s))),p=this.viewer.camera.flyTo({destination:l,orientation:u,duration:m,complete:()=>{c.debug("fitView camera movement completed")},cancel:()=>{c.debug("fitView camera movement cancelled")}});if(p)await p;else{c.debug("Using fallback: flyToBoundingSphere");const n=new a.BoundingSphere(a.Cartesian3.fromDegrees(e,t,i),s/2+r);await this.viewer.camera.flyToBoundingSphere(n,{duration:m,offset:new a.HeadingPitchRange(h,d,0)})}c.info("fitView completed successfully")}catch(e){throw c.error("Camera movement execution failed:",e),e}}static filterEntities(e,t){return Array.isArray(e)&&"function"==typeof t?e.filter(t):[]}};return c.info("CesiumJS Heatbox v0.1.14 loaded"),o.default})());
2
2
  //# sourceMappingURL=cesium-heatbox.umd.min.js.map