s3m-three 0.3.1 → 0.3.2

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.
@@ -361,7 +361,7 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
361
361
  if ( vSel < 0.5 ) discard;
362
362
  gl_FragColor = vec4( uColor, 1.0 );
363
363
  }
364
- `})),Gr=u({LINE_PRIMITIVE:()=>13,POINT_PRIMITIVE:()=>1,buildTileObjects:()=>si});function Kr(e){return e===13||e===2||e===3}function qr(e){return e===1}function Jr(){return ci||(ci=new t.PointsMaterial({size:2,sizeAttenuation:!1,vertexColors:!0})),ci}function Yr(e){return e===`u8`?1:e===`u16`?2:4}function Xr(e,t){switch(e){case`u8`:return new Uint8Array(t);case`u16`:return new Uint16Array(t);case`u32`:return new Uint32Array(t);default:return new Float32Array(t)}}function Zr(e,t){switch(e){case`u8`:return new Uint8Array(t);case`u16`:return new Uint16Array(t);case`u32`:return new Uint32Array(t);default:return new Float32Array(t)}}function Qr(e){let{data:n,stride:r,offsetInBytes:i,dtype:a=`f32`}=e,o=e.components??e.comp??3,s=Yr(a),c=o*s,l=r??c,u=i??0,d=a===`u8`;if(l===c&&u===0){let e=Xr(a,n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength));return new t.BufferAttribute(e,o,d)}let f=Math.floor(n.byteLength/l),p=Zr(a,f*o),m=new DataView(n.buffer,n.byteOffset,n.byteLength);for(let e=0;e<f;e++){let t=e*l+u;for(let n=0;n<o;n++){let r=t+n*s;p[e*o+n]=a===`u8`?m.getUint8(r):a===`u16`?m.getUint16(r,!0):a===`u32`?m.getUint32(r,!0):m.getFloat32(r,!0)}}return new t.BufferAttribute(p,o,d)}function $r(e){let{indices:n,indexType:r,indexCount:i}=e;if(!n||i===0)return null;let a=Math.floor(n.byteLength/i),o=a===4||a!==2&&(r===1||r===3),s=i*(o?4:2);if(s>n.byteLength)return null;let c=n.buffer.slice(n.byteOffset,n.byteOffset+s),l=o?new Uint32Array(c):new Uint16Array(c);return new t.BufferAttribute(l,1)}function ei(e,n){let r=new Float32Array(n*3);if(!e)return r.fill(1),new t.BufferAttribute(r,3);let i=e.data,a=e.components??4,o=e.dtype===`u8`?1/255:1;for(let e=0;e<n;e++){let t=e*a;r[e*3]=(i[t]??255)*o,r[e*3+1]=(i[t+1]??255)*o,r[e*3+2]=(i[t+2]??255)*o}return new t.BufferAttribute(r,3)}function ti(e){if(!e)return[];if(Array.isArray(e))return e;let t=e,n=t.materials??t.material;return Array.isArray(n)?n:[]}function ni(e){return e?.material??e}function ri(e){return e?.name??e?.id}function ii(e){return(e?.textureStates??e?.textureunitstates??[]).map(e=>e?.textureunitstate??e).filter(e=>!!e)}function ai(e){return e.length===16&&e[0]===1&&e[1]===0&&e[2]===0&&e[3]===0&&e[4]===0&&e[5]===1&&e[6]===0&&e[7]===0&&e[8]===0&&e[9]===0&&e[10]===1&&e[11]===0&&e[12]===0&&e[13]===0&&e[14]===0&&e[15]===1}function oi(e){let n=String(e?.cullMode??``).toUpperCase();return n===`CULL_BACK`||n===`BACKWARD`?t.FrontSide:n===`CULL_FRONT`?t.BackSide:t.DoubleSide}async function si(e,n={}){let r=n.uniforms??Dr(),i=n.textureCache??new Map,a=new t.Group,o=[],s={meshes:0,vertices:0,triangles:0,textures:0,instanced:0,edgeLines:0,skipped:[]},c=new t.LineBasicMaterial({color:new t.Color(n.edgeColor??`#1f2937`),transparent:!0,opacity:.75,depthWrite:!1});a.userData.hasNativeEdges=!1;let l=t=>{let n=e.textures?.[t];return n?.packKey?`${t}#${n.packKey}`:t};for(let[t,n]of Object.entries(e.textures??{})){let e=l(t),r=i.get(e);if(r){let t=r.image;if((t?.width??0)*(t?.height??0)>=(n.width??0)*(n.height??0))continue;i.delete(e)}let{texture:a,decoded:o}=await Tr(n);a?(i.set(e,a),s.textures++):s.skipped.push(`texture ${t} → ${o}`)}let u=ti(e.materials),d=(e,n=!1)=>{let a=ni(u.find(t=>ri(ni(t))===e)),o=ii(a),s=o[0],c=s?i.get(l(ri(s)??s.id??``))??null:null,d=o[1],f=globalThis.__S3M_NO_BAKE===!0,p=n&&d&&!f?i.get(l(ri(d)??d.id??``))??null:null,m=s?.texmodmatrix??s?.matrix;if(c&&Array.isArray(m)&&m.length===16&&!ai(m)&&(c=c.clone(),c.matrixAutoUpdate=!1,c.matrix.set(m[0],m[4],m[12],m[1],m[5],m[13],0,0,1)),c&&s?.addressmode){let e=s.addressmode.u,n=s.addressmode.v;(e!==void 0||n!==void 0)&&(c.matrixAutoUpdate&&(c=c.clone()),e!==void 0&&(c.wrapS=e===0?t.RepeatWrapping:t.ClampToEdgeWrapping),n!==void 0&&(c.wrapT=n===0?t.RepeatWrapping:t.ClampToEdgeWrapping))}let h=a?.diffuse??{r:1,g:1,b:1,a:1},g=a?.alphaMode,_=[s,d].some(e=>/\.water$/i.test(String(ri(e)??e?.id??``))),v=g===`AM_BLEND`||(h.a??1)<.999||a?.transparentsorting===!0||_&&!c,y=typeof a?.shininess==`number`&&a.shininess>0?Math.max(.15,1-a.shininess/128):.95,b=c?.userData?.s3mHasAlpha?Math.max(a?.alphaCutoff??0,.01):0;return Or({uniforms:r,map:c,color:_&&!c?li.clone():new t.Color(h.r??1,h.g??1,h.b??1),side:oi(a),transparent:v,opacity:_&&!c?.86:h.a??1,roughness:_&&!c?.12:y,alphaTest:b,atlas:n&&!!c,secMap:p})},f=new Map,p=new Map;for(let[n,r]of Object.entries(e.geoPackage??{})){let i=r.vertexPackage,a=i.vertexAttributes.find(e=>e.semantic===`position`);if(!a){s.skipped.push(`${n} 无 position`);continue}let o=i.verticesCount||0,c={position:Qr(a)},l=null,u=null;for(let e of i.vertexAttributes)e.divisor===void 0&&e.semantic!==`position`&&(e.semantic===`color`?l=e:e.semantic===`batchId`?u=e:e.semantic===`normal`?c.normal=Qr(e):e.semantic===`uv`?c.uv=Qr(e):e.semantic===`uv2`&&(c.uv1=Qr(e)));c.aColor=ei(l,o),c.aBatchId=u?Qr(u):new t.BufferAttribute(new Float32Array(o).fill(-1),1);let d=e.atlasRects?.[n];if(d){c.aAtlasRect=new t.BufferAttribute(d.uv??new Float32Array(o*4),4);let e=c.uv1;d.uv2&&e?(c.aAtlasRect1=new t.BufferAttribute(d.uv2,4),c.aSecUv=e):(c.aAtlasRect1=new t.BufferAttribute(new Float32Array(o*4),4),c.aSecUv=c.uv??new t.BufferAttribute(new Float32Array(o*2),2))}let m=i.instanceIndex!==-1&&(i.instanceMode===16||i.instanceMode===17),h=r.indexPackages??[];h.length===0&&o>0&&(h=[{indexCount:0,indexType:0,useIndex:0,primitiveType:1,indices:null,passNames:[]}]),p.set(n,{indexPackages:h,instanced:m}),s.vertices+=o,h.forEach((e,r)=>{let i=new t.BufferGeometry;for(let[e,t]of Object.entries(c))i.setAttribute(e,t);let a=$r(e);a?i.setIndex(a):i.setDrawRange(0,o),Kr(e.primitiveType)||qr(e.primitiveType)||i.getAttribute(`normal`)||i.computeVertexNormals(),i.computeBoundingBox(),i.computeBoundingSphere(),f.set(`${n}|${r}`,{geometry:i,pack:e})})}let m=new t.Matrix4,h=new Map,g=(e,n,r)=>{let i=0,a=0,o=!1,s=!1,c=!1,l=!1,u=!1,d=!1;for(let t of e){let e=t.cached.geometry,n=e.attributes.position?.count??0;i+=n,a+=e.index?e.index.count:n,e.attributes.normal&&(o=!0),e.attributes.uv&&(s=!0),e.attributes.uv1&&(c=!0),e.attributes.aColor&&(l=!0),e.attributes.aBatchId&&(u=!0),e.attributes.aAtlasRect&&(d=!0)}let f=new Float32Array(i*3),p=o?new Float32Array(i*3):null,h=s?new Float32Array(i*2):null,g=c?new Float32Array(i*2):null,_=l?new Float32Array(i*3):null,v=u?new Float32Array(i):null,y=d?new Float32Array(i*4):null,b=d?new Float32Array(i*4):null,x=d?new Float32Array(i*2):null,S=(e,t,n,r,i,a)=>{if(t){let a=t.array;for(let t=0;t<r;t++)for(let r=0;r<n;r++)e[(i+t)*n+r]=a[t*n+r]??0}else for(let t=0;t<r;t++){let r=[];a?a(t,r):r.push(...Array(n).fill(0));for(let a=0;a<n;a++)e[(i+t)*n+a]=r[a]??0}},C=new(i>65535?Uint32Array:Uint16Array)(a),w=0,T=0,E=new t.Vector3,ee=new t.Matrix3,te=new Map;for(let t of e){let e=t.cached.geometry,n=e.attributes.position.count,r=t.matrix,i=r&&!r.equals(m);if(i&&o&&ee.getNormalMatrix(r),t.geo.pickInfo)for(let e of Object.values(t.geo.pickInfo))typeof e.batchId==`number`&&e.batchId>=0&&te.set(e.batchId,t.geo);let a=e.attributes.position.array;for(let e=0;e<n;e++){let t=e*3,n=(w+e)*3;i?(E.set(a[t],a[t+1],a[t+2]).applyMatrix4(r),f[n]=E.x,f[n+1]=E.y,f[n+2]=E.z):(f[n]=a[t],f[n+1]=a[t+1],f[n+2]=a[t+2])}if(p){let t=e.attributes.normal;if(t){let e=t.array;for(let t=0;t<n;t++){let n=t*3,r=(w+t)*3;i?(E.set(e[n],e[n+1],e[n+2]).applyMatrix3(ee).normalize(),p[r]=E.x,p[r+1]=E.y,p[r+2]=E.z):(p[r]=e[n],p[r+1]=e[n+1],p[r+2]=e[n+2])}}}if(h){let t=e.attributes.uv;if(t){let e=t.array;for(let t=0;t<n;t++)h[(w+t)*2]=e[t*2],h[(w+t)*2+1]=e[t*2+1]}}if(g){let t=e.attributes.uv1;if(t){let e=t.array;for(let t=0;t<n;t++)g[(w+t)*2]=e[t*2],g[(w+t)*2+1]=e[t*2+1]}}if(_){let t=e.attributes.aColor;if(t){let e=t.array;for(let t=0;t<n;t++)_[(w+t)*3]=e[t*3],_[(w+t)*3+1]=e[t*3+1],_[(w+t)*3+2]=e[t*3+2]}else for(let e=0;e<n;e++)_[(w+e)*3]=1,_[(w+e)*3+1]=1,_[(w+e)*3+2]=1}if(v){let t=e.attributes.aBatchId;if(t){let e=t.array;for(let t=0;t<n;t++)v[w+t]=e[t]}else for(let e=0;e<n;e++)v[w+e]=-1}if(y&&(S(y,e.attributes.aAtlasRect,4,n,w,(e,t)=>t.push(0,0,0,0)),S(b,e.attributes.aAtlasRect1,4,n,w,(e,t)=>t.push(0,0,0,0)),S(x,e.attributes.aSecUv,2,n,w)),e.index){let t=e.index.array,n=e.index.count;for(let e=0;e<n;e++)C[T+e]=t[e]+w;T+=n}else{for(let e=0;e<n;e++)C[T+e]=e+w;T+=n}w+=n}let D=new t.BufferGeometry;D.setAttribute(`position`,new t.BufferAttribute(f,3)),p&&D.setAttribute(`normal`,new t.BufferAttribute(p,3)),h&&D.setAttribute(`uv`,new t.BufferAttribute(h,2)),g&&D.setAttribute(`uv1`,new t.BufferAttribute(g,2)),_&&D.setAttribute(`aColor`,new t.BufferAttribute(_,3)),v&&D.setAttribute(`aBatchId`,new t.BufferAttribute(v,1)),y&&(D.setAttribute(`aAtlasRect`,new t.BufferAttribute(y,4)),D.setAttribute(`aAtlasRect1`,new t.BufferAttribute(b,4)),D.setAttribute(`aSecUv`,new t.BufferAttribute(x,2))),D.setIndex(new t.BufferAttribute(C,1)),D.computeBoundingBox(),D.computeBoundingSphere();let O=new t.Mesh(D,n);return O.userData.skeletonName=e[0].name,O.userData.geoRef=e[0].geo,O.userData.tileRef=r,O.userData.primitiveType=4,O.userData.isBatched=!0,O.userData.batchedCount=e.length,te.size>0&&(O.userData.geoByBatchId=te),O},_=(r,i,l,u)=>{let{geometry:f,pack:h}=r,g=d(h.passNames?.[0],!!f.getAttribute(`aAtlasRect`)),_,v=p.get(i),y=l.vertexPackage;if(Kr(h.primitiveType)){let e=new t.LineSegments(f,c);return e.visible=n.edges===!0,e.renderOrder=2,e.raycast=()=>{},e.userData.isEdgeLines=!0,e.userData.skeletonName=i,u&&!u.equals(m)&&u.decompose(e.position,e.quaternion,e.scale),a.add(e),o.push(e),a.userData.hasNativeEdges=!0,s.edgeLines++,e}if(qr(h.primitiveType)){f.getAttribute(`color`)||f.setAttribute(`color`,f.getAttribute(`aColor`));let n=new t.Points(f,Jr());return n.userData.isPointCloud=!0,n.userData.skeletonName=i,n.userData.geoRef=l,n.userData.tileRef=e,n.userData.primitiveType=h.primitiveType,u&&!u.equals(m)&&u.decompose(n.position,n.quaternion,n.scale),a.add(n),o.push(n),s.meshes++,n}if(v?.instanced&&y.instanceBuffer&&y.instanceCount>0){if(!f.getAttribute(`aInstanceBatchId`)){let e=y.instanceBatchIds,n=e&&e.length===y.instanceCount?e.slice():new Float32Array(y.instanceCount).fill(-1);f.setAttribute(`aInstanceBatchId`,new t.InstancedBufferAttribute(n,1));let r=new Float32Array(y.instanceCount);for(let e=0;e<r.length;e++)r[e]=e;f.setAttribute(`aInstanceIndex`,new t.InstancedBufferAttribute(r,1))}let e=new t.InstancedMesh(f,g,y.instanceCount);e.instanceMatrix.setUsage(t.StaticDrawUsage);let n=new t.Matrix4,r=new t.Color,i=y.instanceMode,a=new Float32Array(y.instanceBuffer.buffer,y.instanceBuffer.byteOffset,y.instanceCount*i);for(let t=0;t<y.instanceCount;t++){let o=t*i;if(n.set(a[o+0],a[o+1],a[o+2],a[o+3],a[o+4],a[o+5],a[o+6],a[o+7],a[o+8],a[o+9],a[o+10],a[o+11],0,0,0,1),e.setMatrixAt(t,n),i>=16){let n=a[o+12],i=a[o+13],s=a[o+14];Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(s)&&(r.setRGB(n,i,s),e.setColorAt(t,r))}}e.instanceMatrix.needsUpdate=!0,e.instanceColor&&(e.instanceColor.needsUpdate=!0),e.frustumCulled=!1,s.instanced++,_=e}else _=new t.Mesh(f,g);return u&&!u.equals(m)&&u.decompose(_.position,_.quaternion,_.scale),_.userData.skeletonName=i,_.userData.geoRef=l,_.userData.tileRef=e,_.userData.primitiveType=h.primitiveType,a.add(_),o.push(_),s.meshes++,h.primitiveType===4&&(s.triangles+=(h.indexCount||0)/3),_},v=0;for(let r of e.groupNode?.pageLods??[])for(let i of r.geodes??[]){let r=i.matrix,a=r&&r.length===16?new t.Matrix4().fromArray(r):null;for(let t of i.skeletonNames??[]){let r=p.get(t);if(!r)continue;let i=e.geoPackage[t];if(!i)continue;let o=i.vertexPackage;for(let e=0;e<r.indexPackages.length;e++){let s=f.get(`${t}|${e}`);if(s){if(Kr(s.pack.primitiveType)||r.instanced&&o.instanceBuffer&&o.instanceCount>0)_(s,t,i,a),v++;else if(n.batching!==!1&&s.pack.primitiveType===4){let e=s.pack.passNames?.[0]??`__default__`,n=h.get(e);n||(n=[],h.set(e,n)),n.push({cached:s,name:t,geo:i,matrix:a}),v++}else _(s,t,i,a),v++}}}}if(v===0)for(let[t,r]of p){let i=e.geoPackage[t];if(!i)continue;let a=i.vertexPackage;for(let e=0;e<r.indexPackages.length;e++){let o=f.get(`${t}|${e}`);if(o){if(Kr(o.pack.primitiveType)||r.instanced&&a.instanceBuffer&&a.instanceCount>0)_(o,t,i,null);else if(n.batching!==!1&&o.pack.primitiveType===4){let e=o.pack.passNames?.[0]??`__default__`,n=h.get(e);n||(n=[],h.set(e,n)),n.push({cached:o,name:t,geo:i,matrix:null})}else _(o,t,i,null)}}}if(h.size>0)for(let[t,n]of h)if(s.originalMeshes=(s.originalMeshes??0)+n.length,n.length===1)_(n[0].cached,n[0].name,n[0].geo,n[0].matrix);else{let r=!!n[0].cached.geometry.getAttribute(`aAtlasRect`),i=g(n,d(t===`__default__`?void 0:t,r),e);a.add(i),o.push(i),s.meshes++;for(let e of n)s.triangles+=(e.cached.pack.indexCount||0)/3}return a.children.length||s.skipped.push(`tile 无可用几何`),{group:a,stats:s,objects:o}}var ci,li,ui=c((()=>{Z(),Wr(),ci=null,li=new t.Color(1920611)}));function di(e){return e.slice(0,e.lastIndexOf(`/`)+1)}function fi(e){if(!e)return e;try{let t=typeof document<`u`?document.baseURI:void 0;return t?new URL(e,t).href:new URL(e).href}catch{return e}}function pi(e,t){if(!t)return null;try{return mi(new URL(t,e).href)}catch{return mi(`${di(e)}${t}`)}}function mi(e){if(!/[+ ]/.test(e))return e;let t=e.indexOf(`#`),n=t<0?``:e.slice(t),r=t<0?e:e.slice(0,t),i=r.indexOf(`?`),a=i<0?r:r.slice(0,i),o=i<0?``:r.slice(i);return`${a.replace(/\+/g,`%2B`).replace(/ /g,`%20`)}${o}${n}`}var hi=110540,gi=111320;function _i(e){if(!e||typeof e!=`object`)return null;let t=e;if(![t.left,t.bottom,t.right,t.top].every(e=>typeof e==`number`&&Number.isFinite(e)))return null;let{left:n,bottom:r,right:i,top:a}=t;return Math.abs(n)>180||Math.abs(i)>180||Math.abs(a)>90||Math.abs(r)>90||i===n&&a===r?null:{left:n,bottom:r,right:i,top:a}}function vi(e,t){if(!t)return null;let n=t.replace(/\.(osgb|s3mb|s3m)$/i,`.s3m`),r=e.split(`/`),i=r.pop()??``,a=r.pop()??``,o=r.lastIndexOf(`datas`);return!i||!a||o<1?pi(di(e),n):mi(`${r[r.length-1]===`path`&&r[r.length-2]===`data`?`${r.join(`/`)}/${a}`:`${r.join(`/`)}/data/path/${a}`}/${n}`)}function yi(e){let t=e.trim();if(t.startsWith(`<`)){let e=e=>{let n=RegExp(`<(?:[a-zA-Z0-9_-]+:)?${e}[^>]*>([^<]+)<\\/`,`i`).exec(t);return n?n[1].trim():null},n=t=>parseFloat(e(t)??``),r=n(`X`)||0,i=n(`Y`)||0,a=n(`Z`)||0,o=n(`Left`),s=n(`Right`),c=n(`Top`),l=n(`Bottom`);if(![o,s,c,l].every(Number.isFinite)){let e=n(`MinX`),t=n(`MaxX`),a=n(`MinY`),u=n(`MaxY`);if([e,t,a,u].every(Number.isFinite)&&r&&i){let n=gi*Math.cos(i*Math.PI/180);n>1e-6&&(o=r+e/n,s=r+t/n,l=i+a/hi,c=i+u/hi)}}let u=t.matchAll(/<(?:[a-zA-Z0-9_-]+:)?FileName[^>]*>([^<]+)<\//gi),d=[];for(let e of u)d.push({url:e[1].trim()});let f=n(`MinHeight`),p=n(`MaxHeight`);return{fileType:e(`FileType`)??void 0,position:{x:r,y:i,z:a,units:`Degree`},geoBounds:{left:o,right:s,top:c,bottom:l},heightRange:Number.isFinite(f)||Number.isFinite(p)?{min:f,max:p}:void 0,rootTiles:d,tiles:d}}return JSON.parse(t)}var bi=class{get heightRange(){let e=this.config?.heightRange;return e&&typeof e.min==`number`&&typeof e.max==`number`?{min:e.min,max:e.max}:null}constructor(e){h(this,`configUrl`,void 0),h(this,`config`,null),h(this,`_blockTileIndex`,null),h(this,`anchor`,{lon:0,lat:0,height:0}),h(this,`rootUrls`,[]),h(this,`nodes`,new Map),h(this,`failed`,new Set),h(this,`textureCache`,new Map),h(this,`pending`,new Set),h(this,`atlasLod`,void 0),h(this,`atlasLodCache`,new Map),h(this,`_groupCache`,new Map),h(this,`externalAtlasCache`,new Map),h(this,`leafRequestCache`,new Map),h(this,`_leafPending`,new Map),h(this,`atlasUpgraded`,new Set),h(this,`atlasUpgradeSkipped`,new Map),h(this,`stats`,{tiles:0,loading:0,failed:0,meshes:0,vertices:0,triangles:0,datasets:1}),h(this,`maxConcurrent`,void 0),h(this,`maxTiles`,void 0),h(this,`lodRangeScale`,void 0),h(this,`_onTile`,void 0),h(this,`_onTileRemoved`,void 0),h(this,`_onError`,void 0),h(this,`_onProgress`,void 0),h(this,`_maxRetries`,void 0),h(this,`_retryCount`,new Map),h(this,`_retryAt`,new Map),h(this,`_parentOf`,new Map),h(this,`_frame`,0),h(this,`_lodDbgOnce`,!1),h(this,`_permanentReported`,!1),h(this,`hardCap`,96),h(this,`isS3MV1`,!1),h(this,`_buildTile`,void 0),h(this,`_uniforms`,void 0),h(this,`_queue`,[]),h(this,`_active`,0),this.configUrl=e.configUrl,this.lodRangeScale=e.lodRangeScale??3,this._onTile=e.onTile??(()=>{}),this._onTileRemoved=e.onTileRemoved??(()=>{}),this._onError=e.onError??(e=>console.warn(e)),this._onProgress=e.onProgress??(()=>{}),this._maxRetries=Math.max(0,e.maxRetries??2),this._buildTile=e.buildTile??null,this._uniforms=e.uniforms??null,this.maxConcurrent=e.maxConcurrent??4,this.maxTiles=e.maxTiles??64,this.hardCap=this.maxTiles+Math.max(8,Math.ceil(this.maxTiles*.5)),this.atlasLod=e.atlasLod!==!1}async init(){this.configUrl=fi(this.configUrl);let e=await fetch(this.configUrl);if(!e.ok)throw Error(`配置读取失败 ${e.status} ${this.configUrl}`);let t=yi(await e.text());this.config=t,this.anchor=this._resolveAnchor(t);let n=t.rootTiles??t.tiles??[];if(!n.length)throw Error(`配置中缺少 root tile`);this.rootUrls.length=0;for(let e of n){let t=pi(this.configUrl,e.url);t&&this.rootUrls.push(t)}if(this.isS3MV1=/OSGB/i.test(String(t.fileType??``))||/OSGB/i.test(String(t.dataType??``))||this.rootUrls.length>0&&this.rootUrls.every(e=>/\.s3m($|\?)/i.test(e)),this.rootUrls.every(e=>/\.s3mblock($|\?)/i.test(e))){this._blockTileIndex=new Set(this.rootUrls);for(let e of n){let t=pi(this.configUrl,e.url);t&&this._blockTileIndex.add(t)}}await this._load(this.rootUrls[0]);for(let e of this.rootUrls.slice(1))this._enqueue(e);return this}_enqueue(e,t){if(!e||(t&&this._parentOf.set(e,t),this.nodes.has(e)||this.pending.has(e)||this.failed.has(e))||this._queue.includes(e))return;let n=this._retryAt.get(e);n!==void 0&&performance.now()<n||this.nodes.size+this.pending.size+this._queue.length>=this.hardCap||(this._queue.push(e),this._pump())}_evictOne(e=!1){let t=this._pickVictim(!1,e)??this._pickVictim(!0,e);if(!t)return!1;let n=t.parentUrl??this._parentOf.get(t.url),r=t.childUrls??(t.childUrl?[t.childUrl]:[]),i=!r.some(e=>e!==t.url&&this.nodes.has(e));this.nodes.delete(t.url),t.group.parent?.remove(t.group),this._onTileRemoved(t),this._parentOf.delete(t.url);let a=r.filter(e=>e!==t.url&&this.nodes.has(e));if(a.length){for(let e of a){let t=this.nodes.get(e);t&&(t.parentUrl=n??void 0,n?this._parentOf.set(e,n):this._parentOf.delete(e))}if(n){let e=this.nodes.get(n);if(e){let n=new Set(e.childUrls??[]);e.childUrl&&n.add(e.childUrl),n.delete(t.url);for(let e of a)n.add(e);e.childUrls=[...n],e.childUrl=e.childUrls[0]??null}}}return i&&n&&!this.nodes.has(n)&&!this.pending.has(n)&&this._enqueue(n),!0}_trimBudget(){let e=!1,t=0;for(;this.nodes.size+this.pending.size>this.maxTiles&&t++<=this.maxTiles+8&&this._evictOne(this.nodes.size+this.pending.size>this.hardCap);)e=!0;return e}_pickVictim(e,t=!1){let n=null;for(let r of this.nodes.values()){let i=r.childUrls??(r.childUrl?[r.childUrl]:[]);if((i.length>0&&i.some(e=>e!==r.url&&this.nodes.has(e)))!==e||!t&&r.group.visible&&!i.some(e=>{let t=this.nodes.get(e);return!!t&&t.group.visible}))continue;if(!n){n=r;continue}let a=r.lastSeen??-1,o=n.lastSeen??-1;(a<o||a===o&&(r.distance??0)>(n.distance??0))&&(n=r)}return n}retryFailed(){let e=this.failed.size;return this.failed.clear(),this._retryCount.clear(),this._retryAt.clear(),e}_pump(){for(;this._active<this.maxConcurrent&&this._queue.length;){let e=this._queue.shift();this._active++,this._load(e).finally(()=>{this._active--,this._pump()})}}_resolveAnchor(e){let t=e.position,n=t?.point3D??t,r=!!n&&Number.isFinite(n.x)&&Number.isFinite(n.y),i=_i(e.geoBounds),a=i?(i.left+i.right)/2:void 0,o=i?(i.bottom+i.top)/2:void 0,s=n?.z??0;if(!r)return{lon:a??0,lat:o??0,height:0};if((t?.units??t?.unit??`Degree`)!==`Degree`)return{lon:n.x,lat:n.y,height:s};let c=a===void 0?0:Math.abs(n.x-a),l=o===void 0?0:Math.abs(n.y-o);return c>.5||l>.5?(console.warn(`[s3m] position 与 geoBounds 不一致,改用 geoBounds 中心作为锚点`,{position:n,geoBounds:i}),{lon:a,lat:o,height:s}):{lon:n.x,lat:n.y,height:s}}_pickLod(e){let t=e.groupNode?.pageLods??[];return t.length?t.find(e=>e.childTile&&e.rangeValue>0)??t[0]:null}async _builder(){if(!this._buildTile){let e=await Promise.resolve().then(()=>(ui(),Gr));this._buildTile=e.buildTileObjects}return this._buildTile}_rememberGroups(e,t){for(this._groupCache.delete(e),this._groupCache.set(e,t);this._groupCache.size>24;){let e=this._groupCache.keys().next().value;if(e===void 0)break;this._groupCache.delete(e)}}async _fillExternalAtlases(e,t){let n=e,r=n.texturePackage;if(!r)return;let i=$t(n),a=!1,o=new Map,s=new Map,c=[];for(let[e,t]of Object.entries(r)){let n=un(t.requestNames);if(n.names.length){o.set(e,{tex:t,plan:n});for(let[e,t]of n.packGroups){let n=t.filter(e=>!this.leafRequestCache.has(e));if(!n.length)continue;let r=s.get(e)??[];for(let e of n)r.includes(e)||r.push(e);s.set(e,r)}for(let e of n.plain)!this.leafRequestCache.has(e)&&!c.includes(e)&&c.push(e)}}let l=[];for(let[e,n]of s){let r=null,i=()=>r??(r=this._fetchLeafPack(t,e,n));for(let e of n)l.push(this._ensureLeafFetch(e,i))}for(let e of c)l.push(this._ensureLeafFetch(e,()=>this._fetchLeafFile(t,e)));l.length&&await Promise.all(l);for(let[e,{tex:t,plan:n}]of o){let r=new Map;for(let e of n.names){let t=this.leafRequestCache.get(e);if(t)for(let n of t)r.set(n.id,{source:e,image:n})}let i=dn(t,r);if(i){let n=t;n.composed=!0,n.leafSig=i.sig,n.flipY=!1,t.data=i.data,t.compressType=0,t.pixelFormat=28,t.width=i.width,t.height=i.height,t.rectScale=1,this.atlasUpgraded.add(e),a=!0,(i.missing.length||i.mismatched.length)&&console.warn(`[s3m] leaf 图集部分精灵异常:`,e,{missing:i.missing,mismatched:i.mismatched});continue}let o=!!t.data,s=n=>{if(!o){let r=t.width/t.height,i=n.width/n.height;return Math.abs(i/r-1)<=.02||(this.atlasUpgradeSkipped.set(e,`aspect(no-baseline) ${t.width}x${t.height} vs ${n.width}x${n.height}`),!1)}let r=Sn(t,n);return r.ok?!0:(this.atlasUpgradeSkipped.set(e,`${r.reason} aspectΔ=${(r.aspectDelta*100).toFixed(1)}% scale=${r.scale} err=${Number.isNaN(r.meanAbsError)?`n/a`:r.meanAbsError.toFixed(1)}`),!1)},c=n=>{let r=t;r.composed=!1,r.leafSig=void 0,r.flipY=!0,t.data=n.data,t.compressType=n.compressType,t.pixelFormat=n.pixelFormat,t.rectScale=t.width>0?n.width/t.width:1,t.width=n.width||t.width,t.height=n.height||t.height,this.atlasUpgraded.add(e),a=!0},l=this.externalAtlasCache.get(e);if(l!==null){if(l===void 0){l=null;for(let e of n.plain){let t=this.leafRequestCache.get(e);if(t?.length){l=t[0];break}}this.externalAtlasCache.set(e,l)}l?s(l)&&c(l):this.atlasUpgradeSkipped.has(e)||this.atlasUpgradeSkipped.set(e,`no usable external image(请求失败或只拿到子精灵)`)}}(i||a)&&en(n)}_ensureLeafFetch(e,t){if(this.leafRequestCache.has(e))return Promise.resolve();let n=this._leafPending.get(e);if(n)return n;let r=t().finally(()=>this._leafPending.delete(e));return this._leafPending.set(e,r),r}async _fetchLeafPack(e,t,n){let r=pi(di(e),`${n[0]}.texblock?extratiles=${n.join(`;`)}`);try{if(!r)throw Error(`无法拼出 URL`);let e=await fetch(r);if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await rn(await e.arrayBuffer());if(t.length!==n.length)throw Error(`pack 段数 ${t.length} ≠ 请求名 ${n.length}`);n.forEach((e,n)=>this.leafRequestCache.set(e,t[n]))}catch(e){console.warn(`[s3m] leaf pack 请求失败:`,r,e);for(let e of n)this.leafRequestCache.has(e)||this.leafRequestCache.set(e,null)}}async _fetchLeafFile(e,t){let n=pi(di(e),`${t}.texblock`);try{if(!n)throw Error(`无法拼出 URL`);let e=await fetch(n);if(!e.ok)throw Error(`HTTP ${e.status}`);let r=(await rn(await e.arrayBuffer())).flat();this.leafRequestCache.set(t,r)}catch(e){console.warn(`[s3m] leaf texblock 请求失败:`,n,e),this.leafRequestCache.has(t)||this.leafRequestCache.set(t,null)}}async _upgradeAtlasLod(e,t){}async _load(e){if(!(this.nodes.has(e)||this.pending.has(e)||this.failed.has(e))){this.pending.add(e),this.stats.loading++;try{let t=e.indexOf(`#`),n=t>=0?e.slice(0,t):e,r=t>=0&&Number(e.slice(t+1))||0,i=/\.s3mblock($|\?)/i.test(n),a,o=[],s=this._groupCache.get(n);if(s)o=s.names,a=s.tiles[r]??s.tiles[0];else{let e=await fetch(n);if(!e.ok)throw Error(`HTTP ${e.status} 加载瓦片失败: ${n}`);if((e.headers.get(`content-type`)||``).includes(`text/html`))throw Error(`瓦片请求返回了 HTML 页面(通常为 404/500 服务端拦截): ${n}`);let t=await e.arrayBuffer();if(i){let e=await fn(t);this._rememberGroups(n,e),o=e.names,a=e.tiles[r]??e.tiles[0]}else a=await vt(t)}i&&(await this._fillExternalAtlases(a,n),await this._upgradeAtlasLod(a,n));let{group:c,stats:l}=await(await this._builder())(a,{textureCache:this.textureCache,uniforms:this._uniforms}),u=this._pickLod(a),d=[];for(let t of a.groupNode?.pageLods??[]){let r=String(t.childTile??``).replace(/\.s3mblock$/i,``),a=i&&r?o.indexOf(r):-1,s=a>=0?`${n}#${a}`:this.isS3MV1?vi(e,t.childTile):pi(di(e),t.childTile);s&&s!==e&&!d.includes(s)&&d.push(s)}let f={url:e,tile:a,group:c,sphere:u?.boundingSphere??null,rangeValue:u?.rangeValue??0,rangeMode:u?.rangeMode??1,childUrl:d[0]??(this.isS3MV1?vi(e,u?.childTile):pi(di(e),u?.childTile)),childUrls:d,parentUrl:this._parentOf.get(e),state:`ready`};this.nodes.set(e,f),this.stats.tiles++,this.stats.meshes+=l.meshes??0,this.stats.vertices+=l.vertices??0,this.stats.triangles+=l.triangles??0,this._onTile(f)}catch(t){let n=t?.permanent===!0,r=(this._retryCount.get(e)??0)+1;if(this._retryCount.set(e,r),!n&&r<=this._maxRetries)this._retryAt.set(e,performance.now()+800*r);else{this.stats.failed++,this.failed.add(e),this._retryAt.delete(e);let t=this._parentOf.get(e),n=t?this.nodes.get(t):void 0;n?.childUrls&&(n.childUrls=n.childUrls.filter(t=>t!==e),n.childUrl=n.childUrls[0]??null)}n?this._permanentReported||(this._permanentReported=!0,this._onError(t)):this._onError(t)}finally{this.pending.delete(e),this.stats.loading--,this._onProgress(this.stats)}}}update(e,t,n){this._frame++;let r=!1;for(let t of this.nodes.values()){var i;if(!t.sphere){t.needRefine=!1;continue}let a=t.sphere.center,o=a.x-e[0],s=a.y-e[1],c=a.z-e[2],l=Math.sqrt(o*o+s*s+c*c)||1e-6;t.distance=l;let u,d=t.rangeMode===0;u=d?l:n*.5/Math.tan(Math.PI/8)*(t.sphere.radius/l)*2;let f=this.lodRangeScale>0?this.lodRangeScale:1,p=t.rangeValue*f;(d?l<p*2:u>p*.5)&&(t.lastSeen=this._frame);let m=t.childUrls??(t.childUrl?[t.childUrl]:[]),h=m.length>0&&(d?u<p:u>p);t.needRefine=h;let g=(i=globalThis).__S3M_LOD_SEEN??(i.__S3M_LOD_SEEN=new Set);if(globalThis.__S3M_LOD_DEBUG&&!g.has(t.url)&&g.size<260&&(g.add(t.url),console.log(`[LOD]`,JSON.stringify({url:t.url.split(`/`).pop(),mode:t.rangeMode,rangeValue:t.rangeValue,radius:t.sphere.radius,dist:+l.toFixed(1),metric:+u.toFixed(1),threshold:+p.toFixed(1),needRefine:h,childUrls:m.map(e=>e.split(`/`).pop()),parent:t.parentUrl?t.parentUrl.split(`/`).pop():null}))),h)for(let e of m)this.failed.has(e)||this.nodes.has(e)||this.pending.has(e)||(this._enqueue(e,t.url),r=!0)}let a=new Set,o=new Set(this.rootUrls);for(let[e,t]of this.nodes){let n=t.parentUrl??this._parentOf.get(e);n&&this.nodes.has(n)||o.add(e)}for(let e of o)this._updateNodeVisibility(e,!0,a)&&(r=!0);for(let[e,t]of this.nodes)a.has(e)||t.group.visible&&(t.group.visible=!1,r=!0);this._trimBudget()&&(r=!0);let s=!1;for(let e of this.nodes.values())if(e.group.visible){s=!0;break}if(!s&&this.nodes.size>0)for(let e of this.nodes.values())!(e.childUrls??(e.childUrl?[e.childUrl]:[])).some(t=>{let n=this.nodes.get(t);return!!n&&n!==e&&n.group.visible})&&!e.group.visible&&(e.group.visible=!0,r=!0);return r}_updateNodeVisibility(e,t,n){let r=this.nodes.get(e);if(!r||n.has(e))return!1;n.add(e);let i=!1,a=r.childUrls??(r.childUrl?[r.childUrl]:[]);if(!t){r.group.visible&&(r.group.visible=!1,i=!0);for(let e of a)this._updateNodeVisibility(e,!1,n)&&(i=!0);return i}let o=a.length>0,s=a.filter(e=>this.nodes.has(e)),c=a.every(e=>this.nodes.has(e)||this.failed.has(e));if(r.needRefine&&o&&s.length>0&&c){r.group.visible&&(r.group.visible=!1,i=!0);for(let e of a)this._updateNodeVisibility(e,!0,n)&&(i=!0)}else{r.group.visible||(r.group.visible=!0,i=!0);for(let e of a)this._updateNodeVisibility(e,!1,n)&&(i=!0)}return i}dispose(){for(let e of this.nodes.values())e.group.traverse(e=>{let t=e;t.geometry?.dispose?.(),Array.isArray(t.material)?t.material.forEach(e=>e.dispose?.()):t.material?.dispose?.()});for(let e of this.textureCache.values())e.dispose?.();this.textureCache.clear(),this.nodes.clear()}};Wr();var xi=2;function Si(e){return e===Q.SOLID?`solid`:e===Q.HEIGHT?`height`:`vertex`}var Ci=`
364
+ `})),Gr=u({LINE_PRIMITIVE:()=>13,POINT_PRIMITIVE:()=>1,buildTileObjects:()=>si});function Kr(e){return e===13||e===2||e===3}function qr(e){return e===1}function Jr(){return ci||(ci=new t.PointsMaterial({size:2,sizeAttenuation:!1,vertexColors:!0})),ci}function Yr(e){return e===`u8`?1:e===`u16`?2:4}function Xr(e,t){switch(e){case`u8`:return new Uint8Array(t);case`u16`:return new Uint16Array(t);case`u32`:return new Uint32Array(t);default:return new Float32Array(t)}}function Zr(e,t){switch(e){case`u8`:return new Uint8Array(t);case`u16`:return new Uint16Array(t);case`u32`:return new Uint32Array(t);default:return new Float32Array(t)}}function Qr(e){let{data:n,stride:r,offsetInBytes:i,dtype:a=`f32`}=e,o=e.components??e.comp??3,s=Yr(a),c=o*s,l=r??c,u=i??0,d=a===`u8`;if(l===c&&u===0){let e=Xr(a,n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength));return new t.BufferAttribute(e,o,d)}let f=Math.floor(n.byteLength/l),p=Zr(a,f*o),m=new DataView(n.buffer,n.byteOffset,n.byteLength);for(let e=0;e<f;e++){let t=e*l+u;for(let n=0;n<o;n++){let r=t+n*s;p[e*o+n]=a===`u8`?m.getUint8(r):a===`u16`?m.getUint16(r,!0):a===`u32`?m.getUint32(r,!0):m.getFloat32(r,!0)}}return new t.BufferAttribute(p,o,d)}function $r(e){let{indices:n,indexType:r,indexCount:i}=e;if(!n||i===0)return null;let a=Math.floor(n.byteLength/i),o=a===4||a!==2&&(r===1||r===3),s=i*(o?4:2);if(s>n.byteLength)return null;let c=n.buffer.slice(n.byteOffset,n.byteOffset+s),l=o?new Uint32Array(c):new Uint16Array(c);return new t.BufferAttribute(l,1)}function ei(e,n){let r=new Float32Array(n*3);if(!e)return r.fill(1),new t.BufferAttribute(r,3);let i=e.data,a=e.components??4,o=e.dtype===`u8`?1/255:1;for(let e=0;e<n;e++){let t=e*a;r[e*3]=(i[t]??255)*o,r[e*3+1]=(i[t+1]??255)*o,r[e*3+2]=(i[t+2]??255)*o}return new t.BufferAttribute(r,3)}function ti(e){if(!e)return[];if(Array.isArray(e))return e;let t=e,n=t.materials??t.material;return Array.isArray(n)?n:[]}function ni(e){return e?.material??e}function ri(e){return e?.name??e?.id}function ii(e){return(e?.textureStates??e?.textureunitstates??[]).map(e=>e?.textureunitstate??e).filter(e=>!!e)}function ai(e){return e.length===16&&e[0]===1&&e[1]===0&&e[2]===0&&e[3]===0&&e[4]===0&&e[5]===1&&e[6]===0&&e[7]===0&&e[8]===0&&e[9]===0&&e[10]===1&&e[11]===0&&e[12]===0&&e[13]===0&&e[14]===0&&e[15]===1}function oi(e){let n=String(e?.cullMode??``).toUpperCase();return n===`CULL_BACK`||n===`BACKWARD`?t.FrontSide:n===`CULL_FRONT`?t.BackSide:t.DoubleSide}async function si(e,n={}){let r=n.uniforms??Dr(),i=n.textureCache??new Map,a=new t.Group,o=[],s=[],c={meshes:0,vertices:0,triangles:0,textures:0,instanced:0,edgeLines:0,skipped:[]},l=new t.LineBasicMaterial({color:new t.Color(n.edgeColor??`#1f2937`),transparent:!0,opacity:.75,depthWrite:!1});a.userData.hasNativeEdges=!1;let u=t=>{let n=e.textures?.[t];return n?.packKey?`${t}#${n.packKey}`:t};for(let[t,n]of Object.entries(e.textures??{})){let e=u(t),r=i.get(e);if(r){let t=r.image;if((t?.width??0)*(t?.height??0)>=(n.width??0)*(n.height??0))continue;i.delete(e)}let{texture:a,decoded:o}=await Tr(n);a?(i.set(e,a),s.push(e),c.textures++):c.skipped.push(`texture ${t} → ${o}`)}let d=ti(e.materials),f=(e,n=!1)=>{let a=ni(d.find(t=>ri(ni(t))===e)),o=ii(a),s=o[0],c=s?i.get(u(ri(s)??s.id??``))??null:null,l=o[1],f=globalThis.__S3M_NO_BAKE===!0,p=n&&l&&!f?i.get(u(ri(l)??l.id??``))??null:null,m=s?.texmodmatrix??s?.matrix;if(c&&Array.isArray(m)&&m.length===16&&!ai(m)&&(c=c.clone(),c.matrixAutoUpdate=!1,c.matrix.set(m[0],m[4],m[12],m[1],m[5],m[13],0,0,1)),c&&s?.addressmode){let e=s.addressmode.u,n=s.addressmode.v;(e!==void 0||n!==void 0)&&(c.matrixAutoUpdate&&(c=c.clone()),e!==void 0&&(c.wrapS=e===0?t.RepeatWrapping:t.ClampToEdgeWrapping),n!==void 0&&(c.wrapT=n===0?t.RepeatWrapping:t.ClampToEdgeWrapping))}let h=a?.diffuse??{r:1,g:1,b:1,a:1},g=a?.alphaMode,_=[s,l].some(e=>/\.water$/i.test(String(ri(e)??e?.id??``))),v=g===`AM_BLEND`||(h.a??1)<.999||a?.transparentsorting===!0||_&&!c,y=typeof a?.shininess==`number`&&a.shininess>0?Math.max(.15,1-a.shininess/128):.95,b=c?.userData?.s3mHasAlpha?Math.max(a?.alphaCutoff??0,.01):0;return Or({uniforms:r,map:c,color:_&&!c?li.clone():new t.Color(h.r??1,h.g??1,h.b??1),side:oi(a),transparent:v,opacity:_&&!c?.86:h.a??1,roughness:_&&!c?.12:y,alphaTest:b,atlas:n&&!!c,secMap:p})},p=new Map,m=new Map;for(let[n,r]of Object.entries(e.geoPackage??{})){let i=r.vertexPackage,a=i.vertexAttributes.find(e=>e.semantic===`position`);if(!a){c.skipped.push(`${n} 无 position`);continue}let o=i.verticesCount||0,s={position:Qr(a)},l=null,u=null;for(let e of i.vertexAttributes)e.divisor===void 0&&e.semantic!==`position`&&(e.semantic===`color`?l=e:e.semantic===`batchId`?u=e:e.semantic===`normal`?s.normal=Qr(e):e.semantic===`uv`?s.uv=Qr(e):e.semantic===`uv2`&&(s.uv1=Qr(e)));s.aColor=ei(l,o),s.aBatchId=u?Qr(u):new t.BufferAttribute(new Float32Array(o).fill(-1),1);let d=e.atlasRects?.[n];if(d){s.aAtlasRect=new t.BufferAttribute(d.uv??new Float32Array(o*4),4);let e=s.uv1;d.uv2&&e?(s.aAtlasRect1=new t.BufferAttribute(d.uv2,4),s.aSecUv=e):(s.aAtlasRect1=new t.BufferAttribute(new Float32Array(o*4),4),s.aSecUv=s.uv??new t.BufferAttribute(new Float32Array(o*2),2))}let f=i.instanceIndex!==-1&&(i.instanceMode===16||i.instanceMode===17),h=r.indexPackages??[];h.length===0&&o>0&&(h=[{indexCount:0,indexType:0,useIndex:0,primitiveType:1,indices:null,passNames:[]}]),m.set(n,{indexPackages:h,instanced:f}),c.vertices+=o,h.forEach((e,r)=>{let i=new t.BufferGeometry;for(let[e,t]of Object.entries(s))i.setAttribute(e,t);let a=$r(e);a?i.setIndex(a):i.setDrawRange(0,o),Kr(e.primitiveType)||qr(e.primitiveType)||i.getAttribute(`normal`)||i.computeVertexNormals(),i.computeBoundingBox(),i.computeBoundingSphere(),p.set(`${n}|${r}`,{geometry:i,pack:e})})}let h=new t.Matrix4,g=new Map,_=(e,n,r)=>{let i=0,a=0,o=!1,s=!1,c=!1,l=!1,u=!1,d=!1;for(let t of e){let e=t.cached.geometry,n=e.attributes.position?.count??0;i+=n,a+=e.index?e.index.count:n,e.attributes.normal&&(o=!0),e.attributes.uv&&(s=!0),e.attributes.uv1&&(c=!0),e.attributes.aColor&&(l=!0),e.attributes.aBatchId&&(u=!0),e.attributes.aAtlasRect&&(d=!0)}let f=new Float32Array(i*3),p=o?new Float32Array(i*3):null,m=s?new Float32Array(i*2):null,g=c?new Float32Array(i*2):null,_=l?new Float32Array(i*3):null,v=u?new Float32Array(i):null,y=d?new Float32Array(i*4):null,b=d?new Float32Array(i*4):null,x=d?new Float32Array(i*2):null,S=(e,t,n,r,i,a)=>{if(t){let a=t.array;for(let t=0;t<r;t++)for(let r=0;r<n;r++)e[(i+t)*n+r]=a[t*n+r]??0}else for(let t=0;t<r;t++){let r=[];a?a(t,r):r.push(...Array(n).fill(0));for(let a=0;a<n;a++)e[(i+t)*n+a]=r[a]??0}},C=new(i>65535?Uint32Array:Uint16Array)(a),w=0,T=0,E=new t.Vector3,ee=new t.Matrix3,te=new Map;for(let t of e){let e=t.cached.geometry,n=e.attributes.position.count,r=t.matrix,i=r&&!r.equals(h);if(i&&o&&ee.getNormalMatrix(r),t.geo.pickInfo)for(let e of Object.values(t.geo.pickInfo))typeof e.batchId==`number`&&e.batchId>=0&&te.set(e.batchId,t.geo);let a=e.attributes.position.array;for(let e=0;e<n;e++){let t=e*3,n=(w+e)*3;i?(E.set(a[t],a[t+1],a[t+2]).applyMatrix4(r),f[n]=E.x,f[n+1]=E.y,f[n+2]=E.z):(f[n]=a[t],f[n+1]=a[t+1],f[n+2]=a[t+2])}if(p){let t=e.attributes.normal;if(t){let e=t.array;for(let t=0;t<n;t++){let n=t*3,r=(w+t)*3;i?(E.set(e[n],e[n+1],e[n+2]).applyMatrix3(ee).normalize(),p[r]=E.x,p[r+1]=E.y,p[r+2]=E.z):(p[r]=e[n],p[r+1]=e[n+1],p[r+2]=e[n+2])}}}if(m){let t=e.attributes.uv;if(t){let e=t.array;for(let t=0;t<n;t++)m[(w+t)*2]=e[t*2],m[(w+t)*2+1]=e[t*2+1]}}if(g){let t=e.attributes.uv1;if(t){let e=t.array;for(let t=0;t<n;t++)g[(w+t)*2]=e[t*2],g[(w+t)*2+1]=e[t*2+1]}}if(_){let t=e.attributes.aColor;if(t){let e=t.array;for(let t=0;t<n;t++)_[(w+t)*3]=e[t*3],_[(w+t)*3+1]=e[t*3+1],_[(w+t)*3+2]=e[t*3+2]}else for(let e=0;e<n;e++)_[(w+e)*3]=1,_[(w+e)*3+1]=1,_[(w+e)*3+2]=1}if(v){let t=e.attributes.aBatchId;if(t){let e=t.array;for(let t=0;t<n;t++)v[w+t]=e[t]}else for(let e=0;e<n;e++)v[w+e]=-1}if(y&&(S(y,e.attributes.aAtlasRect,4,n,w,(e,t)=>t.push(0,0,0,0)),S(b,e.attributes.aAtlasRect1,4,n,w,(e,t)=>t.push(0,0,0,0)),S(x,e.attributes.aSecUv,2,n,w)),e.index){let t=e.index.array,n=e.index.count;for(let e=0;e<n;e++)C[T+e]=t[e]+w;T+=n}else{for(let e=0;e<n;e++)C[T+e]=e+w;T+=n}w+=n}let D=new t.BufferGeometry;D.setAttribute(`position`,new t.BufferAttribute(f,3)),p&&D.setAttribute(`normal`,new t.BufferAttribute(p,3)),m&&D.setAttribute(`uv`,new t.BufferAttribute(m,2)),g&&D.setAttribute(`uv1`,new t.BufferAttribute(g,2)),_&&D.setAttribute(`aColor`,new t.BufferAttribute(_,3)),v&&D.setAttribute(`aBatchId`,new t.BufferAttribute(v,1)),y&&(D.setAttribute(`aAtlasRect`,new t.BufferAttribute(y,4)),D.setAttribute(`aAtlasRect1`,new t.BufferAttribute(b,4)),D.setAttribute(`aSecUv`,new t.BufferAttribute(x,2))),D.setIndex(new t.BufferAttribute(C,1)),D.computeBoundingBox(),D.computeBoundingSphere();let O=new t.Mesh(D,n);return O.userData.skeletonName=e[0].name,O.userData.geoRef=e[0].geo,O.userData.tileRef=r,O.userData.primitiveType=4,O.userData.isBatched=!0,O.userData.batchedCount=e.length,te.size>0&&(O.userData.geoByBatchId=te),O},v=(r,i,s,u)=>{let{geometry:d,pack:p}=r,g=f(p.passNames?.[0],!!d.getAttribute(`aAtlasRect`)),_,v=m.get(i),y=s.vertexPackage;if(Kr(p.primitiveType)){let e=new t.LineSegments(d,l);return e.visible=n.edges===!0,e.renderOrder=2,e.raycast=()=>{},e.userData.isEdgeLines=!0,e.userData.skeletonName=i,u&&!u.equals(h)&&u.decompose(e.position,e.quaternion,e.scale),a.add(e),o.push(e),a.userData.hasNativeEdges=!0,c.edgeLines++,e}if(qr(p.primitiveType)){d.getAttribute(`color`)||d.setAttribute(`color`,d.getAttribute(`aColor`));let n=new t.Points(d,Jr());return n.userData.isPointCloud=!0,n.userData.skeletonName=i,n.userData.geoRef=s,n.userData.tileRef=e,n.userData.primitiveType=p.primitiveType,u&&!u.equals(h)&&u.decompose(n.position,n.quaternion,n.scale),a.add(n),o.push(n),c.meshes++,n}if(v?.instanced&&y.instanceBuffer&&y.instanceCount>0){if(!d.getAttribute(`aInstanceBatchId`)){let e=y.instanceBatchIds,n=e&&e.length===y.instanceCount?e.slice():new Float32Array(y.instanceCount).fill(-1);d.setAttribute(`aInstanceBatchId`,new t.InstancedBufferAttribute(n,1));let r=new Float32Array(y.instanceCount);for(let e=0;e<r.length;e++)r[e]=e;d.setAttribute(`aInstanceIndex`,new t.InstancedBufferAttribute(r,1))}let e=new t.InstancedMesh(d,g,y.instanceCount);e.instanceMatrix.setUsage(t.StaticDrawUsage);let n=new t.Matrix4,r=new t.Color,i=y.instanceMode,a=new Float32Array(y.instanceBuffer.buffer,y.instanceBuffer.byteOffset,y.instanceCount*i);for(let t=0;t<y.instanceCount;t++){let o=t*i;if(n.set(a[o+0],a[o+1],a[o+2],a[o+3],a[o+4],a[o+5],a[o+6],a[o+7],a[o+8],a[o+9],a[o+10],a[o+11],0,0,0,1),e.setMatrixAt(t,n),i>=16){let n=a[o+12],i=a[o+13],s=a[o+14];Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(s)&&(r.setRGB(n,i,s),e.setColorAt(t,r))}}e.instanceMatrix.needsUpdate=!0,e.instanceColor&&(e.instanceColor.needsUpdate=!0),e.frustumCulled=!1,c.instanced++,_=e}else _=new t.Mesh(d,g);return u&&!u.equals(h)&&u.decompose(_.position,_.quaternion,_.scale),_.userData.skeletonName=i,_.userData.geoRef=s,_.userData.tileRef=e,_.userData.primitiveType=p.primitiveType,a.add(_),o.push(_),c.meshes++,p.primitiveType===4&&(c.triangles+=(p.indexCount||0)/3),_},y=0;for(let r of e.groupNode?.pageLods??[])for(let i of r.geodes??[]){let r=i.matrix,a=r&&r.length===16?new t.Matrix4().fromArray(r):null;for(let t of i.skeletonNames??[]){let r=m.get(t);if(!r)continue;let i=e.geoPackage[t];if(!i)continue;let o=i.vertexPackage;for(let e=0;e<r.indexPackages.length;e++){let s=p.get(`${t}|${e}`);if(s){if(Kr(s.pack.primitiveType)||r.instanced&&o.instanceBuffer&&o.instanceCount>0)v(s,t,i,a),y++;else if(n.batching!==!1&&s.pack.primitiveType===4){let e=s.pack.passNames?.[0]??`__default__`,n=g.get(e);n||(n=[],g.set(e,n)),n.push({cached:s,name:t,geo:i,matrix:a}),y++}else v(s,t,i,a),y++}}}}if(y===0)for(let[t,r]of m){let i=e.geoPackage[t];if(!i)continue;let a=i.vertexPackage;for(let e=0;e<r.indexPackages.length;e++){let o=p.get(`${t}|${e}`);if(o){if(Kr(o.pack.primitiveType)||r.instanced&&a.instanceBuffer&&a.instanceCount>0)v(o,t,i,null);else if(n.batching!==!1&&o.pack.primitiveType===4){let e=o.pack.passNames?.[0]??`__default__`,n=g.get(e);n||(n=[],g.set(e,n)),n.push({cached:o,name:t,geo:i,matrix:null})}else v(o,t,i,null)}}}if(g.size>0)for(let[t,n]of g)if(c.originalMeshes=(c.originalMeshes??0)+n.length,n.length===1)v(n[0].cached,n[0].name,n[0].geo,n[0].matrix);else{let r=!!n[0].cached.geometry.getAttribute(`aAtlasRect`),i=_(n,f(t===`__default__`?void 0:t,r),e);a.add(i),o.push(i),c.meshes++;for(let e of n)c.triangles+=(e.cached.pack.indexCount||0)/3}return a.children.length||c.skipped.push(`tile 无可用几何`),a.userData.textureKeys=s,{group:a,stats:c,objects:o,textureKeys:s}}var ci,li,ui=c((()=>{Z(),Wr(),ci=null,li=new t.Color(1920611)}));function di(e){return e.slice(0,e.lastIndexOf(`/`)+1)}function fi(e){if(!e)return e;try{let t=typeof document<`u`?document.baseURI:void 0;return t?new URL(e,t).href:new URL(e).href}catch{return e}}function pi(e,t){if(!t)return null;try{return mi(new URL(t,e).href)}catch{return mi(`${di(e)}${t}`)}}function mi(e){if(!/[+ ]/.test(e))return e;let t=e.indexOf(`#`),n=t<0?``:e.slice(t),r=t<0?e:e.slice(0,t),i=r.indexOf(`?`),a=i<0?r:r.slice(0,i),o=i<0?``:r.slice(i);return`${a.replace(/\+/g,`%2B`).replace(/ /g,`%20`)}${o}${n}`}var hi=110540,gi=111320;function _i(e){if(!e||typeof e!=`object`)return null;let t=e;if(![t.left,t.bottom,t.right,t.top].every(e=>typeof e==`number`&&Number.isFinite(e)))return null;let{left:n,bottom:r,right:i,top:a}=t;return Math.abs(n)>180||Math.abs(i)>180||Math.abs(a)>90||Math.abs(r)>90||i===n&&a===r?null:{left:n,bottom:r,right:i,top:a}}function vi(e,t){if(!t)return null;let n=t.replace(/\.(osgb|s3mb|s3m)$/i,`.s3m`),r=e.split(`/`),i=r.pop()??``,a=r.pop()??``,o=r.lastIndexOf(`datas`);return!i||!a||o<1?pi(di(e),n):mi(`${r[r.length-1]===`path`&&r[r.length-2]===`data`?`${r.join(`/`)}/${a}`:`${r.join(`/`)}/data/path/${a}`}/${n}`)}function yi(e){let t=e.trim();if(t.startsWith(`<`)){let e=e=>{let n=RegExp(`<(?:[a-zA-Z0-9_-]+:)?${e}[^>]*>([^<]+)<\\/`,`i`).exec(t);return n?n[1].trim():null},n=t=>parseFloat(e(t)??``),r=n(`X`)||0,i=n(`Y`)||0,a=n(`Z`)||0,o=n(`Left`),s=n(`Right`),c=n(`Top`),l=n(`Bottom`);if(![o,s,c,l].every(Number.isFinite)){let e=n(`MinX`),t=n(`MaxX`),a=n(`MinY`),u=n(`MaxY`);if([e,t,a,u].every(Number.isFinite)&&r&&i){let n=gi*Math.cos(i*Math.PI/180);n>1e-6&&(o=r+e/n,s=r+t/n,l=i+a/hi,c=i+u/hi)}}let u=t.matchAll(/<(?:[a-zA-Z0-9_-]+:)?FileName[^>]*>([^<]+)<\//gi),d=[];for(let e of u)d.push({url:e[1].trim()});let f=n(`MinHeight`),p=n(`MaxHeight`);return{fileType:e(`FileType`)??void 0,position:{x:r,y:i,z:a,units:`Degree`},geoBounds:{left:o,right:s,top:c,bottom:l},heightRange:Number.isFinite(f)||Number.isFinite(p)?{min:f,max:p}:void 0,rootTiles:d,tiles:d}}return JSON.parse(t)}var bi=class{get heightRange(){let e=this.config?.heightRange;return e&&typeof e.min==`number`&&typeof e.max==`number`?{min:e.min,max:e.max}:null}constructor(e){h(this,`configUrl`,void 0),h(this,`config`,null),h(this,`_blockTileIndex`,null),h(this,`anchor`,{lon:0,lat:0,height:0}),h(this,`rootUrls`,[]),h(this,`nodes`,new Map),h(this,`failed`,new Set),h(this,`textureCache`,new Map),h(this,`maxImageCache`,void 0),h(this,`_textureRefs`,new Map),h(this,`_tileTextureKeys`,new Map),h(this,`pending`,new Set),h(this,`atlasLod`,void 0),h(this,`atlasLodCache`,new Map),h(this,`_groupCache`,new Map),h(this,`externalAtlasCache`,new Map),h(this,`leafRequestCache`,new Map),h(this,`_leafPending`,new Map),h(this,`atlasUpgraded`,new Set),h(this,`atlasUpgradeSkipped`,new Map),h(this,`stats`,{tiles:0,loading:0,failed:0,meshes:0,vertices:0,triangles:0,datasets:1}),h(this,`maxConcurrent`,void 0),h(this,`maxTiles`,void 0),h(this,`lodRangeScale`,void 0),h(this,`_onTile`,void 0),h(this,`_onTileRemoved`,void 0),h(this,`_onError`,void 0),h(this,`_onProgress`,void 0),h(this,`_maxRetries`,void 0),h(this,`_retryCount`,new Map),h(this,`_retryAt`,new Map),h(this,`_parentOf`,new Map),h(this,`_frame`,0),h(this,`_lodDbgOnce`,!1),h(this,`_permanentReported`,!1),h(this,`hardCap`,96),h(this,`isS3MV1`,!1),h(this,`_buildTile`,void 0),h(this,`_uniforms`,void 0),h(this,`_queue`,[]),h(this,`_active`,0),this.configUrl=e.configUrl,this.lodRangeScale=e.lodRangeScale??3,this._onTile=e.onTile??(()=>{}),this._onTileRemoved=e.onTileRemoved??(()=>{}),this._onError=e.onError??(e=>console.warn(e)),this._onProgress=e.onProgress??(()=>{}),this._maxRetries=Math.max(0,e.maxRetries??2),this._buildTile=e.buildTile??null,this._uniforms=e.uniforms??null,this.maxConcurrent=e.maxConcurrent??4,this.maxTiles=e.maxTiles??64,this.maxImageCache=e.maxImageCache??128,this.hardCap=this.maxTiles+Math.max(8,Math.ceil(this.maxTiles*.5)),this.atlasLod=e.atlasLod!==!1}async init(){this.configUrl=fi(this.configUrl);let e=await fetch(this.configUrl);if(!e.ok)throw Error(`配置读取失败 ${e.status} ${this.configUrl}`);let t=yi(await e.text());this.config=t,this.anchor=this._resolveAnchor(t);let n=t.rootTiles??t.tiles??[];if(!n.length)throw Error(`配置中缺少 root tile`);this.rootUrls.length=0;for(let e of n){let t=pi(this.configUrl,e.url);t&&this.rootUrls.push(t)}if(this.isS3MV1=/OSGB/i.test(String(t.fileType??``))||/OSGB/i.test(String(t.dataType??``))||this.rootUrls.length>0&&this.rootUrls.every(e=>/\.s3m($|\?)/i.test(e)),this.rootUrls.every(e=>/\.s3mblock($|\?)/i.test(e))){this._blockTileIndex=new Set(this.rootUrls);for(let e of n){let t=pi(this.configUrl,e.url);t&&this._blockTileIndex.add(t)}}await this._load(this.rootUrls[0]);for(let e of this.rootUrls.slice(1))this._enqueue(e);return this}_enqueue(e,t){if(!e||(t&&this._parentOf.set(e,t),this.nodes.has(e)||this.pending.has(e)||this.failed.has(e))||this._queue.includes(e))return;let n=this._retryAt.get(e);n!==void 0&&performance.now()<n||this.nodes.size+this.pending.size+this._queue.length>=this.hardCap||(this._queue.push(e),this._pump())}registerTileTextures(e,t){this._tileTextureKeys.set(e,t);let n=this.nodes.get(e);n&&(n.textureKeys=t);for(let e of t)this._textureRefs.set(e,(this._textureRefs.get(e)??0)+1)}_evictTileNode(e){this.nodes.delete(e.url),e.group?.parent?.remove(e.group),this._onTileRemoved(e),this._parentOf.delete(e.url),this.stats.tiles=Math.max(0,this.stats.tiles-1),e.stats&&(this.stats.meshes=Math.max(0,this.stats.meshes-(e.stats.meshes??0)),this.stats.vertices=Math.max(0,this.stats.vertices-(e.stats.vertices??0)),this.stats.triangles=Math.max(0,this.stats.triangles-(e.stats.triangles??0)));let t=e.textureKeys??this._tileTextureKeys.get(e.url)??e.group?.userData?.textureKeys;if(this._tileTextureKeys.delete(e.url),t?.length)for(let e of t){let t=(this._textureRefs.get(e)??1)-1;if(t<=0){this._textureRefs.delete(e);let t=this.textureCache.get(e);t&&(t.dispose?.(),this.textureCache.delete(e))}else this._textureRefs.set(e,t)}}putExternalAtlas(e,t){if(this.externalAtlasCache.size>=this.maxImageCache&&!this.externalAtlasCache.has(e)){let e=this.externalAtlasCache.keys().next().value;e!==void 0&&this.externalAtlasCache.delete(e)}Map.prototype.set.call(this.externalAtlasCache,e,t)}getExternalAtlas(e){return this.externalAtlasCache.get(e)}putLeafRecords(e,t){if(this.leafRequestCache.size>=this.maxImageCache&&!this.leafRequestCache.has(e)){let e=this.leafRequestCache.keys().next().value;e!==void 0&&this.leafRequestCache.delete(e)}Map.prototype.set.call(this.leafRequestCache,e,t)}getLeafRecords(e){return this.leafRequestCache.get(e)}_evictOne(e=!1){let t=this._pickVictim(!0,e)??this._pickVictim(!1,e);if(!t)return!1;let n=t.parentUrl??this._parentOf.get(t.url),r=t.childUrls??(t.childUrl?[t.childUrl]:[]);r.some(e=>e!==t.url&&this.nodes.has(e)),this._evictTileNode(t);let i=r.filter(e=>e!==t.url&&this.nodes.has(e));if(i.length){for(let e of i){let t=this.nodes.get(e);t&&(t.parentUrl=n??void 0,n?this._parentOf.set(e,n):this._parentOf.delete(e))}if(n){let e=this.nodes.get(n);if(e){let n=new Set(e.childUrls??[]);e.childUrl&&n.add(e.childUrl),n.delete(t.url);for(let e of i)n.add(e);e.childUrls=[...n],e.childUrl=e.childUrls[0]??null}}}return!0}_trimBudget(){let e=!1,t=0;for(;this.nodes.size+this.pending.size>this.maxTiles&&t++<=this.maxTiles+8&&this._evictOne(this.nodes.size+this.pending.size>this.hardCap);)e=!0;return e}_pickVictim(e,t=!1){let n=null;for(let r of this.nodes.values()){let i=r.childUrls??(r.childUrl?[r.childUrl]:[]);if((i.length>0&&i.some(e=>e!==r.url&&this.nodes.has(e)))!==e||!t&&r.group.visible&&!i.some(e=>{let t=this.nodes.get(e);return!!t&&t.group.visible}))continue;if(!n){n=r;continue}let a=r.lastSeen??-1,o=n.lastSeen??-1;(a<o||a===o&&(r.distance??0)>(n.distance??0))&&(n=r)}return n}retryFailed(){let e=this.failed.size;return this.failed.clear(),this._retryCount.clear(),this._retryAt.clear(),e}_pump(){for(;this._active<this.maxConcurrent&&this._queue.length;){let e=this._queue.shift();this._active++,this._load(e).finally(()=>{this._active--,this._pump()})}}_resolveAnchor(e){let t=e.position,n=t?.point3D??t,r=!!n&&Number.isFinite(n.x)&&Number.isFinite(n.y),i=_i(e.geoBounds),a=i?(i.left+i.right)/2:void 0,o=i?(i.bottom+i.top)/2:void 0,s=n?.z??0;if(!r)return{lon:a??0,lat:o??0,height:0};if((t?.units??t?.unit??`Degree`)!==`Degree`)return{lon:n.x,lat:n.y,height:s};let c=a===void 0?0:Math.abs(n.x-a),l=o===void 0?0:Math.abs(n.y-o);return c>.5||l>.5?(console.warn(`[s3m] position 与 geoBounds 不一致,改用 geoBounds 中心作为锚点`,{position:n,geoBounds:i}),{lon:a,lat:o,height:s}):{lon:n.x,lat:n.y,height:s}}_pickLod(e){let t=e.groupNode?.pageLods??[];return t.length?t.find(e=>e.childTile&&e.rangeValue>0)??t[0]:null}async _builder(){if(!this._buildTile){let e=await Promise.resolve().then(()=>(ui(),Gr));this._buildTile=e.buildTileObjects}return this._buildTile}_rememberGroups(e,t){for(this._groupCache.delete(e),this._groupCache.set(e,t);this._groupCache.size>24;){let e=this._groupCache.keys().next().value;if(e===void 0)break;this._groupCache.delete(e)}}async _fillExternalAtlases(e,t){let n=e,r=n.texturePackage;if(!r)return;let i=$t(n),a=!1,o=new Map,s=new Map,c=[];for(let[e,t]of Object.entries(r)){let n=un(t.requestNames);if(n.names.length){o.set(e,{tex:t,plan:n});for(let[e,t]of n.packGroups){let n=t.filter(e=>!this.leafRequestCache.has(e));if(!n.length)continue;let r=s.get(e)??[];for(let e of n)r.includes(e)||r.push(e);s.set(e,r)}for(let e of n.plain)!this.leafRequestCache.has(e)&&!c.includes(e)&&c.push(e)}}let l=[];for(let[e,n]of s){let r=null,i=()=>r??(r=this._fetchLeafPack(t,e,n));for(let e of n)l.push(this._ensureLeafFetch(e,i))}for(let e of c)l.push(this._ensureLeafFetch(e,()=>this._fetchLeafFile(t,e)));l.length&&await Promise.all(l);for(let[e,{tex:t,plan:n}]of o){let r=new Map;for(let e of n.names){let t=this.leafRequestCache.get(e);if(t)for(let n of t)r.set(n.id,{source:e,image:n})}let i=dn(t,r);if(i){let n=t;n.composed=!0,n.leafSig=i.sig,n.flipY=!1,t.data=i.data,t.compressType=0,t.pixelFormat=28,t.width=i.width,t.height=i.height,t.rectScale=1,this.atlasUpgraded.add(e),a=!0,(i.missing.length||i.mismatched.length)&&console.warn(`[s3m] leaf 图集部分精灵异常:`,e,{missing:i.missing,mismatched:i.mismatched});continue}let o=!!t.data,s=n=>{if(!o){let r=t.width/t.height,i=n.width/n.height;return Math.abs(i/r-1)<=.02||(this.atlasUpgradeSkipped.set(e,`aspect(no-baseline) ${t.width}x${t.height} vs ${n.width}x${n.height}`),!1)}let r=Sn(t,n);return r.ok?!0:(this.atlasUpgradeSkipped.set(e,`${r.reason} aspectΔ=${(r.aspectDelta*100).toFixed(1)}% scale=${r.scale} err=${Number.isNaN(r.meanAbsError)?`n/a`:r.meanAbsError.toFixed(1)}`),!1)},c=n=>{let r=t;r.composed=!1,r.leafSig=void 0,r.flipY=!0,t.data=n.data,t.compressType=n.compressType,t.pixelFormat=n.pixelFormat,t.rectScale=t.width>0?n.width/t.width:1,t.width=n.width||t.width,t.height=n.height||t.height,this.atlasUpgraded.add(e),a=!0},l=this.externalAtlasCache.get(e);if(l!==null){if(l===void 0){l=null;for(let e of n.plain){let t=this.leafRequestCache.get(e);if(t?.length){l=t[0];break}}this.putExternalAtlas(e,l)}l?s(l)&&c(l):this.atlasUpgradeSkipped.has(e)||this.atlasUpgradeSkipped.set(e,`no usable external image(请求失败或只拿到子精灵)`)}}(i||a)&&en(n)}_ensureLeafFetch(e,t){if(this.leafRequestCache.has(e))return Promise.resolve();let n=this._leafPending.get(e);if(n)return n;let r=t().finally(()=>this._leafPending.delete(e));return this._leafPending.set(e,r),r}async _fetchLeafPack(e,t,n){let r=pi(di(e),`${n[0]}.texblock?extratiles=${n.join(`;`)}`);try{if(!r)throw Error(`无法拼出 URL`);let e=await fetch(r);if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await rn(await e.arrayBuffer());if(t.length!==n.length)throw Error(`pack 段数 ${t.length} ≠ 请求名 ${n.length}`);n.forEach((e,n)=>this.putLeafRecords(e,t[n]))}catch(e){console.warn(`[s3m] leaf pack 请求失败:`,r,e);for(let e of n)this.leafRequestCache.has(e)||this.putLeafRecords(e,null)}}async _fetchLeafFile(e,t){let n=pi(di(e),`${t}.texblock`);try{if(!n)throw Error(`无法拼出 URL`);let e=await fetch(n);if(!e.ok)throw Error(`HTTP ${e.status}`);let r=(await rn(await e.arrayBuffer())).flat();this.putLeafRecords(t,r)}catch(e){console.warn(`[s3m] leaf texblock 请求失败:`,n,e),this.leafRequestCache.has(t)||this.putLeafRecords(t,null)}}async _upgradeAtlasLod(e,t){}async _load(e){if(!(this.nodes.has(e)||this.pending.has(e)||this.failed.has(e))){this.pending.add(e),this.stats.loading++;try{let t=e.indexOf(`#`),n=t>=0?e.slice(0,t):e,r=t>=0&&Number(e.slice(t+1))||0,i=/\.s3mblock($|\?)/i.test(n),a,o=[],s=this._groupCache.get(n);if(s)o=s.names,a=s.tiles[r]??s.tiles[0];else{let e=await fetch(n);if(!e.ok)throw Error(`HTTP ${e.status} 加载瓦片失败: ${n}`);if((e.headers.get(`content-type`)||``).includes(`text/html`))throw Error(`瓦片请求返回了 HTML 页面(通常为 404/500 服务端拦截): ${n}`);let t=await e.arrayBuffer();if(i){let e=await fn(t);this._rememberGroups(n,e),o=e.names,a=e.tiles[r]??e.tiles[0]}else a=await vt(t)}i&&(await this._fillExternalAtlases(a,n),await this._upgradeAtlasLod(a,n));let c=await(await this._builder())(a,{textureCache:this.textureCache,uniforms:this._uniforms}),{group:l,stats:u}=c,d=c.textureKeys??l.userData?.textureKeys??Object.keys(a.textures??{});this.registerTileTextures(e,d);let f=this._pickLod(a),p=[];for(let t of a.groupNode?.pageLods??[]){let r=String(t.childTile??``).replace(/\.s3mblock$/i,``),a=i&&r?o.indexOf(r):-1,s=a>=0?`${n}#${a}`:this.isS3MV1?vi(e,t.childTile):pi(di(e),t.childTile);s&&s!==e&&!p.includes(s)&&p.push(s)}let m={url:e,tile:a,group:l,sphere:f?.boundingSphere??null,rangeValue:f?.rangeValue??0,rangeMode:f?.rangeMode??1,childUrl:p[0]??(this.isS3MV1?vi(e,f?.childTile):pi(di(e),f?.childTile)),childUrls:p,parentUrl:this._parentOf.get(e),state:`ready`,stats:{meshes:u.meshes??0,vertices:u.vertices??0,triangles:u.triangles??0}};this.nodes.set(e,m),this.stats.tiles++,this.stats.meshes+=u.meshes??0,this.stats.vertices+=u.vertices??0,this.stats.triangles+=u.triangles??0,this._onTile(m)}catch(t){let n=t?.permanent===!0,r=(this._retryCount.get(e)??0)+1;if(this._retryCount.set(e,r),!n&&r<=this._maxRetries)this._retryAt.set(e,performance.now()+800*r);else{this.stats.failed++,this.failed.add(e),this._retryAt.delete(e);let t=this._parentOf.get(e),n=t?this.nodes.get(t):void 0;n?.childUrls&&(n.childUrls=n.childUrls.filter(t=>t!==e),n.childUrl=n.childUrls[0]??null)}n?this._permanentReported||(this._permanentReported=!0,this._onError(t)):this._onError(t)}finally{this.pending.delete(e),this.stats.loading--,this._onProgress(this.stats)}}}update(e,t,n){this._frame++;let r=!1;for(let t of this.nodes.values()){var i;if(!t.sphere){t.needRefine=!1;continue}let a=t.sphere.center,o=a.x-e[0],s=a.y-e[1],c=a.z-e[2],l=Math.sqrt(o*o+s*s+c*c)||1e-6;t.distance=l;let u,d=t.rangeMode===0;u=d?l:n*.5/Math.tan(Math.PI/8)*(t.sphere.radius/l)*2;let f=this.lodRangeScale>0?this.lodRangeScale:1,p=t.rangeValue*f;(d?l<p*2:u>p*.5)&&(t.lastSeen=this._frame);let m=t.childUrls??(t.childUrl?[t.childUrl]:[]),h=m.length>0&&(d?u<p:u>p);t.needRefine=h;let g=(i=globalThis).__S3M_LOD_SEEN??(i.__S3M_LOD_SEEN=new Set);if(globalThis.__S3M_LOD_DEBUG&&!g.has(t.url)&&g.size<260&&(g.add(t.url),console.log(`[LOD]`,JSON.stringify({url:t.url.split(`/`).pop(),mode:t.rangeMode,rangeValue:t.rangeValue,radius:t.sphere.radius,dist:+l.toFixed(1),metric:+u.toFixed(1),threshold:+p.toFixed(1),needRefine:h,childUrls:m.map(e=>e.split(`/`).pop()),parent:t.parentUrl?t.parentUrl.split(`/`).pop():null}))),h)for(let e of m)this.failed.has(e)||this.nodes.has(e)||this.pending.has(e)||(this._enqueue(e,t.url),r=!0)}let a=new Set,o=new Set(this.rootUrls);for(let[e,t]of this.nodes){let n=t.parentUrl??this._parentOf.get(e);n&&this.nodes.has(n)||o.add(e)}for(let e of o)this._updateNodeVisibility(e,!0,a)&&(r=!0);for(let[e,t]of this.nodes)a.has(e)||t.group.visible&&(t.group.visible=!1,r=!0);this._trimBudget()&&(r=!0);let s=!1;for(let e of this.nodes.values())if(e.group.visible){s=!0;break}if(!s&&this.nodes.size>0)for(let e of this.nodes.values())!(e.childUrls??(e.childUrl?[e.childUrl]:[])).some(t=>{let n=this.nodes.get(t);return!!n&&n!==e&&n.group.visible})&&!e.group.visible&&(e.group.visible=!0,r=!0);return r}_updateNodeVisibility(e,t,n){let r=this.nodes.get(e);if(!r||n.has(e))return!1;n.add(e);let i=!1,a=r.childUrls??(r.childUrl?[r.childUrl]:[]);if(!t){r.group.visible&&(r.group.visible=!1,i=!0);for(let e of a)this._updateNodeVisibility(e,!1,n)&&(i=!0);return i}let o=a.length>0,s=a.filter(e=>this.nodes.has(e)),c=a.every(e=>this.nodes.has(e)||this.failed.has(e));if(r.needRefine&&o&&s.length>0&&c){r.group.visible&&(r.group.visible=!1,i=!0);for(let e of a)this._updateNodeVisibility(e,!0,n)&&(i=!0)}else{r.group.visible||(r.group.visible=!0,i=!0);for(let e of a)this._updateNodeVisibility(e,!1,n)&&(i=!0)}return i}dispose(){for(let e of this.nodes.values())e.group.traverse(e=>{let t=e;t.geometry?.dispose?.(),Array.isArray(t.material)?t.material.forEach(e=>e.dispose?.()):t.material?.dispose?.()});for(let e of this.textureCache.values())e.dispose?.();this.textureCache.clear(),this.nodes.clear()}};Wr();var xi=2;function Si(e){return e===Q.SOLID?`solid`:e===Q.HEIGHT?`height`:`vertex`}var Ci=`
365
365
  uniform float uPointSize;
366
366
  varying float vWorldZ;
367
367
  void main() {
@@ -502,7 +502,7 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
502
502
  if ( uOpacity <= 0.003 ) discard;
503
503
  gl_FragColor = vec4( uColor, uOpacity );
504
504
  }
505
- `;function Ri(e,n={}){let r=new t.ShaderMaterial({uniforms:{uResolution:e.uResolution,uDpr:e.uDpr,uColor:{value:new t.Color(n.color??`#ffffff`)},uOpacity:{value:n.opacity??1},uWidth:{value:n.width??1.5},uElevation:{value:n.elevation??0},uTranslation:{value:new t.Vector3(0,0,0)}},vertexShader:Ii,fragmentShader:Li,transparent:!0,depthWrite:!1,side:t.DoubleSide,polygonOffset:!0,polygonOffsetFactor:-2,polygonOffsetUnits:-2});return r.userData.isThickLine=!0,r}function zi(e){let n=Math.floor(e.length/6),r=n*4,i=new Float32Array(r*3),a=new Float32Array(r*3),o=new Float32Array(r),s=r>65535?new Uint32Array(n*6):new Uint16Array(n*6);for(let t=0;t<n;t++){let n=t*6,r=e[n],i=e[n+1],a=e[n+2],o=e[n+3],l=e[n+4],u=e[n+5],d=t*4;c(d,r,i,a,o,l,u,-1),c(d+1,r,i,a,o,l,u,1),c(d+2,o,l,u,r,i,a,1),c(d+3,o,l,u,r,i,a,-1);let f=t*6;s[f]=d,s[f+1]=d+1,s[f+2]=d+2,s[f+3]=d,s[f+4]=d+2,s[f+5]=d+3}function c(e,t,n,r,s,c,l,u){let d=e*3;i[d]=t,i[d+1]=n,i[d+2]=r,a[d]=s,a[d+1]=c,a[d+2]=l,o[e]=u}let l=new t.BufferGeometry;return l.setAttribute(`position`,new t.BufferAttribute(i,3)),l.setAttribute(`aOther`,new t.BufferAttribute(a,3)),l.setAttribute(`aSide`,new t.BufferAttribute(o,1)),l.setIndex(new t.BufferAttribute(s,1)),l.computeBoundingSphere(),l}var Bi=6e4,Vi=100;function Hi(e,t,n=40){let r=e.getAttribute(`position`);if(!r)return null;let i=r.count;if(i<3)return null;let a=new Float32Array(i),o=new Float32Array(i),s=new Float32Array(i);for(let e=0;e<i;e++)a[e]=r.getX(e),o[e]=r.getY(e),s[e]=r.getZ(e);let c=null,l=null;if(!e.index){let e=new Map;c=new Uint32Array(i),l=new Uint32Array(i);let t=0;for(let n=0;n<i;n++){let r=`${Math.round(a[n]*Vi)},${Math.round(o[n]*Vi)},${Math.round(s[n]*Vi)}`,i=e.get(r);i===void 0&&(i=t++,e.set(r,i),l[i]=n),c[n]=i}}let u=e=>c?c[e]:e,d=e=>l?l[e]:e,f=e.index,p=f?f.array:null,m=Math.floor(f?f.count/3:i/3);if(m<1)return null;let h=null;if(t&&t.length>0){h=new Uint8Array(i);for(let e of t){let t=Math.max(0,e.vertexOffset|0),n=Math.min(i,t+(e.vertexCount|0));n>t&&h.fill(1,t,n)}if(!h.includes(1))return null}let g=new Float32Array(m*3),_=new Map,v=i+1,y=[],b=Math.cos(n*Math.PI/180),x=-1,S=0,C=0,w=0,T=(e,t)=>{if(y.length>=Bi*6)return!1;let n=d(e),r=d(t);return y.push(a[n],o[n],s[n],a[r],o[r],s[r]),!0},E=(e,t)=>{if(e===t)return;let n=e<t?e:t,r=e<t?t:e,i=n*v+r,a=_.get(i);a===void 0?_.set(i,x):a<0||(S*g[a*3]+C*g[a*3+1]+w*g[a*3+2]<b?(T(n,r),_.set(i,-1)):_.set(i,-2))};for(x=0;x<m;x++){let e=p?p[x*3]:x*3,t=p?p[x*3+1]:x*3+1,n=p?p[x*3+2]:x*3+2;if(h&&!(h[e]&&h[t]&&h[n]))continue;let r=a[t]-a[e],i=o[t]-o[e],c=s[t]-s[e],l=a[n]-a[e],d=o[n]-o[e],f=s[n]-s[e];S=i*f-c*d,C=c*l-r*f,w=r*d-i*l;let m=Math.hypot(S,C,w);m<1e-12||(S/=m,C/=m,w/=m,g[x*3]=S,g[x*3+1]=C,g[x*3+2]=w,E(u(e),u(t)),E(u(t),u(n)),E(u(n),u(e)))}for(let[e,t]of _){if(t<0)continue;let n=Math.floor(e/v);if(!T(n,e-n*v))break}return y.length>0?new Float32Array(y):null}var Ui=class{constructor(){h(this,`datasets`,new Map),h(this,`sceneAnchor`,null)}computeAlignOffset(e,t){if(!t||t===`origin`||!e)return 0;let n=e.heightRange;if(!n)return 0;switch(t){case`top`:return-n.max;case`bottom`:return-n.min;case`center`:return-(n.min+n.max)/2;default:return 0}}async addDataset(e,n,r,i,a,o,s,c,l){let u=this.datasets.get(e.id);if(u)return u;let d=new t.Group;d.name=`s3m-dataset:${e.id}`,d.visible=e.visible!==!1,n.add(d);let f={id:e.id,name:e.name??e.id,options:e,root:d,tileset:null,anchor:null,baseAlignOffset:0,userOffset:e.heightOffset??0,heightOffset:e.heightOffset??0,offset:[0,0,0],visible:e.visible!==!1,error:null};this.datasets.set(e.id,f);let p=new bi({configUrl:e.configUrl,maxTiles:e.maxTiles??s,maxConcurrent:c,lodRangeScale:e.lodRangeScale??a,buildTile:o??null,uniforms:i,onTile:e=>{l.onTile(e,f)},onTileRemoved:e=>{l.onTileRemoved(e,f)},onProgress:()=>{l.onStats(),l.triggerRepaint()},onError:e=>{f.error=e,l.onError(e),l.onStats()}});f.tileset=p;try{await p.init()}catch(e){return f.error=e,l.onError(e),f}return f.anchor=p.anchor,f.baseAlignOffset=this.computeAlignOffset(p,e.align),f.userOffset=e.heightOffset??0,f.heightOffset=f.baseAlignOffset+f.userOffset,this.layoutDataset(f,r),l.onReady(f),l.triggerRepaint(),f}removeDataset(e,t,n,r){let i=this.datasets.get(e);return i?(r(i),i.tileset?.dispose(),t.remove(i.root),this.datasets.delete(e),this.datasets.size>0?this.recomputeAnchors(n):this.sceneAnchor=null,!0):!1}clearDatasets(e,t){for(let n of this.datasets.values())t(n),n.tileset?.dispose(),e.remove(n.root);this.datasets.clear(),this.sceneAnchor=null}layoutDataset(e,t){if(!e.anchor)return;this.sceneAnchor||(this.sceneAnchor=Mt(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0));let n=this.sceneAnchor.meterInMercator,r=Mt(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0);e.offset=[(r.x-this.sceneAnchor.x)/n,-(r.y-this.sceneAnchor.y)/n,(r.z-this.sceneAnchor.z)/n+(e.heightOffset??0)],e.root.position.set(e.offset[0],e.offset[1],e.offset[2]),e.root.updateMatrixWorld(!0)}recomputeAnchors(e){if(this.datasets.size!==0){this.sceneAnchor=null;for(let t of this.datasets.values())this.layoutDataset(t,e)}}getDatasetHeight(e){let t=e??this.datasets.keys().next().value;return t?this.datasets.get(t)?.userOffset??0:0}setDatasetHeight(e,t,n){let r=this.datasets.get(e);r&&(r.userOffset=t,r.heightOffset=r.baseAlignOffset+t,this.layoutDataset(r,n))}setDatasetAlign(e,t,n){let r=this.datasets.get(e);if(!r)return;let i=r.heightOffset-r.baseAlignOffset;r.baseAlignOffset=this.computeAlignOffset(r.tileset,t),r.userOffset=i,r.heightOffset=r.baseAlignOffset+i,r.options.align=t,this.layoutDataset(r,n)}setDatasetVisible(e,t){let n=this.datasets.get(e);n&&(n.visible=t,n.root.visible=t)}getBounds(){let e=1/0,t=1/0,n=-1/0,r=-1/0,i=!1;for(let a of this.datasets.values()){if(!a.visible||!a.tileset?.config)continue;let o=_i(a.tileset.config.geoBounds);o&&(e=Math.min(e,o.left),t=Math.min(t,o.bottom),n=Math.max(n,o.right),r=Math.max(r,o.top),i=!0)}return i?[[e,t],[n,r]]:null}};Ct();function Wi(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function Gi(e,t){if(e.length<2)return e[0].clone();let n=Math.min(1,Math.max(0,t))*(e.length-1),r=Math.min(e.length-2,Math.floor(n));return e[r].clone().lerp(e[r+1],n-r)}function Ki(e,t,n){if(n.keep&&!n.keep(e,t))return!1;if(n.values?.length){let t=e==null?``:String(e);if(!n.values.some(e=>String(e)===t))return!1}if(n.min!=null||n.max!=null){let t=Number(e);if(!Number.isFinite(t)||n.min!=null&&t<n.min||n.max!=null&&t>n.max)return!1}return!n.keep&&!n.values?.length&&n.min==null&&n.max==null?e!=null&&String(e)!==``:!0}function qi(e){if(!Number.isFinite(e))return`—`;let t=Math.abs(e);return t>=100?e.toFixed(0):t>=10?e.toFixed(1):e.toFixed(2)}var Ji=class{constructor(e,t,n,r,i){h(this,`_getLayerFloorHeight`,void 0),h(this,`_triggerRepaint`,void 0),h(this,`_onStyleChanged`,void 0),h(this,`_getAllMeshes`,void 0),h(this,`_applyOverrideHook`,void 0),h(this,`featureStyles`,new Map),h(this,`thematicColors`,new Map),h(this,`thematicElevation`,new Map),h(this,`thematicField`,null),h(this,`elevationField`,null),h(this,`filter`,null),h(this,`fieldFilter`,null),h(this,`_meshBatchTextures`,new WeakMap),h(this,`_markedMeshes`,new Set),h(this,`_dirtyAll`,!1),h(this,`_flushScheduled`,!1),h(this,`_batchConflictWarned`,!1),this._getLayerFloorHeight=e,this._triggerRepaint=t,this._onStyleChanged=n,this._getAllMeshes=r,this._applyOverrideHook=i}setFeatureStyle(e,t,n){this.featureStyles.set(e,t),this.markOverridesDirty(n),this._onStyleChanged(),this._triggerRepaint()}setFeaturesStyle(e,t,n){for(let n of e)this.featureStyles.set(n,t);this.markOverridesDirty(n),this._onStyleChanged(),this._triggerRepaint()}getFeatureStyle(e){return this.featureStyles.get(e)??null}getFeatureEffectiveOffset(e){if(e==null)return{};let t=this.featureStyles.get(e),n=t?.elevation??this.thematicElevation.get(e);return{translation:t?.translation,elevation:n}}getFeatureStyles(){return new Map(this.featureStyles)}removeFeatureStyle(e,t){this.featureStyles.delete(e)&&(this.markOverridesDirty(t),this._onStyleChanged(),this._triggerRepaint())}clearFeatureStyles(){this.featureStyles.size>0&&(this.featureStyles.clear(),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint())}setThematicColors(e,t=`custom`){this.thematicColors=e&&e.size>0?new Map(e):new Map,this.thematicField=this.thematicColors.size>0?t:null,this.markOverridesDirty(),this._triggerRepaint()}clearThematicColors(){this.thematicColors.size!==0&&(this.thematicColors=new Map,this.thematicField=null,this.markOverridesDirty(),this._triggerRepaint())}setThematicElevation(e,t=`custom`){this.thematicElevation=e&&e.size>0?new Map([...e].filter(([,e])=>Number.isFinite(e)&&e>0)):new Map,this.elevationField=this.thematicElevation.size>0?t:null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint()}clearThematicElevation(){this.thematicElevation.size!==0&&(this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint())}setFilter(e,t){this.filter=e,e&&(e.minHeight!=null||e.maxHeight!=null)?(t.uFilterMinZ&&(t.uFilterMinZ.value=e.minHeight??-99999),t.uFilterMaxZ&&(t.uFilterMaxZ.value=e.maxHeight??99999),t.uFilterHeightActive&&(t.uFilterHeightActive.value=1)):t.uFilterHeightActive&&(t.uFilterHeightActive.value=0),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint()}clearFilter(e){this.setFilter(null,e)}async colorByField(e,n,r){if(!n)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let i=e.smids?.length?[...new Set(e.smids)]:r;if(!i.length)return this.clearThematicColors(),{field:e.field,type:`discrete`,matched:0,missing:0,legend:[]};let a=await n.queryBySmids(i),o=[],s=[];for(let t of i){let n=a.get(t),r=n?n[e.field]:void 0;if(r==null||r===``)continue;let i=Number(r);Number.isFinite(i)?o.push({smid:t,val:i}):s.push({smid:t,val:String(r)})}let c=o.length>=s.length&&o.length>0,l=new Map,u=[],d=e.defaultColor??`#64748b`,f=e.nullColor??`#334155`;if(c){let n=o.map(e=>e.val),r=Math.min(...n),i=Math.max(...n)-r||1,a=(e.ramp??[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`]).map(e=>new t.Color(e)),s=Math.max(2,e.stops??5);for(let e=0;e<s;e++){let t=e/s,n=(e+1)/s,o=Gi(a,(t+n)/2),c=r+t*i,l=r+n*i;u.push({color:`#${o.getHexString()}`,label:`${qi(c)} ~ ${qi(l)}`,count:0,min:c,max:l})}for(let{smid:e,val:t}of o){let n=Math.min(1,Math.max(0,(t-r)/i)),a=Math.min(s-1,Math.floor(n*s)),o=u[a].color;l.set(e,o),u[a].count++}}else{let t=new Map;for(let{val:e}of s)t.set(e,(t.get(e)??0)+1);let n=[...t.entries()].sort((e,t)=>t[1]-e[1]),r=Array.isArray(e.colors)?e.colors:[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`,`#8b5cf6`,`#ec4899`,`#06b6d4`,`#84cc16`],i=!Array.isArray(e.colors)&&e.colors?e.colors:null;for(let e=0;e<n.length;e++){let[t,a]=n[e],o=i?.[t]??r[e%r.length];u.push({color:o,label:t,count:a})}let a=new Map(u.map(e=>[e.label,e.color]));for(let{smid:e,val:t}of s)l.set(e,a.get(t)??d)}let p=0;for(let e of i)l.has(e)||(l.set(e,f),p++);return p>0&&u.push({color:f,label:`无数据 / 缺失`,count:p}),this.setThematicColors(l,e.field),{field:e.field,type:c?`continuous`:`discrete`,matched:i.length-p,missing:p,legend:u}}async filterByField(e,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n,i=e.mode??`keep`,a=e.onMissing??`drop`,o={field:e.field,mode:i,matched:0,hidden:[]};if(!r.length)return this.fieldFilter=null,this.markOverridesDirty(),o;let s=await t.queryBySmids(r),c=new Set;for(let t of r){let n=s.get(t);n?Ki(n[e.field]??null,n,e)&&c.add(t):a===`keep`&&c.add(t)}o.matched=c.size;let l=i===`keep`;return this.fieldFilter=c.size||l?{field:e.field,mode:l?`keep`:`drop`,matched:c}:null,o.hidden=r.filter(e=>l?!c.has(e):c.has(e)),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),o}clearFieldFilter(){this.fieldFilter&&(this.fieldFilter=null,this.markOverridesDirty(),this._triggerRepaint())}async elevateByField(e,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n,i={field:e.field,matched:0,missing:r.length,min:0,max:0,appliedMax:0};if(!r.length)return this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),i;let a=await t.queryBySmids(r),o=new Map;for(let t of r){let n=Number(a.get(t)?.[e.field]);Number.isFinite(n)&&o.set(t,n)}if(o.size===0)return this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),i;let s=[...o.values()],c=Math.min(...s),l=Math.max(...s),u=e.scale??1,d=e.offset??0,f=new Map,p=0;for(let[t,n]of o){let r=e.map?e.map(n,{min:c,max:l}):n*u+d;Number.isFinite(r)&&(e.max!=null&&r>e.max&&(r=e.max),!(r<=0)&&(f.set(t,r),r>p&&(p=r)))}return this.thematicElevation=f,this.elevationField=e.field,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),{field:e.field,matched:f.size,missing:r.length-o.size,min:c,max:l,appliedMax:p}}auditBatches(e){let t=[],n=new Set,r=0;for(let i of e){let e=i.mesh.userData.geoRef?.pickInfo;if(!e)continue;let a=new Map;for(let[t,n]of Object.entries(e)){let e=B(n);if(e<0)continue;let r=Number(t),i=a.get(e);i?i.push(r):a.set(e,[r])}r+=a.size;for(let[e,r]of a)if(!(r.length<2)){for(let e of r)n.add(e);t.push({datasetId:i.datasetId,batchId:e,smids:r})}}return{smids:0,batches:r,conflicts:t,conflictingSmids:n.size}}applyOverridesToMesh(e){let n=Wi(e);if(!n)return;let r=e.userData,i=r.geoRef?.pickInfo,a=this.featureStyles.size>0||this.thematicColors.size>0||this.thematicElevation.size>0,o=this.filter,s=this.fieldFilter!=null||o!=null&&((o.include?.length??0)>0||(o.exclude?.length??0)>0||o.predicate!=null);if(!a&&!s||!i||Object.keys(i).length===0){n.userData.uBatchTexActive&&(n.userData.uBatchTexActive.value=0);return}let c=0;for(let e of Object.values(i)){let t=B(e);t>c&&(c=t)}let l=Math.max(c+1,1),u=this._meshBatchTextures.get(e);if(!u||u.width<l){let r=new Float32Array(l*2*4),i=new t.DataTexture(r,l,2,t.RGBAFormat,t.FloatType);i.minFilter=t.NearestFilter,i.magFilter=t.NearestFilter,u={texture:i,data:r,width:l},this._meshBatchTextures.set(e,u),n.userData.uBatchTex.value=i,n.userData.uBatchTexWidth.value=l}let{data:d,texture:f}=u,p=u.width;for(let e=0;e<p;e++){d[e*4+0]=-1,d[e*4+1]=-1,d[e*4+2]=-1,d[e*4+3]=0;let t=(p+e)*4;d[t+0]=0,d[t+1]=0,d[t+2]=0,d[t+3]=0}let m=!1,h=new Set,g=new Map,_=new Map,v=new Map,y=new Map;for(let[t,n]of Object.entries(i)){let i=Number(t),a=B(n);if(a<0||a>=u.width)continue;y.set(a,(y.get(a)??0)+1);let s=!1;if(o&&(o.include&&o.include.length>0&&!o.include.includes(i)&&(s=!0),o.exclude&&o.exclude.length>0&&o.exclude.includes(i)&&(s=!0),o.predicate)){let{segments:t}=V(r.geoRef,a),n=xt({smid:i,box:bt(e.geometry,t),triangles:0,floorHeight:this._getLayerFloorHeight()});o.predicate({...n,smid:i})||(s=!0)}if(s){h.add(a);continue}if(this.fieldFilter){let e=this.fieldFilter.matched.has(i);if(this.fieldFilter.mode===`keep`?!e:e){h.add(a);continue}}let c=this.featureStyles.get(i);if(c?.hidden){h.add(a);continue}let l=c?.color??this.thematicColors.get(i);l&&!g.has(a)&&g.set(a,l);let d=c?.elevation??this.thematicElevation.get(i);d!=null&&!_.has(a)&&_.set(a,d),c?.translation&&!v.has(a)&&v.set(a,c.translation)}for(let e of h)d[e*4+3]=-1,m=!0;let b=new t.Color;for(let[e,t]of g)h.has(e)||(b.set(t),d[e*4+0]=b.r,d[e*4+1]=b.g,d[e*4+2]=b.b,m=!0);for(let[e,t]of _){if(h.has(e))continue;d[e*4+3]=t;let n=(p+e)*4;d[n+2]=t,m=!0}for(let[e,t]of v){if(h.has(e))continue;let n=(p+e)*4;d[n+0]=t[0],d[n+1]=t[1],d[n+2]=t[2]+(_.get(e)??0),m=!0}let x=0;for(let[e,t]of y)t<2||(h.has(e)||g.has(e)||_.has(e))&&x++;x>0&&!this._batchConflictWarned&&(this._batchConflictWarned=!0,console.warn(`[s3m] 有 ${x} 个单体状态写不进独立的 batch(多个 SMID 共用同一个 batchId,\n S3M 的单体化粒度只到 batch,无法单独隐藏/改色其中一部分)。
505
+ `;function Ri(e,n={}){let r=new t.ShaderMaterial({uniforms:{uResolution:e.uResolution,uDpr:e.uDpr,uColor:{value:new t.Color(n.color??`#ffffff`)},uOpacity:{value:n.opacity??1},uWidth:{value:n.width??1.5},uElevation:{value:n.elevation??0},uTranslation:{value:new t.Vector3(0,0,0)}},vertexShader:Ii,fragmentShader:Li,transparent:!0,depthWrite:!1,side:t.DoubleSide,polygonOffset:!0,polygonOffsetFactor:-2,polygonOffsetUnits:-2});return r.userData.isThickLine=!0,r}function zi(e){let n=Math.floor(e.length/6),r=n*4,i=new Float32Array(r*3),a=new Float32Array(r*3),o=new Float32Array(r),s=r>65535?new Uint32Array(n*6):new Uint16Array(n*6);for(let t=0;t<n;t++){let n=t*6,r=e[n],i=e[n+1],a=e[n+2],o=e[n+3],l=e[n+4],u=e[n+5],d=t*4;c(d,r,i,a,o,l,u,-1),c(d+1,r,i,a,o,l,u,1),c(d+2,o,l,u,r,i,a,1),c(d+3,o,l,u,r,i,a,-1);let f=t*6;s[f]=d,s[f+1]=d+1,s[f+2]=d+2,s[f+3]=d,s[f+4]=d+2,s[f+5]=d+3}function c(e,t,n,r,s,c,l,u){let d=e*3;i[d]=t,i[d+1]=n,i[d+2]=r,a[d]=s,a[d+1]=c,a[d+2]=l,o[e]=u}let l=new t.BufferGeometry;return l.setAttribute(`position`,new t.BufferAttribute(i,3)),l.setAttribute(`aOther`,new t.BufferAttribute(a,3)),l.setAttribute(`aSide`,new t.BufferAttribute(o,1)),l.setIndex(new t.BufferAttribute(s,1)),l.computeBoundingSphere(),l}var Bi=6e4,Vi=100;function Hi(e,t,n=40){let r=e.getAttribute(`position`);if(!r)return null;let i=r.count;if(i<3)return null;let a=new Float32Array(i),o=new Float32Array(i),s=new Float32Array(i);for(let e=0;e<i;e++)a[e]=r.getX(e),o[e]=r.getY(e),s[e]=r.getZ(e);let c=null,l=null;if(!e.index){let e=new Map;c=new Uint32Array(i),l=new Uint32Array(i);let t=0;for(let n=0;n<i;n++){let r=`${Math.round(a[n]*Vi)},${Math.round(o[n]*Vi)},${Math.round(s[n]*Vi)}`,i=e.get(r);i===void 0&&(i=t++,e.set(r,i),l[i]=n),c[n]=i}}let u=e=>c?c[e]:e,d=e=>l?l[e]:e,f=e.index,p=f?f.array:null,m=Math.floor(f?f.count/3:i/3);if(m<1)return null;let h=null;if(t&&t.length>0){h=new Uint8Array(i);for(let e of t){let t=Math.max(0,e.vertexOffset|0),n=Math.min(i,t+(e.vertexCount|0));n>t&&h.fill(1,t,n)}if(!h.includes(1))return null}let g=new Float32Array(m*3),_=new Map,v=i+1,y=[],b=Math.cos(n*Math.PI/180),x=-1,S=0,C=0,w=0,T=(e,t)=>{if(y.length>=Bi*6)return!1;let n=d(e),r=d(t);return y.push(a[n],o[n],s[n],a[r],o[r],s[r]),!0},E=(e,t)=>{if(e===t)return;let n=e<t?e:t,r=e<t?t:e,i=n*v+r,a=_.get(i);a===void 0?_.set(i,x):a<0||(S*g[a*3]+C*g[a*3+1]+w*g[a*3+2]<b?(T(n,r),_.set(i,-1)):_.set(i,-2))};for(x=0;x<m;x++){let e=p?p[x*3]:x*3,t=p?p[x*3+1]:x*3+1,n=p?p[x*3+2]:x*3+2;if(h&&!(h[e]&&h[t]&&h[n]))continue;let r=a[t]-a[e],i=o[t]-o[e],c=s[t]-s[e],l=a[n]-a[e],d=o[n]-o[e],f=s[n]-s[e];S=i*f-c*d,C=c*l-r*f,w=r*d-i*l;let m=Math.hypot(S,C,w);m<1e-12||(S/=m,C/=m,w/=m,g[x*3]=S,g[x*3+1]=C,g[x*3+2]=w,E(u(e),u(t)),E(u(t),u(n)),E(u(n),u(e)))}for(let[e,t]of _){if(t<0)continue;let n=Math.floor(e/v);if(!T(n,e-n*v))break}return y.length>0?new Float32Array(y):null}var Ui=class{constructor(){h(this,`datasets`,new Map),h(this,`sceneAnchor`,null),h(this,`totalMaxTiles`,0)}get(e){return this.datasets.get(e)}values(){return this.datasets.values()}registerDataset(e){let n=this.datasets.get(e.id);if(n)return n;let r=new t.Group;r.name=`s3m-dataset:${e.id}`,r.visible=e.visible!==!1;let i={id:e.id,name:e.name??e.id,options:e,root:r,tileset:null,anchor:null,baseAlignOffset:0,userOffset:e.heightOffset??0,heightOffset:e.heightOffset??0,offset:[0,0,0],visible:e.visible!==!1,error:null};return this.datasets.set(e.id,i),this.rebalanceBudgets(),i}rebalanceBudgets(e){let t=e??this.totalMaxTiles;if(!t||t<=0)return;this.totalMaxTiles=t;let n=Array.from(this.datasets.values()).filter(e=>e.visible&&e.tileset),r=Math.max(1,n.length),i=Math.max(8,Math.floor(t/r));for(let e of this.datasets.values())e.tileset&&(e.visible?(e.tileset.maxTiles=i,e.tileset.hardCap=i+Math.max(4,Math.ceil(i*.5))):(e.tileset.maxTiles=Math.min(4,e.tileset.maxTiles),e.tileset.hardCap=Math.min(6,e.tileset.hardCap)))}computeAlignOffset(e,t){if(!t||t===`origin`||!e)return 0;let n=e.heightRange;if(!n)return 0;switch(t){case`top`:return-n.max;case`bottom`:return-n.min;case`center`:return-(n.min+n.max)/2;default:return 0}}async addDataset(e,n,r,i,a,o,s,c,l){let u=this.datasets.get(e.id);if(u)return u;let d=new t.Group;d.name=`s3m-dataset:${e.id}`,d.visible=e.visible!==!1,n.add(d);let f={id:e.id,name:e.name??e.id,options:e,root:d,tileset:null,anchor:null,baseAlignOffset:0,userOffset:e.heightOffset??0,heightOffset:e.heightOffset??0,offset:[0,0,0],visible:e.visible!==!1,error:null};this.datasets.set(e.id,f);let p=new bi({configUrl:e.configUrl,maxTiles:e.maxTiles??s,maxConcurrent:c,lodRangeScale:e.lodRangeScale??a,buildTile:o??null,uniforms:i,onTile:e=>{l.onTile(e,f)},onTileRemoved:e=>{l.onTileRemoved(e,f)},onProgress:()=>{l.onStats(),l.triggerRepaint()},onError:e=>{f.error=e,l.onError(e),l.onStats()}});f.tileset=p,this.rebalanceBudgets();try{await p.init()}catch(e){return f.error=e,l.onError(e),f}return f.anchor=p.anchor,f.baseAlignOffset=this.computeAlignOffset(p,e.align),f.userOffset=e.heightOffset??0,f.heightOffset=f.baseAlignOffset+f.userOffset,this.layoutDataset(f,r),l.onReady(f),l.triggerRepaint(),f}removeDataset(e,t,n,r){let i=this.datasets.get(e);return i?(r(i),i.tileset?.dispose(),t.remove(i.root),this.datasets.delete(e),this.rebalanceBudgets(),this.datasets.size>0?this.recomputeAnchors(n):this.sceneAnchor=null,!0):!1}clearDatasets(e,t){for(let n of this.datasets.values())t(n),n.tileset?.dispose(),e.remove(n.root);this.datasets.clear(),this.sceneAnchor=null}layoutDataset(e,t){if(!e.anchor)return;this.sceneAnchor||(this.sceneAnchor=Mt(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0));let n=this.sceneAnchor.meterInMercator,r=Mt(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0);e.offset=[(r.x-this.sceneAnchor.x)/n,-(r.y-this.sceneAnchor.y)/n,(r.z-this.sceneAnchor.z)/n+(e.heightOffset??0)],e.root.position.set(e.offset[0],e.offset[1],e.offset[2]),e.root.updateMatrixWorld(!0)}recomputeAnchors(e){if(this.datasets.size!==0){this.sceneAnchor=null;for(let t of this.datasets.values())this.layoutDataset(t,e)}}getDatasetHeight(e){let t=e??this.datasets.keys().next().value;return t?this.datasets.get(t)?.userOffset??0:0}setDatasetHeight(e,t,n){let r=this.datasets.get(e);r&&(r.userOffset=t,r.heightOffset=r.baseAlignOffset+t,this.layoutDataset(r,n))}setDatasetAlign(e,t,n){let r=this.datasets.get(e);if(!r)return;let i=r.heightOffset-r.baseAlignOffset;r.baseAlignOffset=this.computeAlignOffset(r.tileset,t),r.userOffset=i,r.heightOffset=r.baseAlignOffset+i,r.options.align=t,this.layoutDataset(r,n)}setDatasetVisible(e,t){let n=this.datasets.get(e);n&&(n.visible=t,n.root.visible=t,this.rebalanceBudgets())}getBounds(){let e=1/0,t=1/0,n=-1/0,r=-1/0,i=!1;for(let a of this.datasets.values()){if(!a.visible||!a.tileset?.config)continue;let o=_i(a.tileset.config.geoBounds);o&&(e=Math.min(e,o.left),t=Math.min(t,o.bottom),n=Math.max(n,o.right),r=Math.max(r,o.top),i=!0)}return i?[[e,t],[n,r]]:null}};Ct();function Wi(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function Gi(e,t){if(e.length<2)return e[0].clone();let n=Math.min(1,Math.max(0,t))*(e.length-1),r=Math.min(e.length-2,Math.floor(n));return e[r].clone().lerp(e[r+1],n-r)}function Ki(e,t,n){if(n.keep&&!n.keep(e,t))return!1;if(n.values?.length){let t=e==null?``:String(e);if(!n.values.some(e=>String(e)===t))return!1}if(n.min!=null||n.max!=null){let t=Number(e);if(!Number.isFinite(t)||n.min!=null&&t<n.min||n.max!=null&&t>n.max)return!1}return!n.keep&&!n.values?.length&&n.min==null&&n.max==null?e!=null&&String(e)!==``:!0}function qi(e){if(!Number.isFinite(e))return`—`;let t=Math.abs(e);return t>=100?e.toFixed(0):t>=10?e.toFixed(1):e.toFixed(2)}var Ji=class{constructor(e,t,n,r,i){h(this,`_getLayerFloorHeight`,void 0),h(this,`_triggerRepaint`,void 0),h(this,`_onStyleChanged`,void 0),h(this,`_getAllMeshes`,void 0),h(this,`_applyOverrideHook`,void 0),h(this,`featureStyles`,new Map),h(this,`thematicColors`,new Map),h(this,`thematicElevation`,new Map),h(this,`thematicField`,null),h(this,`elevationField`,null),h(this,`filter`,null),h(this,`fieldFilter`,null),h(this,`_meshBatchTextures`,new WeakMap),h(this,`_markedMeshes`,new Set),h(this,`_dirtyAll`,!1),h(this,`_flushScheduled`,!1),h(this,`_batchConflictWarned`,!1),this._getLayerFloorHeight=e,this._triggerRepaint=t,this._onStyleChanged=n,this._getAllMeshes=r,this._applyOverrideHook=i}setFeatureStyle(e,t,n){this.featureStyles.set(e,t),this.markOverridesDirty(n),this._onStyleChanged(),this._triggerRepaint()}setFeaturesStyle(e,t,n){for(let n of e)this.featureStyles.set(n,t);this.markOverridesDirty(n),this._onStyleChanged(),this._triggerRepaint()}getFeatureStyle(e){return this.featureStyles.get(e)??null}getFeatureEffectiveOffset(e){if(e==null)return{};let t=this.featureStyles.get(e),n=t?.elevation??this.thematicElevation.get(e);return{translation:t?.translation,elevation:n}}getFeatureStyles(){return new Map(this.featureStyles)}removeFeatureStyle(e,t){this.featureStyles.delete(e)&&(this.markOverridesDirty(t),this._onStyleChanged(),this._triggerRepaint())}clearFeatureStyles(){this.featureStyles.size>0&&(this.featureStyles.clear(),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint())}setThematicColors(e,t=`custom`){this.thematicColors=e&&e.size>0?new Map(e):new Map,this.thematicField=this.thematicColors.size>0?t:null,this.markOverridesDirty(),this._triggerRepaint()}clearThematicColors(){this.thematicColors.size!==0&&(this.thematicColors=new Map,this.thematicField=null,this.markOverridesDirty(),this._triggerRepaint())}setThematicElevation(e,t=`custom`){this.thematicElevation=e&&e.size>0?new Map([...e].filter(([,e])=>Number.isFinite(e)&&e>0)):new Map,this.elevationField=this.thematicElevation.size>0?t:null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint()}clearThematicElevation(){this.thematicElevation.size!==0&&(this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint())}setFilter(e,t){this.filter=e,e&&(e.minHeight!=null||e.maxHeight!=null)?(t.uFilterMinZ&&(t.uFilterMinZ.value=e.minHeight??-99999),t.uFilterMaxZ&&(t.uFilterMaxZ.value=e.maxHeight??99999),t.uFilterHeightActive&&(t.uFilterHeightActive.value=1)):t.uFilterHeightActive&&(t.uFilterHeightActive.value=0),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint()}clearFilter(e){this.setFilter(null,e)}async colorByField(e,n,r){if(!n)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let i=e.smids?.length?[...new Set(e.smids)]:r;if(!i.length)return this.clearThematicColors(),{field:e.field,type:`discrete`,matched:0,missing:0,legend:[]};let a=await n.queryBySmids(i),o=[],s=[];for(let t of i){let n=a.get(t),r=n?n[e.field]:void 0;if(r==null||r===``)continue;let i=Number(r);Number.isFinite(i)?o.push({smid:t,val:i}):s.push({smid:t,val:String(r)})}let c=o.length>=s.length&&o.length>0,l=new Map,u=[],d=e.defaultColor??`#64748b`,f=e.nullColor??`#334155`;if(c){let n=o.map(e=>e.val),r=Math.min(...n),i=Math.max(...n)-r||1,a=(e.ramp??[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`]).map(e=>new t.Color(e)),s=Math.max(2,e.stops??5);for(let e=0;e<s;e++){let t=e/s,n=(e+1)/s,o=Gi(a,(t+n)/2),c=r+t*i,l=r+n*i;u.push({color:`#${o.getHexString()}`,label:`${qi(c)} ~ ${qi(l)}`,count:0,min:c,max:l})}for(let{smid:e,val:t}of o){let n=Math.min(1,Math.max(0,(t-r)/i)),a=Math.min(s-1,Math.floor(n*s)),o=u[a].color;l.set(e,o),u[a].count++}}else{let t=new Map;for(let{val:e}of s)t.set(e,(t.get(e)??0)+1);let n=[...t.entries()].sort((e,t)=>t[1]-e[1]),r=Array.isArray(e.colors)?e.colors:[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`,`#8b5cf6`,`#ec4899`,`#06b6d4`,`#84cc16`],i=!Array.isArray(e.colors)&&e.colors?e.colors:null;for(let e=0;e<n.length;e++){let[t,a]=n[e],o=i?.[t]??r[e%r.length];u.push({color:o,label:t,count:a})}let a=new Map(u.map(e=>[e.label,e.color]));for(let{smid:e,val:t}of s)l.set(e,a.get(t)??d)}let p=0;for(let e of i)l.has(e)||(l.set(e,f),p++);return p>0&&u.push({color:f,label:`无数据 / 缺失`,count:p}),this.setThematicColors(l,e.field),{field:e.field,type:c?`continuous`:`discrete`,matched:i.length-p,missing:p,legend:u}}async filterByField(e,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n,i=e.mode??`keep`,a=e.onMissing??`drop`,o={field:e.field,mode:i,matched:0,hidden:[]};if(!r.length)return this.fieldFilter=null,this.markOverridesDirty(),o;let s=await t.queryBySmids(r),c=new Set;for(let t of r){let n=s.get(t);n?Ki(n[e.field]??null,n,e)&&c.add(t):a===`keep`&&c.add(t)}o.matched=c.size;let l=i===`keep`;return this.fieldFilter=c.size||l?{field:e.field,mode:l?`keep`:`drop`,matched:c}:null,o.hidden=r.filter(e=>l?!c.has(e):c.has(e)),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),o}clearFieldFilter(){this.fieldFilter&&(this.fieldFilter=null,this.markOverridesDirty(),this._triggerRepaint())}async elevateByField(e,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n,i={field:e.field,matched:0,missing:r.length,min:0,max:0,appliedMax:0};if(!r.length)return this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),i;let a=await t.queryBySmids(r),o=new Map;for(let t of r){let n=Number(a.get(t)?.[e.field]);Number.isFinite(n)&&o.set(t,n)}if(o.size===0)return this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),i;let s=[...o.values()],c=Math.min(...s),l=Math.max(...s),u=e.scale??1,d=e.offset??0,f=new Map,p=0;for(let[t,n]of o){let r=e.map?e.map(n,{min:c,max:l}):n*u+d;Number.isFinite(r)&&(e.max!=null&&r>e.max&&(r=e.max),!(r<=0)&&(f.set(t,r),r>p&&(p=r)))}return this.thematicElevation=f,this.elevationField=e.field,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),{field:e.field,matched:f.size,missing:r.length-o.size,min:c,max:l,appliedMax:p}}auditBatches(e){let t=[],n=new Set,r=0;for(let i of e){let e=i.mesh.userData.geoRef?.pickInfo;if(!e)continue;let a=new Map;for(let[t,n]of Object.entries(e)){let e=B(n);if(e<0)continue;let r=Number(t),i=a.get(e);i?i.push(r):a.set(e,[r])}r+=a.size;for(let[e,r]of a)if(!(r.length<2)){for(let e of r)n.add(e);t.push({datasetId:i.datasetId,batchId:e,smids:r})}}return{smids:0,batches:r,conflicts:t,conflictingSmids:n.size}}applyOverridesToMesh(e){let n=Wi(e);if(!n)return;let r=e.userData,i=r.geoRef?.pickInfo,a=this.featureStyles.size>0||this.thematicColors.size>0||this.thematicElevation.size>0,o=this.filter,s=this.fieldFilter!=null||o!=null&&((o.include?.length??0)>0||(o.exclude?.length??0)>0||o.predicate!=null);if(!a&&!s||!i||Object.keys(i).length===0){n.userData.uBatchTexActive&&(n.userData.uBatchTexActive.value=0);return}let c=0;for(let e of Object.values(i)){let t=B(e);t>c&&(c=t)}let l=Math.max(c+1,1),u=this._meshBatchTextures.get(e);if(!u||u.width<l){let r=new Float32Array(l*2*4),i=new t.DataTexture(r,l,2,t.RGBAFormat,t.FloatType);i.minFilter=t.NearestFilter,i.magFilter=t.NearestFilter,u={texture:i,data:r,width:l},this._meshBatchTextures.set(e,u),n.userData.uBatchTex.value=i,n.userData.uBatchTexWidth.value=l}let{data:d,texture:f}=u,p=u.width;for(let e=0;e<p;e++){d[e*4+0]=-1,d[e*4+1]=-1,d[e*4+2]=-1,d[e*4+3]=0;let t=(p+e)*4;d[t+0]=0,d[t+1]=0,d[t+2]=0,d[t+3]=0}let m=!1,h=new Set,g=new Map,_=new Map,v=new Map,y=new Map;for(let[t,n]of Object.entries(i)){let i=Number(t),a=B(n);if(a<0||a>=u.width)continue;y.set(a,(y.get(a)??0)+1);let s=!1;if(o&&(o.include&&o.include.length>0&&!o.include.includes(i)&&(s=!0),o.exclude&&o.exclude.length>0&&o.exclude.includes(i)&&(s=!0),o.predicate)){let{segments:t}=V(r.geoRef,a),n=xt({smid:i,box:bt(e.geometry,t),triangles:0,floorHeight:this._getLayerFloorHeight()});o.predicate({...n,smid:i})||(s=!0)}if(s){h.add(a);continue}if(this.fieldFilter){let e=this.fieldFilter.matched.has(i);if(this.fieldFilter.mode===`keep`?!e:e){h.add(a);continue}}let c=this.featureStyles.get(i);if(c?.hidden){h.add(a);continue}let l=c?.color??this.thematicColors.get(i);l&&!g.has(a)&&g.set(a,l);let d=c?.elevation??this.thematicElevation.get(i);d!=null&&!_.has(a)&&_.set(a,d),c?.translation&&!v.has(a)&&v.set(a,c.translation)}for(let e of h)d[e*4+3]=-1,m=!0;let b=new t.Color;for(let[e,t]of g)h.has(e)||(b.set(t),d[e*4+0]=b.r,d[e*4+1]=b.g,d[e*4+2]=b.b,m=!0);for(let[e,t]of _){if(h.has(e))continue;d[e*4+3]=t;let n=(p+e)*4;d[n+2]=t,m=!0}for(let[e,t]of v){if(h.has(e))continue;let n=(p+e)*4;d[n+0]=t[0],d[n+1]=t[1],d[n+2]=t[2]+(_.get(e)??0),m=!0}let x=0;for(let[e,t]of y)t<2||(h.has(e)||g.has(e)||_.has(e))&&x++;x>0&&!this._batchConflictWarned&&(this._batchConflictWarned=!0,console.warn(`[s3m] 有 ${x} 个单体状态写不进独立的 batch(多个 SMID 共用同一个 batchId,\n S3M 的单体化粒度只到 batch,无法单独隐藏/改色其中一部分)。
506
506
  当前规则:任一 SMID 需要隐藏则整批隐藏,颜色 / 抬高取首个。
507
507
  用 layer.auditBatches() 可以列出具体是哪些 SMID 共用了 batchId。`)),f.needsUpdate=!0,n.userData.uBatchTexActive&&(n.userData.uBatchTexActive.value=+!!m)}markOverridesDirty(e,t){if(e)for(let t of e)this._markedMeshes.add(t);else if(t)for(let e of t)this._markedMeshes.add(e);else this._dirtyAll=!0,this._markedMeshes.clear();this._flushScheduled||(this._flushScheduled=!0,queueMicrotask(()=>this.flushOverrides()))}disposeMesh(e){this._markedMeshes.delete(e);let t=this._meshBatchTextures.get(e);t&&(t.texture.dispose(),this._meshBatchTextures.delete(e))}flushOverrides(){if(!this._flushScheduled&&!this._dirtyAll&&this._markedMeshes.size===0)return;this._flushScheduled=!1;let e=this._applyOverrideHook??(e=>this.applyOverridesToMesh(e));if(this._dirtyAll){this._dirtyAll=!1,this._markedMeshes.clear();let t=this._getAllMeshes?this._getAllMeshes():[];for(let n of t)e(n);this._triggerRepaint()}else{for(let t of this._markedMeshes)e(t);this._markedMeshes.clear(),this._triggerRepaint()}}},Yi=class{constructor(e={}){h(this,`mode`,void 0),h(this,`opacity`,void 0),h(this,`color`,void 0),h(this,`gridColor`,void 0),h(this,`gridSize`,void 0),h(this,`excavationBounds`,null),h(this,`size`,void 0),h(this,`groundHeight`,0),h(this,`occlude`,void 0),h(this,`trackHeight`,void 0),h(this,`group`,void 0),h(this,`_mesh`,null),h(this,`_material`,null),h(this,`_depthMesh`,null),h(this,`_depthMaterial`,null),h(this,`_geom`,null),h(this,`_occludeExplicit`,void 0),this.mode=e.mode??`none`,this.opacity=e.opacity??.62,this.color=new t.Color(e.color??`#0f172a`),this.gridColor=new t.Color(e.gridColor??`#38bdf8`),this.gridSize=e.gridSize??10,this.excavationBounds=e.excavationBounds??null,this.size=e.size??6e3,this._occludeExplicit=e.occlude!==void 0,this.occlude=e.occlude??this.mode===`excavate`,this.trackHeight=e.trackHeight??!0,this.group=new t.Group,this.group.name=`s3m-ground-surface`,this._initMesh(),this._applyMode()}_initMesh(){let e=new t.PlaneGeometry(this.size,this.size,1,1);this._geom=e;let n=new t.ShaderMaterial({transparent:!0,depthTest:!0,depthWrite:!1,side:t.DoubleSide,uniforms:{uColor:{value:this.color},uGridColor:{value:this.gridColor},uOpacity:{value:this.opacity},uGridSize:{value:this.gridSize},uMode:{value:this.mode===`excavate`?2:+(this.mode===`translucent`)},uHasExcavation:{value:0},uExcavationMin:{value:new t.Vector2(-9999,-9999)},uExcavationMax:{value:new t.Vector2(9999,9999)}},vertexShader:`
508
508
  varying vec2 vEnuPos;
@@ -582,4 +582,4 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
582
582
  }
583
583
  gl_FragColor = vec4(1.0);
584
584
  }
585
- `}),a=new t.Mesh(e,i);a.position.set(0,0,-.02),a.renderOrder=-1e3,a.name=`s3m-ground-depth`,a.visible=!1,this.group.add(a),this._depthMesh=a,this._depthMaterial=i,this._syncUniforms()}_applyMode(){this._mesh&&(this._mesh.visible=this.mode!==`none`),this._material&&(this._material.uniforms.uMode.value=this.mode===`excavate`?2:+(this.mode===`translucent`),this._material.depthWrite=this.mode===`excavate`),this._depthMesh&&(this._depthMesh.visible=this.occlude,this._depthMaterial&&(this._depthMaterial.uniforms.uPunchPit.value=+(this.mode===`excavate`)))}update(e){e&&this.group.position.set(e.position.x,e.position.y,this.groundHeight)}setGroundHeight(e){this.groundHeight=e,this.group.position.z=e}setMode(e){this.mode=e,this._occludeExplicit||(this.occlude=e===`excavate`),this._applyMode()}setOcclude(e){this.occlude=e,this._occludeExplicit=!0,this._applyMode()}setOpacity(e){this.opacity=Math.max(0,Math.min(1,e)),this._material&&(this._material.uniforms.uOpacity.value=this.opacity)}setColors(e,t){this.color.set(e),t&&this.gridColor.set(t),this._material&&(this._material.uniforms.uColor.value=this.color,this._material.uniforms.uGridColor.value=this.gridColor)}setExcavationBounds(e){this.excavationBounds=e,this._syncUniforms()}autoFitExcavation(e){let t=1/0,n=1/0,r=-1/0,i=-1/0,a=!1;for(let o of e){let e=o.tileset?.config,s=e?.rootTiles??e?.tiles;if(Array.isArray(s))for(let e of s){let s=e.boundingBox;if(!s)continue;let c=s.center??{x:0,y:0},l=s.xExtent?.x?Math.abs(s.xExtent.x):50,u=s.yExtent?.y?Math.abs(s.yExtent.y):50,d=c.x+o.offset[0]-l,f=c.x+o.offset[0]+l,p=c.y+o.offset[1]-u,m=c.y+o.offset[1]+u;d<t&&(t=d),f>r&&(r=f),p<n&&(n=p),m>i&&(i=m),a=!0}}a&&Number.isFinite(t)&&this.setExcavationBounds([t-5,n-5,r+5,i+5])}_syncUniforms(){let e=this.excavationBounds;if(this._material){let t=this._material.uniforms;e?(t.uHasExcavation.value=1,t.uExcavationMin.value.set(e[0],e[1]),t.uExcavationMax.value.set(e[2],e[3])):t.uHasExcavation.value=0}if(this._depthMaterial){let t=this._depthMaterial.uniforms;e?(t.uHasExcavation.value=1,t.uExcavationMin.value.set(e[0],e[1]),t.uExcavationMax.value.set(e[2],e[3])):t.uHasExcavation.value=0}}dispose(){this._geom?.dispose(),this._geom=null,this._material?.dispose(),this._material=null,this._depthMaterial?.dispose(),this._depthMaterial=null,this._mesh=null,this._depthMesh=null,this.group.clear()}};Z(),Wr(),Ct();var Xi=65534;function Zi(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function Qi(e){return e.isPoints===!0}var $i=class{get datasets(){return this._datasetManager.datasets}get sceneAnchor(){return this._datasetManager.sceneAnchor}set sceneAnchor(e){this._datasetManager.sceneAnchor=e}_requestRepaint(){this._onRequestRepaint()}constructor(e={}){h(this,`options`,void 0),h(this,`pickable`,void 0),h(this,`onStats`,void 0),h(this,`onReady`,void 0),h(this,`onPick`,void 0),h(this,`onError`,void 0),h(this,`geo`,null),h(this,`canvas`,null),h(this,`renderer`,null),h(this,`scene`,null),h(this,`camera`,null),h(this,`picker`,null),h(this,`uniforms`,void 0),h(this,`style`,void 0),h(this,`outlineMaterial`,void 0),h(this,`lineShared`,void 0),h(this,`edgeMaterial`,void 0),h(this,`selectionEdgeMaterial`,void 0),h(this,`groundManager`,void 0),h(this,`_datasetManager`,new Ui),h(this,`_featureStyleManager`,void 0),h(this,`_pickables`,new Map),h(this,`_pickSeq`,0),h(this,`_freePickIds`,[]),h(this,`_smidMeshes`,new Map),h(this,`_meshHeight`,new Map),h(this,`_heightMin`,1/0),h(this,`_heightMax`,-1/0),h(this,`_boxScratch`,new t.Box3),h(this,`_selection`,null),h(this,`_selectedMeshes`,[]),h(this,`_outlineMesh`,null),h(this,`_outlineMeshes`,[]),h(this,`_selectionEdges`,null),h(this,`_selectionEdgeMeshes`,[]),h(this,`_edgesEnabled`,!1),h(this,`attributeQuery`,null),h(this,`_enuMatrix`,new t.Matrix4),h(this,`_needsRepaint`,!0),h(this,`_frame`,0),h(this,`_fps`,{value:0,last:0}),h(this,`_keyLight`,null),h(this,`_fillLight`,null),h(this,`_datasetQueue`,void 0),h(this,`_onRequestRepaint`,()=>{}),h(this,`_getBearing`,void 0),h(this,`_lodRangeScale`,1),this.options=e,this.pickable=e.pickable!==!1,this._lodRangeScale=e.lodRangeScale??1,this._onRequestRepaint=e.onRequestRepaint??(()=>{}),this._getBearing=e.getBearing,this.onStats=e.onStats??(()=>{}),this.onReady=e.onReady??(()=>{}),this.onPick=e.onPick??(()=>{}),this.onError=e.onError??(e=>console.warn(`[s3m]`,e)),this.groundManager=new Yi(e.ground),this._featureStyleManager=new Ji(()=>this.style.floorHeight,()=>this._requestRepaint(),()=>{this._selection&&this._syncSelectionStyle()},()=>this.getAllMeshes(),e=>this._applyOverridesToMesh(e)),this.uniforms=Dr(),this.style={...Mr,...e.style??{}},this.outlineMaterial=kr(this.uniforms),this.lineShared=Fi(),this.edgeMaterial=Ri(this.lineShared,{color:this.style.edgeColor,opacity:this.style.edgeOpacity??.45,width:this.style.edgeWidth??1.2}),this.selectionEdgeMaterial=Ri(this.lineShared,{color:this.style.outlineColor??this.style.selectColor,opacity:1,width:this.style.outlineWidthPx??3}),this._fps.last=performance.now(),this._datasetQueue=this._normalizeDatasets(e),e.attributes&&(this.attributeQuery=new Ot(e.attributes))}mount(e,n){this.canvas=e,this.renderer=new t.WebGLRenderer({canvas:e,context:n,antialias:!0}),this.renderer.autoClear=!1,this.renderer.setPixelRatio(1),this.renderer.toneMapping=t.ACESFilmicToneMapping,this.renderer.toneMappingExposure=1,vr(this.renderer.capabilities.getMaxAnisotropy()),this.scene=new t.Scene,this.scene.add(this.groundManager.group),this._addLights(),this.camera=new t.Camera,this.camera.matrixAutoUpdate=!1,this.picker=new Pi(this.renderer),this._applyStyleUniforms();for(let e of this._datasetQueue)this.addDataset(e).catch(e=>this.onError(e));this._recomputeAnchors()}unmount(){for(let e of[...this.datasets.keys()])this.removeDataset(e);this.groundManager.dispose(),this.picker?.dispose(),this.picker=null,this.outlineMaterial.dispose(),this.edgeMaterial.dispose(),this.selectionEdgeMaterial.dispose(),this.scene?.clear(),this._selectedMeshes=[],this._outlineMeshes=[],this._selectionEdgeMeshes=[],this._outlineMesh=null,this._selectionEdges=null,this._smidMeshes.clear(),this._meshHeight.clear(),this._heightMin=1/0,this._heightMax=-1/0,this.renderer?.dispose(),this.renderer=null,this.canvas=null}_addLights(){this.scene&&(this.scene.add(new t.AmbientLight(16777215,.4)),this.scene.add(new t.HemisphereLight(16777215,11976907,.8)),this._keyLight=new t.DirectionalLight(16777215,1),this._fillLight=new t.DirectionalLight(16777215,.35),this.scene.add(this._keyLight,this._fillLight))}_updateLights(){let e=(this._getBearing?.()??0)*Math.PI/180,t=(t,n,r)=>{if(!t)return;let i=e+n*Math.PI/180,a=r*Math.PI/180,o=Math.cos(a);t.position.set(Math.sin(i)*o,Math.cos(i)*o,Math.sin(a)).multiplyScalar(1e3)};t(this._keyLight,150,50),t(this._fillLight,215,30)}_normalizeDatasets(e){return Array.isArray(e.datasets)?e.datasets.filter(e=>!!e?.configUrl):e.configUrl?[{id:`default`,name:`默认数据集`,configUrl:e.configUrl}]:[]}async addDataset(e){if(!this.scene)throw Error(`[s3m] 图层尚未 addLayer,不能添加数据集`);return await this._datasetManager.addDataset(e,this.scene,this.geo,this.uniforms,this._lodRangeScale,this.options.buildTile,this.options.maxTiles??64,this.options.maxConcurrent??4,{onTile:(e,t)=>{this._registerTile(e,t),this.onStats(this.stats),this._needsRepaint=!0,this._requestRepaint()},onTileRemoved:(e,t)=>{this._unregisterTile(e,t),this.onStats(this.stats),this._needsRepaint=!0,this._requestRepaint()},onStats:()=>{this.onStats(this.stats),this._requestRepaint()},onError:e=>{this.onError(e),this.onStats(this.stats)},onReady:e=>{this.onReady(e),this._refreshAllHeights(),this.groundManager.excavationBounds||this.groundManager.autoFitExcavation(this.datasets.values())},triggerRepaint:()=>{this._requestRepaint()}})}_lngLatFromWorld(e,t){return Nt(this.geo,e,t)}recomputeAnchors(){this._datasetManager.recomputeAnchors(this.geo),this._refreshAllHeights(),this._requestRepaint()}_recomputeAnchors(){this.recomputeAnchors()}getDatasetHeight(e){return this._datasetManager.getDatasetHeight(e)}setDatasetHeight(e,t){let n,r;typeof e==`number`?(n=this.datasets.keys().next().value??``,r=e):(n=e,r=t??0),this._datasetManager.setDatasetHeight(n,r,this.geo),this._syncGroundHeight(),this._refreshAllHeights(),this._requestRepaint()}_syncGroundHeight(){if(!this.groundManager.trackHeight)return;let e=this.datasets.keys().next().value;if(!e)return;let t=this._datasetManager.getDatasetHeight(e);this.groundManager.setGroundHeight(t)}setDatasetAlign(e,t){let n,r;t===void 0&&(e===`origin`||e===`bottom`||e===`top`||e===`center`)?(n=this.datasets.keys().next().value??``,r=e):(n=e,r=t??`origin`),this._datasetManager.setDatasetAlign(n,r,this.geo),this._refreshAllHeights(),this._requestRepaint()}_computeAlignOffset(e,t){return this._datasetManager.computeAlignOffset(e,t)}computeAlignOffset(e,t){return this._datasetManager.computeAlignOffset(e,t)}setFeatureStyle(e,t){this._featureStyleManager.setFeatureStyle(e,t,this._meshesOf([e]))}setFeaturesStyle(e,t){this._featureStyleManager.setFeaturesStyle(e,t,this._meshesOf(e))}getFeatureStyle(e){return this._featureStyleManager.getFeatureStyle(e)}getFeatureStyles(){return this._featureStyleManager.getFeatureStyles()}removeFeatureStyle(e){this._featureStyleManager.removeFeatureStyle(e,this._meshesOf([e]))}clearFeatureStyles(){this._featureStyleManager.clearFeatureStyles()}setAttributeSource(e){this.attributeQuery=e?new Ot(e):null}getLoadedSmids(){return[...this._smidMeshes.keys()]}auditBatches(){let e=this._featureStyleManager.auditBatches(this._pickables.values());return e.smids=this._smidMeshes.size,e}getThematicField(){return this._featureStyleManager.thematicField}setThematicColors(e,t=`custom`){this._featureStyleManager.setThematicColors(e,t)}clearThematic(){this._featureStyleManager.clearThematicColors()}getFilterField(){return this._featureStyleManager.fieldFilter?.field??null}filterByField(e){return this._featureStyleManager.filterByField(e,this.attributeQuery,this.getLoadedSmids())}clearFieldFilter(){this._featureStyleManager.clearFieldFilter()}getElevationField(){return this._featureStyleManager.elevationField}elevateByField(e){return this._featureStyleManager.elevateByField(e,this.attributeQuery,this.getLoadedSmids())}setThematicElevation(e,t=`custom`){this._featureStyleManager.setThematicElevation(e,t)}clearThematicElevation(){this._featureStyleManager.clearThematicElevation()}colorByField(e){return this._featureStyleManager.colorByField(e,this.attributeQuery,this.getLoadedSmids())}setFilter(e){this._featureStyleManager.setFilter(e,this.uniforms)}getFilter(){return this._featureStyleManager.filter}clearFilter(){this._featureStyleManager.clearFilter(this.uniforms)}setGroundMode(e){this.groundManager.setMode(e),this._requestRepaint()}setGroundOpacity(e){this.groundManager.setOpacity(e),this._requestRepaint()}setExcavationBounds(e){this.groundManager.setExcavationBounds(e),this._requestRepaint()}setGroundOcclude(e){this.groundManager.setOcclude(e),this._requestRepaint()}_isFeatureHidden(e,t){if(e==null)return!1;let n=this._featureStyleManager.fieldFilter;if(n){let t=n.matched.has(e);if(n.mode===`keep`?!t:t)return!0}let r=this._featureStyleManager.filter;return!!(r&&(r.include&&r.include.length>0&&!r.include.includes(e)||r.exclude&&r.exclude.length>0&&r.exclude.includes(e))||this._featureStyleManager.featureStyles.get(e)?.hidden)}getAllMeshes(){let e=[];for(let t of this._pickables.values())e.push(t.mesh);return e}_meshesOf(e){let t=new Set;for(let n of e){let e=this._smidMeshes.get(n);if(e)for(let n of e)t.add(n)}return t}_markOverridesDirty(e=`all`){e===`all`?this._featureStyleManager.markOverridesDirty(void 0,this.getAllMeshes()):this._featureStyleManager.markOverridesDirty(e)}flushOverrides(){this._featureStyleManager.flushOverrides()}_applyOverridesToMesh(e){this._featureStyleManager.applyOverridesToMesh(e)}removeDataset(e){if(this.datasets.get(e)){this._selection?.datasetId===e&&this.select(null),this._datasetManager.removeDataset(e,this.scene,this.geo,e=>{e.root.traverse(e=>{let t=e,n=t.userData;n.pickId!=null&&(this._pickables.delete(n.pickId),this._releasePickId(n.pickId),n.pickId=void 0),this._unindexMeshSmids(t),this._removeMeshHeight(t),t.geometry?.dispose?.();let r=Zi(t);r&&r.dispose(),Oi(t.material)&&t.material.dispose(),this._featureStyleManager.disposeMesh(t)})});for(let[t,n]of this._pickables)n.datasetId===e&&this._pickables.delete(t);this.onStats(this.stats),this._requestRepaint()}}clearDatasets(){for(let e of[...this.datasets.keys()])this.removeDataset(e)}setDatasetVisible(e,t){this._datasetManager.setDatasetVisible(e,t),!t&&this._selection?.datasetId===e&&this.select(null),this._requestRepaint()}_registerTile(e,t){t.root.add(e.group),e.group.updateMatrixWorld(!0);let n=e.group.userData.hasNativeEdges===!0;for(let r of e.group.children){if(r.isLineSegments&&r.userData.isEdgeLines){r.visible=this._edgesEnabled,this._styleEdgeLine(r);continue}let i=Qi(r),a=r;if(!a.isMesh&&!i)continue;let o=a.userData;if(o.pickId=this._allocPickId(),o.datasetId=t.id,o.nativeEdges=n,this._pickables.set(o.pickId,{datasetId:t.id,mesh:a,tile:e.tile,skeletonName:o.skeletonName??``}),this._indexMeshSmids(a),this._addMeshHeight(a),this._edgesEnabled&&!n&&!i&&this._ensureEdges(a),i)this._applyPointCloudStyle(r);else{let e=Zi(a);if(e){let t=Math.min(1,Math.max(.05,this.style.opacity??1));e.opacity=t,e.transparent=t<.999,e.depthWrite=t>=.999,e.flatShading=this.style.shading!==`smooth`,e.needsUpdate=!0,this._featureStyleManager.applyOverridesToMesh(a)}}this._replaySelectionOnto(a)}}_replaySelectionOnto(e){let t=this._selection;if(!t)return;let n=Zi(e);if(!n)return;let r=e.userData,i=-1;if(t.smid!=null){let e=r.geoRef?.pickInfo,n=e?.[t.smid]??e?.[String(t.smid)];i=n?B(n):-1}e===t.mesh&&(i=t.batchId),!(i<0&&e!==t.mesh)&&(n.userData.uSelBatch.value=i,n.userData.uSelWhole.value=+(i<0),this._selectedMeshes.includes(e)||this._selectedMeshes.push(e),Qi(e)&&this._applyPointCloudStyle(e,!0),this.uniforms.uSelMix.value=1,this.uniforms.uDim.value=+!!this.style.dimOthers)}_unregisterTile(e,t){for(let t of[...e.group.children]){let e=t;if(!e.isMesh)continue;let n=e.userData;if(this._selectedMeshes.includes(e)&&(this._selectedMeshes=this._selectedMeshes.filter(t=>t!==e)),this._selection?.mesh===e){let t=this._selection.smid,n=t==null?void 0:[...this._smidMeshes.get(t)??[]].find(t=>t!==e&&t.parent);n?(this._selection={...this._selection,mesh:n},this._replaySelectionOnto(n)):this.select(null)}n.pickId!=null&&(this._pickables.delete(n.pickId),this._releasePickId(n.pickId),n.pickId=void 0),this._unindexMeshSmids(e),this._removeMeshHeight(e),this._featureStyleManager.disposeMesh(e),Zi(e)?.dispose?.(),Oi(e.material)&&e.material.dispose(),e.geometry?.dispose?.()}t.root.remove(e.group)}_allocPickId(){let e=this._freePickIds.pop();if(e!==void 0)return e;if(this._pickSeq>Xi){for(let e=0;e<=Xi;e++)if(!this._pickables.has(e))return e;throw Error(`[s3m] 可拾取网格超过 65535 个,2 字节 ID 编码不够用`)}return this._pickSeq++}_releasePickId(e){this._freePickIds.push(e)}setOpacity(e){this.setStyle({opacity:e})}setStyle(e={}){this.style={...this.style,...e},this._applyStyleUniforms(),(`opacity`in e||`depthWrite`in e)&&this._applyOpacity(),`mode`in e&&this._applyPointCloudStyles(),`shading`in e&&this._applyShading(),`edges`in e?this.setEdges(!!this.style.edges):(`edgeColor`in e||`edgeWidth`in e||`opacity`in e||`edgeOpacity`in e)&&this._refreshEdgeLines(),this._selection&&(`outline`in e||`outlineStyle`in e?this.select(this._selection,{silent:!0}):this._syncSelectionStyle()),this._requestRepaint()}getStyle(){return{...this.style,modeLabel:Ar[this.style.mode]}}_applyStyleUniforms(){let e=this.uniforms,t=this.style;e.uMode.value=t.mode,e.uColorA.value.set(t.colorA),e.uColorB.value.set(t.colorB),e.uColorC.value.set(t.colorC),e.uSelColor.value.set(t.selectColor),e.uFloorHeight.value=t.floorHeight;let n=t.selectMode??$.OVERLAY;e.uSelMode&&(e.uSelMode.value=n===$.REPLACE?0:n===$.MULTIPLY?2:n===$.GLOW_ONLY?3:1),e.uSelOpacity&&t.selectOpacity!=null&&(e.uSelOpacity.value=t.selectOpacity),e.uSelEmissive&&t.selectEmissive!=null&&(e.uSelEmissive.value=t.selectEmissive),e.uSelElevation&&t.selectElevation!=null&&(e.uSelElevation.value=t.selectElevation),e.uDimFactor&&t.dimFactor!=null&&(e.uDimFactor.value=t.dimFactor),e.uRoofThreshold&&t.roofThreshold!=null&&(e.uRoofThreshold.value=t.roofThreshold),e.uTexMix&&t.texMix!=null&&(e.uTexMix.value=t.texMix),this.outlineMaterial&&(this.outlineMaterial.uniforms.uElevation&&t.selectElevation!=null&&(this.outlineMaterial.uniforms.uElevation.value=t.selectElevation),t.outlineWidth!=null&&(this.outlineMaterial.uniforms.uWidth.value=t.outlineWidth),t.outlineColor==null?this.outlineMaterial.uniforms.uColor.value.set(t.selectColor):this.outlineMaterial.uniforms.uColor.value.set(t.outlineColor))}_applyOpacity(){let e=Math.min(1,Math.max(.05,this.style.opacity??1)),t=e<.999,n=this.style.depthWrite!==!1;for(let r of this._pickables.values()){if(Qi(r.mesh)){this._applyPointCloudStyle(r.mesh);continue}let i=Zi(r.mesh);i&&(i.opacity=e,i.transparent=t,i.depthWrite=!t||n)}this._requestRepaint()}_applyPointCloudStyle(e,t=this._selectedMeshes.includes(e)){Di(e,this.style,this.uniforms,t)}_applyPointCloudStyles(){for(let e of this._pickables.values())Qi(e.mesh)&&this._applyPointCloudStyle(e.mesh);this._requestRepaint()}_applyShading(){let e=this.style.shading!==`smooth`;for(let t of this._pickables.values()){let n=Zi(t.mesh);n&&n.flatShading!==e&&(n.flatShading=e,n.needsUpdate=!0)}this._requestRepaint()}_addMeshHeight(e){let t=e.geometry?.boundingBox;if(!t)return;this._boxScratch.copy(t).applyMatrix4(e.matrixWorld);let n=this._boxScratch.min.z,r=this._boxScratch.max.z;Number.isFinite(n)&&Number.isFinite(r)&&(this._meshHeight.set(e,{min:n,max:r}),n<this._heightMin&&(this._heightMin=n),r>this._heightMax&&(this._heightMax=r),this._pushHeightRange())}_removeMeshHeight(e){let t=this._meshHeight.get(e);t&&(this._meshHeight.delete(e),t.min===this._heightMin||t.max===this._heightMax?this._recomputeHeightRange():this._pushHeightRange())}_refreshAllHeights(){if(this._meshHeight.size===0)return;let e=[...this._meshHeight.keys()];this._meshHeight.clear(),this._heightMin=1/0,this._heightMax=-1/0;for(let t of e)this._addMeshHeight(t);this._pushHeightRange()}_recomputeHeightRange(){let e=1/0,t=-1/0;for(let n of this._meshHeight.values())n.min<e&&(e=n.min),n.max>t&&(t=n.max);this._heightMin=e,this._heightMax=t,this._pushHeightRange()}_pushHeightRange(){let e=this._heightMin,t=this._heightMax;(!Number.isFinite(e)||!Number.isFinite(t)||t<=e)&&(e=0,t=100),this.uniforms.uHeightMin.value=e,this.uniforms.uHeightMax.value=t}_indexMeshSmids(e){let t=e.userData.geoRef?.pickInfo;if(t)for(let n of Object.keys(t)){let t=Number(n);if(!Number.isFinite(t)||t<0)continue;let r=this._smidMeshes.get(t);r||this._smidMeshes.set(t,r=new Set),r.add(e)}}_unindexMeshSmids(e){let t=e.userData.geoRef?.pickInfo;if(t)for(let n of Object.keys(t)){let t=Number(n),r=this._smidMeshes.get(t);r&&(r.delete(e),r.size===0&&this._smidMeshes.delete(t))}}setEdges(e){this._edgesEnabled=e,this.style.edges=e;for(let t of this.datasets.values())t.root.traverse(t=>{t.userData.isEdgeLines&&(t.visible=e,this._styleEdgeLine(t))});if(this._syncEdgeStyle(),!e){for(let e of this._pickables.values())this._removeEdges(e.mesh);this._requestRepaint();return}let t=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e.userData;return!t.edges&&!t.nativeEdges&&!Qi(e)}),n=0,r=()=>{let e=performance.now();for(;n<t.length&&performance.now()-e<8;)this._ensureEdges(t[n++]);n<t.length?setTimeout(r,0):this._requestRepaint()};r()}_syncEdgeStyle(){let e=this.style,t=this.edgeMaterial.uniforms;t.uColor.value.set(e.edgeColor),t.uWidth.value=Math.max(.1,e.edgeWidth??1.2),t.uOpacity.value=Math.min(1,Math.max(0,e.edgeOpacity??.45))*Math.min(1,Math.max(.05,e.opacity??1))}_styleEdgeLine(e){let t=e.material;t&&t.color&&(t.color.set(this.style.edgeColor),t.opacity=(this.style.edgeOpacity??.45)*Math.min(1,Math.max(.05,this.style.opacity??1)),t.transparent=!0,t.polygonOffset=!0,t.polygonOffsetFactor=-1,t.polygonOffsetUnits=-1,t.needsUpdate=!0)}_refreshEdgeLines(){this._syncEdgeStyle();for(let e of this.datasets.values())e.root.traverse(e=>{e.userData.isEdgeLines&&this._styleEdgeLine(e)})}_ensureEdges(e){let n=e.userData;if(n.edges||n.nativeEdges||!e.geometry||(e.geometry.index?.count??0)>12e4)return;let r=new t.EdgesGeometry(e.geometry,40),i=r.getAttribute(`position`),a=i?i.array:null;if(r.dispose(),!a||a.length<6)return;let o=new t.Mesh(zi(a),this.edgeMaterial);o.renderOrder=2,o.frustumCulled=!1,o.raycast=()=>{},o.userData.isThickEdge=!0,n.edges=o,e.add(o)}_removeEdges(e){let t=e.userData,n=t.edges;n&&(e.remove(n),n.geometry?.dispose(),t.edges=null)}getRayAt(e,n){if(!this.camera||!this.canvas)return null;let r=this.canvas,i=r.clientWidth||r.width,a=r.clientHeight||r.height;if(!i||!a)return null;let o=e/i*2-1,s=-(n/a)*2+1,c=new t.Vector3(o,s,-1).unproject(this.camera),l=new t.Vector3(o,s,1).unproject(this.camera).clone().sub(c).normalize();return new t.Ray(c,l)}_intersectMeshAtRay(e,n,r){let i=new t.Raycaster;i.ray.copy(n);let a=i.intersectObject(e,!1);if(!a.length)return null;if(r!=null){let e=a.find(e=>e.instanceId===r);return e?e.point:a[0].point}return a[0].point}_buildPickResult(e,n,r,i){let a=n.mesh.userData,o=null,s=e.batchId,c=e.instanceIndex,l=a.geoRef,u=[];if(c!=null){let e=this._instanceFeature(n.mesh,l,c);if(!e)return null;o=e.smid,s=e.batchId}else{l=a.geoByBatchId?.get(e.batchId)??a.geoRef;let t=V(l,e.batchId);o=t.smid,u=t.segments}if(this._isFeatureHidden(o,s))return null;let d=null,f=0;if(c!=null)d=this._instanceBox(n.mesh,c),f=n.mesh.geometry.index?Math.round(n.mesh.geometry.index.count/3):0;else if(o!=null&&this._smidMeshes.has(o)){let e=this._smidMeshes.get(o),t=1/0,n=1/0,r=1/0,i=-1/0,a=-1/0,s=-1/0,c=0;for(let l of e){let e=l.userData,u=e.geoRef?.pickInfo,d=u?.[o]??u?.[String(o)],p=d?B(d):-1,m=d?.segments??(p>=0?V(e.geoRef,p).segments:[]),h=bt(l.geometry,m);h&&(h.minX<t&&(t=h.minX),h.minY<n&&(n=h.minY),h.minZ<r&&(r=h.minZ),h.maxX>i&&(i=h.maxX),h.maxY>a&&(a=h.maxY),h.maxZ>s&&(s=h.maxZ),c+=h.count,f+=h.triangles)}c>0&&(d={minX:t,minY:n,minZ:r,maxX:i,maxY:a,maxZ:s,count:c,triangles:f})}if(!d&&(d=bt(n.mesh.geometry,u),!d&&n.mesh.geometry)){n.mesh.geometry.boundingBox||n.mesh.geometry.computeBoundingBox();let e=n.mesh.geometry.boundingBox;e&&(d={minX:e.min.x,maxX:e.max.x,minY:e.min.y,maxY:e.max.y,minZ:e.min.z,maxZ:e.max.z,count:0,triangles:0})}let p=n.mesh.geometry,m=f>0?f:p.index?Math.round(p.index.count/3):0,h=xt({smid:o,box:d,triangles:m,floorHeight:this.style.floorHeight}),g=null;if(d&&this.sceneAnchor){let e=new t.Vector3((d.minX+d.maxX)/2,(d.minY+d.maxY)/2,(d.minZ+d.maxZ)/2);e.applyMatrix4(n.mesh.matrixWorld);let r=this.sceneAnchor.meterInMercator;g=this._lngLatFromWorld(e.x*r+this.sceneAnchor.x,-e.y*r+this.sceneAnchor.y)}let _=r??null;!_&&i&&(_=this._intersectMeshAtRay(n.mesh,i,c));let v=null,y=null,b=null;if(_&&this.sceneAnchor){let e=o==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(o),n=e.translation,r=e.elevation,i=_.clone();n?i.add(new t.Vector3(n[0],n[1],n[2])):r&&(i.z+=r),v=[i.x,i.y,i.z];let a=this.sceneAnchor.meterInMercator;y=this._lngLatFromWorld(i.x*a+this.sceneAnchor.x,-i.y*a+this.sceneAnchor.y),b=i.z+(this.sceneAnchor.altitude??0)}else g&&d&&this.sceneAnchor&&(y=g,b=(d.minZ+d.maxZ)/2+(this.sceneAnchor.altitude??0));return{datasetId:n.datasetId,datasetName:this.datasets.get(n.datasetId)?.name??n.datasetId,objectId:e.objectId,batchId:s,instanceIndex:c,skeletonName:n.skeletonName,centerLngLat:g,point:v,lngLat:y,altitude:b,...h,mesh:n.mesh}}pick(e,t){if(!this.picker||!this.scene||!this.camera||!this.sceneAnchor)return null;let n=this.picker.pick(this.scene,this.camera,e,t);if(!n)return null;let r=this._pickables.get(n.objectId);if(!r)return null;let i=this.getRayAt(e,t);return this._buildPickResult(n,r,void 0,i??void 0)}pickPosition(e,n){if(!this.camera||!this.sceneAnchor)return null;let r=this.pick(e,n);if(r?.point&&r?.lngLat&&r.altitude!=null)return{lngLat:r.lngLat,altitude:r.altitude,point:r.point};let i=this.getRayAt(e,n);if(!i)return null;let a=new t.Plane(new t.Vector3(0,0,1),0),o=new t.Vector3,s=i.intersectPlane(a,o);if(s){let e=this.sceneAnchor.meterInMercator;return{lngLat:this._lngLatFromWorld(s.x*e+this.sceneAnchor.x,-s.y*e+this.sceneAnchor.y),altitude:s.z+(this.sceneAnchor.altitude??0),point:[s.x,s.y,s.z]}}return null}drillPick(e,n,r=10){if(!this.sceneAnchor||!this.camera)return[];let i=this.getRayAt(e,n);if(!i)return[];let a=new t.Raycaster;a.ray.copy(i);let o=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e;for(;t;){if(!t.visible)return!1;t=t.parent}return!0}),s=a.intersectObjects(o,!1);if(!s.length)return[];let c=[],l=new Set,u=new Set;for(let e of s){if(c.length>=r)break;let t=e.object,n=t.userData;if(n.pickId==null)continue;let i=this._pickables.get(n.pickId);if(!i)continue;let a=null,o=-1,s=e.instanceId;if(s!=null){let e=this._instanceFeature(t,n.geoRef,s);if(!e)continue;a=e.smid,o=e.batchId}else if(e.faceIndex!=null){let r=t.geometry.attributes.aBatchId;if(r){let i=t.geometry.index?t.geometry.index.getX(e.faceIndex*3):e.faceIndex*3;o=Math.round(r.getX(i)),a=V(n.geoByBatchId?.get(o)??n.geoRef,o).smid}}if(a!=null){if(l.has(a))continue;l.add(a)}else{let e=`${n.pickId}:${o}:${s??-1}`;if(u.has(e))continue;u.add(e)}if(this._isFeatureHidden(a,o))continue;let d={objectId:n.pickId,batchId:o,instanceIndex:s},f=this._buildPickResult(d,i,e.point);f&&c.push(f)}return c}getFeatureBounds(e){if(!this.sceneAnchor)return null;let n=1/0,r=-1/0,i=1/0,a=-1/0,o=!1;for(let s of this._pickables.values()){let c=s.mesh,l=c.userData,u=l.geoRef,d=u?.pickInfo;if(!d)continue;let f=null;if(c.isInstancedMesh){let t=l.instanceLookup;t||(t=yt(d),l.instanceLookup=t);for(let[n,r]of t)if(r.smid===e){f=this._instanceBox(c,n);break}}else{let t=d,n=t[e]??t[String(e)];if(n){let e=V(u,B(n));if(f=bt(c.geometry,e.segments),!f&&c.geometry){c.geometry.boundingBox||c.geometry.computeBoundingBox();let e=c.geometry.boundingBox;e&&(f={minX:e.min.x,maxX:e.max.x,minY:e.min.y,maxY:e.max.y,minZ:e.min.z,maxZ:e.max.z,count:0,triangles:0})}}}if(f){o=!0;let s=[new t.Vector3(f.minX,f.minY,f.minZ),new t.Vector3(f.maxX,f.minY,f.minZ),new t.Vector3(f.minX,f.maxY,f.minZ),new t.Vector3(f.maxX,f.maxY,f.minZ),new t.Vector3(f.minX,f.minY,f.maxZ),new t.Vector3(f.maxX,f.minY,f.maxZ),new t.Vector3(f.minX,f.maxY,f.maxZ),new t.Vector3(f.maxX,f.maxY,f.maxZ)],l=e==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(e),u=l.translation,d=l.elevation;for(let e of s){u?e.add(new t.Vector3(u[0],u[1],u[2])):d&&(e.z+=d),e.applyMatrix4(c.matrixWorld);let o=this.sceneAnchor.meterInMercator,[s,l]=this._lngLatFromWorld(e.x*o+this.sceneAnchor.x,-e.y*o+this.sceneAnchor.y);s<n&&(n=s),s>r&&(r=s),l<i&&(i=l),l>a&&(a=l)}}}return o?[[n,i],[r,a]]:null}_instanceFeature(e,t,n){let r=e.userData;return r.instanceLookup||(r.instanceLookup=yt(t?.pickInfo)),r.instanceLookup.get(n)??null}_instanceBox(e,n){let r=e;if(!r.isInstancedMesh)return null;let i=e.geometry;i.boundingBox||i.computeBoundingBox();let a=i.boundingBox;if(!a)return null;let o=new t.Matrix4;r.getMatrixAt(n,o);let s=a.clone().applyMatrix4(o);return{minX:s.min.x,minY:s.min.y,minZ:s.min.z,maxX:s.max.x,maxY:s.max.y,maxZ:s.max.z,count:i.getAttribute(`position`)?.count??0,triangles:i.index?Math.round(i.index.count/3):0}}select(e,{silent:t=!1}={}){if(this._selection){for(let e of this._selectedMeshes){if(Qi(e)){this._applyPointCloudStyle(e,!1);continue}let t=Zi(e);t&&(t.userData.uSelBatch.value=-1,t.userData.uSelWhole.value=0)}this._selectedMeshes=[],this._clearSelectionDecoration(),this._selection=null}if(!e){this.uniforms.uSelMix.value=0,this.uniforms.uDim.value=0,this.outlineMaterial.uniforms.uSelBatch.value=-1,this.outlineMaterial.uniforms.uSelWhole.value=0,this.outlineMaterial.uniforms.uElevation.value=0,this._requestRepaint(),t||this.onPick(null);return}this._selection=e;let n=new Set;if(e.smid!=null){let t=this._smidMeshes.get(e.smid);if(t)for(let e of t)n.add(e)}n.add(e.mesh);for(let t of n){let n=Zi(t);if(!n)continue;let r=e.batchId;if(e.instanceIndex!=null&&t===e.mesh)r=e.batchId;else if(e.smid!=null){let n=t.userData.geoRef?.pickInfo,i=n?.[e.smid]??n?.[String(e.smid)],a=i?B(i):-1;r=a>=0?a:t===e.mesh?e.batchId:-1}n.userData.uSelBatch.value=r,n.userData.uSelWhole.value=+(r<0),this._selectedMeshes.push(t)}for(let e of this._selectedMeshes)Qi(e)&&this._applyPointCloudStyle(e,!0);if(this.uniforms.uSelMix.value=1,this.uniforms.uDim.value=+!!this.style.dimOthers,this.style.outline){let t=[...n].filter(e=>!Qi(e));t.length&&((this.style.outlineStyle??`edges`)===`edges`?this._addSelectionEdges(e,t):this._addSelectionHull(e,t))}this._requestRepaint()}_addSelectionEdges(e,n){this._syncSelectionStyle();for(let r of n){let n=r.userData,i=n.geoRef,a=[];if(r===e.mesh&&e.instanceIndex!=null)a=[{vertexOffset:0,vertexCount:r.geometry.getAttribute(`position`)?.count??0}];else if(e.smid!=null){let t=i?.pickInfo,n=t?.[e.smid]??t?.[String(e.smid)],r=n?B(n):-1;a=n?.segments??(r>=0?V(i,r).segments:[])}else r===e.mesh&&(a=V(n.geoByBatchId?.get(e.batchId)??i,e.batchId).segments);let o=Hi(r.geometry,a);if(o&&o.length>0){let n=new t.Mesh(zi(o),this.selectionEdgeMaterial);n.renderOrder=4,n.frustumCulled=!1,n.raycast=()=>{},n.userData.isSelectionEdge=!0,r===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(n,e),r.add(n),this._selectionEdgeMeshes.push(n)}}this._selectionEdgeMeshes.length===0?this._addSelectionHull(e,n):this._selectionEdges=this._selectionEdgeMeshes[0]??null}_applyInstanceTransform(e,n){let r=n.mesh;if(n.instanceIndex==null||!r.isInstancedMesh)return;let i=new t.Matrix4;r.getMatrixAt(n.instanceIndex,i),i.decompose(e.position,e.quaternion,e.scale)}_addSelectionHull(e,n){let r=e.instanceIndex!=null;this.outlineMaterial.uniforms.uSelBatch.value=r?-1:e.batchId,this.outlineMaterial.uniforms.uSelWhole.value=r||e.batchId<0?1:0,this.outlineMaterial.uniforms.uElevation.value=r?this._selectionElevation(e):this.style.selectElevation??0;for(let r of n){let n=Zi(r);n?.userData?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=n.userData.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=n.userData.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=n.userData.uBatchTexActive.value);let i=new t.Mesh(r.geometry,this.outlineMaterial);i.renderOrder=3,i.frustumCulled=!1,i.raycast=()=>{},r===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(i,e),r.add(i),this._outlineMeshes.push(i)}this._outlineMesh=this._outlineMeshes[0]??null}_syncSelectionStyle(){let e=this.style,t=this.selectionEdgeMaterial.uniforms;t.uColor.value.set(e.outlineColor??e.selectColor),t.uWidth.value=Math.max(.1,e.outlineWidthPx??3),t.uOpacity.value=Math.min(1,Math.max(.05,e.opacity??1)),t.uElevation.value=this._selection?this._selectionElevation(this._selection):0;for(let e of this._outlineMeshes){let t=e.parent,n=t?Zi(t)?.userData:null;n?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=n.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=n.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=n.uBatchTexActive.value)}}_selectionElevation(e){let t=this.style.selectElevation??0;if(e.smid!=null){let n=this._featureStyleManager.getFeatureEffectiveOffset(e.smid);n.elevation&&(t+=n.elevation)}return t}_clearSelectionDecoration(){for(let e of this._outlineMeshes)e.parent?.remove(e);this._outlineMeshes=[],this._outlineMesh=null;for(let e of this._selectionEdgeMeshes)e.parent?.remove(e),e.geometry.dispose();this._selectionEdgeMeshes=[],this._selectionEdges=null}_updateLineResolution(e){let t=e.width||1,n=e.height||1,r=e.clientWidth||t;this.lineShared.uResolution.value.set(t,n),this.lineShared.uDpr.value=Math.max(1,t/r)}get lodRangeScale(){return this._lodRangeScale}setLodRangeScale(e,t){if(!(e<=0)){if(t){let n=this.datasets.get(t);n?.tileset&&(n.tileset.lodRangeScale=e)}else{this._lodRangeScale=e;for(let t of this.datasets.values())t.tileset&&(t.tileset.lodRangeScale=e)}this._requestRepaint()}}renderFrame(e){if(!this.renderer||!this.scene||!this.camera||!this.sceneAnchor||!this.canvas)return!1;this.flushOverrides();let n=this.canvas,r=this.sceneAnchor.meterInMercator;this._enuMatrix.set(r,0,0,this.sceneAnchor.x,0,-r,0,this.sceneAnchor.y,0,0,r,this.sceneAnchor.z,0,0,0,1);let i=new t.Matrix4().fromArray(e.mvp);i.multiply(this._enuMatrix),this.camera.projectionMatrix.copy(i),this.camera.projectionMatrixInverse.copy(i).invert();let a=e.cameraEnu;this.camera.position.set(a[0],a[1],a[2]),this.camera.matrixWorld.setPosition(a[0],a[1],a[2]),this.camera.matrixWorldInverse.copy(this.camera.matrixWorld).invert(),this.groundManager.update(this.camera);let o=!1;for(let t of this.datasets.values()){if(!t.visible||!t.tileset)continue;let n=[a[0]-t.offset[0],a[1]-t.offset[1],a[2]-t.offset[2]];t.tileset.update(n,e.fovRad,e.canvasHeight)&&(o=!0)}this.style.mode===Q.DYNAMIC&&(this.uniforms.uTime.value+=.016*(this.style.speed??1)),this._updateLights(),this._updateLineResolution(n),this.renderer.setViewport(0,0,n.width,n.height),this.renderer.resetState(),this.renderer.render(this.scene,this.camera),this._frame++;let s=performance.now();return s-this._fps.last>500&&(this._fps.value=Math.round(this._frame*1e3/(s-this._fps.last)),this._frame=0,this._fps.last=s),this.style.mode===Q.DYNAMIC||this.stats.loading>0||o}get fps(){return this._fps.value}get stats(){let e={tiles:0,loading:0,failed:0,meshes:0,vertices:0,triangles:0,datasets:this.datasets.size};for(let t of this.datasets.values()){let n=t.tileset?.stats;n&&(e.tiles+=n.tiles,e.loading+=n.loading,e.failed+=n.failed,e.meshes+=n.meshes,e.vertices+=n.vertices,e.triangles+=n.triangles)}return e}getBounds(){let e=1/0,t=1/0,n=-1/0,r=-1/0;for(let i of this.datasets.values()){let a=_i(i.tileset?.config?.geoBounds);a&&(e=Math.min(e,a.left),n=Math.max(n,a.right),t=Math.min(t,a.bottom),r=Math.max(r,a.top))}return isFinite(e)?[[e,t],[n,r]]:null}dispose(){this.unmount()}};ui();var ea=1e-4;function ta(e,t){let n=e.elements;for(let e=0;e<16;e++){let r=Math.max(1,Math.abs(n[e]),Math.abs(t[e]));if(Math.abs(n[e]-t[e])>ea*r)return!1}return!0}function na(e){let t=e.elements,n=1;for(let e=0;e<16;e++){let r=Math.abs(t[e]);r>n&&(n=r)}let r=1e-6*n;return Math.abs(t[3])<r&&Math.abs(t[7])<r&&Math.abs(t[11])<r&&Math.abs(t[15]-1)<r}function ra(e,t){return t>0&&Math.abs(e.elements[5]*Math.tan(t/2)-1)<.001}function ia(e){if(!e||typeof e!=`object`)return null;let t=e;return t.defaultProjectionData?.projectionMatrix??t.projectionMatrix??null}function aa(e){let t={nearZ:null,farZ:null};if(!e||typeof e!=`object`)return t;let n=e,r=n.defaultProjectionData,i=e=>{let t=n[e];if(typeof t==`number`&&Number.isFinite(t))return t;let i=r?.[e];return typeof i==`number`&&Number.isFinite(i)?i:null};return{nearZ:i(`nearZ`),farZ:i(`farZ`)}}function oa(e,t){if(e&&typeof e==`object`){let t=e.fov;if(typeof t==`number`&&Number.isFinite(t)&&t>0)return t}return typeof t==`number`&&Number.isFinite(t)&&t>0?t:null}function sa(e,n){let r=e.projectionMatrix;if(!r||r.length<16)return null;let i=new t.Matrix4().fromArray(Array.from(r)),a=new t.Matrix4().fromArray(Array.from(e.mvp));if(i.determinant()===0||!ra(i,n.fov))return null;let o=i.clone().invert().multiply(a);if(!ta(i.clone().multiply(o),Array.from(e.mvp))||!na(o)||!ra(i,n.fov))return null;let{distance:s,fov:c,aspect:l}=n;if(!(s>0)||!(c>0)||!(l>0))return null;let u=s*Math.tan(c/2),d=u*l,f=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,p=e.farZ!=null&&e.farZ>f?e.farZ:s*4+1e3;p>f||(p=f+1e3);let m=new t.OrthographicCamera(-d,d,u,-u,f,p);return m.updateProjectionMatrix(),{matrix:m.projectionMatrix.clone().multiply(o),view:o}}var ca=u({AttributeQuery:()=>Ot,BinaryReader:()=>g,DEFAULT_FLOOR_HEIGHT:()=>St,DEFAULT_STYLE:()=>Mr,DatasetManager:()=>Ui,EARTH_RADIUS:()=>kt,FeatureStyleManager:()=>Ji,GroundManager:()=>Yi,Picker:()=>Pi,PixelFormat:()=>X,S3MFormatError:()=>_t,S3MTileset:()=>bi,S3MViewer:()=>$i,S3M_VERSION:()=>Ve,SELECT_MODE:()=>$,SELECT_MODE_LABELS:()=>jr,STYLE:()=>Q,STYLE_LABELS:()=>Ar,TextureCompress:()=>U,VertexTag:()=>R,VertexTagV3:()=>He,buildAttributes:()=>xt,buildFeatureEdgeSegments:()=>Hi,buildOrthoMVP:()=>sa,buildThickLineGeometry:()=>zi,buildTileObjects:()=>si,createLineSharedUniforms:()=>Fi,createOutlineMaterial:()=>kr,createSharedUniforms:()=>Dr,createStyledMaterial:()=>Or,createTexture:()=>Tr,createThickLineMaterial:()=>Ri,default:()=>$i,dxtPixelFormatOf:()=>gn,extractFovRadians:()=>oa,extractNearFar:()=>aa,extractProjectionMatrix:()=>ia,isS3M1Buffer:()=>je,lngLatFromMercator:()=>jt,lngLatFromWorld:()=>Nt,measureSegments:()=>bt,mercatorFromLngLat:()=>At,parseS3M1:()=>Be,parseS3MB:()=>vt,resolveFeature:()=>V,resolveTextureKind:()=>hn,setMaxAnisotropy:()=>vr,worldFromLngLat:()=>Mt});Ct(),Wr(),Z(),yn(),Ct(),yn(),Z(),Wr(),ui();var la=globalThis;return la.THREE||(la.THREE=t),la.S3M=ca,e.AttributeQuery=Ot,e.BinaryReader=g,e.DEFAULT_FLOOR_HEIGHT=St,e.DEFAULT_STYLE=Mr,e.DatasetManager=Ui,e.EARTH_RADIUS=kt,e.FeatureStyleManager=Ji,e.GroundManager=Yi,e.Picker=Pi,e.PixelFormat=X,e.S3MFormatError=_t,e.S3MTileset=bi,e.S3MViewer=$i,e.default=$i,e.S3M_VERSION=Ve,e.SELECT_MODE=$,e.SELECT_MODE_LABELS=jr,e.STYLE=Q,e.STYLE_LABELS=Ar,e.TextureCompress=U,e.VertexTag=R,e.VertexTagV3=He,e.buildAttributes=xt,e.buildFeatureEdgeSegments=Hi,e.buildOrthoMVP=sa,e.buildThickLineGeometry=zi,e.buildTileObjects=si,e.createLineSharedUniforms=Fi,e.createOutlineMaterial=kr,e.createSharedUniforms=Dr,e.createStyledMaterial=Or,e.createTexture=Tr,e.createThickLineMaterial=Ri,e.dxtPixelFormatOf=gn,e.extractFovRadians=oa,e.extractNearFar=aa,e.extractProjectionMatrix=ia,e.isS3M1Buffer=je,e.lngLatFromMercator=jt,e.lngLatFromWorld=Nt,e.measureSegments=bt,e.mercatorFromLngLat=At,e.parseS3M1=Be,e.parseS3MB=vt,e.resolveFeature=V,e.resolveTextureKind=hn,e.setMaxAnisotropy=vr,e.worldFromLngLat=Mt,e})({},THREE);
585
+ `}),a=new t.Mesh(e,i);a.position.set(0,0,-.02),a.renderOrder=-1e3,a.name=`s3m-ground-depth`,a.visible=!1,this.group.add(a),this._depthMesh=a,this._depthMaterial=i,this._syncUniforms()}_applyMode(){this._mesh&&(this._mesh.visible=this.mode!==`none`),this._material&&(this._material.uniforms.uMode.value=this.mode===`excavate`?2:+(this.mode===`translucent`),this._material.depthWrite=this.mode===`excavate`),this._depthMesh&&(this._depthMesh.visible=this.occlude,this._depthMaterial&&(this._depthMaterial.uniforms.uPunchPit.value=+(this.mode===`excavate`)))}update(e){e&&this.group.position.set(e.position.x,e.position.y,this.groundHeight)}setGroundHeight(e){this.groundHeight=e,this.group.position.z=e}setMode(e){this.mode=e,this._occludeExplicit||(this.occlude=e===`excavate`),this._applyMode()}setOcclude(e){this.occlude=e,this._occludeExplicit=!0,this._applyMode()}setOpacity(e){this.opacity=Math.max(0,Math.min(1,e)),this._material&&(this._material.uniforms.uOpacity.value=this.opacity)}setColors(e,t){this.color.set(e),t&&this.gridColor.set(t),this._material&&(this._material.uniforms.uColor.value=this.color,this._material.uniforms.uGridColor.value=this.gridColor)}setExcavationBounds(e){this.excavationBounds=e,this._syncUniforms()}autoFitExcavation(e){let t=1/0,n=1/0,r=-1/0,i=-1/0,a=!1;for(let o of e){let e=o.tileset?.config,s=e?.rootTiles??e?.tiles;if(Array.isArray(s))for(let e of s){let s=e.boundingBox;if(!s)continue;let c=s.center??{x:0,y:0},l=s.xExtent?.x?Math.abs(s.xExtent.x):50,u=s.yExtent?.y?Math.abs(s.yExtent.y):50,d=c.x+o.offset[0]-l,f=c.x+o.offset[0]+l,p=c.y+o.offset[1]-u,m=c.y+o.offset[1]+u;d<t&&(t=d),f>r&&(r=f),p<n&&(n=p),m>i&&(i=m),a=!0}}a&&Number.isFinite(t)&&this.setExcavationBounds([t-5,n-5,r+5,i+5])}_syncUniforms(){let e=this.excavationBounds;if(this._material){let t=this._material.uniforms;e?(t.uHasExcavation.value=1,t.uExcavationMin.value.set(e[0],e[1]),t.uExcavationMax.value.set(e[2],e[3])):t.uHasExcavation.value=0}if(this._depthMaterial){let t=this._depthMaterial.uniforms;e?(t.uHasExcavation.value=1,t.uExcavationMin.value.set(e[0],e[1]),t.uExcavationMax.value.set(e[2],e[3])):t.uHasExcavation.value=0}}dispose(){this._geom?.dispose(),this._geom=null,this._material?.dispose(),this._material=null,this._depthMaterial?.dispose(),this._depthMaterial=null,this._mesh=null,this._depthMesh=null,this.group.clear()}};Z(),Wr(),Ct();var Xi=65534;function Zi(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function Qi(e){return e.isPoints===!0}var $i=class{get datasets(){return this._datasetManager.datasets}get sceneAnchor(){return this._datasetManager.sceneAnchor}set sceneAnchor(e){this._datasetManager.sceneAnchor=e}_requestRepaint(){this._onRequestRepaint()}triggerRepaint(){this._requestRepaint()}constructor(e={}){h(this,`options`,void 0),h(this,`pickable`,void 0),h(this,`onStats`,void 0),h(this,`onReady`,void 0),h(this,`onPick`,void 0),h(this,`onError`,void 0),h(this,`geo`,null),h(this,`canvas`,null),h(this,`renderer`,null),h(this,`scene`,null),h(this,`camera`,null),h(this,`picker`,null),h(this,`uniforms`,void 0),h(this,`style`,void 0),h(this,`outlineMaterial`,void 0),h(this,`lineShared`,void 0),h(this,`edgeMaterial`,void 0),h(this,`selectionEdgeMaterial`,void 0),h(this,`groundManager`,void 0),h(this,`_datasetManager`,new Ui),h(this,`_featureStyleManager`,void 0),h(this,`_pickables`,new Map),h(this,`_pickSeq`,0),h(this,`_freePickIds`,[]),h(this,`_smidMeshes`,new Map),h(this,`_meshHeight`,new Map),h(this,`_heightMin`,1/0),h(this,`_heightMax`,-1/0),h(this,`_boxScratch`,new t.Box3),h(this,`_selection`,null),h(this,`_selectedMeshes`,[]),h(this,`_outlineMesh`,null),h(this,`_outlineMeshes`,[]),h(this,`_selectionEdges`,null),h(this,`_selectionEdgeMeshes`,[]),h(this,`_edgesEnabled`,!1),h(this,`attributeQuery`,null),h(this,`_enuMatrix`,new t.Matrix4),h(this,`_needsRepaint`,!0),h(this,`_frame`,0),h(this,`_fps`,{value:0,last:0}),h(this,`_ambientLight`,void 0),h(this,`_hemiLight`,void 0),h(this,`_keyLight`,void 0),h(this,`_fillLight`,void 0),h(this,`_lightOptions`,{ambientIntensity:.4,ambientColor:16777215,hemisphereIntensity:.8,hemisphereColor:16777215,hemisphereGroundColor:11976907,keyLightIntensity:1,keyLightColor:16777215,fillLightIntensity:.35,fillLightColor:16777215,mode:`headlamp`,azimuth:150,altitude:50}),h(this,`_datasetQueue`,void 0),h(this,`_onRequestRepaint`,()=>{}),h(this,`_getBearing`,void 0),h(this,`_lodRangeScale`,1),this.options=e,this.pickable=e.pickable!==!1,this._lodRangeScale=e.lodRangeScale??1,e.light&&Object.assign(this._lightOptions,e.light),e.totalMaxTiles&&(this._datasetManager.totalMaxTiles=e.totalMaxTiles),this._onRequestRepaint=e.onRequestRepaint??(()=>{}),this._getBearing=e.getBearing,this.onStats=e.onStats??(()=>{}),this.onReady=e.onReady??(()=>{}),this.onPick=e.onPick??(()=>{}),this.onError=e.onError??(e=>console.warn(`[s3m]`,e)),this.groundManager=new Yi(e.ground),this.scene||(this.scene=new t.Scene,this.scene.add(this.groundManager.group),this._addLights()),this._featureStyleManager=new Ji(()=>this.style.floorHeight,()=>this._requestRepaint(),()=>{this._selection&&this._syncSelectionStyle()},()=>this.getAllMeshes(),e=>this._applyOverridesToMesh(e)),this.uniforms=Dr(),this.style={...Mr,...e.style??{}},this.outlineMaterial=kr(this.uniforms),this.lineShared=Fi(),this.edgeMaterial=Ri(this.lineShared,{color:this.style.edgeColor,opacity:this.style.edgeOpacity??.45,width:this.style.edgeWidth??1.2}),this.selectionEdgeMaterial=Ri(this.lineShared,{color:this.style.outlineColor??this.style.selectColor,opacity:1,width:this.style.outlineWidthPx??3}),this._fps.last=performance.now(),this._datasetQueue=this._normalizeDatasets(e),e.attributes&&(this.attributeQuery=new Ot(e.attributes))}mount(e,n){this.canvas=e,this.renderer=new t.WebGLRenderer({canvas:e,context:n,antialias:!0}),this.renderer.autoClear=!1,this.renderer.setPixelRatio(1),this.renderer.toneMapping=t.ACESFilmicToneMapping,this.renderer.toneMappingExposure=1,vr(this.renderer.capabilities.getMaxAnisotropy()),this.scene=new t.Scene,this.scene.add(this.groundManager.group),this._addLights(),this.camera=new t.Camera,this.camera.matrixAutoUpdate=!1,this.picker=new Pi(this.renderer),this._applyStyleUniforms();for(let e of this._datasetQueue)this.addDataset(e).catch(e=>this.onError(e));this._recomputeAnchors()}unmount(){for(let e of[...this.datasets.keys()])this.removeDataset(e);this.groundManager.dispose(),this.picker?.dispose(),this.picker=null,this.outlineMaterial.dispose(),this.edgeMaterial.dispose(),this.selectionEdgeMaterial.dispose(),this.scene?.clear(),this._selectedMeshes=[],this._outlineMeshes=[],this._selectionEdgeMeshes=[],this._outlineMesh=null,this._selectionEdges=null,this._smidMeshes.clear(),this._meshHeight.clear(),this._heightMin=1/0,this._heightMax=-1/0,this.renderer?.dispose(),this.renderer=null,this.canvas=null}_createLights(){this._ambientLight=new t.AmbientLight(this._lightOptions.ambientColor,this._lightOptions.ambientIntensity),this._hemiLight=new t.HemisphereLight(this._lightOptions.hemisphereColor,this._lightOptions.hemisphereGroundColor,this._lightOptions.hemisphereIntensity),this._keyLight=new t.DirectionalLight(this._lightOptions.keyLightColor,this._lightOptions.keyLightIntensity),this._fillLight=new t.DirectionalLight(this._lightOptions.fillLightColor,this._lightOptions.fillLightIntensity),this._updateLights()}_addLights(){this.scene&&(this._ambientLight||this._createLights(),this.scene.add(this._ambientLight,this._hemiLight,this._keyLight,this._fillLight))}_applyLightOptions(){this._ambientLight&&(this._ambientLight.intensity=this._lightOptions.ambientIntensity,this._ambientLight.color.set(this._lightOptions.ambientColor)),this._hemiLight&&(this._hemiLight.intensity=this._lightOptions.hemisphereIntensity,this._hemiLight.color.set(this._lightOptions.hemisphereColor),this._hemiLight.groundColor.set(this._lightOptions.hemisphereGroundColor)),this._keyLight&&(this._keyLight.intensity=this._lightOptions.keyLightIntensity,this._keyLight.color.set(this._lightOptions.keyLightColor)),this._fillLight&&(this._fillLight.intensity=this._lightOptions.fillLightIntensity,this._fillLight.color.set(this._lightOptions.fillLightColor))}setLight(e){Object.assign(this._lightOptions,e),this._applyLightOptions(),this._updateLights(),this._needsRepaint=!0,this.triggerRepaint()}getLight(){return{...this._lightOptions}}_updateLights(){if(!this._keyLight||!this._fillLight)return;let e=this._lightOptions.mode===`fixed`?0:(this._getBearing?.()??0)*Math.PI/180,t=(t,n,r)=>{if(!t)return;let i=e+n*Math.PI/180,a=r*Math.PI/180,o=Math.cos(a);t.position.set(Math.sin(i)*o,Math.cos(i)*o,Math.sin(a)).multiplyScalar(1e3)};t(this._keyLight,this._lightOptions.azimuth,this._lightOptions.altitude),t(this._fillLight,this._lightOptions.azimuth+65,Math.max(10,this._lightOptions.altitude-20))}_normalizeDatasets(e){return Array.isArray(e.datasets)?e.datasets.filter(e=>!!e?.configUrl):e.configUrl?[{id:`default`,name:`默认数据集`,configUrl:e.configUrl}]:[]}async addDataset(e){if(!this.scene)throw Error(`[s3m] 图层尚未 addLayer,不能添加数据集`);return await this._datasetManager.addDataset(e,this.scene,this.geo,this.uniforms,this._lodRangeScale,this.options.buildTile,this.options.maxTiles??64,this.options.maxConcurrent??4,{onTile:(e,t)=>{this._registerTile(e,t),this.onStats(this.stats),this._needsRepaint=!0,this._requestRepaint()},onTileRemoved:(e,t)=>{this._unregisterTile(e,t),this.onStats(this.stats),this._needsRepaint=!0,this._requestRepaint()},onStats:()=>{this.onStats(this.stats),this._requestRepaint()},onError:e=>{this.onError(e),this.onStats(this.stats)},onReady:e=>{this.onReady(e),this._refreshAllHeights(),this.groundManager.excavationBounds||this.groundManager.autoFitExcavation(this.datasets.values())},triggerRepaint:()=>{this._requestRepaint()}})}_lngLatFromWorld(e,t){return Nt(this.geo,e,t)}recomputeAnchors(){this._datasetManager.recomputeAnchors(this.geo),this._refreshAllHeights(),this._requestRepaint()}_recomputeAnchors(){this.recomputeAnchors()}getDatasetHeight(e){return this._datasetManager.getDatasetHeight(e)}setDatasetHeight(e,t){let n,r;typeof e==`number`?(n=this.datasets.keys().next().value??``,r=e):(n=e,r=t??0),this._datasetManager.setDatasetHeight(n,r,this.geo),this._syncGroundHeight(),this._refreshAllHeights(),this._requestRepaint()}_syncGroundHeight(){if(!this.groundManager.trackHeight)return;let e=this.datasets.keys().next().value;if(!e)return;let t=this._datasetManager.getDatasetHeight(e);this.groundManager.setGroundHeight(t)}setDatasetAlign(e,t){let n,r;t===void 0&&(e===`origin`||e===`bottom`||e===`top`||e===`center`)?(n=this.datasets.keys().next().value??``,r=e):(n=e,r=t??`origin`),this._datasetManager.setDatasetAlign(n,r,this.geo),this._refreshAllHeights(),this._requestRepaint()}_computeAlignOffset(e,t){return this._datasetManager.computeAlignOffset(e,t)}computeAlignOffset(e,t){return this._datasetManager.computeAlignOffset(e,t)}setFeatureStyle(e,t){this._featureStyleManager.setFeatureStyle(e,t,this._meshesOf([e]))}setFeaturesStyle(e,t){this._featureStyleManager.setFeaturesStyle(e,t,this._meshesOf(e))}getFeatureStyle(e){return this._featureStyleManager.getFeatureStyle(e)}getFeatureStyles(){return this._featureStyleManager.getFeatureStyles()}removeFeatureStyle(e){this._featureStyleManager.removeFeatureStyle(e,this._meshesOf([e]))}clearFeatureStyles(){this._featureStyleManager.clearFeatureStyles()}setAttributeSource(e){this.attributeQuery=e?new Ot(e):null}getLoadedSmids(){return[...this._smidMeshes.keys()]}auditBatches(){let e=this._featureStyleManager.auditBatches(this._pickables.values());return e.smids=this._smidMeshes.size,e}getThematicField(){return this._featureStyleManager.thematicField}setThematicColors(e,t=`custom`){this._featureStyleManager.setThematicColors(e,t)}clearThematic(){this._featureStyleManager.clearThematicColors()}getFilterField(){return this._featureStyleManager.fieldFilter?.field??null}filterByField(e){return this._featureStyleManager.filterByField(e,this.attributeQuery,this.getLoadedSmids())}clearFieldFilter(){this._featureStyleManager.clearFieldFilter()}getElevationField(){return this._featureStyleManager.elevationField}elevateByField(e){return this._featureStyleManager.elevateByField(e,this.attributeQuery,this.getLoadedSmids())}setThematicElevation(e,t=`custom`){this._featureStyleManager.setThematicElevation(e,t)}clearThematicElevation(){this._featureStyleManager.clearThematicElevation()}colorByField(e){return this._featureStyleManager.colorByField(e,this.attributeQuery,this.getLoadedSmids())}setFilter(e){this._featureStyleManager.setFilter(e,this.uniforms)}getFilter(){return this._featureStyleManager.filter}clearFilter(){this._featureStyleManager.clearFilter(this.uniforms)}setGroundMode(e){this.groundManager.setMode(e),this._requestRepaint()}setGroundOpacity(e){this.groundManager.setOpacity(e),this._requestRepaint()}setExcavationBounds(e){this.groundManager.setExcavationBounds(e),this._requestRepaint()}setGroundOcclude(e){this.groundManager.setOcclude(e),this._requestRepaint()}_isFeatureHidden(e,t){if(e==null)return!1;let n=this._featureStyleManager.fieldFilter;if(n){let t=n.matched.has(e);if(n.mode===`keep`?!t:t)return!0}let r=this._featureStyleManager.filter;return!!(r&&(r.include&&r.include.length>0&&!r.include.includes(e)||r.exclude&&r.exclude.length>0&&r.exclude.includes(e))||this._featureStyleManager.featureStyles.get(e)?.hidden)}getAllMeshes(){let e=[];for(let t of this._pickables.values())e.push(t.mesh);return e}_meshesOf(e){let t=new Set;for(let n of e){let e=this._smidMeshes.get(n);if(e)for(let n of e)t.add(n)}return t}_markOverridesDirty(e=`all`){e===`all`?this._featureStyleManager.markOverridesDirty(void 0,this.getAllMeshes()):this._featureStyleManager.markOverridesDirty(e)}flushOverrides(){this._featureStyleManager.flushOverrides()}_applyOverridesToMesh(e){this._featureStyleManager.applyOverridesToMesh(e)}removeDataset(e){if(this.datasets.get(e)){this._selection?.datasetId===e&&this.select(null),this._datasetManager.removeDataset(e,this.scene,this.geo,e=>{e.root.traverse(e=>{let t=e,n=t.userData;n.pickId!=null&&(this._pickables.delete(n.pickId),this._releasePickId(n.pickId),n.pickId=void 0),this._unindexMeshSmids(t),this._removeMeshHeight(t),t.geometry?.dispose?.();let r=Zi(t);r&&r.dispose(),Oi(t.material)&&t.material.dispose(),this._featureStyleManager.disposeMesh(t)})});for(let[t,n]of this._pickables)n.datasetId===e&&this._pickables.delete(t);this.onStats(this.stats),this._requestRepaint()}}clearDatasets(){for(let e of[...this.datasets.keys()])this.removeDataset(e)}setDatasetVisible(e,t){this._datasetManager.setDatasetVisible(e,t),!t&&this._selection?.datasetId===e&&this.select(null),this._requestRepaint()}_registerTile(e,t){t.root.add(e.group),e.group.updateMatrixWorld(!0);let n=e.group.userData.hasNativeEdges===!0;for(let r of e.group.children){if(r.isLineSegments&&r.userData.isEdgeLines){r.visible=this._edgesEnabled,this._styleEdgeLine(r);continue}let i=Qi(r),a=r;if(!a.isMesh&&!i)continue;let o=a.userData;if(o.pickId=this._allocPickId(),o.datasetId=t.id,o.nativeEdges=n,this._pickables.set(o.pickId,{datasetId:t.id,mesh:a,tile:e.tile,skeletonName:o.skeletonName??``}),this._indexMeshSmids(a),this._addMeshHeight(a),this._edgesEnabled&&!n&&!i&&this._ensureEdges(a),i)this._applyPointCloudStyle(r);else{let e=Zi(a);if(e){let t=Math.min(1,Math.max(.05,this.style.opacity??1));e.opacity=t,e.transparent=t<.999,e.depthWrite=t>=.999,e.flatShading=this.style.shading!==`smooth`,e.needsUpdate=!0,this._featureStyleManager.applyOverridesToMesh(a)}}this._replaySelectionOnto(a)}}_isMeshCoveringSelection(e,n){if(!n.point)return!1;let r=e.geometry;if(!r||(r.boundingBox||r.computeBoundingBox(),!r.boundingBox))return!1;let i=new t.Vector3(n.point[0],n.point[1],n.point[2]);e.updateWorldMatrix(!0,!1);let a=e.matrixWorld.clone().invert(),o=i.applyMatrix4(a);return r.boundingBox.clone().expandByScalar(.5).containsPoint(o)}_replaySelectionOnto(e){let t=this._selection;if(!t)return;let n=Zi(e);if(!n)return;let r=e.userData,i=-1;if(t.smid!=null){let e=r.geoRef?.pickInfo,n=e?.[t.smid]??e?.[String(t.smid)];i=n?B(n):-1}if(e===t.mesh&&(i=t.batchId),i<0&&e!==t.mesh){if(t.smid==null&&r.datasetId===t.datasetId&&this._isMeshCoveringSelection(e,t))i=-1;else return}n.userData.uSelBatch.value=i,n.userData.uSelWhole.value=+(i<0),this._selectedMeshes.includes(e)||this._selectedMeshes.push(e),Qi(e)&&this._applyPointCloudStyle(e,!0),this.uniforms.uSelMix.value=1,this.uniforms.uDim.value=+!!this.style.dimOthers}_unregisterTile(e,t){e.group.traverse(e=>{let t=e;if(t.userData?.pickId!=null&&(this._pickables.delete(t.userData.pickId),this._releasePickId(t.userData.pickId),t.userData.pickId=void 0),t.isMesh){this._selectedMeshes.includes(t)&&(this._selectedMeshes=this._selectedMeshes.filter(e=>e!==t));let e=this._selection;if(e&&e.mesh===t){let n=e.smid,r=n==null?this._selectedMeshes.find(e=>e!==t&&e.parent&&e.parent.visible)??this._selectedMeshes.find(e=>e!==t&&e.parent):[...this._smidMeshes.get(n)??[]].find(e=>e!==t&&e.parent);r?(this._selection={...e,mesh:r},this._replaySelectionOnto(r)):this.select(null)}this._unindexMeshSmids(t),this._removeMeshHeight(t),this._featureStyleManager.disposeMesh(t),Zi(t)?.dispose?.()}Oi(t.material)?t.material.dispose():t.material&&(Array.isArray(t.material)?t.material.forEach(e=>e?.dispose?.()):t.material.dispose?.()),t.geometry?.dispose?.()}),t.root.remove(e.group)}_allocPickId(){let e=this._freePickIds.pop();if(e!==void 0)return e;if(this._pickSeq>Xi){for(let e=0;e<=Xi;e++)if(!this._pickables.has(e))return e;throw Error(`[s3m] 可拾取网格超过 65535 个,2 字节 ID 编码不够用`)}return this._pickSeq++}_releasePickId(e){this._freePickIds.push(e)}setOpacity(e){this.setStyle({opacity:e})}setStyle(e={}){this.style={...this.style,...e},this._applyStyleUniforms(),(`opacity`in e||`depthWrite`in e)&&this._applyOpacity(),`mode`in e&&this._applyPointCloudStyles(),`shading`in e&&this._applyShading(),`edges`in e?this.setEdges(!!this.style.edges):(`edgeColor`in e||`edgeWidth`in e||`opacity`in e||`edgeOpacity`in e)&&this._refreshEdgeLines(),this._selection&&(`outline`in e||`outlineStyle`in e?this.select(this._selection,{silent:!0}):this._syncSelectionStyle()),this._requestRepaint()}getStyle(){return{...this.style,modeLabel:Ar[this.style.mode]}}_applyStyleUniforms(){let e=this.uniforms,t=this.style;e.uMode.value=t.mode,e.uColorA.value.set(t.colorA),e.uColorB.value.set(t.colorB),e.uColorC.value.set(t.colorC),e.uSelColor.value.set(t.selectColor),e.uFloorHeight.value=t.floorHeight;let n=t.selectMode??$.OVERLAY;e.uSelMode&&(e.uSelMode.value=n===$.REPLACE?0:n===$.MULTIPLY?2:n===$.GLOW_ONLY?3:1),e.uSelOpacity&&t.selectOpacity!=null&&(e.uSelOpacity.value=t.selectOpacity),e.uSelEmissive&&t.selectEmissive!=null&&(e.uSelEmissive.value=t.selectEmissive),e.uSelElevation&&t.selectElevation!=null&&(e.uSelElevation.value=t.selectElevation),e.uDimFactor&&t.dimFactor!=null&&(e.uDimFactor.value=t.dimFactor),e.uRoofThreshold&&t.roofThreshold!=null&&(e.uRoofThreshold.value=t.roofThreshold),e.uTexMix&&t.texMix!=null&&(e.uTexMix.value=t.texMix),this.outlineMaterial&&(this.outlineMaterial.uniforms.uElevation&&t.selectElevation!=null&&(this.outlineMaterial.uniforms.uElevation.value=t.selectElevation),t.outlineWidth!=null&&(this.outlineMaterial.uniforms.uWidth.value=t.outlineWidth),t.outlineColor==null?this.outlineMaterial.uniforms.uColor.value.set(t.selectColor):this.outlineMaterial.uniforms.uColor.value.set(t.outlineColor))}_applyOpacity(){let e=Math.min(1,Math.max(.05,this.style.opacity??1)),t=e<.999,n=this.style.depthWrite!==!1;for(let r of this._pickables.values()){if(Qi(r.mesh)){this._applyPointCloudStyle(r.mesh);continue}let i=Zi(r.mesh);i&&(i.opacity=e,i.transparent=t,i.depthWrite=!t||n)}this._requestRepaint()}_applyPointCloudStyle(e,t=this._selectedMeshes.includes(e)){Di(e,this.style,this.uniforms,t)}_applyPointCloudStyles(){for(let e of this._pickables.values())Qi(e.mesh)&&this._applyPointCloudStyle(e.mesh);this._requestRepaint()}_applyShading(){let e=this.style.shading!==`smooth`;for(let t of this._pickables.values()){let n=Zi(t.mesh);n&&n.flatShading!==e&&(n.flatShading=e,n.needsUpdate=!0)}this._requestRepaint()}_addMeshHeight(e){let t=e.geometry?.boundingBox;if(!t)return;this._boxScratch.copy(t).applyMatrix4(e.matrixWorld);let n=this._boxScratch.min.z,r=this._boxScratch.max.z;Number.isFinite(n)&&Number.isFinite(r)&&(this._meshHeight.set(e,{min:n,max:r}),n<this._heightMin&&(this._heightMin=n),r>this._heightMax&&(this._heightMax=r),this._pushHeightRange())}_removeMeshHeight(e){let t=this._meshHeight.get(e);t&&(this._meshHeight.delete(e),t.min===this._heightMin||t.max===this._heightMax?this._recomputeHeightRange():this._pushHeightRange())}_refreshAllHeights(){if(this._meshHeight.size===0)return;let e=[...this._meshHeight.keys()];this._meshHeight.clear(),this._heightMin=1/0,this._heightMax=-1/0;for(let t of e)this._addMeshHeight(t);this._pushHeightRange()}_recomputeHeightRange(){let e=1/0,t=-1/0;for(let n of this._meshHeight.values())n.min<e&&(e=n.min),n.max>t&&(t=n.max);this._heightMin=e,this._heightMax=t,this._pushHeightRange()}_pushHeightRange(){let e=this._heightMin,t=this._heightMax;(!Number.isFinite(e)||!Number.isFinite(t)||t<=e)&&(e=0,t=100),this.uniforms.uHeightMin.value=e,this.uniforms.uHeightMax.value=t}_indexMeshSmids(e){let t=e.userData.geoRef?.pickInfo;if(t)for(let n of Object.keys(t)){let t=Number(n);if(!Number.isFinite(t)||t<0)continue;let r=this._smidMeshes.get(t);r||this._smidMeshes.set(t,r=new Set),r.add(e)}}_unindexMeshSmids(e){let t=e.userData.geoRef?.pickInfo;if(t)for(let n of Object.keys(t)){let t=Number(n),r=this._smidMeshes.get(t);r&&(r.delete(e),r.size===0&&this._smidMeshes.delete(t))}}setEdges(e){this._edgesEnabled=e,this.style.edges=e;for(let t of this.datasets.values())t.root.traverse(t=>{t.userData.isEdgeLines&&(t.visible=e,this._styleEdgeLine(t))});if(this._syncEdgeStyle(),!e){for(let e of this._pickables.values())this._removeEdges(e.mesh);this._requestRepaint();return}let t=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e.userData;return!t.edges&&!t.nativeEdges&&!Qi(e)}),n=0,r=()=>{let e=performance.now();for(;n<t.length&&performance.now()-e<8;)this._ensureEdges(t[n++]);n<t.length?setTimeout(r,0):this._requestRepaint()};r()}_syncEdgeStyle(){let e=this.style,t=this.edgeMaterial.uniforms;t.uColor.value.set(e.edgeColor),t.uWidth.value=Math.max(.1,e.edgeWidth??1.2),t.uOpacity.value=Math.min(1,Math.max(0,e.edgeOpacity??.45))*Math.min(1,Math.max(.05,e.opacity??1))}_styleEdgeLine(e){let t=e.material;t&&t.color&&(t.color.set(this.style.edgeColor),t.opacity=(this.style.edgeOpacity??.45)*Math.min(1,Math.max(.05,this.style.opacity??1)),t.transparent=!0,t.polygonOffset=!0,t.polygonOffsetFactor=-1,t.polygonOffsetUnits=-1,t.needsUpdate=!0)}_refreshEdgeLines(){this._syncEdgeStyle();for(let e of this.datasets.values())e.root.traverse(e=>{e.userData.isEdgeLines&&this._styleEdgeLine(e)})}_ensureEdges(e){let n=e.userData;if(n.edges||n.nativeEdges||!e.geometry||(e.geometry.index?.count??0)>12e4)return;let r=new t.EdgesGeometry(e.geometry,40),i=r.getAttribute(`position`),a=i?i.array:null;if(r.dispose(),!a||a.length<6)return;let o=new t.Mesh(zi(a),this.edgeMaterial);o.renderOrder=2,o.frustumCulled=!1,o.raycast=()=>{},o.userData.isThickEdge=!0,n.edges=o,e.add(o)}_removeEdges(e){let t=e.userData,n=t.edges;n&&(e.remove(n),n.geometry?.dispose(),t.edges=null)}getRayAt(e,n){if(!this.camera||!this.canvas)return null;let r=this.canvas,i=r.clientWidth||r.width,a=r.clientHeight||r.height;if(!i||!a)return null;let o=e/i*2-1,s=-(n/a)*2+1,c=new t.Vector3(o,s,-1).unproject(this.camera),l=new t.Vector3(o,s,1).unproject(this.camera).clone().sub(c).normalize();return new t.Ray(c,l)}_intersectMeshAtRay(e,n,r){let i=new t.Raycaster;i.ray.copy(n);let a=i.intersectObject(e,!1);if(!a.length)return null;if(r!=null){let e=a.find(e=>e.instanceId===r);return e?e.point:a[0].point}return a[0].point}_buildPickResult(e,n,r,i){let a=n.mesh.userData,o=null,s=e.batchId,c=e.instanceIndex,l=a.geoRef,u=[];if(c!=null){let e=this._instanceFeature(n.mesh,l,c);if(!e)return null;o=e.smid,s=e.batchId}else{l=a.geoByBatchId?.get(e.batchId)??a.geoRef;let t=V(l,e.batchId);o=t.smid,u=t.segments}if(this._isFeatureHidden(o,s))return null;let d=null,f=0;if(c!=null)d=this._instanceBox(n.mesh,c),f=n.mesh.geometry.index?Math.round(n.mesh.geometry.index.count/3):0;else if(o!=null&&this._smidMeshes.has(o)){let e=this._smidMeshes.get(o),t=1/0,n=1/0,r=1/0,i=-1/0,a=-1/0,s=-1/0,c=0;for(let l of e){let e=l.userData,u=e.geoRef?.pickInfo,d=u?.[o]??u?.[String(o)],p=d?B(d):-1,m=d?.segments??(p>=0?V(e.geoRef,p).segments:[]),h=bt(l.geometry,m);h&&(h.minX<t&&(t=h.minX),h.minY<n&&(n=h.minY),h.minZ<r&&(r=h.minZ),h.maxX>i&&(i=h.maxX),h.maxY>a&&(a=h.maxY),h.maxZ>s&&(s=h.maxZ),c+=h.count,f+=h.triangles)}c>0&&(d={minX:t,minY:n,minZ:r,maxX:i,maxY:a,maxZ:s,count:c,triangles:f})}if(!d&&(d=bt(n.mesh.geometry,u),!d&&n.mesh.geometry)){n.mesh.geometry.boundingBox||n.mesh.geometry.computeBoundingBox();let e=n.mesh.geometry.boundingBox;e&&(d={minX:e.min.x,maxX:e.max.x,minY:e.min.y,maxY:e.max.y,minZ:e.min.z,maxZ:e.max.z,count:0,triangles:0})}let p=n.mesh.geometry,m=f>0?f:p.index?Math.round(p.index.count/3):0,h=xt({smid:o,box:d,triangles:m,floorHeight:this.style.floorHeight}),g=null;if(d&&this.sceneAnchor){let e=new t.Vector3((d.minX+d.maxX)/2,(d.minY+d.maxY)/2,(d.minZ+d.maxZ)/2);e.applyMatrix4(n.mesh.matrixWorld);let r=this.sceneAnchor.meterInMercator;g=this._lngLatFromWorld(e.x*r+this.sceneAnchor.x,-e.y*r+this.sceneAnchor.y)}let _=r??null;!_&&i&&(_=this._intersectMeshAtRay(n.mesh,i,c));let v=null,y=null,b=null;if(_&&this.sceneAnchor){let e=o==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(o),n=e.translation,r=e.elevation,i=_.clone();n?i.add(new t.Vector3(n[0],n[1],n[2])):r&&(i.z+=r),v=[i.x,i.y,i.z];let a=this.sceneAnchor.meterInMercator;y=this._lngLatFromWorld(i.x*a+this.sceneAnchor.x,-i.y*a+this.sceneAnchor.y),b=i.z+(this.sceneAnchor.altitude??0)}else g&&d&&this.sceneAnchor&&(y=g,b=(d.minZ+d.maxZ)/2+(this.sceneAnchor.altitude??0));return{datasetId:n.datasetId,datasetName:this.datasets.get(n.datasetId)?.name??n.datasetId,objectId:e.objectId,batchId:s,instanceIndex:c,skeletonName:n.skeletonName,centerLngLat:g,point:v,lngLat:y,altitude:b,...h,mesh:n.mesh}}pick(e,t){if(!this.picker||!this.scene||!this.camera||!this.sceneAnchor)return null;let n=this.picker.pick(this.scene,this.camera,e,t);if(!n)return null;let r=this._pickables.get(n.objectId);if(!r)return null;let i=this.getRayAt(e,t);return this._buildPickResult(n,r,void 0,i??void 0)}pickPosition(e,n){if(!this.camera||!this.sceneAnchor)return null;let r=this.pick(e,n);if(r?.point&&r?.lngLat&&r.altitude!=null)return{lngLat:r.lngLat,altitude:r.altitude,point:r.point};let i=this.getRayAt(e,n);if(!i)return null;let a=new t.Plane(new t.Vector3(0,0,1),0),o=new t.Vector3,s=i.intersectPlane(a,o);if(s){let e=this.sceneAnchor.meterInMercator;return{lngLat:this._lngLatFromWorld(s.x*e+this.sceneAnchor.x,-s.y*e+this.sceneAnchor.y),altitude:s.z+(this.sceneAnchor.altitude??0),point:[s.x,s.y,s.z]}}return null}drillPick(e,n,r=10){if(!this.sceneAnchor||!this.camera)return[];let i=this.getRayAt(e,n);if(!i)return[];let a=new t.Raycaster;a.ray.copy(i);let o=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e;for(;t;){if(!t.visible)return!1;t=t.parent}return!0}),s=a.intersectObjects(o,!1);if(!s.length)return[];let c=[],l=new Set,u=new Set;for(let e of s){if(c.length>=r)break;let t=e.object,n=t.userData;if(n.pickId==null)continue;let i=this._pickables.get(n.pickId);if(!i)continue;let a=null,o=-1,s=e.instanceId;if(s!=null){let e=this._instanceFeature(t,n.geoRef,s);if(!e)continue;a=e.smid,o=e.batchId}else if(e.faceIndex!=null){let r=t.geometry.attributes.aBatchId;if(r){let i=t.geometry.index?t.geometry.index.getX(e.faceIndex*3):e.faceIndex*3;o=Math.round(r.getX(i)),a=V(n.geoByBatchId?.get(o)??n.geoRef,o).smid}}if(a!=null){if(l.has(a))continue;l.add(a)}else{let e=`${n.pickId}:${o}:${s??-1}`;if(u.has(e))continue;u.add(e)}if(this._isFeatureHidden(a,o))continue;let d={objectId:n.pickId,batchId:o,instanceIndex:s},f=this._buildPickResult(d,i,e.point);f&&c.push(f)}return c}getFeatureBounds(e){if(!this.sceneAnchor)return null;let n=1/0,r=-1/0,i=1/0,a=-1/0,o=!1;for(let s of this._pickables.values()){let c=s.mesh,l=c.userData,u=l.geoRef,d=u?.pickInfo;if(!d)continue;let f=null;if(c.isInstancedMesh){let t=l.instanceLookup;t||(t=yt(d),l.instanceLookup=t);for(let[n,r]of t)if(r.smid===e){f=this._instanceBox(c,n);break}}else{let t=d,n=t[e]??t[String(e)];if(n){let e=V(u,B(n));if(f=bt(c.geometry,e.segments),!f&&c.geometry){c.geometry.boundingBox||c.geometry.computeBoundingBox();let e=c.geometry.boundingBox;e&&(f={minX:e.min.x,maxX:e.max.x,minY:e.min.y,maxY:e.max.y,minZ:e.min.z,maxZ:e.max.z,count:0,triangles:0})}}}if(f){o=!0;let s=[new t.Vector3(f.minX,f.minY,f.minZ),new t.Vector3(f.maxX,f.minY,f.minZ),new t.Vector3(f.minX,f.maxY,f.minZ),new t.Vector3(f.maxX,f.maxY,f.minZ),new t.Vector3(f.minX,f.minY,f.maxZ),new t.Vector3(f.maxX,f.minY,f.maxZ),new t.Vector3(f.minX,f.maxY,f.maxZ),new t.Vector3(f.maxX,f.maxY,f.maxZ)],l=e==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(e),u=l.translation,d=l.elevation;for(let e of s){u?e.add(new t.Vector3(u[0],u[1],u[2])):d&&(e.z+=d),e.applyMatrix4(c.matrixWorld);let o=this.sceneAnchor.meterInMercator,[s,l]=this._lngLatFromWorld(e.x*o+this.sceneAnchor.x,-e.y*o+this.sceneAnchor.y);s<n&&(n=s),s>r&&(r=s),l<i&&(i=l),l>a&&(a=l)}}}return o?[[n,i],[r,a]]:null}_instanceFeature(e,t,n){let r=e.userData;return r.instanceLookup||(r.instanceLookup=yt(t?.pickInfo)),r.instanceLookup.get(n)??null}_instanceBox(e,n){let r=e;if(!r.isInstancedMesh)return null;let i=e.geometry;i.boundingBox||i.computeBoundingBox();let a=i.boundingBox;if(!a)return null;let o=new t.Matrix4;r.getMatrixAt(n,o);let s=a.clone().applyMatrix4(o);return{minX:s.min.x,minY:s.min.y,minZ:s.min.z,maxX:s.max.x,maxY:s.max.y,maxZ:s.max.z,count:i.getAttribute(`position`)?.count??0,triangles:i.index?Math.round(i.index.count/3):0}}select(e,{silent:t=!1}={}){if(this._selection){for(let e of this._selectedMeshes){if(Qi(e)){this._applyPointCloudStyle(e,!1);continue}let t=Zi(e);t&&(t.userData.uSelBatch.value=-1,t.userData.uSelWhole.value=0)}this._selectedMeshes=[],this._clearSelectionDecoration(),this._selection=null}if(!e){this.uniforms.uSelMix.value=0,this.uniforms.uDim.value=0,this.outlineMaterial.uniforms.uSelBatch.value=-1,this.outlineMaterial.uniforms.uSelWhole.value=0,this.outlineMaterial.uniforms.uElevation.value=0,this._requestRepaint(),t||this.onPick(null);return}this._selection=e;let n=new Set;if(e.smid!=null){let t=this._smidMeshes.get(e.smid);if(t)for(let e of t)n.add(e)}n.add(e.mesh);for(let t of n){let n=Zi(t);if(!n)continue;let r=e.batchId;if(e.instanceIndex!=null&&t===e.mesh)r=e.batchId;else if(e.smid!=null){let n=t.userData.geoRef?.pickInfo,i=n?.[e.smid]??n?.[String(e.smid)],a=i?B(i):-1;r=a>=0?a:t===e.mesh?e.batchId:-1}n.userData.uSelBatch.value=r,n.userData.uSelWhole.value=+(r<0),this._selectedMeshes.push(t)}for(let e of this._selectedMeshes)Qi(e)&&this._applyPointCloudStyle(e,!0);if(this.uniforms.uSelMix.value=1,this.uniforms.uDim.value=+!!this.style.dimOthers,this.style.outline){let t=[...n].filter(e=>!Qi(e));t.length&&((this.style.outlineStyle??`edges`)===`edges`?this._addSelectionEdges(e,t):this._addSelectionHull(e,t))}this._requestRepaint()}_addSelectionEdges(e,n){this._syncSelectionStyle();for(let r of n){let n=r.userData,i=n.geoRef,a=[];if(r===e.mesh&&e.instanceIndex!=null)a=[{vertexOffset:0,vertexCount:r.geometry.getAttribute(`position`)?.count??0}];else if(e.smid!=null){let t=i?.pickInfo,n=t?.[e.smid]??t?.[String(e.smid)],r=n?B(n):-1;a=n?.segments??(r>=0?V(i,r).segments:[])}else r===e.mesh&&(a=V(n.geoByBatchId?.get(e.batchId)??i,e.batchId).segments);let o=Hi(r.geometry,a);if(o&&o.length>0){let n=new t.Mesh(zi(o),this.selectionEdgeMaterial);n.renderOrder=4,n.frustumCulled=!1,n.raycast=()=>{},n.userData.isSelectionEdge=!0,r===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(n,e),r.add(n),this._selectionEdgeMeshes.push(n)}}this._selectionEdgeMeshes.length===0?this._addSelectionHull(e,n):this._selectionEdges=this._selectionEdgeMeshes[0]??null}_applyInstanceTransform(e,n){let r=n.mesh;if(n.instanceIndex==null||!r.isInstancedMesh)return;let i=new t.Matrix4;r.getMatrixAt(n.instanceIndex,i),i.decompose(e.position,e.quaternion,e.scale)}_addSelectionHull(e,n){let r=e.instanceIndex!=null;this.outlineMaterial.uniforms.uSelBatch.value=r?-1:e.batchId,this.outlineMaterial.uniforms.uSelWhole.value=r||e.batchId<0?1:0,this.outlineMaterial.uniforms.uElevation.value=r?this._selectionElevation(e):this.style.selectElevation??0;for(let r of n){let n=Zi(r);n?.userData?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=n.userData.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=n.userData.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=n.userData.uBatchTexActive.value);let i=new t.Mesh(r.geometry,this.outlineMaterial);i.renderOrder=3,i.frustumCulled=!1,i.raycast=()=>{},r===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(i,e),r.add(i),this._outlineMeshes.push(i)}this._outlineMesh=this._outlineMeshes[0]??null}_syncSelectionStyle(){let e=this.style,t=this.selectionEdgeMaterial.uniforms;t.uColor.value.set(e.outlineColor??e.selectColor),t.uWidth.value=Math.max(.1,e.outlineWidthPx??3),t.uOpacity.value=Math.min(1,Math.max(.05,e.opacity??1)),t.uElevation.value=this._selection?this._selectionElevation(this._selection):0;for(let e of this._outlineMeshes){let t=e.parent,n=t?Zi(t)?.userData:null;n?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=n.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=n.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=n.uBatchTexActive.value)}}_selectionElevation(e){let t=this.style.selectElevation??0;if(e.smid!=null){let n=this._featureStyleManager.getFeatureEffectiveOffset(e.smid);n.elevation&&(t+=n.elevation)}return t}_clearSelectionDecoration(){for(let e of this._outlineMeshes)e.parent?.remove(e);this._outlineMeshes=[],this._outlineMesh=null;for(let e of this._selectionEdgeMeshes)e.parent?.remove(e),e.geometry.dispose();this._selectionEdgeMeshes=[],this._selectionEdges=null}_updateLineResolution(e){let t=e.width||1,n=e.height||1,r=e.clientWidth||t;this.lineShared.uResolution.value.set(t,n),this.lineShared.uDpr.value=Math.max(1,t/r)}get lodRangeScale(){return this._lodRangeScale}setLodRangeScale(e,t){if(!(e<=0)){if(t){let n=this.datasets.get(t);n?.tileset&&(n.tileset.lodRangeScale=e)}else{this._lodRangeScale=e;for(let t of this.datasets.values())t.tileset&&(t.tileset.lodRangeScale=e)}this._requestRepaint()}}renderFrame(e){if(!this.renderer||!this.scene||!this.camera||!this.sceneAnchor||!this.canvas)return!1;this.flushOverrides();let n=this.canvas,r=this.sceneAnchor.meterInMercator;this._enuMatrix.set(r,0,0,this.sceneAnchor.x,0,-r,0,this.sceneAnchor.y,0,0,r,this.sceneAnchor.z,0,0,0,1);let i=new t.Matrix4().fromArray(e.mvp);i.multiply(this._enuMatrix),this.camera.projectionMatrix.copy(i),this.camera.projectionMatrixInverse.copy(i).invert();let a=e.cameraEnu;this.camera.position.set(a[0],a[1],a[2]),this.camera.matrixWorld.setPosition(a[0],a[1],a[2]),this.camera.matrixWorldInverse.copy(this.camera.matrixWorld).invert(),this.groundManager.update(this.camera);let o=!1;for(let t of this.datasets.values()){if(!t.visible||!t.tileset)continue;let n=[a[0]-t.offset[0],a[1]-t.offset[1],a[2]-t.offset[2]];t.tileset.update(n,e.fovRad,e.canvasHeight)&&(o=!0)}this.style.mode===Q.DYNAMIC&&(this.uniforms.uTime.value+=.016*(this.style.speed??1)),this._updateLights(),this._updateLineResolution(n),this.renderer.setViewport(0,0,n.width,n.height),this.renderer.resetState(),this.renderer.render(this.scene,this.camera),this._frame++;let s=performance.now();return s-this._fps.last>500&&(this._fps.value=Math.round(this._frame*1e3/(s-this._fps.last)),this._frame=0,this._fps.last=s),this.style.mode===Q.DYNAMIC||this.stats.loading>0||o}get fps(){return this._fps.value}get stats(){let e={tiles:0,loading:0,failed:0,meshes:0,vertices:0,triangles:0,datasets:this.datasets.size};for(let t of this.datasets.values()){let n=t.tileset?.stats;n&&(e.tiles+=n.tiles,e.loading+=n.loading,e.failed+=n.failed,e.meshes+=n.meshes,e.vertices+=n.vertices,e.triangles+=n.triangles)}return e}getBounds(){let e=1/0,t=1/0,n=-1/0,r=-1/0;for(let i of this.datasets.values()){let a=_i(i.tileset?.config?.geoBounds);a&&(e=Math.min(e,a.left),n=Math.max(n,a.right),t=Math.min(t,a.bottom),r=Math.max(r,a.top))}return isFinite(e)?[[e,t],[n,r]]:null}dispose(){this.unmount()}};ui();var ea=1e-4;function ta(e,t){let n=e.elements;for(let e=0;e<16;e++){let r=Math.max(1,Math.abs(n[e]),Math.abs(t[e]));if(Math.abs(n[e]-t[e])>ea*r)return!1}return!0}function na(e){let t=e.elements,n=1;for(let e=0;e<16;e++){let r=Math.abs(t[e]);r>n&&(n=r)}let r=1e-6*n;return Math.abs(t[3])<r&&Math.abs(t[7])<r&&Math.abs(t[11])<r&&Math.abs(t[15]-1)<r}function ra(e,t){return t>0&&Math.abs(e.elements[5]*Math.tan(t/2)-1)<.001}function ia(e){if(!e||typeof e!=`object`)return null;let t=e;return t.defaultProjectionData?.projectionMatrix??t.projectionMatrix??null}function aa(e){let t={nearZ:null,farZ:null};if(!e||typeof e!=`object`)return t;let n=e,r=n.defaultProjectionData,i=e=>{let t=n[e];if(typeof t==`number`&&Number.isFinite(t))return t;let i=r?.[e];return typeof i==`number`&&Number.isFinite(i)?i:null};return{nearZ:i(`nearZ`),farZ:i(`farZ`)}}function oa(e,t){if(e&&typeof e==`object`){let t=e.fov;if(typeof t==`number`&&Number.isFinite(t)&&t>0)return t}return typeof t==`number`&&Number.isFinite(t)&&t>0?t:null}function sa(e,n){let r=e.projectionMatrix;if(!r||r.length<16)return null;let i=new t.Matrix4().fromArray(Array.from(r)),a=new t.Matrix4().fromArray(Array.from(e.mvp));if(i.determinant()===0||!ra(i,n.fov))return null;let o=i.clone().invert().multiply(a);if(!ta(i.clone().multiply(o),Array.from(e.mvp))||!na(o)||!ra(i,n.fov))return null;let{distance:s,fov:c,aspect:l}=n;if(!(s>0)||!(c>0)||!(l>0))return null;let u=s*Math.tan(c/2),d=u*l,f=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,p=e.farZ!=null&&e.farZ>f?e.farZ:s*4+1e3;p>f||(p=f+1e3);let m=new t.OrthographicCamera(-d,d,u,-u,f,p);return m.updateProjectionMatrix(),{matrix:m.projectionMatrix.clone().multiply(o),view:o}}var ca=u({AttributeQuery:()=>Ot,BinaryReader:()=>g,DEFAULT_FLOOR_HEIGHT:()=>St,DEFAULT_STYLE:()=>Mr,DatasetManager:()=>Ui,EARTH_RADIUS:()=>kt,FeatureStyleManager:()=>Ji,GroundManager:()=>Yi,Picker:()=>Pi,PixelFormat:()=>X,S3MFormatError:()=>_t,S3MTileset:()=>bi,S3MViewer:()=>$i,S3M_VERSION:()=>Ve,SELECT_MODE:()=>$,SELECT_MODE_LABELS:()=>jr,STYLE:()=>Q,STYLE_LABELS:()=>Ar,TextureCompress:()=>U,VertexTag:()=>R,VertexTagV3:()=>He,buildAttributes:()=>xt,buildFeatureEdgeSegments:()=>Hi,buildOrthoMVP:()=>sa,buildThickLineGeometry:()=>zi,buildTileObjects:()=>si,createLineSharedUniforms:()=>Fi,createOutlineMaterial:()=>kr,createSharedUniforms:()=>Dr,createStyledMaterial:()=>Or,createTexture:()=>Tr,createThickLineMaterial:()=>Ri,default:()=>$i,dxtPixelFormatOf:()=>gn,extractFovRadians:()=>oa,extractNearFar:()=>aa,extractProjectionMatrix:()=>ia,isS3M1Buffer:()=>je,lngLatFromMercator:()=>jt,lngLatFromWorld:()=>Nt,measureSegments:()=>bt,mercatorFromLngLat:()=>At,parseS3M1:()=>Be,parseS3MB:()=>vt,resolveFeature:()=>V,resolveTextureKind:()=>hn,setMaxAnisotropy:()=>vr,worldFromLngLat:()=>Mt});Ct(),Wr(),Z(),yn(),Ct(),yn(),Z(),Wr(),ui();var la=globalThis;return la.THREE||(la.THREE=t),la.S3M=ca,e.AttributeQuery=Ot,e.BinaryReader=g,e.DEFAULT_FLOOR_HEIGHT=St,e.DEFAULT_STYLE=Mr,e.DatasetManager=Ui,e.EARTH_RADIUS=kt,e.FeatureStyleManager=Ji,e.GroundManager=Yi,e.Picker=Pi,e.PixelFormat=X,e.S3MFormatError=_t,e.S3MTileset=bi,e.S3MViewer=$i,e.default=$i,e.S3M_VERSION=Ve,e.SELECT_MODE=$,e.SELECT_MODE_LABELS=jr,e.STYLE=Q,e.STYLE_LABELS=Ar,e.TextureCompress=U,e.VertexTag=R,e.VertexTagV3=He,e.buildAttributes=xt,e.buildFeatureEdgeSegments=Hi,e.buildOrthoMVP=sa,e.buildThickLineGeometry=zi,e.buildTileObjects=si,e.createLineSharedUniforms=Fi,e.createOutlineMaterial=kr,e.createSharedUniforms=Dr,e.createStyledMaterial=Or,e.createTexture=Tr,e.createThickLineMaterial=Ri,e.dxtPixelFormatOf=gn,e.extractFovRadians=oa,e.extractNearFar=aa,e.extractProjectionMatrix=ia,e.isS3M1Buffer=je,e.lngLatFromMercator=jt,e.lngLatFromWorld=Nt,e.measureSegments=bt,e.mercatorFromLngLat=At,e.parseS3M1=Be,e.parseS3MB=vt,e.resolveFeature=V,e.resolveTextureKind=hn,e.setMaxAnisotropy=vr,e.worldFromLngLat=Mt,e})({},THREE);